package timere

  1. Overview
  2. Docs
OCaml date time reasoning library

Install

Dune Dependency

Authors

Maintainers

Sources

v0.7.0.tar.gz
sha256=1fee8b8201899be96982918c17a4fa2952b18343f91d97b90743a38e4eb8b792

doc/timere/Timere/index.html

Module TimereSource

Date time reasoning

Timere provides a set of highly expressive APIs to describe scheduling constraints, and an efficient resolution algorithm

Sourcetype timestamp = Timedesc.timestamp
Sourcetype t

This is the core type of Timere that represents sets of points in time, more precisely, unions of time intervals. For example, "all Mondays of year 2000 at the UTC timezone".

We call Timere.t values "timere object"; internally they are rich expressions representing the time computations (union, intersection, etc.), lazily forced into more low-level descriptions (lazy sequences of intervals).

Sourcetype inc_exc = [
  1. | `Inc
  2. | `Exc
]
Sourcetype 'a range = [
  1. | `Range_inc of 'a * 'a
  2. | `Range_exc of 'a * 'a
]

Basic constructors

Sourceval now : unit -> t

Time right now

Sourceval always : t

Entire interval that Timere can handle, i.e. [0000 Jan 01 14:00:00 +00:00:00, 9999 Dec 31 09:59:58 +00:00:00)

Sourceval empty : t

Empty interval

Sourceval before : Timedesc.t -> t
Sourceval since : Timedesc.t -> t
Sourceval after : Timedesc.t -> t
Sourceval date_time : Timedesc.t -> t
Sourceval date_times : Timedesc.t list -> t
Sourceval date_time_seq : Timedesc.t Seq.t -> t
Sourceval sorted_date_times : Timedesc.t list -> t
Sourceval sorted_date_time_seq : Timedesc.t Seq.t -> t
Sourceexception Invalid_timestamp
Sourceval timestamp : Timedesc.timestamp -> t
Sourceval before_timestamp : Timedesc.timestamp -> t
Sourceval since_timestamp : Timedesc.timestamp -> t
Sourceval after_timestamp : Timedesc.timestamp -> t
Sourceval timestamps : ?skip_invalid:bool -> Timedesc.timestamp list -> t

timestamps l

skip_invalid defaults to false

Sourceval timestamp_seq : ?skip_invalid:bool -> timestamp Seq.t -> t

timestamps s

skip_invalid defaults to false

Sourceval sorted_timestamps : ?skip_invalid:bool -> timestamp list -> t
Sourceval sorted_timestamp_seq : ?skip_invalid:bool -> timestamp Seq.t -> t

Pattern matching constructors

Sourceval pattern : ?years:int list -> ?year_ranges:int range list -> ?months:int list -> ?month_ranges:int range list -> ?days:int list -> ?day_ranges:int range list -> ?weekdays:Timedesc.weekday list -> ?weekday_ranges:Timedesc.weekday range list -> ?hours:int list -> ?hour_ranges:int range list -> ?minutes:int list -> ?minute_ranges:int range list -> ?seconds:int list -> ?second_ranges:int range list -> ?ns:int list -> ?ns_ranges:int range list -> unit -> t

Pattern matches over date times.

A pattern p matches date time dt if

(year of dt is in p.years or p.year_ranges)
&& (month of dt is in p.months or p.month_ranges)
&& (month day of dt is in p.month_days or p.month_day_ranges)
&& (weekday of dt is in p.weekdays or p.weekday_ranges)
&& (hour of dt is in p.hours or p.hour_ranges)
&& (minute of dt is in p.minutes or p.minute_ranges)
&& (second of dt is in p.seconds or p.second_ranges)
&& (ns of dt is in p.ns or p.ns_ranges)

Empty pattern levels are treated as wildcard, e.g. if p.years and p.year_ranges are both empty, then (dt.year is in p.years or p.year_ranges) is true.

Sourceval years : int list -> t

years l is a shorthand for pattern ~years:l ()

Sourceval year_ranges : int range list -> t

year_ranges l is a shorthand for pattern ~year_ranges:l ()

Sourceval months : int list -> t

months l is a shorthand for pattern ~months:l ()

Sourceval month_ranges : int range list -> t

month_ranges l is a shorthand for pattern ~month_ranges:l ()

Sourceval days : int list -> t

days l is a shorthand for pattern ~month_days:l ()

Sourceval day_ranges : int range list -> t

day_ranges l is a shorthand for pattern ~month_day_ranges:l ()

Sourceval weekdays : Timedesc.weekday list -> t

weekdays l is a shorthand for pattern ~weekdays:l ()

Sourceval weekday_ranges : Timedesc.weekday range list -> t

weekday_ranges l is a shorthand for pattern ~weekday_ranges:l ()

Sourceval hours : int list -> t

hours l is a shorthand for pattern ~hours:l ()

Sourceval hour_ranges : int range list -> t

hour_ranges l is a shorthand for pattern ~hour_ranges:l ()

Sourceval minutes : int list -> t

minutes l is a shorthand for pattern ~minutes:l ()

Sourceval minute_ranges : int range list -> t

minute_ranges l is a shorthand for pattern ~minute_ranges:l ()

Sourceval seconds : int list -> t

seconds l is a shorthand for pattern ~seconds:l ()

Sourceval second_ranges : int range list -> t

second_ranges l is a shorthand for pattern ~second_ranges:l ()

Sourceval ns : int list -> t

ns l is a shorthand for pattern ~ns:l ()

Sourceval ns_ranges : int range list -> t

ns_ranges l is a shorthand for pattern ~ns_ranges:l ()

Sourceval nth_weekday_of_month : int -> Timedesc.weekday -> t

nth_weekday_of_month n wday picks the nth weekday of all months, where 1 <= n && n <= 5

Intervals

Explicit intervals

Sourceexception Interval_is_invalid
Sourceexception Intervals_are_not_sorted
Sourceval intervals : ?skip_invalid:bool -> Timedesc.Interval.t list -> t

intervals l

skip_invalid defaults to false

Sourceval interval_seq : ?skip_invalid:bool -> Timedesc.Interval.t Seq.t -> t

interval_seq s

skip_invalid defaults to false

Sourceval sorted_intervals : ?skip_invalid:bool -> Timedesc.Interval.t list -> t

sorted_intervals l

skip_invalid defaults to false

Sourceval sorted_interval_seq : ?skip_invalid:bool -> Timedesc.Interval.t Seq.t -> t

sorted_interval_seq s

skip_invalid defaults to false

Pattern matching intervals

Pattern matching intervals are designed to handle intervals where start and end points follow some pattern, but cannot be captured by pattern efficiently, e.g. you cannot represent "5:30pm to 6:11pm" via a single pattern

Sourcemodule Points : sig ... end
Sourcetype points = Points.t
Sourceval pattern_intervals : ?inc_exc:inc_exc -> ?bound:Timedesc.Span.t -> [ `Whole | `Fst | `Snd ] -> points -> points -> t

pattern_intervals mode p1 p2 for each point x matched by p1, then for the earliest point y matched by p2 such that x < y && y - x <= bound

  • if mode = `Whole && inc_exc = `Exc, yields (x, y)
  • if mode = `Whole && inc_exc = `Inc, yields (x, y + 1)
  • if mode = `Fst, yields (x, x + 1)
  • if mode = `Snd, yields (y, y + 1)

above implies inc_exc does not impact operations if mode is `Fst or `Snd.

inc_exc defaults to `Exc.

Default bound is inferred as follows, and should suffice in yielding desired results for most cases:

if p2 is YMDHMS then (year of p2 - year of p1 + 1) * 366 days
if p2 is  MDHMS then 366 days
if p2 is   DHMS then
  if day of p1 < day of p2 then 31 - day of p2 days
  else                                      31 days
if p2 is    HMS then  30 hours
if p2 is     MS then   1 hours
if p2 is      S then   1 minutes

where we say p2 is YMDHMS if p2 = Points.make_exn ~year:_ ... () and so on.

Examples:

  pattern_intervals `Whole
    (Points.make ~hour:13 ~minute:0 ~second:0 ()) (* p1 *)
    (Points.make ~hour:14 ~minute:0 ~second:0 ()) (* p2 *)

yields all the "1pm to 2pm" intervals, since at each "1pm" mark represented by p1, searching forward up to 24 hour period, we can find a "2pm" mark in p2

  pattern_intervals `Whole
    (Points.make ~month:2 ~day:10 ~hour:13 ~minute:0 ~second:0 ()) (* p1 *)
    (Points.make                  ~hour:14 ~minute:0 ~second:0 ()) (* p2 *)

yields all the "Feb 10th 1pm to 2pm" intervals (or specifically "Feb 10th 1pm to Feb 10th 2pm")

  pattern_intervals `Whole
    (Points.make ~month:`Feb ~day:10 ~hour:23 ~minute:0 ~second:0 ()) (* p1 *)
    (Points.make                     ~hour:3  ~minute:0 ~second:0 ()) (* p2 *)

yields all the "Feb 10th 11pm to 3am" intervals (or specifically "Feb 10th 11pm to Feb 11th 3am")

  • raises Invalid_argument

    if precision (number of date time arguments passed to make_points during construction) of p1 < precision of p2

For example, Points.make_exn ~hour:3 ~minute:0 ~second:0 () has a lower precision than make_points_exn ~day:10 ~hour:12 ~minute:30 ~second:0 ().

Hour minute second intervals

Convenience wrappers around points and pattern_intervals

Sourceval hms_intervals : ?inc_exc:inc_exc -> Timedesc.Time.t -> Timedesc.Time.t -> t

Same as pattern_intervals ... with bound fixed to Span.For_human.make ~days:1 ()

inc_exc defaults to `Exc

Algebraic operations

Sourceval inter : t list -> t

Intersection of list of timeres.

inter [] is equivalent to always.

Sourceval union : t list -> t

Union of list of timeres.

union [] is equivalent to empty.

Sourceval not : t -> t

Negation of timere.

not t is equivalent to all the intervals not included in t.

Sourceval shift : Timedesc.Span.t -> t -> t
Sourceval lengthen : Timedesc.Span.t -> t -> t
Sourceval with_tz : Timedesc.Time_zone.t -> t -> t

with_tz tz t changes the time zone to evaluate t in to tz

Chunking

Sourcetype chunked
Sourcetype chunking = [
  1. | `Disjoint_intervals
  2. | `By_duration of Timedesc.Span.t
  3. | `By_duration_drop_partial of Timedesc.Span.t
  4. | `At_year_boundary
  5. | `At_month_boundary
]

Ways to chunk/slice time intervals for the selector.

  • `Disjoint_intervals gives a sequence of disjoint intervals to the selector, specifically they are in ascending order, non-overlapping, non-connecting, and unique
  • `By_duration slices in the fixed size specified by the duration. Partial chunks (chunks less than the fixed size) are preserved.
  • `By_duration_drop_partial slices in the fixed size specified by the duration. Partial chunks (chunks less than the fixed size) are discarded.
  • `At_year_boundary slices at the year boundary (e.g. 2021 Jan 1st 00:00:00)
  • `At_month_boundary slices at the month boundary (e.g. Aug 1st 00:00:00)
Sourceval chunk : chunking -> (chunked -> chunked) -> t -> t

chunk chunking f t applies chunked selector f on t.

  • raises Invalid_argument

    if duration is negative in `By_duration or `By_duration_drop_partial

Chunked selectors

You may find (%>) useful for chaining selectors together, e.g. drop 5 %> take 2

Sourceval chunk_again : chunking -> chunked -> chunked

chunk_again chunking f applies chunked selector f as a selector

Sourceval first : chunked -> chunked

Takes only first chunk

Sourceval take : int -> chunked -> chunked

Takes n chunks

Sourceval take_nth : int -> chunked -> chunked

Take every nth chunk, specifically 0th, nth, 2nth, 3nth, ...

Sourceval drop : int -> chunked -> chunked

Discard n chunks

Infix operators

Sourceval (&&&) : t -> t -> t
Sourceval (|||) : t -> t -> t
Sourceval (%>) : ('a -> 'b) -> ('b -> 'c) -> 'a -> 'c

Composition, mainly for chunked selectors

f1 %> f2 is equivalent to fun x -> x |> f1 |> f2.

Resolution

Sourceval resolve : ?search_using_tz:Timedesc.Time_zone.t -> t -> (Timedesc.Interval.t Seq.t, string) result

Resolves a Timere object into a concrete interval sequence. * * Intervals are left-closed, right-open, i.e. each interval is * of the form [x, y), which includes x and excludes y. *

Sourceexception Resolution_error of string
Sourceval resolve_exn : ?search_using_tz:Timedesc.Time_zone.t -> t -> Timedesc.Interval.t Seq.t

S-expressions

These functions are suitable for debugging, serializing and deserializing timeres.

The sexp is a precise description of the steps used to construct a timere. As such deserialization is accurate and goes through the exact same construction steps (including validation) as one would using the construction API directly.

Sourceval to_sexp : t -> CCSexp.t
Sourceval to_sexp_string : t -> string
Sourceval of_sexp : CCSexp.t -> (t, string) result
Sourceval of_sexp_string : string -> (t, string) result
Sourceval pp_sexp : Format.formatter -> t -> unit

Misc

Sourcemodule Utils : sig ... end
OCaml

Innovation. Community. Security.