Module Expr.Temporal
Temporal values.
A datetime column holds instants or wall clocks (Instants and wall clocks), and a zone is an argument only of the conversions wall and localize. field, and floor or offset by a calendar step, read a wall clock as it is; on an instant they are a problem that names wall.
A zone's clock can repeat or skip a reading. The readings of a fold occur twice, on the offset before the change and then on the one after, and those of a gap never occur. A policy resolves such a reading:
`Earlieris the earlier instant, a fold's first occurrence or a gap's reading moved back by the gap's length;`Lateris the later instant, a fold's second occurrence or a gap's reading moved forward by the gap's length;`Nullis null, and`Faila data error naming the reading.
add a d is a advanced by d, of a's type: a datetime, a duration or a clock, d being a duration of a's unit or a coarser one, or a date, d being whole days. A literal d that is not whole days is a problem, and another a data error. A result out of range, or a clock outside its day, is a data error.
diff a b is the span from b to a: a duration of their common unit for datetimes, durations and clocks, which meet as Type.common says, and duration[s] for dates.
div a b is how many of b fit in a, as float64, for example div (diff ts signup) (span (Time.Span.days 1)). Both operands are durations, each converted to float64 and the coarser scaled to the finer's unit, so a quotient of values that float64 holds exactly rounds once. A zero b gives an infinity or NaN as IEEE 754 divides them. A clock is a problem; cast it to a duration first. It is null where an operand is.
The type for calendar fields:
`Year, astronomical: year0is 1 BC;`Month,1to12, and`Day, the day of the month,1to31;`Hour,0to23,`Minuteand`Second,0to59;`Nanosecond, the nanosecond within the second;`Weekday, the ISO day of the week,1for Monday to7;`Yearday, the day of the year,1to366.
field f a is the field f of a, as int64: field `Year orderdate. a is a date, a clock or a wall clock. A date has no time-of-day field and a clock no calendar field: asking for one is a problem.
floor step a is the first value of the period of step that holds a, a date or a datetime. Periods are counted from 1970-01-01 00:00, and weeks from Monday 1970-01-05. A date floors by calendar steps only, a wall clock by either, and an instant by exact steps; an exact step is whole ticks of the datetime's unit. Its type is a's.
Raises Invalid_argument if step is not positive.
offset step a is a, a date or a datetime, moved by step: an exact step adds ticks, and a calendar step moves the calendar date of a wall clock; a day of the month past the month's end becomes its last day. A date moves by calendar steps only, a wall clock by either, and an instant by exact steps of whole ticks of its unit. Its type is a's.
wall z a is the reading of z's wall clock at the instant a, in a's unit: a plus the offset of z at a (Tz.offset_s). A result out of range is a data error.
The type for what localize and localize_ordered do with a reading that a zone repeats or skips, as the section's preamble describes.
val localize :
Tz.zone ->
ambiguous:policy ->
gap:policy ->
(Time.wall, 's) t ->
(Time.instant, 's) tlocalize z ~ambiguous ~gap a is the instant at which z's wall clock reads a, in a's unit: a - o for the offset o of Tz.local's Unique o. A reading that z repeats follows ambiguous, and one it skips gap. On a gap, `Later is a - before and `Earlier is a - after in Tz.local's terms. localize z ~ambiguous ~gap (wall z a) is a where z repeats no reading. An instant out of range is a data error.
val localize_ordered :
Tz.zone ->
ambiguous:policy ->
gap:policy ->
(Time.wall, row) t ->
(Time.instant, row) tlocalize_ordered z ~ambiguous ~gap a is localize where the order of each frame's rows (Frames), which must be time order, decides the pass of a reading that z repeats. The rows of one fold, consecutive apart from nulls, read as the fold's first pass up to the first row strictly below its predecessor, and as the second from it. Two equal rows that are a fold's only rows read one per pass when the row on each side lies the fold's length from them, as a logger of that cadence writes them. Other rows of a fold follow ambiguous. Order finds the pass only at a cadence at or below the fold's length, and at that cadence a duplicate whose other pass is lost reads as the two passes. Nulls and rows moved by gap are not a previous row. An equal instant is allowed. A row not moved by gap whose instant is before the previous row's is a data error, as is an instant out of range.
parse fmt ty a reads the text a in the format fmt as a value of ty, a date, datetime or clock type. fmt holds the directives %Y (the year), %m, %d, %H, %M, %S (two digits each), %f (one to nine digits of a fraction of a second), %z (Z or a ±hh:mm offset) and %%; other characters match themselves. A year is four digits, or a sign and at least four digits, as Time.Date.pp writes it. A field that fmt leaves out is that of 1970-01-01 00:00:00; a date reads the day alone, and a clock the time of day. An instant needs %z in fmt, and a wall clock takes none. Text that does not match, and a value that ty does not hold, are data errors.
Raises Invalid_argument if fmt holds another directive.