/*----------------------------------------------------------------------------
   Copyright 2012-2021, Microsoft Research, Daan Leijen

   Licensed under the Apache License, Version 2.0 ("The Licence"). You may not
   use this file except in compliance with the License. A copy of the License
   can be found in the LICENSE file at the root of this distribution.
----------------------------------------------------------------------------*/

/* Time represents instants as human readable calendar time.

  A `:time` represents an `:instant` in time in a given `:calendar` and `:timezone`
  as a "human" calendar time. Months, days etc. are always 1-based.
*/
module std/time/timestd/time/time

import std/num/float64std/num/float64
import std/num/ddoublestd/num/ddouble
import std/time/timestampstd/time/timestamp
import std/time/durationstd/time/duration
import std/time/instantstd/time/instant
import std/time/utcstd/time/utc
import std/time/datestd/time/date
import std/time/calendarstd/time/calendar
import std/time/chronostd/time/chrono

// Represents an instant in time for a certain calendar and timezone.
abstract struct timestd/time/time/time: V (
  // The year.
  pub  datedate: date    : datestd/time/date/date: V,
  pub  clockclock: clock   : clockstd/time/date/clock: V,
  pub  calendarcalendar: calendar: calendarstd/time/calendar/calendar: V,
  pub  tzdeltatzdelta: duration : durationstd/time/duration/duration: V = zerostd/time/duration/zero: duration,
  pub  tzabbrvtzabbrv: string : stringstd/core/types/string: V   = ""literal: string
count= 0
, pub timezonetimezone: timezone: timezonestd/time/calendar/timezone: V = tz-utcstd/time/calendar/tz-utc: timezone, pub instantinstant: instant : instantstd/time/instant/instant: V // the timescale of the instant is the timescale of the calendar
) // The `:timescale` of the time. pub fun timescalestd/time/time/timescale: (t : time) -> timescale( tt: time : timestd/time/time/time: V )result: -> total timescale : timescalestd/time/instant/timescale: V tt: time.instantstd/time/time/time/instant: (time : time) -> instant.timescalestd/time/instant/instant/timescale: (i : instant) -> timescale // Return the year of a `:time`. pub fun yearstd/time/time/year: (t : time) -> int( tt: time : timestd/time/time/time: V )result: -> total int : intstd/core/types/int: V tt: time.datestd/time/time/time/date: (time : time) -> date.yearstd/time/date/date/year: (date : date) -> int // Return the month of a `:time`. (starting at 1) pub fun monthstd/time/time/month: (t : time) -> int( tt: time : timestd/time/time/time: V )result: -> total int : intstd/core/types/int: V tt: time.datestd/time/time/time/date: (time : time) -> date.monthstd/time/date/date/month: (date : date) -> int // Return the day of the month of a `:time`. (starting at 1) pub fun daystd/time/time/day: (t : time) -> int( tt: time : timestd/time/time/time: V )result: -> total int : intstd/core/types/int: V tt: time.datestd/time/time/time/date: (time : time) -> date.daystd/time/date/date/day: (date : date) -> int // Return the whole hours of a `:time`. pub fun hoursstd/time/time/hours: (t : time) -> int( tt: time : timestd/time/time/time: V )result: -> total int : intstd/core/types/int: V tt: time.clockstd/time/time/time/clock: (time : time) -> clock.hoursstd/time/date/clock/hours: (clock : clock) -> int // Return the whole minutes of a `:time`. pub fun minutesstd/time/time/minutes: (t : time) -> int( tt: time : timestd/time/time/time: V )result: -> total int : intstd/core/types/int: V tt: time.clockstd/time/time/time/clock: (time : time) -> clock.minutesstd/time/date/clock/minutes: (clock : clock) -> int // Return the fractional seconds of a `:time`. pub fun secondsstd/time/time/seconds: (t : time) -> timespan( tt: time : timestd/time/time/time: V )result: -> total timespan : timespanstd/time/timestamp/timespan: V tt: time.clockstd/time/time/time/clock: (time : time) -> clock.secondsstd/time/date/clock/seconds: (clock : clock) -> ddouble // Compare two `:time`s. Compares the actual instants in time // and can thus compare across calendars and timezones.\ // `time(2001,7,2,tz=tz-fixed("GMT+1",duration(3600))) > time(2001,7,1,23,30,0)` &quad; (`False`!) pub fun cmpstd/time/time/cmp: (t1 : time, t2 : time) -> order( t1t1: time : timestd/time/time/time: V, t2t2: time : timestd/time/time/time: V )result: -> total order : orderstd/core/types/order: V cmpstd/time/instant/cmp: (i : instant, j : instant) -> order(t1t1: time.instantstd/time/time/time/instant: (time : time) -> instant,t2t2: time.instantstd/time/time/time/instant: (time : time) -> instant) pub fun (<)std/time/time/(<): (i : time, j : time) -> bool( ii: time : timestd/time/time/time: V, jj: time : timestd/time/time/time: V )result: -> total bool : boolstd/core/types/bool: V { cmpstd/time/time/cmp: (t1 : time, t2 : time) -> order(ii: time,jj: time) ==std/core/order/(==): (x : order, y : order) -> bool Ltstd/core/types/Lt: order } pub fun (<=)std/time/time/(<=): (i : time, j : time) -> bool( ii: time : timestd/time/time/time: V, jj: time : timestd/time/time/time: V )result: -> total bool : boolstd/core/types/bool: V { cmpstd/time/time/cmp: (t1 : time, t2 : time) -> order(ii: time,jj: time) !=std/core/order/(!=): (x : order, y : order) -> bool Gtstd/core/types/Gt: order } pub fun (>)std/time/time/(>): (i : time, j : time) -> bool( ii: time : timestd/time/time/time: V, jj: time : timestd/time/time/time: V )result: -> total bool : boolstd/core/types/bool: V { cmpstd/time/time/cmp: (t1 : time, t2 : time) -> order(ii: time,jj: time) ==std/core/order/(==): (x : order, y : order) -> bool Gtstd/core/types/Gt: order } pub fun (>=)std/time/time/(>=): (i : time, j : time) -> bool( ii: time : timestd/time/time/time: V, jj: time : timestd/time/time/time: V )result: -> total bool : boolstd/core/types/bool: V { cmpstd/time/time/cmp: (t1 : time, t2 : time) -> order(ii: time,jj: time) !=std/core/order/(!=): (x : order, y : order) -> bool Ltstd/core/types/Lt: order } pub fun (==)std/time/time/(==): (i : time, j : time) -> bool( ii: time : timestd/time/time/time: V, jj: time : timestd/time/time/time: V )result: -> total bool : boolstd/core/types/bool: V { cmpstd/time/time/cmp: (t1 : time, t2 : time) -> order(ii: time,jj: time) ==std/core/order/(==): (x : order, y : order) -> bool Eqstd/core/types/Eq: order } pub fun (!=)std/time/time/(!=): (i : time, j : time) -> bool( ii: time : timestd/time/time/time: V, jj: time : timestd/time/time/time: V )result: -> total bool : boolstd/core/types/bool: V { cmpstd/time/time/cmp: (t1 : time, t2 : time) -> order(ii: time,jj: time) !=std/core/order/(!=): (x : order, y : order) -> bool Eqstd/core/types/Eq: order } // The minimum of two times (as by their actual instant in time) pub fun minstd/time/time/min: (i : time, j : time) -> time( ii: time : timestd/time/time/time: V, jj: time : timestd/time/time/time: V )result: -> total time : timestd/time/time/time: V if ii: time <=std/time/time/(<=): (i : time, j : time) -> bool jj: time then ii: time else jj: time // The maximum of two times (as by their actual instant in time) pub fun maxstd/time/time/max: (i : time, j : time) -> time( ii: time : timestd/time/time/time: V, jj: time : timestd/time/time/time: V )result: -> total time : timestd/time/time/time: V if ii: time >=std/time/time/(>=): (i : time, j : time) -> bool jj: time then ii: time else jj: time // Round a time to a specified second precision. pub fun round-to-precstd/time/time/round-to-prec: (t : time, prec : int) -> time( tt: time : timestd/time/time/time: V, precprec: int : intstd/core/types/int: V )result: -> total time : timestd/time/time/time: V if precprec: int.is-negstd/core/int/is-neg: (i : int) -> bool then returnreturn: time tt: time val cc: clock = tt: time.clockstd/time/time/time/clock: (time : time) -> clock val secssecs: ddouble = cc: clock.secondsstd/time/date/clock/seconds: (clock : clock) -> ddouble.round-to-precstd/num/ddouble/round-to-prec: (x : ddouble, prec : int) -> ddouble(precprec: int) val riri: instant = tt: time.instantstd/time/time/time/instant: (time : time) -> instant.round-to-precstd/time/instant/round-to-prec: (i : instant, prec : int) -> instant(precprec: int) //trace("time.round-to-prec: " + t.show-raw + ", t.seconds: " + t.seconds.show + ", secs: " + secs.show) if secssecs: ddouble.truncatestd/num/ddouble/truncate: (x : ddouble) -> ddouble ==std/num/ddouble/(==): (x : ddouble, y : ddouble) -> bool tt: time.secondsstd/time/time/seconds: (t : time) -> timespan.truncatestd/num/ddouble/truncate: (x : ddouble) -> ddouble then // whole seconds stay the same, just update with the rounded seconds and instant tt: time(clock=cc: clock(seconds=secssecs: ddouble), instant = riri: instant) else // otherwise recalculate the time from the rounded instant riri: instant.timestd/time/time/instant/time: (i : instant, tz : ? timezone, cal : ? calendar, ts : ? timescale) -> time(tt: time.timezonestd/time/time/time/timezone: (time : time) -> timezone,tt: time.calendarstd/time/time/time/calendar: (time : time) -> calendar) // Show a `:time` in [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) format. pub fun showstd/time/time/show: (t : time, prec : ? int) -> string(tt: time : timestd/time/time/time: V, precprec: ? int : intstd/core/types/int: V = 9literal: int
dec = 9
hex8 = 0x09
bit8 = 0b00001001
)result: -> total string : stringstd/core/types/string: V val tptp: time = tt: time.round-to-precstd/time/time/round-to-prec: (t : time, prec : int) -> time(precprec: int) tptp: time.show-rawstd/time/time/show-raw: (tp : time, prec : ? int) -> string(precprec: int
) pub fun show-rawstd/time/time/show-raw: (tp : time, prec : ? int) -> string( tptp: time : timestd/time/time/time: V, precprec: ? int : intstd/core/types/int: V = 9literal: int
dec = 9
hex8 = 0x09
bit8 = 0b00001001
)result: -> total string : stringstd/core/types/string: V val tsnametsname: string = tptp: time.timescalestd/time/time/timescale: (t : time) -> timescale.namestd/time/instant/timescale/name: (timescale : timescale) -> string tptp: time.datestd/time/time/time/date: (time : time) -> date.showstd/time/date/show: (d : date, month-prefix : ? string) -> string(tptp: time.calendarstd/time/time/time/calendar: (time : time) -> calendar.month-prefixstd/time/calendar/calendar/month-prefix: (calendar : calendar) -> string) ++std/core/types/(++): (x : string, y : string) -> string "T"literal: string
count= 1
++std/core/types/(++): (x : string, y : string) -> string tptp: time.clockstd/time/time/time/clock: (time : time) -> clock.showstd/time/date/clock/show: (c : clock, prec : ? int) -> string(precprec: int) ++std/core/types/(++): (x : string, y : string) -> string show-tzdeltastd/time/time/show-tzdelta: (delta : duration, utc : ? string, hmsep : ? string, hrwidth : ? int) -> string(tptp: time.tzdeltastd/time/time/time/tzdelta: (time : time) -> duration ) ++std/core/types/(++): (x : string, y : string) -> string (if tptp: time.tzabbrvstd/time/time/time/tzabbrv: (time : time) -> string.is-numericstd/time/time/is-numeric: (abbrv : string) -> bool then ""literal: string
count= 0
else " ("literal: string
count= 2
++std/core/types/(++): (x : string, y : string) -> string tptp: time.tzabbrvstd/time/time/time/tzabbrv: (time : time) -> string ++std/core/types/(++): (x : string, y : string) -> string ")"literal: string
count= 1
) ++std/core/types/(++): (x : string, y : string) -> string (if tptp: time.calendarstd/time/time/time/calendar: (time : time) -> calendar.namestd/time/calendar/calendar/name: (calendar : calendar) -> string.is-emptystd/core/string/is-empty: (s : string) -> bool ||std/core/types/(||): (x : bool, y : bool) -> bool tptp: time.calendarstd/time/time/time/calendar: (time : time) -> calendar.month-prefixstd/time/calendar/calendar/month-prefix: (calendar : calendar) -> string.is-notemptystd/core/string/is-notempty: (s : string) -> bool then ""literal: string
count= 0
else " "literal: string
count= 1
++std/core/types/(++): (x : string, y : string) -> string tptp: time.calendarstd/time/time/time/calendar: (time : time) -> calendar.namestd/time/calendar/calendar/name: (calendar : calendar) -> string) ++std/core/types/(++): (x : string, y : string) -> string (if tsnametsname: string.is-emptystd/core/string/is-empty: (s : string) -> bool ||std/core/types/(||): (x : bool, y : bool) -> bool tsnametsname: string ==std/core/string/(==): (string, string) -> bool "UTC"literal: string
count= 3
then ""literal: string
count= 0
else " "literal: string
count= 1
++std/core/types/(++): (x : string, y : string) -> string tsnametsname: string
) fun is-numericstd/time/time/is-numeric: (abbrv : string) -> bool( abbrvabbrv: string : stringstd/core/types/string: V )result: -> total bool : boolstd/core/types/bool: V (abbrvabbrv: string.is-emptystd/core/string/is-empty: (s : string) -> bool ||std/core/types/(||): (x : bool, y : bool) -> bool abbrvabbrv: string.headstd/core/sslice/head: (s : string) -> string==std/core/string/(==): (string, string) -> bool"+"literal: string
count= 1
||std/core/types/(||): (x : bool, y : bool) -> bool abbrvabbrv: string.headstd/core/sslice/head: (s : string) -> string==std/core/string/(==): (string, string) -> bool"-"literal: string
count= 1
) fun show-datestd/time/time/show-date: (d : date) -> string(dd: date : datestd/time/date/date: V)result: -> total string : stringstd/core/types/string: V dd: date.showstd/time/date/show: (d : date, month-prefix : ? string) -> string // Show a time zone delta. // Optional `utc` for displaying a zero timezone delta (=`"Z"`). // Optional `hmsep` for the hour-minute separator (=`":"`). // Optional `hrwidth` to give the minimal width of the hour field (=`2`). pub fun show-tzdeltastd/time/time/show-tzdelta: (delta : duration, utc : ? string, hmsep : ? string, hrwidth : ? int) -> string(deltadelta: duration : durationstd/time/duration/duration: V, utcutc: ? string : stringstd/core/types/string: V = "Z"literal: string
count= 1
, hmsephmsep: ? string : stringstd/core/types/string: V = ":"literal: string
count= 1
, hrwidthhrwidth: ? int : intstd/core/types/int: V = 2literal: int
dec = 2
hex8 = 0x02
bit8 = 0b00000010
)result: -> total string : stringstd/core/types/string: V val dtdt: int = deltadelta: duration.secondsstd/time/duration/seconds: (d : duration) -> timespan.intstd/num/ddouble/int: (x : ddouble, nonfin : ? int) -> int if dtdt: int.is-zerostd/core/int/is-zero: (x : int) -> bool returnreturn: string utcutc: string val (std/core/types/Tuple2: forall<a,b> (fst : a, snd : b) -> (a, b)minsmins: int,secssecs: int)std/core/types/Tuple2: forall<a,b> (fst : a, snd : b) -> (a, b) = divmodstd/core/int/divmod: (x : int, y : int) -> (int, int)(dtdt: int.absstd/core/int/abs: (i : int) -> int,60literal: int
dec = 60
hex8 = 0x3C
bit8 = 0b00111100
) val tztz: string = (if dtdt: int.is-negstd/core/int/is-neg: (i : int) -> bool then "-"literal: string
count= 1
else "+"literal: string
count= 1
) ++std/core/types/(++): (x : string, y : string) -> string (minsmins: int/std/core/int/(/): (x : int, y : int) -> int60literal: int
dec = 60
hex8 = 0x3C
bit8 = 0b00111100
).show0std/time/time/show0: (i : int, width : ? int) -> string(hrwidthhrwidth: int) ++std/core/types/(++): (x : string, y : string) -> string hmsephmsep: string ++std/core/types/(++): (x : string, y : string) -> string (minsmins: int%std/core/int/(%): (int, int) -> int60literal: int
dec = 60
hex8 = 0x3C
bit8 = 0b00111100
).show0std/time/time/show0: (i : int, width : ? int) -> string val tzstzs: string = if secssecs: int.is-zerostd/core/int/is-zero: (x : int) -> bool then ""literal: string
count= 0
else ":"literal: string
count= 1
++std/core/types/(++): (x : string, y : string) -> string secssecs: int.show0std/time/time/show0: (i : int, width : ? int) -> string tztz: string ++std/core/types/(++): (x : string, y : string) -> string tzstzs: string
// pad with zeros fun show0std/time/time/show0: (i : int, width : ? int) -> string( ii: int : intstd/core/types/int: V, widthwidth: ? int : intstd/core/types/int: V = 2literal: int
dec = 2
hex8 = 0x02
bit8 = 0b00000010
)result: -> total string : stringstd/core/types/string: V ii: int.showstd/core/int/show: (i : int) -> string.pad-leftstd/core/string/pad-left: (s : string, width : int, fill : ? char) -> string(widthwidth: int,'0'literal: char
unicode= u0030
) /*---------------------------------------------------------------------------- Convenience functions over time ----------------------------------------------------------------------------*/ // Convert an `:instant` to a `:time` value in a given timezone `tz` (=`tz-utc` by default) // and calendar (=`cal-iso` by default). pub fun instant/timestd/time/time/instant/time: (i : instant, tz : ? timezone, cal : ? calendar, ts : ? timescale) -> time( ii: instant : instantstd/time/instant/instant: V, tztz: ? timezone : timezonestd/time/calendar/timezone: V = tz-utcstd/time/calendar/tz-utc: timezone, calcal: ? calendar : calendarstd/time/calendar/calendar: V = cal-isostd/time/calendar/cal-iso: calendar, tsts: ? timescale : timescalestd/time/instant/timescale: V = ii: instant.timescalestd/time/instant/instant/timescale: (i : instant) -> timescale )result: -> total time : timestd/time/time/time: V val jj: instant = ii: instant.use-timescalestd/time/instant/use-timescale: (i : instant, tscale : timescale) -> instant(tsts: timescale) val (std/core/types/Tuple4: forall<a,b,c,d> (fst : a, snd : b, thd : c, field4 : d) -> (a, b, c, d)dd: date,cc: clock,tzdeltatzdelta: duration,tzabbrvtzabbrv: string)std/core/types/Tuple4: forall<a,b,c,d> (fst : a, snd : b, thd : c, field4 : d) -> (a, b, c, d) = instant-dcstd/time/calendar/instant-dc: (i : instant, tz : ? timezone, cal : ? calendar) -> (date, clock, duration, string)(jj: instant,tztz: timezone,calcal: calendar) Timestd/time/time/Time: (date : date, clock : clock, calendar : calendar, tzdelta : ? duration, tzabbrv : ? string, timezone : ? timezone, instant : instant) -> time(dd: date,cc: clock,calcal: calendar,tzdeltatzdelta: duration,tzabbrvtzabbrv: string,tztz: timezone,jj: instant) // Convert a `:time` `t` to a new `:time` value in a potentially different // timezone `tz` (=`t.timezone` by default) and calendar (=`t.calendar` by default). pub fun time/timestd/time/time/time/time: (t : time, tz : ? timezone, cal : ? calendar, ts : ? timescale) -> time( tt: time : timestd/time/time/time: V, tztz: ? timezone : timezonestd/time/calendar/timezone: V = tt: time.timezonestd/time/time/time/timezone: (time : time) -> timezone, calcal: ? calendar : calendarstd/time/calendar/calendar: V = tt: time.calendarstd/time/time/time/calendar: (time : time) -> calendar, tsts: ? timescale : timescalestd/time/instant/timescale: V = tt: time.instantstd/time/time/time/instant: (time : time) -> instant.timescalestd/time/instant/instant/timescale: (i : instant) -> timescale )result: -> total time : timestd/time/time/time: V timestd/time/time/instant/time: (i : instant, tz : ? timezone, cal : ? calendar, ts : ? timescale) -> time(tt: time.instantstd/time/time/time/instant: (time : time) -> instant,tztz: timezone,calcal: calendar,tsts: timescale) pub fun timescale/timestd/time/time/timescale/time: (ts : timescale, year : int, month : ? int, day : ? int, hours : ? int, minutes : ? int, secs : ? int, frac : ? float64, tz : ? timezone, cal : ? calendar) -> time( tsts: timescale : timescalestd/time/instant/timescale: V, yearyear: int : intstd/core/types/int: V, monthmonth: ? int : intstd/core/types/int: V = 1literal: int
dec = 1
hex8 = 0x01
bit8 = 0b00000001
, dayday: ? int : intstd/core/types/int: V = 1literal: int
dec = 1
hex8 = 0x01
bit8 = 0b00000001
, hourshours: ? int : intstd/core/types/int: V = 0literal: int
dec = 0
hex8 = 0x00
bit8 = 0b00000000
, minutesminutes: ? int : intstd/core/types/int: V = 0literal: int
dec = 0
hex8 = 0x00
bit8 = 0b00000000
, secssecs: ? int : intstd/core/types/int: V = 0literal: int
dec = 0
hex8 = 0x00
bit8 = 0b00000000
, fracfrac: ? float64 : float64std/core/types/float64: V = 0.0literal: float64
hex64= 0x0p+0
, tztz: ? timezone : timezonestd/time/calendar/timezone: V = tz-utcstd/time/calendar/tz-utc: timezone, calcal: ? calendar : calendarstd/time/calendar/calendar: V = cal-isostd/time/calendar/cal-iso: calendar )result: -> total time : timestd/time/time/time: V timestd/time/time/instant/time: (i : instant, tz : ? timezone, cal : ? calendar, ts : ? timescale) -> time(tsts: timescale.instantstd/time/calendar/timescale/instant: (ts : timescale, year : int, month : ? int, day : ? int, hours : ? int, minutes : ? int, seconds : ? int, frac : ? float64, tz : ? timezone, cal : ? calendar) -> instant(yearyear: int,monthmonth: int,dayday: int,hourshours: int,minutesminutes: int,secssecs: int,fracfrac: float64,tztz: timezone,calcal: calendar),tztz: timezone,calcal: calendar,tsts: timescale
) /* Return the `:time` value for a given date and clock in a timezone `tz` (=`tz-utc` by default) interpreted by calendar `cal` (=`cal-iso`). The `month`, `day`, `hour`, `minutes` may be outside their usual ranges and will be normalized during the conversion. For example, January 33 converts to February 2. This makes it very easy to add- or subtract days or months to an existing time. When the `seconds` or fraction of seconds `frac` add up over 60 though, those extra seconds are interpreted as leap seconds. Due to timezone transitions, or leap seconds, it is possible to specify dates that never happened (as it was skipped by a timezone change), or ambigious times (as a timezone springs back). In such cases, the time is always interpreted in the earlier timezone. */ pub fun timestd/time/time/time: (year : int, month : ? int, day : ? int, hours : ? int, minutes : ? int, secs : ? int, frac : ? float64, tz : ? timezone, cal : ? calendar, ts : ? timescale) -> utc time( yearyear: int : intstd/core/types/int: V, monthmonth: ? int : intstd/core/types/int: V = 1literal: int
dec = 1
hex8 = 0x01
bit8 = 0b00000001
, dayday: ? int : intstd/core/types/int: V = 1literal: int
dec = 1
hex8 = 0x01
bit8 = 0b00000001
, hourshours: ? int : intstd/core/types/int: V = 0literal: int
dec = 0
hex8 = 0x00
bit8 = 0b00000000
, minutesminutes: ? int : intstd/core/types/int: V = 0literal: int
dec = 0
hex8 = 0x00
bit8 = 0b00000000
, secssecs: ? int : intstd/core/types/int: V = 0literal: int
dec = 0
hex8 = 0x00
bit8 = 0b00000000
, fracfrac: ? float64 : float64std/core/types/float64: V = 0.0literal: float64
hex64= 0x0p+0
, tztz: ? timezone : timezonestd/time/calendar/timezone: V = tz-utcstd/time/calendar/tz-utc: timezone, calcal: ? calendar : calendarstd/time/calendar/calendar: V = cal-isostd/time/calendar/cal-iso: calendar, tsts: ? timescale : timescalestd/time/instant/timescale: V = utcstd/time/utc/utc: () -> utc timescale() )result: -> utc time : <std/core/types/total: Eutcstd/time/utc/utc: (E, V) -> V> timestd/time/time/time: V tsts: timescale.timestd/time/time/timescale/time: (ts : timescale, year : int, month : ? int, day : ? int, hours : ? int, minutes : ? int, secs : ? int, frac : ? float64, tz : ? timezone, cal : ? calendar) -> utc time(yearyear: int,monthmonth: int,dayday: int,hourshours: int,minutesminutes: int,secssecs: int,fracfrac: float64,tztz: timezone,calcal: calendar
) pub fun time-utcstd/time/time/time-utc: (i : instant, tz : ? timezone, cal : ? calendar) -> utc time( ii: instant : instantstd/time/instant/instant: V, tztz: ? timezone : timezonestd/time/calendar/timezone: V = tz-utcstd/time/calendar/tz-utc: timezone, calcal: ? calendar : calendarstd/time/calendar/calendar: V = cal-isostd/time/calendar/cal-iso: calendar)result: -> utc time : <std/core/types/total: Eutcstd/time/utc/utc: (E, V) -> V> timestd/time/time/time: V timestd/time/time/instant/time: (i : instant, tz : ? timezone, cal : ? calendar, ts : ? timescale) -> utc time(ii: instant,tztz: timezone,calcal: calendar,utcstd/time/utc/utc: () -> utc timescale()) pub fun time-taistd/time/time/time-tai: (i : instant, tz : ? timezone, cal : ? calendar) -> utc time( ii: instant : instantstd/time/instant/instant: V, tztz: ? timezone : timezonestd/time/calendar/timezone: V = tz-utcstd/time/calendar/tz-utc: timezone, calcal: ? calendar : calendarstd/time/calendar/calendar: V = cal-isostd/time/calendar/cal-iso: calendar )result: -> utc time : <std/core/types/total: Eutcstd/time/utc/utc: (E, V) -> V> timestd/time/time/time: V timestd/time/time/instant/time: (i : instant, tz : ? timezone, cal : ? calendar, ts : ? timescale) -> utc time(ii: instant,tztz: timezone,calcal: calendar,ts-taistd/time/instant/ts-tai: timescale) pub fun time-gpsstd/time/time/time-gps: (i : instant, tz : ? timezone, cal : ? calendar) -> utc time( ii: instant : instantstd/time/instant/instant: V, tztz: ? timezone : timezonestd/time/calendar/timezone: V = tz-utcstd/time/calendar/tz-utc: timezone, calcal: ? calendar : calendarstd/time/calendar/calendar: V = cal-isostd/time/calendar/cal-iso: calendar )result: -> utc time : <std/core/types/total: Eutcstd/time/utc/utc: (E, V) -> V> timestd/time/time/time: V timestd/time/time/instant/time: (i : instant, tz : ? timezone, cal : ? calendar, ts : ? timescale) -> utc time(ii: instant,tztz: timezone,calcal: calendar,ts-gpsstd/time/instant/ts-gps: timescale) pub fun time-ttstd/time/time/time-tt: (i : instant, tz : ? timezone, cal : ? calendar) -> utc time( ii: instant : instantstd/time/instant/instant: V, tztz: ? timezone : timezonestd/time/calendar/timezone: V = tz-utcstd/time/calendar/tz-utc: timezone, calcal: ? calendar : calendarstd/time/calendar/calendar: V = cal-isostd/time/calendar/cal-iso: calendar )result: -> utc time : <std/core/types/total: Eutcstd/time/utc/utc: (E, V) -> V> timestd/time/time/time: V timestd/time/time/instant/time: (i : instant, tz : ? timezone, cal : ? calendar, ts : ? timescale) -> utc time(ii: instant,tztz: timezone,calcal: calendar,ts-ttstd/time/instant/ts-tt: timescale) pub fun time-tistd/time/time/time-ti: (i : instant, tz : ? timezone, cal : ? calendar) -> utc time( ii: instant : instantstd/time/instant/instant: V, tztz: ? timezone : timezonestd/time/calendar/timezone: V = tz-utcstd/time/calendar/tz-utc: timezone, calcal: ? calendar : calendarstd/time/calendar/calendar: V = cal-isostd/time/calendar/cal-iso: calendar )result: -> utc time : <std/core/types/total: Eutcstd/time/utc/utc: (E, V) -> V> timestd/time/time/time: V timestd/time/time/instant/time: (i : instant, tz : ? timezone, cal : ? calendar, ts : ? timescale) -> utc time(ii: instant,tztz: timezone,calcal: calendar,ts-tistd/time/utc/ts-ti: timescale) pub fun timescale/date/timestd/time/time/timescale/date/time: (ts : timescale, d : date, c : ? clock, tz : ? timezone, cal : ? calendar) -> time( tsts: timescale : timescalestd/time/instant/timescale: V, dd: date : datestd/time/date/date: V, cc: ? clock : clockstd/time/date/clock: V = clock0std/time/date/clock0: clock, tztz: ? timezone : timezonestd/time/calendar/timezone: V = tz-utcstd/time/calendar/tz-utc: timezone, calcal: ? calendar : calendarstd/time/calendar/calendar: V = cal-isostd/time/calendar/cal-iso: calendar)result: -> total time : timestd/time/time/time: V timestd/time/time/instant/time: (i : instant, tz : ? timezone, cal : ? calendar, ts : ? timescale) -> time(tsts: timescale.instantstd/time/calendar/date/instant: (ts : timescale, d : date, c : ? clock, tz : ? timezone, cal : ? calendar) -> instant(dd: date,cc: clock,tztz: timezone,calcal: calendar),tztz: timezone,calcal: calendar,tsts: timescale) // Return the `:time` value for a given `:date` and `:clock` (=`clock0`) in a timezone `tz` (=`tz-utc` by default) // interpreted by calendar `cal` (=`cal-iso`) pub fun date/timestd/time/time/date/time: (d : date, c : ? clock, tz : ? timezone, cal : ? calendar, ts : ? timescale) -> utc time( dd: date : datestd/time/date/date: V, cc: ? clock : clockstd/time/date/clock: V = clock0std/time/date/clock0: clock, tztz: ? timezone : timezonestd/time/calendar/timezone: V = tz-utcstd/time/calendar/tz-utc: timezone, calcal: ? calendar : calendarstd/time/calendar/calendar: V = cal-isostd/time/calendar/cal-iso: calendar, tsts: ? timescale : timescalestd/time/instant/timescale: V = utcstd/time/utc/utc: () -> utc timescale() )result: -> utc time : <std/core/types/total: Eutcstd/time/utc/utc: (E, V) -> V> timestd/time/time/time: V tsts: timescale.timestd/time/time/timescale/date/time: (ts : timescale, d : date, c : ? clock, tz : ? timezone, cal : ? calendar) -> utc time(dd: date,cc: clock,tztz: timezone,calcal: calendar) // Add a date (years, months, days) and optional clock to a time. Takes leap years, leap seconds, etc. into account. pub fun add-datestd/time/time/add-date: (t : time, d : date, c : ? clock) -> time( tt: time : timestd/time/time/time: V, dd: date : datestd/time/date/date: V, cc: ? clock : clockstd/time/date/clock: V = clock0std/time/date/clock0: clock )result: -> total time : timestd/time/time/time: V tt: time.timescalestd/time/time/timescale: (t : time) -> timescale.timestd/time/time/timescale/date/time: (ts : timescale, d : date, c : ? clock, tz : ? timezone, cal : ? calendar) -> time( tt: time.datestd/time/time/time/date: (time : time) -> date +std/time/date/(+): (d1 : date, d2 : date) -> date dd: date, tt: time.clockstd/time/time/time/clock: (time : time) -> clock +std/time/date/clock/(+): (c : clock, d : clock) -> clock cc: clock, tt: time.timezonestd/time/time/time/timezone: (time : time) -> timezone, tt: time.calendarstd/time/time/time/calendar: (time : time) -> calendar ) // Add a clock (hours, minutes, seconds) to a time. Takes leap years, leap seconds, etc. into account. pub fun add-clockstd/time/time/add-clock: (t : time, c : clock) -> time( tt: time : timestd/time/time/time: V, cc: clock : clockstd/time/date/clock: V )result: -> total time : timestd/time/time/time: V tt: time.timescalestd/time/time/timescale: (t : time) -> timescale.timestd/time/time/timescale/date/time: (ts : timescale, d : date, c : ? clock, tz : ? timezone, cal : ? calendar) -> time( tt: time.datestd/time/time/time/date: (time : time) -> date, tt: time.clockstd/time/time/time/clock: (time : time) -> clock +std/time/date/clock/(+): (c : clock, d : clock) -> clock cc: clock, tt: time.timezonestd/time/time/time/timezone: (time : time) -> timezone, tt: time.calendarstd/time/time/time/calendar: (time : time) -> calendar ) // Add a specified number of days to a calendar time. Takes leap years etc. into account.\ // `time(2016,12,31,12).add-days(1).show == "2017-01-01T12:00:00Z"` &quad; (over a leap second)\ // `time(1582,10,4,cal=cal-jg).add-days(1).show == "1582-10-15T00:00:00Z JG"` &quad; (transition from Julian (`cal-julian`) to Gregorian (`cal-gregorian`) calendar)\ pub fun add-daysstd/time/time/add-days: (t : time, days : int, c : ? clock) -> time( tt: time : timestd/time/time/time: V, daysdays: int : intstd/core/types/int: V, cc: ? clock : clockstd/time/date/clock: V = clock0std/time/date/clock0: clock )result: -> total time : timestd/time/time/time: V tt: time.add-datestd/time/time/add-date: (t : time, d : date, c : ? clock) -> time( Datestd/time/date/Date: (year : int, month : int, day : int) -> date(0literal: int
dec = 0
hex8 = 0x00
bit8 = 0b00000000
, 0literal: int
dec = 0
hex8 = 0x00
bit8 = 0b00000000
, daysdays: int), cc: clock
) // Add a specified number of weeks to a calendar time. pub fun add-weeksstd/time/time/add-weeks: (t : time, weeks : int) -> time( tt: time : timestd/time/time/time: V, weeksweeks: int : intstd/core/types/int: V )result: -> total time : timestd/time/time/time: V tt: time.add-daysstd/time/time/add-days: (t : time, days : int, c : ? clock) -> time( weeksweeks: int*std/core/int/(*): (int, int) -> int7literal: int
dec = 7
hex8 = 0x07
bit8 = 0b00000111
) // Add a specified number of months to a calendar time. pub fun add-monthsstd/time/time/add-months: (t : time, months : int) -> time( tt: time : timestd/time/time/time: V, monthsmonths: int : intstd/core/types/int: V )result: -> total time : timestd/time/time/time: V tt: time.add-datestd/time/time/add-date: (t : time, d : date, c : ? clock) -> time( Datestd/time/date/Date: (year : int, month : int, day : int) -> date(0literal: int
dec = 0
hex8 = 0x00
bit8 = 0b00000000
,monthsmonths: int,0literal: int
dec = 0
hex8 = 0x00
bit8 = 0b00000000
)
) // Add a specified number of years to a calendar time. pub fun add-yearsstd/time/time/add-years: (t : time, years : int) -> time( tt: time : timestd/time/time/time: V, yearsyears: int : intstd/core/types/int: V )result: -> total time : timestd/time/time/time: V tt: time.add-datestd/time/time/add-date: (t : time, d : date, c : ? clock) -> time( Datestd/time/date/Date: (year : int, month : int, day : int) -> date(yearsyears: int,0literal: int
dec = 0
hex8 = 0x00
bit8 = 0b00000000
,0literal: int
dec = 0
hex8 = 0x00
bit8 = 0b00000000
)
) // Add an SI second `:duration` to a time.\ // `(time(2015,12,31,23,59,59,0.5) + duration(1)).show == "2016-01-01T00:00:00.500Z"`\ // `(time(2016,12,31,23,59,59,0.5) + duration(1)).show == "2016-12-31T23:59:60.500Z"` &quad; (into a leap second) pub fun duration/(+)std/time/time/duration/(+): (t : time, d : duration) -> time( tt: time : timestd/time/time/time: V, dd: duration : durationstd/time/duration/duration: V )result: -> total time : timestd/time/time/time: V (tt: time.instantstd/time/time/time/instant: (time : time) -> instant +std/time/instant/(+): (i : instant, d : duration) -> instant dd: duration).timestd/time/time/instant/time: (i : instant, tz : ? timezone, cal : ? calendar, ts : ? timescale) -> time(tt: time.timezonestd/time/time/time/timezone: (time : time) -> timezone,tt: time.calendarstd/time/time/time/calendar: (time : time) -> calendar) // Subtract an SI second `:duration` from a time.\ // `(time(2016,1,1,0,0,0,0.5) - duration(1)).show == "2015-12-31T23:59:59.500Z"`\ // `(time(2017,1,1,0,0,0,0.5) - duration(1)).show == "2016-12-31T23:59:60.500Z"` &quad; (into a leap second) pub fun duration/(-)std/time/time/duration/(-): (t : time, d : duration) -> time( tt: time : timestd/time/time/time: V, dd: duration : durationstd/time/duration/duration: V )result: -> total time : timestd/time/time/time: V tt: time +std/time/time/duration/(+): (t : time, d : duration) -> time (~std/time/duration/(~): (d : duration) -> durationdd: duration) // Return the exact SI second duration between to times.\ // `(time(2016,1,1,0,0,0,0.5) - time(2015,12,31,23,59,59)).show == "1.5s"`\ // `(time(2017,1,1,0,0,0,0.5) - time(2016,12,31,23,59,59)).show == "2.5s"` &quad; (over a leap second)\ // `(time(2017,1,1,0,0,0,0.5) - time(2017,1,1,2,59,59,tz=tz-fixed(3)).show == "2.5s"` &quad; (GMT+3, and over a leap second)\ pub fun (-)std/time/time/(-): (t1 : time, t2 : time) -> duration( t1t1: time : timestd/time/time/time: V, t2t2: time : timestd/time/time/time: V )result: -> total duration : durationstd/time/duration/duration: V (t1t1: time.instantstd/time/time/time/instant: (time : time) -> instant -std/time/instant/(-): (i : instant, j : instant) -> duration t2t2: time.instantstd/time/time/time/instant: (time : time) -> instant) // Copy a `:time` with optionally changing any of its attributes.\ // `t.copy(month=1,day=1,hours=0,minutes=0,seconds=zero)` &quad; (copy to start of the year)\ // `t.copy(month=t.month+2,day=t.day+3) ` &quad; (add 2 months and 3 days)\ // `t.copy(tz=tz-local()) ` &quad; (change to a different time zone) pub fun copystd/time/time/copy: (t : time, year : ? int, month : ? int, day : ? int, hours : ? int, minutes : ? int, seconds : ? ddouble, tz : ? timezone, cal : ? calendar, ts : ? timescale) -> time( tt: time : timestd/time/time/time: V, yearyear: ? int : intstd/core/types/int: V = tt: time.yearstd/time/time/year: (t : time) -> int, monthmonth: ? int : intstd/core/types/int: V = tt: time.monthstd/time/time/month: (t : time) -> int, dayday: ? int : intstd/core/types/int: V = tt: time.daystd/time/time/day: (t : time) -> int, hourshours: ? int : intstd/core/types/int: V = tt: time.hoursstd/time/time/hours: (t : time) -> int, minutesminutes: ? int : intstd/core/types/int: V = tt: time.minutesstd/time/time/minutes: (t : time) -> int, secondsseconds: ? ddouble : ddoublestd/num/ddouble/ddouble: V = tt: time.secondsstd/time/time/seconds: (t : time) -> timespan, tztz: ? timezone : timezonestd/time/calendar/timezone: V = tt: time.timezonestd/time/time/time/timezone: (time : time) -> timezone, calcal: ? calendar : calendarstd/time/calendar/calendar: V = tt: time.calendarstd/time/time/time/calendar: (time : time) -> calendar, tsts: ? timescale : timescalestd/time/instant/timescale: V = tt: time.timescalestd/time/time/timescale: (t : time) -> timescale )result: -> total time : timestd/time/time/time: V tsts: timescale.timestd/time/time/timescale/date/time: (ts : timescale, d : date, c : ? clock, tz : ? timezone, cal : ? calendar) -> time( Datestd/time/date/Date: (year : int, month : int, day : int) -> date(yearyear: int,monthmonth: int,dayday: int), Clockstd/time/date/Clock: (hours : int, minutes : int, seconds : ddouble) -> clock(hourshours: int,minutesminutes: int,secondsseconds: ddouble), tztz: timezone, calcal: calendar) // Copy a `:time` with a new `:date` and optional `:clock` (=`t.clock`), and optionally a new // timezone (=`t.timezone`) and calendar (=`t.calendar`). pub fun copy-dcstd/time/time/copy-dc: (t : time, d : ? date, c : ? clock, tz : ? timezone, cal : ? calendar, ts : ? timescale) -> time( tt: time : timestd/time/time/time: V, dd: ? date : datestd/time/date/date: V = tt: time.datestd/time/time/time/date: (time : time) -> date, cc: ? clock : clockstd/time/date/clock: V = tt: time.clockstd/time/time/time/clock: (time : time) -> clock, tztz: ? timezone : timezonestd/time/calendar/timezone: V = tt: time.timezonestd/time/time/time/timezone: (time : time) -> timezone, calcal: ? calendar : calendarstd/time/calendar/calendar: V = tt: time.calendarstd/time/time/time/calendar: (time : time) -> calendar, tsts: ? timescale : timescalestd/time/instant/timescale: V = tt: time.timescalestd/time/time/timescale: (t : time) -> timescale )result: -> total time : timestd/time/time/time: V tsts: timescale.timestd/time/time/timescale/date/time: (ts : timescale, d : date, c : ? clock, tz : ? timezone, cal : ? calendar) -> time( dd: date, cc: clock, tztz: timezone, calcal: calendar) // Return the time at the start of the day of time `t`. pub fun start-of-daystd/time/time/start-of-day: (t : time) -> time( tt: time : timestd/time/time/time: V )result: -> total time : timestd/time/time/time: V tt: time.copy-dcstd/time/time/copy-dc: (t : time, d : ? date, c : ? clock, tz : ? timezone, cal : ? calendar, ts : ? timescale) -> time(tt: time.datestd/time/time/time/date: (time : time) -> date,clock0std/time/date/clock0: clock) // Return the time at the start of the month of time `t`. pub fun start-of-monthstd/time/time/start-of-month: (t : time) -> time( tt: time : timestd/time/time/time: V )result: -> total time : timestd/time/time/time: V tt: time.copy-dcstd/time/time/copy-dc: (t : time, d : ? date, c : ? clock, tz : ? timezone, cal : ? calendar, ts : ? timescale) -> time((tt: time.datestd/time/time/time/date: (time : time) -> date)(day=1literal: int
dec = 1
hex8 = 0x01
bit8 = 0b00000001
),clock0std/time/date/clock0: clock
) // Return the time at the start of the week (Monday) of time `t`. pub fun start-of-weekstd/time/time/start-of-week: (t : time) -> time( tt: time : timestd/time/time/time: V )result: -> total time : timestd/time/time/time: V val dowdow: weekday = tt: time.weekdaystd/time/time/weekday: (t : time) -> weekday if dowdow: weekday==std/time/date/weekday/(==): (i : weekday, j : weekday) -> boolMonstd/time/date/Mon: weekday then tt: time.start-of-daystd/time/time/start-of-day: (t : time) -> time else tt: time.copy-dcstd/time/time/copy-dc: (t : time, d : ? date, c : ? clock, tz : ? timezone, cal : ? calendar, ts : ? timescale) -> time( (tt: time.datestd/time/time/time/date: (time : time) -> date)(day=(tt: time.daystd/time/time/day: (t : time) -> int -std/core/int/(-): (x : int, y : int) -> int dowdow: weekday.intstd/time/date/int: (wd : weekday) -> int)+std/core/int/(+): (x : int, y : int) -> int1literal: int
dec = 1
hex8 = 0x01
bit8 = 0b00000001
), clock0std/time/date/clock0: clock
) // Return the time at the start of the year of time `t`. pub fun start-of-yearstd/time/time/start-of-year: (t : time) -> time( tt: time : timestd/time/time/time: V )result: -> total time : timestd/time/time/time: V tt: time.copy-dcstd/time/time/copy-dc: (t : time, d : ? date, c : ? clock, tz : ? timezone, cal : ? calendar, ts : ? timescale) -> time(Datestd/time/date/Date: (year : int, month : int, day : int) -> date(tt: time.yearstd/time/time/year: (t : time) -> int,1literal: int
dec = 1
hex8 = 0x01
bit8 = 0b00000001
,1literal: int
dec = 1
hex8 = 0x01
bit8 = 0b00000001
),clock0std/time/date/clock0: clock
) /*---------------------------------------------------------------------------- Generic calendar calculations; Surprisingly, all of these work for any calendar and do not make assumptions about the length of month, the number of months in a year etc. ----------------------------------------------------------------------------*/ // Return the weekday of a given time `t`. pub fun weekdaystd/time/time/weekday: (t : time) -> weekday( tt: time : timestd/time/time/time: V )result: -> total weekday : weekdaystd/time/date/weekday: V val daysdays: int = tt: time.mjdstd/time/time/mjd: (t : time) -> ddouble.floorstd/num/ddouble/floor: (x : ddouble) -> ddouble.intstd/num/ddouble/int: (x : ddouble, nonfin : ? int) -> int val dowdow: int = (daysdays: int+std/core/int/(+): (x : int, y : int) -> int3literal: int
dec = 3
hex8 = 0x03
bit8 = 0b00000011
)%std/core/int/(%): (int, int) -> int7literal: int
dec = 7
hex8 = 0x07
bit8 = 0b00000111
// plus 3 since MJD epoch was a wednesday (note: 0 = sunday, 1 = monday, ..) dowdow: int.weekdaystd/time/date/weekday: (i : int) -> weekday
// to ISO week day // Return a `:time` as a fractional year.\ // `year-frac(time(2000,7,2)) == fixed(2000.5)` pub fun year-fracstd/time/time/year-frac: (t : time) -> ddouble( tt: time : timestd/time/time/time: V )result: -> total ddouble : ddoublestd/num/ddouble/ddouble: V val dfracdfrac: float64 = tt: time.mjdstd/time/time/mjd: (t : time) -> ddouble.fractionstd/num/ddouble/fraction: (x : ddouble) -> ddouble.float64std/num/ddouble/float64: (x : ddouble) -> float64 // t.clock.total-seconds.float64 / 86400.0 val yfracyfrac: float64 = ((tt: time.day-of-yearstd/time/time/day-of-year: (t : time) -> int -std/core/int/(-): (x : int, y : int) -> int 1literal: int
dec = 1
hex8 = 0x01
bit8 = 0b00000001
).float64std/num/float64/float64: (i : int) -> float64 +std/num/float64/(+): (x : float64, y : float64) -> float64 dfracdfrac: float64) /std/num/float64/(/): (x : float64, y : float64) -> float64 tt: time.days-in-yearstd/time/time/days-in-year: (t : time) -> int.float64std/num/float64/float64: (i : int) -> float64 timespanstd/time/timestamp/int/timespan: (seconds : int, frac : ? float64) -> timespan(tt: time.yearstd/time/time/year: (t : time) -> int,yfracyfrac: float64
) // Return the total months in the year of time `t`. // For Gregorian calendars this is always 12 but some calendars have a varying number of months per year. pub fun months-in-yearstd/time/time/months-in-year: (t : time) -> int( tt: time : timestd/time/time/time: V )result: -> total int : intstd/core/types/int: V tt: time.copy-dcstd/time/time/copy-dc: (t : time, d : ? date, c : ? clock, tz : ? timezone, cal : ? calendar, ts : ? timescale) -> time( Datestd/time/date/Date: (year : int, month : int, day : int) -> date(tt: time.yearstd/time/time/year: (t : time) -> int +std/core/int/(+): (x : int, y : int) -> int 1literal: int
dec = 1
hex8 = 0x01
bit8 = 0b00000001
,1literal: int
dec = 1
hex8 = 0x01
bit8 = 0b00000001
,0literal: int
dec = 0
hex8 = 0x00
bit8 = 0b00000000
) ).monthstd/time/time/month: (t : time) -> int
// Return the `n`th week day following (and including) time `t`. // Use `n = 1` for the first week day `wd` following `t`; // Use `0` for the last occurence of week day `wd` before `t`.\ // `time(2016,10,10).nth-weekday(1,Sun)` &quad; (2016-10-13, first Sunday following October 10, 2016) // `time(2016,11,16).start-of-month.nth-weekday(0,Wed)` &quad; (2016-10-26, the last Wednesday before 2016-11-01) pub fun nth-weekdaystd/time/time/nth-weekday: (t : time, n : int, wd : weekday) -> time( tt: time : timestd/time/time/time: V, nn: int : intstd/core/types/int: V, wdwd: weekday : weekdaystd/time/date/weekday: V )result: -> total time : timestd/time/time/time: V val dowdow: weekday = tt: time.weekdaystd/time/time/weekday: (t : time) -> weekday val incinc: int = wdwd: weekday -std/time/date/weekday/(-): (wd1 : weekday, wd2 : weekday) -> int dowdow: weekday val wdaywday: int= tt: time.daystd/time/time/day: (t : time) -> int +std/core/int/(+): (x : int, y : int) -> int incinc: int +std/core/int/(+): (x : int, y : int) -> int 7literal: int
dec = 7
hex8 = 0x07
bit8 = 0b00000111
*std/core/int/(*): (int, int) -> int(nn: int -std/core/int/(-): (x : int, y : int) -> int 1literal: int
dec = 1
hex8 = 0x01
bit8 = 0b00000001
) tt: time.copy-dcstd/time/time/copy-dc: (t : time, d : ? date, c : ? clock, tz : ? timezone, cal : ? calendar, ts : ? timescale) -> time( Datestd/time/date/Date: (year : int, month : int, day : int) -> date(tt: time.yearstd/time/time/year: (t : time) -> int,tt: time.monthstd/time/time/month: (t : time) -> int,wdaywday: int)
) // Return the first week day following (and including) time `t`. fun first-weekdaystd/time/time/first-weekday: (t : time, wd : weekday) -> time( tt: time : timestd/time/time/time: V, wdwd: weekday : weekdaystd/time/date/weekday: V )result: -> total time : timestd/time/time/time: V tt: time.nth-weekdaystd/time/time/nth-weekday: (t : time, n : int, wd : weekday) -> time(1literal: int
dec = 1
hex8 = 0x01
bit8 = 0b00000001
,wdwd: weekday
) // Return the last week day before time `t`.\ // `time(2016,11,1).last-weekday(Sun)` &quad; (2016-10-30, Last Sunday of October 2016) fun last-weekdaystd/time/time/last-weekday: (t : time, wd : weekday) -> time( tt: time : timestd/time/time/time: V, wdwd: weekday : weekdaystd/time/date/weekday: V )result: -> total time : timestd/time/time/time: V tt: time.nth-weekdaystd/time/time/nth-weekday: (t : time, n : int, wd : weekday) -> time(0literal: int
dec = 0
hex8 = 0x00
bit8 = 0b00000000
,wdwd: weekday
) // Return the `n`th week day since the beginning of the month of time `t`.\ // `time(2016,10,10).nth-weekday-of-month(2,Sun).date` &quad; (2016-10-09, Second Sunday of October 2016)\ // `time(2016,10,10).nth-weekday-of-month(60,Sun).date` &quad; (2017-11-19, 60th Sunday since October 1, 2016)\ pub fun nth-weekday-of-monthstd/time/time/nth-weekday-of-month: (t : time, n : int, wd : weekday) -> time( tt: time : timestd/time/time/time: V, nn: int : intstd/core/types/int: V, wdwd: weekday : weekdaystd/time/date/weekday: V )result: -> total time : timestd/time/time/time: V tt: time.copy-dcstd/time/time/copy-dc: (t : time, d : ? date, c : ? clock, tz : ? timezone, cal : ? calendar, ts : ? timescale) -> time(Datestd/time/date/Date: (year : int, month : int, day : int) -> date(tt: time.yearstd/time/time/year: (t : time) -> int,tt: time.monthstd/time/time/month: (t : time) -> int,1literal: int
dec = 1
hex8 = 0x01
bit8 = 0b00000001
)).nth-weekdaystd/time/time/nth-weekday: (t : time, n : int, wd : weekday) -> time(nn: int,wdwd: weekday
) // Return the first week day of the month of time `t`.\ // `time(2016,10,10).first-weekday-of-month(Sun)` &quad; (2016-10-02, First Sunday of October 2016) fun first-weekday-of-monthstd/time/time/first-weekday-of-month: (t : time, wd : weekday) -> time( tt: time : timestd/time/time/time: V, wdwd: weekday : weekdaystd/time/date/weekday: V )result: -> total time : timestd/time/time/time: V tt: time.nth-weekday-of-monthstd/time/time/nth-weekday-of-month: (t : time, n : int, wd : weekday) -> time(1literal: int
dec = 1
hex8 = 0x01
bit8 = 0b00000001
,wdwd: weekday
) // Return the last week day of the month of time `t`.\ // `time(2016,10,10).last-weekday-of-month(Sun).date` &quad; (2016-10-30, Last Sunday of October 2016) pub fun last-weekday-of-monthstd/time/time/last-weekday-of-month: (t : time, wd : weekday) -> time( tt: time : timestd/time/time/time: V, wdwd: weekday : weekdaystd/time/date/weekday: V )result: -> total time : timestd/time/time/time: V tt: time.copy-dcstd/time/time/copy-dc: (t : time, d : ? date, c : ? clock, tz : ? timezone, cal : ? calendar, ts : ? timescale) -> time(Datestd/time/date/Date: (year : int, month : int, day : int) -> date(tt: time.yearstd/time/time/year: (t : time) -> int,tt: time.monthstd/time/time/month: (t : time) -> int+std/core/int/(+): (x : int, y : int) -> int1literal: int
dec = 1
hex8 = 0x01
bit8 = 0b00000001
,1literal: int
dec = 1
hex8 = 0x01
bit8 = 0b00000001
)).last-weekdaystd/time/time/last-weekday: (t : time, wd : weekday) -> time(wdwd: weekday
) // --------------------------------------------------- // The following functions are generic in the calendar // and are relied upon by other routines for efficiency. // We may want to optimize this by using specialized // implementations if the ISO calendar is in use. // --------------------------------------------------- // Return the day of the year of time `t` (starting at 1). pub fun day-of-yearstd/time/time/day-of-year: (t : time) -> int( tt: time : timestd/time/time/time: V )result: -> total int : intstd/core/types/int: V tt: time.calendarstd/time/time/time/calendar: (time : time) -> calendar.days-untilstd/time/calendar/days-until: (cal : calendar, d1 : date, d2 : date) -> int(Datestd/time/date/Date: (year : int, month : int, day : int) -> date(tt: time.yearstd/time/time/year: (t : time) -> int,1literal: int
dec = 1
hex8 = 0x01
bit8 = 0b00000001
,1literal: int
dec = 1
hex8 = 0x01
bit8 = 0b00000001
),tt: time.datestd/time/time/time/date: (time : time) -> date) +std/core/int/(+): (x : int, y : int) -> int
1literal: int
dec = 1
hex8 = 0x01
bit8 = 0b00000001
// Return the total days in the month of time `t`. pub fun days-in-monthstd/time/time/days-in-month: (t : time) -> int( tt: time : timestd/time/time/time: V )result: -> total int : intstd/core/types/int: V val dd: date = tt: time.datestd/time/time/time/date: (time : time) -> date tt: time.calendarstd/time/time/time/calendar: (time : time) -> calendar.days-untilstd/time/calendar/days-until: (cal : calendar, d1 : date, d2 : date) -> int(Datestd/time/date/Date: (year : int, month : int, day : int) -> date(dd: date.yearstd/time/date/date/year: (date : date) -> int,dd: date.monthstd/time/date/date/month: (date : date) -> int,1literal: int
dec = 1
hex8 = 0x01
bit8 = 0b00000001
),Datestd/time/date/Date: (year : int, month : int, day : int) -> date(dd: date.yearstd/time/date/date/year: (date : date) -> int,dd: date.monthstd/time/date/date/month: (date : date) -> int+std/core/int/(+): (x : int, y : int) -> int1literal: int
dec = 1
hex8 = 0x01
bit8 = 0b00000001
,1literal: int
dec = 1
hex8 = 0x01
bit8 = 0b00000001
)
) // Return the total days in the year of time `t`. pub fun days-in-yearstd/time/time/days-in-year: (t : time) -> int( tt: time : timestd/time/time/time: V)result: -> total int : intstd/core/types/int: V tt: time.calendarstd/time/time/time/calendar: (time : time) -> calendar.days-untilstd/time/calendar/days-until: (cal : calendar, d1 : date, d2 : date) -> int(Datestd/time/date/Date: (year : int, month : int, day : int) -> date(tt: time.yearstd/time/time/year: (t : time) -> int,1literal: int
dec = 1
hex8 = 0x01
bit8 = 0b00000001
,1literal: int
dec = 1
hex8 = 0x01
bit8 = 0b00000001
),Datestd/time/date/Date: (year : int, month : int, day : int) -> date(tt: time.yearstd/time/time/year: (t : time) -> int+std/core/int/(+): (x : int, y : int) -> int1literal: int
dec = 1
hex8 = 0x01
bit8 = 0b00000001
,1literal: int
dec = 1
hex8 = 0x01
bit8 = 0b00000001
,1literal: int
dec = 1
hex8 = 0x01
bit8 = 0b00000001
)
) // Return the days between two times. Uses the calendar and timezone // of the first time `t1` to determine the date of `t2`. // ``` // days-until( time(2000,1,1), time(2000,1,1) ) == 0 // days-until( time(2000,1,1), time(2000,1,2) ) == 1 // days-until( time(2000,1,1), time(2000,1,2,tz=tz-fixed(1)) ) == 0 // days-until( time(2000,1,1), time(2000,3,1) ) == 60 // days-until( time(2000,2,1), time(2000,1,1) ) == -1 // ``` pub fun days-untilstd/time/time/days-until: (t1 : time, t2 : time) -> int( t1t1: time : timestd/time/time/time: V, t2t2: time : timestd/time/time/time: V )result: -> total int : intstd/core/types/int: V val d2d2: date = if t1t1: time.calendarstd/time/time/time/calendar: (time : time) -> calendar ==std/time/calendar/(==): (c1 : calendar, c2 : calendar) -> bool t2t2: time.calendarstd/time/time/time/calendar: (time : time) -> calendar &&std/core/types/(&&): (x : bool, y : bool) -> bool t1t1: time.timezonestd/time/time/time/timezone: (time : time) -> timezone ==std/time/calendar/timezone/(==): (tz1 : timezone, tz2 : timezone) -> bool t2t2: time.timezonestd/time/time/time/timezone: (time : time) -> timezone then t2t2: time.datestd/time/time/time/date: (time : time) -> date else t2t2: time.instantstd/time/time/time/instant: (time : time) -> instant.timestd/time/time/instant/time: (i : instant, tz : ? timezone, cal : ? calendar, ts : ? timescale) -> time(tz=t1t1: time.timezonestd/time/time/time/timezone: (time : time) -> timezone,cal=t1t1: time.calendarstd/time/time/time/calendar: (time : time) -> calendar).datestd/time/time/time/date: (time : time) -> date t1t1: time.calendarstd/time/time/time/calendar: (time : time) -> calendar.days-untilstd/time/calendar/days-until: (cal : calendar, d1 : date, d2 : date) -> int( t1t1: time.datestd/time/time/time/date: (time : time) -> date, d2d2: date ) // Return the modified Julian date ([MJD](https://en.wikipedia.org/wiki/Julian_day#Variants)) // number for a given `:time`. This interprets the Modified Julian Date in the calendar // system of `t` with the timezone applied.\ // `time(1972,1,2,tz=tz-fixed(1)).mjd == "41318"`\ // `time(1972,1,2,tz=tz-fixed(1)).instant.mjd(ts-utc).show == "41317.958333335"` &quad; (one hour earlier) // // Also takes leap seconds into account:\ // `time(2015,12,31,12,0,0).mjd.show == "57387.5"` &quad; (exactly mid-day)\ // `time(2016,12,31,12,0,0).mjd.show(9) == "57753.499994213"` &quad; (this day has a leap second, so it is just before the real middle of the day)\ // `time(2016,12,31,12,0,0,0.5).mjd.show == "57753.5"` &quad; (real middle of the day)\ pub fun mjdstd/time/time/mjd: (t : time) -> ddouble( tt: time : timestd/time/time/time: V )result: -> total ddouble : ddoublestd/num/ddouble/ddouble: V //trace("offset: " + t.tzdelta.show) // adjust with the timezone delta so we display the mjd on the date. val ii: instant = tt: time.instantstd/time/time/time/instant: (time : time) -> instant ii: instant.mjdstd/time/instant/mjd: (i : instant, tscale : timescale, tzdelta : ? timespan) -> ddouble( ii: instant.timescalestd/time/instant/instant/timescale: (i : instant) -> timescale, tt: time.tzdeltastd/time/time/time/tzdelta: (time : time) -> duration.timespanstd/time/duration/timespan: (d : duration) -> timespan ) val mjd-epoch-deltastd/time/time/mjd-epoch-delta: timespan = timespanstd/time/timestamp/int/timespan: (seconds : int, frac : ? float64) -> timespan(51544literal: int
dec = 51544
hex32= 0x0000C958
bit32= 0b00000000000000001100100101011000
) /* Return the Julian date ([JD](https://en.wikipedia.org/wiki/Julian_day)) number for a given `:time` `t`. This interprets the Julian date in the calendar of `t` with the timezone of `t` applied.\ `time(-4713,11,24,12,cal=cal-tt).jd == "0"`\ `time(1972,1,2,tz=tz-fixed(1)).jd == "2441318.5"`\ `time(1972,1,2,tz=tz-fixed(1)).instant.jd(ts-ti).show(9) == "2441318.458333333"` Takes leap seconds into account when calculating the fraction of the day, see `mjd` for examples. */ pub fun jdstd/time/time/jd: (t : time) -> ddouble( tt: time : timestd/time/time/time: V )result: -> total ddouble : ddoublestd/num/ddouble/ddouble: V //trace("offset: " + t.tzdelta.show) // adjust with the timezone delta so we display the mjd on the date. tt: time.mjdstd/time/time/mjd: (t : time) -> ddouble() +std/num/ddouble/(+): (x : ddouble, y : ddouble) -> ddouble jd-epoch-deltastd/time/time/jd-epoch-delta: timespan val jd-epoch-deltastd/time/time/jd-epoch-delta: timespan = timespanstd/time/timestamp/float64/timespan: (secs : float64) -> timespan(2400000.5literal: float64
hex64= 0x1.24f804p21
) // Return the current time in an optional timezone (=`tz-utc`) and optional calendar (=`cal-iso`). pub fun timescale/time-nowstd/time/time/timescale/time-now: (ts : timescale, tz : ? timezone, cal : ? calendar) -> ndet time(tsts: timescale : timescalestd/time/instant/timescale: V, tztz: ? timezone : timezonestd/time/calendar/timezone: V = tz-utcstd/time/calendar/tz-utc: timezone, calcal: ? calendar : calendarstd/time/calendar/calendar: V = cal-isostd/time/calendar/cal-iso: calendar)result: -> ndet time : <std/core/types/total: Endetstd/core/types/ndet: X> timestd/time/time/time: V now-instd/time/chrono/now-in: (ts : ? timescale) -> ndet instant(tsts: timescale).timestd/time/time/instant/time: (i : instant, tz : ? timezone, cal : ? calendar, ts : ? timescale) -> ndet time(tztz: timezone,calcal: calendar) // Return the current time in an optional timezone (=`tz-utc`) and optional calendar (=`cal-iso`). pub fun timezone/time-nowstd/time/time/timezone/time-now: (tz : ? timezone, cal : ? calendar, ts : ? timescale) -> <ndet,utc> time(tztz: ? timezone : timezonestd/time/calendar/timezone: V = tz-utcstd/time/calendar/tz-utc: timezone, calcal: ? calendar : calendarstd/time/calendar/calendar: V = cal-isostd/time/calendar/cal-iso: calendar, tsts: ? timescale : timescalestd/time/instant/timescale: V = utcstd/time/utc/utc: () -> <utc,ndet> timescale() )result: -> <ndet,utc> time : <std/core/types/total: Endetstd/core/types/ndet: X,utcstd/time/utc/utc: (E, V) -> V> timestd/time/time/time: V tsts: timescale.time-nowstd/time/time/timescale/time-now: (ts : timescale, tz : ? timezone, cal : ? calendar) -> <ndet,utc> time(tztz: timezone,calcal: calendar) // Return the current time in the local timezone and optional calendar (=`cal-iso`). pub fun timescale/local-time-nowstd/time/time/timescale/local-time-now: (ts : timescale, cal : ? calendar) -> ndet time(tsts: timescale : timescalestd/time/instant/timescale: V, calcal: ? calendar : calendarstd/time/calendar/calendar: V = cal-isostd/time/calendar/cal-iso: calendar)result: -> ndet time : ndetstd/core/types/ndet: X timestd/time/time/time: V tsts: timescale.time-nowstd/time/time/timescale/time-now: (ts : timescale, tz : ? timezone, cal : ? calendar) -> ndet time(tz-localstd/time/calendar/tz-local: () -> ndet timezone(),calcal: calendar) // Return the current time in the local timezone and optional calendar (=`cal-iso`). pub fun calendar/local-time-nowstd/time/time/calendar/local-time-now: (cal : ? calendar) -> <ndet,utc> time(calcal: ? calendar : calendarstd/time/calendar/calendar: V = cal-isostd/time/calendar/cal-iso: calendar)result: -> <ndet,utc> time : <std/core/types/total: Endetstd/core/types/ndet: X,utcstd/time/utc/utc: (E, V) -> V> timestd/time/time/time: V time-nowstd/time/time/timezone/time-now: (tz : ? timezone, cal : ? calendar, ts : ? timescale) -> <ndet,utc> time(tz-localstd/time/calendar/tz-local: () -> <ndet,utc> timezone(),calcal: calendar) // Convert a `:time` `t` to a new `:time` value in the local time zone // in an optional calendar (=`t.calendar` by default). pub fun local-timestd/time/time/local-time: (t : time, cal : ? calendar) -> ndet time( tt: time : timestd/time/time/time: V, calcal: ? calendar : calendarstd/time/calendar/calendar: V = tt: time.calendarstd/time/time/time/calendar: (time : time) -> calendar )result: -> ndet time : ndetstd/core/types/ndet: X timestd/time/time/time: V tt: time.timestd/time/time/time/time: (t : time, tz : ? timezone, cal : ? calendar, ts : ? timescale) -> ndet time(tz-localstd/time/calendar/tz-local: () -> ndet timezone(),calcal: calendar) // Convert an `:instant` to a `:time` value in the local timezone, in an optional calendar (=`cal-iso` by default). pub fun instant/local-timestd/time/time/instant/local-time: (i : instant, cal : ? calendar) -> ndet time( ii: instant : instantstd/time/instant/instant: V, calcal: ? calendar : calendarstd/time/calendar/calendar: V = cal-isostd/time/calendar/cal-iso: calendar )result: -> ndet time : ndetstd/core/types/ndet: X timestd/time/time/time: V timestd/time/time/instant/time: (i : instant, tz : ? timezone, cal : ? calendar, ts : ? timescale) -> ndet time(ii: instant,tz-localstd/time/calendar/tz-local: () -> ndet timezone(),calcal: calendar) // Return the `:time` value for a given date and clock in the local timezone // interpreted by calendar `cal` (=`cal-iso`). See `instant` for roll-over behaviour. pub fun timescale/local-timestd/time/time/timescale/local-time: (ts : timescale, year : int, month : ? int, day : ? int, hours : ? int, minutes : ? int, secs : ? int, frac : ? float64, cal : ? calendar) -> ndet time( tsts: timescale : timescalestd/time/instant/timescale: V, yearyear: int : intstd/core/types/int: V, monthmonth: ? int : intstd/core/types/int: V = 1literal: int
dec = 1
hex8 = 0x01
bit8 = 0b00000001
, dayday: ? int : intstd/core/types/int: V = 1literal: int
dec = 1
hex8 = 0x01
bit8 = 0b00000001
, hourshours: ? int : intstd/core/types/int: V = 0literal: int
dec = 0
hex8 = 0x00
bit8 = 0b00000000
, minutesminutes: ? int : intstd/core/types/int: V = 0literal: int
dec = 0
hex8 = 0x00
bit8 = 0b00000000
, secssecs: ? int : intstd/core/types/int: V = 0literal: int
dec = 0
hex8 = 0x00
bit8 = 0b00000000
, fracfrac: ? float64 : float64std/core/types/float64: V = 0.0literal: float64
hex64= 0x0p+0
, calcal: ? calendar : calendarstd/time/calendar/calendar: V = cal-isostd/time/calendar/cal-iso: calendar )result: -> ndet time : ndetstd/core/types/ndet: X timestd/time/time/time: V tsts: timescale.timestd/time/time/timescale/time: (ts : timescale, year : int, month : ? int, day : ? int, hours : ? int, minutes : ? int, secs : ? int, frac : ? float64, tz : ? timezone, cal : ? calendar) -> ndet time(yearyear: int,monthmonth: int,dayday: int,hourshours: int,minutesminutes: int,secssecs: int,fracfrac: float64,tz-localstd/time/calendar/tz-local: () -> ndet timezone(),calcal: calendar
) // Return the `:time` value for a given date and clock in the local timezone // interpreted by calendar `cal` (=`cal-iso`). See `instant` for roll-over behaviour. pub fun year/local-timestd/time/time/year/local-time: (year : int, month : ? int, day : ? int, hours : ? int, minutes : ? int, secs : ? int, frac : ? float64, cal : ? calendar, ts : ? timescale) -> <ndet,utc> time( yearyear: int : intstd/core/types/int: V, monthmonth: ? int : intstd/core/types/int: V = 1literal: int
dec = 1
hex8 = 0x01
bit8 = 0b00000001
, dayday: ? int : intstd/core/types/int: V = 1literal: int
dec = 1
hex8 = 0x01
bit8 = 0b00000001
, hourshours: ? int : intstd/core/types/int: V = 0literal: int
dec = 0
hex8 = 0x00
bit8 = 0b00000000
, minutesminutes: ? int : intstd/core/types/int: V = 0literal: int
dec = 0
hex8 = 0x00
bit8 = 0b00000000
, secssecs: ? int : intstd/core/types/int: V = 0literal: int
dec = 0
hex8 = 0x00
bit8 = 0b00000000
, fracfrac: ? float64 : float64std/core/types/float64: V = 0.0literal: float64
hex64= 0x0p+0
, calcal: ? calendar : calendarstd/time/calendar/calendar: V = cal-isostd/time/calendar/cal-iso: calendar, tsts: ? timescale : timescalestd/time/instant/timescale: V = utcstd/time/utc/utc: () -> <utc,ndet> timescale() )result: -> <ndet,utc> time : <std/core/types/total: Endetstd/core/types/ndet: X,utcstd/time/utc/utc: (E, V) -> V> timestd/time/time/time: V tsts: timescale.local-timestd/time/time/timescale/local-time: (ts : timescale, year : int, month : ? int, day : ? int, hours : ? int, minutes : ? int, secs : ? int, frac : ? float64, cal : ? calendar) -> <ndet,utc> time(yearyear: int,monthmonth: int,dayday: int,hourshours: int,minutesminutes: int,secssecs: int,fracfrac: float64,calcal: calendar
) // Return the `:time` value for a given `:date` and `:clock` (=`clock0`) in the local timezone // interpreted by calendar `cal` (=`cal-iso`) pub fun date/local-timestd/time/time/date/local-time: (ts : timescale, d : date, c : ? clock, cal : ? calendar) -> ndet time( tsts: timescale : timescalestd/time/instant/timescale: V, dd: date : datestd/time/date/date: V, cc: ? clock : clockstd/time/date/clock: V = clock0std/time/date/clock0: clock, calcal: ? calendar : calendarstd/time/calendar/calendar: V = cal-isostd/time/calendar/cal-iso: calendar )result: -> ndet time : ndetstd/core/types/ndet: X timestd/time/time/time: V tsts: timescale.timestd/time/time/timescale/date/time: (ts : timescale, d : date, c : ? clock, tz : ? timezone, cal : ? calendar) -> ndet time(dd: date,cc: clock,tz-localstd/time/calendar/tz-local: () -> ndet timezone(),calcal: calendar) // Return the `:time` value for a given `:date` and `:clock` (=`clock0`) in the local timezone // interpreted by calendar `cal` (=`cal-iso`) pub fun dateutc/local-timestd/time/time/dateutc/local-time: (d : date, c : ? clock, cal : ? calendar, ts : ? timescale) -> <ndet,utc> time( dd: date : datestd/time/date/date: V, cc: ? clock : clockstd/time/date/clock: V = clock0std/time/date/clock0: clock, calcal: ? calendar : calendarstd/time/calendar/calendar: V = cal-isostd/time/calendar/cal-iso: calendar, tsts: ? timescale : timescalestd/time/instant/timescale: V = utcstd/time/utc/utc: () -> <utc,ndet> timescale() )result: -> <ndet,utc> time : <std/core/types/total: Endetstd/core/types/ndet: X,utcstd/time/utc/utc: (E, V) -> V> timestd/time/time/time: V tsts: timescale.timestd/time/time/timescale/date/time: (ts : timescale, d : date, c : ? clock, tz : ? timezone, cal : ? calendar) -> <ndet,utc> time(dd: date,cc: clock,tz-localstd/time/calendar/tz-local: () -> <ndet,utc> timezone(),calcal: calendar)