Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Evaluating: the periods library #37

Open
1 task
vindarel opened this issue Nov 9, 2023 · 1 comment
Open
1 task

Evaluating: the periods library #37

vindarel opened this issue Nov 9, 2023 · 1 comment

Comments

@vindarel
Copy link
Contributor

vindarel commented Nov 9, 2023

bo-tato:

The periods library you might want to consider inclusion in CIEL, it has convenient macros like do-times there for looping over a range of dates.
I've written a couple standalone ciel scripts with it. Like this for catching up on reading the #commonlisp irc channel.

periods might bring some more high-level functions and macros, complementing local-time.

goal: bring the good in a common package, for instance import & reexport symbols into a new ciel/time package.


do-times

not exported

Signature
((var start duration end &optional (result)) &body body)

A 'do' style version of the functional MAP-TIMES macro.

The disadvantage to DO-TIMES is that there is no way to ask for a reversed
time sequence, or specify an inclusive endpoint.

example:

do-times (day (-> +last-date-file+ str:from-file str:trim parse-timestring)
              (duration :days 1)
              (today))
  …)

also do-time-period (un-exported), do-over-time (exported but doesn't exist?), map-over-time (doesn't exist ?)

subtract-time, add-time

equivalent to local-time:timestamp- ?

(periods:subtract-time (local-time:now) (periods:duration :days 2))

==

(local-time:timestamp- (local-time:now) 2 :day)

not exported: add-[hours, days, years, months, minutes, seconds, microseconds, milliseconds]

(periods::add-hours (periods:duration :days 1) 3)
#S(PERIODS:DURATION
   :YEARS 0
   :MONTHS 0
   :DAYS 1
   :HOURS 3
   :MINUTES 0
   :SECONDS 0
   :MILLISECONDS 0
   :MICROSECONDS 0
   :NANOSECONDS 0)

duration

(periods:duration :days 3)
#S(PERIODS:DURATION
   :YEARS 0
   :MONTHS 0
   :DAYS 3
   :HOURS 0
   :MINUTES 0
   :SECONDS 0
   :MILLISECONDS 0
   :MICROSECONDS 0
   :NANOSECONDS 0)

time-range

(periods:time-range :begin (local-time:now) :end (local-time:now))
#S(PERIODS:TIME-RANGE
   :FIXED-BEGIN NIL
   :BEGIN @2023-11-09T14:21:56.804175+01:00
   :BEGIN-INCLUSIVE-P T
   :FIXED-END NIL
   :END @2023-11-09T14:21:56.804177+01:00
   :END-INCLUSIVE-P NIL
   :DURATION NIL
   :ANCHOR NIL)

fixed-time

Signature
(&rest args)

Return a fixed point in time relative to the time of the call.  ARGS is a
property list giving a specific precision for the return value.

  If the keyword argument :NOW is given, all else is ignored; this is
equivalent to calling LOCAL-TIME:NOW.

  Otherwise, any keyword arguments given override their corresponding elements
in the current time.  Further, any elements smaller in resolution than the
finest specified element are reduced to 0 or 1, according to their position.

  For example, assuming the current time is "@2007-11-17T23:02:00.000",
compare these outputs:

  (fixed-time :month 4) => @2007-04-01T00:00:00.000
  (fixed-time :day 10)  => @2007-11-10T00:00:00.000
  (fixed-time :hour 15) => @2007-11-17T15:00:00.000

This behavior makes it very easy to return a fixed time for "april of this
year", etc.  If you wish to determine the date of the previous April, while
preserving the current day of the month, hour of the day, etc., then see the
function PREVIOUS-TIME.

parse-time-range, parse-time-period

Parse a human-readable string and give a time-range, or parse a date with a time-range of 1 day.

(periods:parse-time-range "2 months")

#S(PERIODS:TIME-RANGE
   :FIXED-BEGIN NIL
   :BEGIN @2023-11-09T00:00:00.000000+01:00
   :BEGIN-INCLUSIVE-P T
   :FIXED-END NIL
   :END NIL
   :END-INCLUSIVE-P NIL
   :DURATION #S(PERIODS:DURATION
                :YEARS 0
                :MONTHS 2
                :DAYS 0
                :HOURS 0
                :MINUTES 0
                :SECONDS 0
                :MILLISECONDS 0
                :MICROSECONDS 0
                :NANOSECONDS 0)
   :ANCHOR NIL)

Possible strings:

(defun time-parser-tests ()
  (dolist
      (expr '("this year"
	      "next year"
	      "last year"
	      "the year before last"
	      "jan 8"
	      "jan 2008"
	      "2008/01/01"
	      "2 months"
	      "2 months since jan 8"
	      "january of last year"
	      "three months ago"
	      "1 months, 2 days ago"
	      "every friday starting tomorrow"
	      "every day this week"
	      "every day of this week"
	      "every ten days"
	      "the day after tuesday"
	      "monthly"
	      "monthly from the beginning of this year"
	      "monthly from now until the end of the year"
	      "the last week of last year"
	      ;; "every weekend this year"
	      ))
    (format t "EXPR <  ~A~%     >= ~S~%" expr
	    (p/time (make-string-input-stream expr)))))
  • is this correct?
(periods:parse-time-range "every day this week")
@2023-11-09T00:00:00.000000+01:00
;; no time-range structure?

Convenience functions

current-year

leapp

local-time has it in a flet, my PR to bring it to an accessible function got rejected: dlowe-net/local-time#106 (add weaks-in-year, leap-year-p, tomorrow, yesterday)

falls-on-weekend-p

sleep-until


it doesn't have tests? (I know it's CL, but still)

@vindarel
Copy link
Contributor Author

vindarel commented Nov 11, 2023

Added the current periods doc online, with syntax highlighting: https://lisp-maintainers.github.io/periods/

It should be extended now (and probably by using a real documentation builder).

While working on the doc, ciel -s simplehttpserver was helpful ;)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant