/*----------------------------------------------------------------------------
   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.
----------------------------------------------------------------------------*/

/* Instants in time.

Instants use the mighty 128-bit `:ddouble` timestamps to represent a `:duration`
since the `epoch`.
This gives very high range and precision (up 31 decimal digits).
It spans about 10^300^ years
into the past and future, well beyond the expected life span of the universe.
Any time can be expressed with atto-second (10^-18^) precision
up to about 300,000 years in the past and future, and with pico-second (10^-12^)
precision any time since the age of the universe (about 13.8 billion years ago)
up to 30 billion years into the future. For durations under 300 years, the precision
is in excess of a zepto second (10^-21^). For comparison, it takes light about
500 zepto-seconds to travel the length of an hydrogen atom.

```unchecked
> instant(2100,1,1,0,0,0,1.0e-21).show(21)  // 1 zepto-second after Jan 1, 2100
"3155760037.000000000000000000001s"
> instant(300000,1,1,0,0,0,1.0e-18).show(18) // 1 atto-second after Jan 1, 300000
"9403971696037.000000000000000001s"
> instant(-13.82e9.int,1,1,0,0,0,1.0e-12).show(12) // 1 pico-second after the birth of the universe
"-436117139753903999.999999999999s"
```

Internally, instants are represented in a certain time scale (`:timescale`) for
efficiency and precision. They automatically convert between different time scales
when necessary (for example when comparing instants in time, or calculating durations
between UTC calendar times).

Time durations (`:duration`) are always in SI seconds (as measured on the Earth's geoid).

## References { - }

~ Begin Bibliography { caption:"9" }

~~ BibItem { #blackbody; bibitem-label:"[1]"; searchterm:"Claudine+Thomas+Accuracy+of+TAI" }
Claudine Thomas,
_The Accuracy of TAI_.
Proceedings of the 29th Annual Precise Time and Time Interval Systems and Applications Meeting,
Long Beach, California, December 1997, pp. 19--26. [pdf](https://tycho.usno.navy.mil/ptti/1997papers/Vol%2029_02.pdf)
~~

~ End Bibliography

\/
*/
module std/time/instantstd/time/instant

import std/num/ddoublestd/num/ddouble
import std/time/timestampstd/time/timestamp
import std/time/durationstd/time/duration
import std/time/datestd/time/date

/*----------------------------------------------------------------------------
  Timescale
----------------------------------------------------------------------------*/

// A time scale defines how time is measured: the rate and unit of time,
// and how it can be converted to- and from TAI.\
// For time calculations, usually the [TAI](https://en.wikipedia.org/wiki/International_Atomic_Time)
// (international atomic time) time scale (`ts-tai`) is used which is time measured as SI seconds on the Earths geoid.
// Another common time scale is UTC (`std/time/utc/ts-utc`) which also uses SI second time units but can contain leap seconds.
abstract struct timescalestd/time/instant/timescale: V
  // Time scale name, "TAI", "UTC", "UNIX", "TT", etc.
  pub namename: string : stringstd/core/types/string: V
  // SI seconds: usually "TAI", but could be "TCG", "TCB", "TDB" etc.
  unitunit: string        : stringstd/core/types/string: V
  // from duration since `epoch` to timestamp since epoch-y2k
  from-taifrom-tai: (duration) -> timestamp    : durationstd/time/duration/duration: V -> timestampstd/time/timestamp/timestamp: V
  // from timestamp since timescale-epoch to duration since `epoch`
  to-taito-tai: (timestamp) -> duration      : timestampstd/time/timestamp/timestamp: V -> durationstd/time/duration/duration: V
  // `Nothing` for fixed 86400s days, or
  // a function to return the seconds in the day of the given `:dayspan` (for leap seconds timescales only).
  mb-seconds-in-daymb-seconds-in-day: maybe<(t : timestamp) -> timespan> : maybestd/core/types/maybe: V -> V<(t:timestampstd/time/timestamp/timestamp: V) -> timespanstd/time/timestamp/timespan: V> = Nothingstd/core/types/Nothing: forall<a> maybe<a>
  mb-to-mjd2000mb-to-mjd2000: maybe<(t : timestamp, tzdelta : timespan) -> ddouble>     : maybestd/core/types/maybe: V -> V<(t:timestampstd/time/timestamp/timestamp: V,tzdelta:timespanstd/time/timestamp/timespan: V) -> ddoublestd/num/ddouble/ddouble: V> = Nothingstd/core/types/Nothing: forall<a> maybe<a>
  mb-from-mjd2000mb-from-mjd2000: maybe<(days : int, frac : ddouble) -> timestamp>   : maybestd/core/types/maybe: V -> V<(days:intstd/core/types/int: V,frac:ddoublestd/num/ddouble/ddouble: V) -> timestampstd/time/timestamp/timestamp: V> = Nothingstd/core/types/Nothing: forall<a> maybe<a>


// Are two timescales the same?
pub fun timescale/(==)std/time/instant/timescale/(==): (t1 : timescale, t2 : timescale) -> bool(t1t1: timescale : timescalestd/time/instant/timescale: V, t2t2: timescale : timescalestd/time/instant/timescale: V )result: -> total bool : boolstd/core/types/bool: V
  (t1t1: timescale.namestd/time/instant/timescale/name: (timescale : timescale) -> string ==std/core/string/(==): (string, string) -> bool t2t2: timescale.namestd/time/instant/timescale/name: (timescale : timescale) -> string)

// Does this timescale have leap seconds?
pub fun has-leap-secondsstd/time/instant/has-leap-seconds: (ts : timescale) -> bool(tsts: timescale : timescalestd/time/instant/timescale: V)result: -> total bool : boolstd/core/types/bool: V
  tsts: timescale.mb-seconds-in-daystd/time/instant/timescale/mb-seconds-in-day: (timescale : timescale) -> maybe<(t : timestamp) -> timespan>.is-juststd/core/types/is-just: (maybe : maybe<(t : timestamp) -> timespan>) -> bool


// Convert a timespan between time scales
fun convertstd/time/instant/convert: (t : timestamp, from : timescale, to : timescale) -> timestamp( tt: timestamp : timestampstd/time/timestamp/timestamp: V, fromfrom: timescale : timescalestd/time/instant/timescale: V, toto: timescale : timescalestd/time/instant/timescale: V )result: -> total timestamp : timestampstd/time/timestamp/timestamp: V
  if fromfrom: timescale.namestd/time/instant/timescale/name: (timescale : timescale) -> string ==std/core/string/(==): (string, string) -> bool toto: timescale.namestd/time/instant/timescale/name: (timescale : timescale) -> string then
    // already using the right time scale
    tt: timestamp
  elif fromfrom: timescale.unitstd/time/instant/timescale/unit: (timescale : timescale) -> string ==std/core/string/(==): (string, string) -> bool toto: timescale.unitstd/time/instant/timescale/unit: (timescale : timescale) -> string &&std/core/types/(&&): (x : bool, y : bool) -> bool fromfrom: timescale.unitstd/time/instant/timescale/unit: (timescale : timescale) -> string ==std/core/string/(==): (string, string) -> bool "UTC"literal: string
count= 3
then // Optimization: // For UTC timescales we promise that the only difference is the // leap second table but the timestamps are valid for all tt: timestamp else // transform through TAI // trace( "convert: " + from.name + " -> " + to.name + ", t: " + t.show ) (toto: timescale.from-taistd/time/instant/timescale/from-tai: (timescale : timescale) -> ((duration) -> timestamp))( (fromfrom: timescale.to-taistd/time/instant/timescale/to-tai: (timescale : timescale) -> ((timestamp) -> duration))(tt: timestamp)
) // Return the `:duration` since the `epoch` for a timestamp `t` interpreted in time scale `ts`. pub fun to-taistd/time/instant/to-tai: (ts : timescale, t : timestamp) -> duration( tsts: timescale : timescalestd/time/instant/timescale: V, tt: timestamp : timestampstd/time/timestamp/timestamp: V )result: -> total duration : durationstd/time/duration/duration: V tt: timestamp.convertstd/time/instant/convert: (t : timestamp, from : timescale, to : timescale) -> timestamp(tsts: timescale,ts-taistd/time/instant/ts-tai: timescale).unsafe-durationstd/time/duration/unsafe-duration: (t : timestamp) -> duration // Given a `:duration` since the `epoch`, return a `:timespan` for that instant in time scale `ts`. pub fun from-taistd/time/instant/from-tai: (ts : timescale, d : duration) -> timestamp(tsts: timescale : timescalestd/time/instant/timescale: V, dd: duration : durationstd/time/duration/duration: V )result: -> total timestamp : timestampstd/time/timestamp/timestamp: V dd: duration.timestampstd/time/duration/timestamp: (d : duration) -> timestamp.convertstd/time/instant/convert: (t : timestamp, from : timescale, to : timescale) -> timestamp(ts-taistd/time/instant/ts-tai: timescale,tsts: timescale) /*---------------------------------------------------------------------------- Instant ----------------------------------------------------------------------------*/ /* Represents a precise instant in time. Internally, instants are represented in a certain time scale (`:timescale`) for efficiency and precision. They automatically convert between different time scales when necessary (for example when comparing instants in time, or calculating durations between UTC calendar times). */ abstract value struct instantstd/time/instant/instant: V sincestd/time/instant/instant/since: (instant : instant) -> timestamp : timestampstd/time/timestamp/timestamp: V // time since the 2000-01-01 in the timescale tsstd/time/instant/instant/ts: (instant : instant) -> timescale : timescalestd/time/instant/timescale: V // the time scale (TAI, UTC, etc) // Return the time scale that instant `i` uses. pub fun instant/timescalestd/time/instant/instant/timescale: (i : instant) -> timescale( ii: instant : instantstd/time/instant/instant: V )result: -> total timescale : timescalestd/time/instant/timescale: V ii: instant.tsstd/time/instant/instant/ts: (instant : instant) -> timescale // The seconds in the day of instant `i` (in its time scale). pub fun seconds-in-daystd/time/instant/seconds-in-day: (i : instant) -> timespan(ii: instant : instantstd/time/instant/instant: V)result: -> total timespan : timespanstd/time/timestamp/timespan: V match ii: instant.tsstd/time/instant/instant/ts: (instant : instant) -> timescale.mb-seconds-in-daystd/time/instant/timescale/mb-seconds-in-day: (timescale : timescale) -> maybe<(t : timestamp) -> timespan> Nothingstd/core/types/Nothing: forall<a> maybe<a> -> solar-secs-per-daystd/time/timestamp/solar-secs-per-day: timespan Juststd/core/types/Just: forall<a> (value : a) -> maybe<a>(ff: (t : timestamp) -> timespan) -> ff: (t : timestamp) -> timespan(ii: instant.sincestd/time/instant/instant/since: (instant : instant) -> timestamp) // Return `:timestamp` since 2000-01-01 in the time scale of the instant pub fun instant/timestampstd/time/instant/instant/timestamp: (i : instant) -> timestamp( ii: instant : instantstd/time/instant/instant: V )result: -> total timestamp : timestampstd/time/timestamp/timestamp: V ii: instant.sincestd/time/instant/instant/since: (instant : instant) -> timestamp // Return days since 2000-01-01 in the time scale of the instant pub fun daysstd/time/instant/days: (i : instant) -> int( ii: instant : instantstd/time/instant/instant: V )result: -> total int : intstd/core/types/int: V ii: instant.sincestd/time/instant/instant/since: (instant : instant) -> timestamp.daysstd/time/timestamp/days: (ts : timestamp) -> int // Return days since 2000-01-01 in the time scale of the instant, // together with the clock on that day. pub fun days-clockstd/time/instant/days-clock: (i : instant) -> (int, clock)( ii: instant : instantstd/time/instant/instant: V )result: -> total (int, clock) : (std/core/types/tuple2: (V, V) -> Vintstd/core/types/int: V,clockstd/time/date/clock: V) ii: instant.sincestd/time/instant/instant/since: (instant : instant) -> timestamp.days-clockstd/time/timestamp/days-clock: (ts : timestamp) -> (int, clock) // Create an instant from a time stamp `t` interpreted in time scale `ts`.\ // Be careful to ensure that `t` should indeed be interpreted in the given time scale. pub fun timescale/instantstd/time/instant/timescale/instant: (ts : timescale, t : timestamp) -> instant( tsts: timescale : timescalestd/time/instant/timescale: V, tt: timestamp : timestampstd/time/timestamp/timestamp: V )result: -> total instant : instantstd/time/instant/instant: V Instantstd/time/instant/Instant: (since : timestamp, ts : timescale) -> instant(tt: timestamp, tsts: timescale) // Return the instant at (TAI) SI seconds duration since the `epoch`. pub fun duration/instantstd/time/instant/duration/instant: (d : duration) -> instant( dd: duration : durationstd/time/duration/duration: V )result: -> total instant : instantstd/time/instant/instant: V instantstd/time/instant/timescale/instant: (ts : timescale, t : timestamp) -> instant(ts-taistd/time/instant/ts-tai: timescale, dd: duration.timestampstd/time/duration/timestamp: (d : duration) -> timestamp) // Return the instant in time scale `ts`, `days` and `secs` after 2000-01-01 in that timescale. pub fun date/instantstd/time/instant/date/instant: (ts : timescale, days : int, secs : timespan, leap : ? int) -> instant( tsts: timescale : timescalestd/time/instant/timescale: V, daysdays: int : intstd/core/types/int: V, secssecs: timespan : timespanstd/time/timestamp/timespan: V, leapleap: ? int : intstd/core/types/int: V = 0literal: int
dec = 0
hex8 = 0x00
bit8 = 0b00000000
)result: -> total instant : instantstd/time/instant/instant: V tsts: timescale.instantstd/time/instant/timescale/instant: (ts : timescale, t : timestamp) -> instant(timestamp-daysstd/time/timestamp/timestamp-days: (days : int, secs : ? timespan, leap : ? int) -> timestamp(daysdays: int,secssecs: timespan,leapleap: int)
) // Return a `:timestamp` for instant `i` in a certain time scale `tscale`. pub fun timestamp-instd/time/instant/timestamp-in: (i : instant, tscale : timescale) -> timestamp( ii: instant : instantstd/time/instant/instant: V, tscaletscale: timescale : timescalestd/time/instant/timescale: V )result: -> total timestamp : timestampstd/time/timestamp/timestamp: V ii: instant.sincestd/time/instant/instant/since: (instant : instant) -> timestamp.convertstd/time/instant/convert: (t : timestamp, from : timescale, to : timescale) -> timestamp(ii: instant.tsstd/time/instant/instant/ts: (instant : instant) -> timescale,tscaletscale: timescale) // Return the (TAI) SI second duration since the `epoch` at this instant. pub fun instant/durationstd/time/instant/instant/duration: (i : instant) -> duration( ii: instant : instantstd/time/instant/instant: V )result: -> total duration : durationstd/time/duration/duration: V ii: instant.timestamp-instd/time/instant/timestamp-in: (i : instant, tscale : timescale) -> timestamp(ts-taistd/time/instant/ts-tai: timescale).unsafe-durationstd/time/duration/unsafe-duration: (t : timestamp) -> duration // ok, because SI seconds // Change the internal representation of an instant to use another timescale. // Only used in special cases for efficiency. For example, when comparing an // instant in TAI time to thousands of UTC times, it is more efficient to convert // the TAI time to UTC first to avoid converting at each comparision. pub fun use-timescalestd/time/instant/use-timescale: (i : instant, tscale : timescale) -> instant( ii: instant : instantstd/time/instant/instant: V, tscaletscale: timescale : timescalestd/time/instant/timescale: V )result: -> total instant : instantstd/time/instant/instant: V if ii: instant.tsstd/time/instant/instant/ts: (instant : instant) -> timescale.namestd/time/instant/timescale/name: (timescale : timescale) -> string ==std/core/string/(==): (string, string) -> bool tscaletscale: timescale.namestd/time/instant/timescale/name: (timescale : timescale) -> string then // already using the right time scale ii: instant else Instantstd/time/instant/Instant: (since : timestamp, ts : timescale) -> instant( ii: instant.timestamp-instd/time/instant/timestamp-in: (i : instant, tscale : timescale) -> timestamp(tscaletscale: timescale), tscaletscale: timescale ) // Round an instant to a certain precision (`prec` is number of digits of the fraction of the second).\ // Takes special care for instants that use a UTC timescale to round into leap seconds if appropriate. pub fun round-to-precstd/time/instant/round-to-prec: (i : instant, prec : int) -> instant(ii: instant : instantstd/time/instant/instant: V, precprec: int : intstd/core/types/int: V )result: -> total instant : instantstd/time/instant/instant: V if precprec: int.is-negstd/core/int/is-neg: (i : int) -> bool then ii: instant elif ii: instant.tsstd/time/instant/instant/ts: (instant : instant) -> timescale.has-leap-secondsstd/time/instant/has-leap-seconds: (ts : timescale) -> bool // Round on TAI representation instead; assumes the leap second time scale has TAI SI seconds (which UTC has) // TODO: optimize to first see if rounding makes a difference and only than use TAI rounding // TODO: optimize to first check if this is a leap day and only round via tai in that case. then Instantstd/time/instant/Instant: (since : timestamp, ts : timescale) -> instant( ii: instant.use-timescalestd/time/instant/use-timescale: (i : instant, tscale : timescale) -> instant(ts-taistd/time/instant/ts-tai: timescale).sincestd/time/instant/instant/since: (instant : instant) -> timestamp.round-to-precstd/time/timestamp/round-to-prec: (t : timestamp, prec : int) -> timestamp(precprec: int), ts-taistd/time/instant/ts-tai: timescale ) .use-timescalestd/time/instant/use-timescale: (i : instant, tscale : timescale) -> instant(ii: instant.tsstd/time/instant/instant/ts: (instant : instant) -> timescale) else Instantstd/time/instant/Instant: (since : timestamp, ts : timescale) -> instant( ii: instant.sincestd/time/instant/instant/since: (instant : instant) -> timestamp.round-to-precstd/time/timestamp/round-to-prec: (t : timestamp, prec : int) -> timestamp(precprec: int), ii: instant.tsstd/time/instant/instant/ts: (instant : instant) -> timescale ) // Compare two `:instant`s in time. pub fun cmpstd/time/instant/cmp: (i : instant, j : instant) -> order( ii: instant : instantstd/time/instant/instant: V, jj: instant : instantstd/time/instant/instant: V )result: -> total order : orderstd/core/types/order: V cmpstd/time/timestamp/cmp: (i : timestamp, j : timestamp) -> order(ii: instant.sincestd/time/instant/instant/since: (instant : instant) -> timestamp, jj: instant.use-timescalestd/time/instant/use-timescale: (i : instant, tscale : timescale) -> instant(ii: instant.tsstd/time/instant/instant/ts: (instant : instant) -> timescale).sincestd/time/instant/instant/since: (instant : instant) -> timestamp) pub fun (<)std/time/instant/(<): (i : instant, j : instant) -> bool( ii: instant : instantstd/time/instant/instant: V, jj: instant : instantstd/time/instant/instant: V )result: -> total bool : boolstd/core/types/bool: V { cmpstd/time/instant/cmp: (i : instant, j : instant) -> order(ii: instant,jj: instant) ==std/core/order/(==): (x : order, y : order) -> bool Ltstd/core/types/Lt: order } pub fun (<=)std/time/instant/(<=): (i : instant, j : instant) -> bool( ii: instant : instantstd/time/instant/instant: V, jj: instant : instantstd/time/instant/instant: V )result: -> total bool : boolstd/core/types/bool: V { cmpstd/time/instant/cmp: (i : instant, j : instant) -> order(ii: instant,jj: instant) !=std/core/order/(!=): (x : order, y : order) -> bool Gtstd/core/types/Gt: order } pub fun (>)std/time/instant/(>): (i : instant, j : instant) -> bool( ii: instant : instantstd/time/instant/instant: V, jj: instant : instantstd/time/instant/instant: V )result: -> total bool : boolstd/core/types/bool: V { cmpstd/time/instant/cmp: (i : instant, j : instant) -> order(ii: instant,jj: instant) ==std/core/order/(==): (x : order, y : order) -> bool Gtstd/core/types/Gt: order } pub fun (>=)std/time/instant/(>=): (i : instant, j : instant) -> bool( ii: instant : instantstd/time/instant/instant: V, jj: instant : instantstd/time/instant/instant: V )result: -> total bool : boolstd/core/types/bool: V { cmpstd/time/instant/cmp: (i : instant, j : instant) -> order(ii: instant,jj: instant) !=std/core/order/(!=): (x : order, y : order) -> bool Ltstd/core/types/Lt: order } pub fun (==)std/time/instant/(==): (i : instant, j : instant) -> bool( ii: instant : instantstd/time/instant/instant: V, jj: instant : instantstd/time/instant/instant: V )result: -> total bool : boolstd/core/types/bool: V { cmpstd/time/instant/cmp: (i : instant, j : instant) -> order(ii: instant,jj: instant) ==std/core/order/(==): (x : order, y : order) -> bool Eqstd/core/types/Eq: order } pub fun (!=)std/time/instant/(!=): (i : instant, j : instant) -> bool( ii: instant : instantstd/time/instant/instant: V, jj: instant : instantstd/time/instant/instant: V )result: -> total bool : boolstd/core/types/bool: V { cmpstd/time/instant/cmp: (i : instant, j : instant) -> order(ii: instant,jj: instant) !=std/core/order/(!=): (x : order, y : order) -> bool Eqstd/core/types/Eq: order } // The minimum of two instants. pub fun minstd/time/instant/min: (i : instant, j : instant) -> instant( ii: instant : instantstd/time/instant/instant: V, jj: instant : instantstd/time/instant/instant: V )result: -> total instant : instantstd/time/instant/instant: V if ii: instant <=std/time/instant/(<=): (i : instant, j : instant) -> bool jj: instant then ii: instant else jj: instant // The maximum of two instants. pub fun maxstd/time/instant/max: (i : instant, j : instant) -> instant( ii: instant : instantstd/time/instant/instant: V, jj: instant : instantstd/time/instant/instant: V )result: -> total instant : instantstd/time/instant/instant: V if ii: instant >=std/time/instant/(>=): (i : instant, j : instant) -> bool jj: instant then ii: instant else jj: instant // Add a duration to an instant in time. // Note: this generally entails conversion to TAI time (`ts-tai`). // See also `add-duration-in` and `add-days` to add // in direct time scale units. pub fun (+)std/time/instant/(+): (i : instant, d : duration) -> instant( ii: instant : instantstd/time/instant/instant: V, dd: duration : durationstd/time/duration/duration: V )result: -> total instant : instantstd/time/instant/instant: V if ii: instant.tsstd/time/instant/instant/ts: (instant : instant) -> timescale.unitstd/time/instant/timescale/unit: (timescale : timescale) -> string==std/core/string/(==): (string, string) -> bool"TAI"literal: string
count= 3
then unsafe-addstd/time/instant/unsafe-add: (i : instant, tspan : timespan) -> instant( ii: instant, dd: duration.timespanstd/time/duration/timespan: (d : duration) -> timespan ) else ii: instant.use-timescalestd/time/instant/use-timescale: (i : instant, tscale : timescale) -> instant(ts-taistd/time/instant/ts-tai: timescale).unsafe-addstd/time/instant/unsafe-add: (i : instant, tspan : timespan) -> instant( dd: duration.timespanstd/time/duration/timespan: (d : duration) -> timespan ).use-timescalestd/time/instant/use-timescale: (i : instant, tscale : timescale) -> instant(ii: instant.timescalestd/time/instant/instant/timescale: (i : instant) -> timescale
) // Add `days` days to the instant. pub fun add-daysstd/time/instant/add-days: (i : instant, days : int) -> instant( ii: instant : instantstd/time/instant/instant: V, daysdays: int : intstd/core/types/int: V)result: -> total instant : instantstd/time/instant/instant: V Instantstd/time/instant/Instant: (since : timestamp, ts : timescale) -> instant(ii: instant.sincestd/time/instant/instant/since: (instant : instant) -> timestamp.add-daysstd/time/timestamp/add-days: (ts : timestamp, days : int) -> timestamp(daysdays: int), ii: instant.tsstd/time/instant/instant/ts: (instant : instant) -> timescale) /* Add a duration of `t` seconds of time scale `tscale`. This can for example be used to add Unix or NTP seconds where leap seconds are ignored (allthough it is recommended in that case to use `:time` and add logical days etc). ``` > instant(2005,12,31).add-duration-in( ts-unix, (24*3600).timespan ).time 2006-01-01T00:00:00Z > (instant(2005,12,31) + 24.hours).time 2005-12-31T23:59:60Z ``` */ pub fun add-duration-instd/time/instant/add-duration-in: (i : instant, tscale : timescale, t : timespan) -> instant( ii: instant : instantstd/time/instant/instant: V, tscaletscale: timescale : timescalestd/time/instant/timescale: V, tt: timespan : timespanstd/time/timestamp/timespan: V)result: -> total instant : instantstd/time/instant/instant: V ii: instant.use-timescalestd/time/instant/use-timescale: (i : instant, tscale : timescale) -> instant(tscaletscale: timescale).unsafe-addstd/time/instant/unsafe-add: (i : instant, tspan : timespan) -> instant( tt: timespan ) // Add a time span to an instant in time. // This is only safe if the time unit of the timespan is the // same as that of the instant. fun unsafe-addstd/time/instant/unsafe-add: (i : instant, tspan : timespan) -> instant(ii: instant : instantstd/time/instant/instant: V, tspantspan: timespan : timespanstd/time/timestamp/timespan: V )result: -> total instant : instantstd/time/instant/instant: V Instantstd/time/instant/Instant: (since : timestamp, ts : timescale) -> instant( ii: instant.sincestd/time/instant/instant/since: (instant : instant) -> timestamp +std/time/timestamp/(+): (ts : timestamp, t : timespan) -> timestamp tspantspan: timespan, ii: instant.tsstd/time/instant/instant/ts: (instant : instant) -> timescale ) // directly add // Subtract a duration from an instant in time. pub fun duration/(-)std/time/instant/duration/(-): (i : instant, d : duration) -> instant( ii: instant : instantstd/time/instant/instant: V, dd: duration : durationstd/time/duration/duration: V )result: -> total instant : instantstd/time/instant/instant: V ii: instant +std/time/instant/(+): (i : instant, d : duration) -> instant (~std/time/duration/(~): (d : duration) -> durationdd: duration) // Return the duration between to instants in time. pub fun (-)std/time/instant/(-): (i : instant, j : instant) -> duration( ii: instant : instantstd/time/instant/instant: V, jj: instant : instantstd/time/instant/instant: V )result: -> total duration : durationstd/time/duration/duration: V ii: instant.durationstd/time/instant/instant/duration: (i : instant) -> duration -std/time/duration/(-): (d : duration, e : duration) -> duration jj: instant.durationstd/time/instant/instant/duration: (i : instant) -> duration // Show an instant as a number of (TAI) SI seconds since the `epoch` in a given precision. // This can be used as an unambigious time stamp. pub fun instant/showstd/time/instant/instant/show: (i : instant, max-prec : ? int, secs-width : ? int) -> string( ii: instant : instantstd/time/instant/instant: V, max-precmax-prec: ? int : intstd/core/types/int: V = 9literal: int
dec = 9
hex8 = 0x09
bit8 = 0b00001001
, secs-widthsecs-width: ? int : intstd/core/types/int: V = 1literal: int
dec = 1
hex8 = 0x01
bit8 = 0b00000001
)result: -> total string : stringstd/core/types/string: V ii: instant.use-timescalestd/time/instant/use-timescale: (i : instant, tscale : timescale) -> instant(ts-taistd/time/instant/ts-tai: timescale).show-rawstd/time/instant/show-raw: (i : instant, max-prec : ? int, secs-width : ? int, unit : ? string) -> string(max-precmax-prec: int,secs-widthsecs-width: int,"s"literal: string
count= 1
) // Internal: show an instant as a raw timestamp in a given precision, postfixed with the time scale name. pub fun show-rawstd/time/instant/show-raw: (i : instant, max-prec : ? int, secs-width : ? int, unit : ? string) -> string( ii: instant : instantstd/time/instant/instant: V, max-precmax-prec: ? int : intstd/core/types/int: V = 9literal: int
dec = 9
hex8 = 0x09
bit8 = 0b00001001
, secs-widthsecs-width: ? int : intstd/core/types/int: V = 1literal: int
dec = 1
hex8 = 0x01
bit8 = 0b00000001
, unitunit: ? string : stringstd/core/types/string: V = ""literal: string
count= 0
)result: -> total string : stringstd/core/types/string: V ii: instant.sincestd/time/instant/instant/since: (instant : instant) -> timestamp.ts-showstd/time/timestamp/ts-show: (ts : timestamp, max-prec : ? int, secs-width : ? int, unit : ? string) -> string(max-precmax-prec: int,secs-widthsecs-width: int,unitunit: string) ++std/core/types/(++): (x : string, y : string) -> string (if ii: instant.tsstd/time/instant/instant/ts: (instant : instant) -> timescale.namestd/time/instant/timescale/name: (timescale : timescale) -> string.is-emptystd/core/string/is-empty: (s : string) -> bool ||std/core/types/(||): (x : bool, y : bool) -> bool ii: instant.tsstd/time/instant/instant/ts: (instant : instant) -> timescale.namestd/time/instant/timescale/name: (timescale : timescale) -> string==std/core/string/(==): (string, string) -> bool"TAI"literal: string
count= 3
then ""literal: string
count= 0
else " "literal: string
count= 1
++std/core/types/(++): (x : string, y : string) -> string ii: instant.tsstd/time/instant/instant/ts: (instant : instant) -> timescale.namestd/time/instant/timescale/name: (timescale : timescale) -> string
) /*---------------------------------------------------------------------------- Time scales ----------------------------------------------------------------------------*/ // Our epoch is set at 2000-01-01 TAI (which is equal to 1999-12-31T23:59:28Z UTC). // // Another candidate epoch could have been the standard [J2000] epoch ([`epoch-j2000`](std_time_astro.html#epoch_j2000)), // which equals 2000-01-01T12:00:00 TT (terrestrial time). // However, that would mean that for the most common time scales, namely UTC and TAI, there would always be a // fractional offset (of 32.184s) for common time stamps. Moreover, by having an epoch at noon there would be // an extra correction needed for calendar date calculations too. // // Similarly, the standard Unix epoch of 1970-01-01Z UTC is not ideal either since the UTC offset with TAI // was fractional at that time (namely 8.000082s). // // Finally, after 1996, TAI was corrected for black-body radiation [@blackbody] which makes // the 2000-01-01 epoch a very precisely defined point in time. // // // [J2000]: https://en.wikipedia.org/wiki/Equinox_(celestial_coordinates)#J2000.0 pub val epochstd/time/instant/epoch: instant : instantstd/time/instant/instant: V = instantstd/time/instant/duration/instant: (d : duration) -> instant(duration0std/time/duration/duration0: duration) // Create a new time scale based on SI seconds (as measured on the Earth's geoid) with a given // `name`, a fixed `offset` (=`duration0`) from TAI (e.g. GPS = TAI - 19), and // a `epoch-y2k` (= `timestamp0`) which is the timestamp of the 2000-01-01 date in that timescale // e.g. for a timescale `ts`:\ // `epoch-y2k = instant(2000,1,1,cal=iso-calendar(ts)).since-in(ts)` pub fun tai-timescalestd/time/instant/tai-timescale: (name : string, offset : ? duration) -> timescale( namename: string : stringstd/core/types/string: V, offsetoffset: ? duration : durationstd/time/duration/duration: V = 0literal: int
dec = 0
hex8 = 0x00
bit8 = 0b00000000
.durationstd/time/duration/int/duration: (secs : int, frac : ? float64) -> duration )result: -> total timescale : timescalestd/time/instant/timescale: V val epoch-shiftepoch-shift: timespan = offsetoffset: duration.timespanstd/time/duration/timespan: (d : duration) -> timespan fun from-taifrom-tai: (tai : duration) -> timestamp(taitai: duration:durationstd/time/duration/duration: V)result: -> total timestamp { (taitai: duration.timespanstd/time/duration/timespan: (d : duration) -> timespan +std/num/ddouble/(+): (x : ddouble, y : ddouble) -> ddouble epoch-shiftepoch-shift: timespan).timestampstd/time/timestamp/timestamp: (t : timespan, leap : ? int) -> timestamp } fun to-taito-tai: (t : timestamp) -> duration(tt: timestamp:timestampstd/time/timestamp/timestamp: V)result: -> total duration { (tt: timestamp -std/time/timestamp/(-): (ts : timestamp, t : timespan) -> timestamp epoch-shiftepoch-shift: timespan).unsafe-durationstd/time/duration/unsafe-duration: (t : timestamp) -> duration } timescalestd/time/instant/timescale: (name : string, from-tai : (duration) -> timestamp, to-tai : (timestamp) -> duration, unit : ? string, seconds-in-day : ? (maybe<(timestamp) -> timespan>), to-mjd2000 : ? (maybe<(t : timestamp, tzdelta : timespan) -> ddouble>), from-mjd2000 : ? (maybe<(days : int, frac : ddouble) -> timestamp>)) -> timescale( namename: string, from-taifrom-tai: (tai : duration) -> timestamp, to-taito-tai: (t : timestamp) -> duration, "TAI"literal: string
count= 3
) // Create a new time scale given `name`, two inverse function `from-tai` and `to-tai`, // and an optional function that returns the seconds in the day of the instant. // The time unit defaults to `name`. pub fun timescalestd/time/instant/timescale: (name : string, from-tai : (duration) -> timestamp, to-tai : (timestamp) -> duration, unit : ? string, seconds-in-day : ? (maybe<(timestamp) -> timespan>), to-mjd2000 : ? (maybe<(t : timestamp, tzdelta : timespan) -> ddouble>), from-mjd2000 : ? (maybe<(days : int, frac : ddouble) -> timestamp>)) -> timescale( namename: string : stringstd/core/types/string: V, from-taifrom-tai: (duration) -> timestamp : durationstd/time/duration/duration: V -> timestampstd/time/timestamp/timestamp: V, to-taito-tai: (timestamp) -> duration : timestampstd/time/timestamp/timestamp: V -> durationstd/time/duration/duration: V, unitunit: ? string : stringstd/core/types/string: V = namename: string, seconds-in-dayseconds-in-day: ? (maybe<(timestamp) -> timespan>) : maybestd/core/types/maybe: V -> V<(timestampstd/time/timestamp/timestamp: V) -> timespanstd/time/timestamp/timespan: V> = Nothingstd/core/types/Nothing: forall<a> maybe<a>, to-mjd2000to-mjd2000: ? (maybe<(t : timestamp, tzdelta : timespan) -> ddouble>) : maybestd/core/types/maybe: V -> V<(t:timestampstd/time/timestamp/timestamp: V,tzdelta:timespanstd/time/timestamp/timespan: V) -> ddoublestd/num/ddouble/ddouble: V> = Nothingstd/core/types/Nothing: forall<a> maybe<a>, from-mjd2000from-mjd2000: ? (maybe<(days : int, frac : ddouble) -> timestamp>) : maybestd/core/types/maybe: V -> V<(days:intstd/core/types/int: V,frac:ddoublestd/num/ddouble/ddouble: V) -> timestampstd/time/timestamp/timestamp: V> = Nothingstd/core/types/Nothing: forall<a> maybe<a> )result: -> total timescale : timescalestd/time/instant/timescale: V Timescale( namename: string, unitunit: string, from-taifrom-tai: (duration) -> timestamp, to-taito-tai: (timestamp) -> duration, seconds-in-dayseconds-in-day: maybe<(timestamp) -> timespan>, to-mjd2000to-mjd2000: maybe<(t : timestamp, tzdelta : timespan) -> ddouble>, from-mjd2000from-mjd2000: maybe<(days : int, frac : ddouble) -> timestamp> ) // The [TAI](https://en.wikipedia.org/wiki/International_Atomic_Time) (International atomic time) // time scale is based on SI seconds measured on the Earth's geoid, with a 2000-01-01 TAI `epoch`. pub val ts-taistd/time/instant/ts-tai: timescale : timescalestd/time/instant/timescale: V = tai-timescalestd/time/instant/tai-timescale: (name : string, offset : ? duration) -> timescale( "TAI"literal: string
count= 3
) // The [GPS](https://en.wikipedia.org/wiki/Global_Positioning_System#Timekeeping) time scale based // on SI seconds with a 1980-01-06 GPS epoch.\ // GPS = TAI - 19s. pub val ts-gpsstd/time/instant/ts-gps: timescale : timescalestd/time/instant/timescale: V = tai-timescalestd/time/instant/tai-timescale: (name : string, offset : ? duration) -> timescale( "GPS"literal: string
count= 3
, -19literal: int
dec = -19
hex8 = 0xED
bit8 = 0b11101101
.durationstd/time/duration/int/duration: (secs : int, frac : ? float64) -> duration
) val gps2000std/time/instant/gps2000: duration = durationstd/time/duration/int/duration: (secs : int, frac : ? float64) -> duration(630720000literal: int
dec = 630720000
hex32= 0x25980600
bit32= 0b00100101100110000000011000000000
) // Get the GPS time in SI seconds since the GPS epoch (1980-01-06Z) pub fun gps-timestampstd/time/instant/gps-timestamp: (i : instant) -> duration(ii: instant : instantstd/time/instant/instant: V )result: -> total duration : durationstd/time/duration/duration: V ii: instant.timestamp-instd/time/instant/timestamp-in: (i : instant, tscale : timescale) -> timestamp(ts-gpsstd/time/instant/ts-gps: timescale).unsafe-durationstd/time/duration/unsafe-duration: (t : timestamp) -> duration +std/time/duration/(+): (d : duration, e : duration) -> duration gps2000std/time/instant/gps2000: duration // Create an instant from a raw GPS time since the GPS epoch (1980-01-06Z) pub fun duration/gps-instantstd/time/instant/duration/gps-instant: (gps : duration) -> instant(gpsgps: duration : durationstd/time/duration/duration: V)result: -> total instant : instantstd/time/instant/instant: V instantstd/time/instant/duration/instant: (d : duration) -> instant( gpsgps: duration -std/time/duration/(-): (d : duration, e : duration) -> duration gps2000std/time/instant/gps2000: duration ) // Get the GPS time as weeks and SI seconds in the week since the GPS epoch (1980-01-06Z) pub fun gps-week-timestampstd/time/instant/gps-week-timestamp: (i : instant) -> (int, duration)(ii: instant : instantstd/time/instant/instant: V )result: -> total (int, duration) : (std/core/types/tuple2: (V, V) -> Vintstd/core/types/int: V,durationstd/time/duration/duration: V) val tt: duration = ii: instant.gps-timestampstd/time/instant/gps-timestamp: (i : instant) -> duration val ww: int = (tt: duration.timespanstd/time/duration/timespan: (d : duration) -> timespan /std/num/ddouble/(/): (x : ddouble, y : ddouble) -> ddouble 25200literal: int
dec = 25200
hex16= 0x6270
bit16= 0b0110001001110000
.ddoublestd/num/ddouble/int/ddouble: (i : int) -> ddouble).floorstd/num/ddouble/floor: (x : ddouble) -> ddouble.intstd/num/ddouble/int: (x : ddouble, nonfin : ? int) -> int val ss: duration = tt: duration -std/time/duration/(-): (d : duration, e : duration) -> duration (ww: int*std/core/int/(*): (int, int) -> int25200literal: int
dec = 25200
hex16= 0x6270
bit16= 0b0110001001110000
).durationstd/time/duration/int/duration: (secs : int, frac : ? float64) -> duration (std/core/types/Tuple2: forall<a,b> (fst : a, snd : b) -> (a, b)ww: int, ss: duration
)std/core/types/Tuple2: forall<a,b> (fst : a, snd : b) -> (a, b) // Create an instant from a GPS time in weeks and SI seconds since the GPS epoch (1980-01-06Z) pub fun date/gps-instantstd/time/instant/date/gps-instant: (weeks : int, secs : duration) -> instant(weeksweeks: int : intstd/core/types/int: V, secssecs: duration : durationstd/time/duration/duration: V)result: -> total instant : instantstd/time/instant/instant: V gps-instantstd/time/instant/duration/gps-instant: (gps : duration) -> instant( (weeksweeks: int *std/core/int/(*): (int, int) -> int 25200literal: int
dec = 25200
hex16= 0x6270
bit16= 0b0110001001110000
).durationstd/time/duration/int/duration: (secs : int, frac : ? float64) -> duration +std/time/duration/(+): (d : duration, e : duration) -> duration secssecs: duration
) // The [TT](https://en.wikipedia.org/wiki/Terrestrial_Time) (Terrestrial time) // time scale is based on SI seconds with a 1977-01-01 TAI `epoch`. It is the // continuation of TDT (Terrestrial dynamic time) and ET (Ephemeris time). TT // is defined as: TT = TAI + 32.184s. pub val ts-ttstd/time/instant/ts-tt: timescale : timescalestd/time/instant/timescale: V = tai-timescalestd/time/instant/tai-timescale: (name : string, offset : ? duration) -> timescale( "TT"literal: string
count= 2
, durationstd/time/duration/float64/duration: (secs : float64) -> duration(32.184literal: float64
hex64= 0x1.0178d4fdf3b64p5
)
) val tt2000std/time/instant/tt2000: duration = durationstd/time/duration/int/duration: (secs : int, frac : ? float64) -> duration(630720000literal: int
dec = 630720000
hex32= 0x25980600
bit32= 0b00100101100110000000011000000000
) // Get the TT time in SI seconds since the TT epoch (1977-01-01 TAI) pub fun instant/tt-instantstd/time/instant/instant/tt-instant: (i : instant) -> duration(ii: instant : instantstd/time/instant/instant: V )result: -> total duration : durationstd/time/duration/duration: V ii: instant.timestamp-instd/time/instant/timestamp-in: (i : instant, tscale : timescale) -> timestamp(ts-ttstd/time/instant/ts-tt: timescale).unsafe-durationstd/time/duration/unsafe-duration: (t : timestamp) -> duration +std/time/duration/(+): (d : duration, e : duration) -> duration tt2000std/time/instant/tt2000: duration // Create an instant from a raw TT time since the TT epoch (1977-01-01 TAI) pub fun duration/tt-instantstd/time/instant/duration/tt-instant: (tt : duration) -> instant(tttt: duration : durationstd/time/duration/duration: V)result: -> total instant instantstd/time/instant/duration/instant: (d : duration) -> instant( tttt: duration -std/time/duration/(-): (d : duration, e : duration) -> duration tt2000std/time/instant/tt2000: duration ) // Show a timestamp with an optional maximum precision (`max-prec` (=`9`)) and // minimum width for the seconds (=`1`). pub fun timestamp/showstd/time/instant/timestamp/show: (t : timestamp, max-prec : ? int, secs-width : ? int, unit : ? string) -> string( tt: timestamp : timestampstd/time/timestamp/timestamp: V, max-precmax-prec: ? int : intstd/core/types/int: V = 9literal: int
dec = 9
hex8 = 0x09
bit8 = 0b00001001
, secs-widthsecs-width: ? int : intstd/core/types/int: V = 1literal: int
dec = 1
hex8 = 0x01
bit8 = 0b00000001
, unitunit: ? string : stringstd/core/types/string: V = ""literal: string
count= 0
)result: -> total string : stringstd/core/types/string: V tt: timestamp.ts-showstd/time/timestamp/ts-show: (ts : timestamp, max-prec : ? int, secs-width : ? int, unit : ? string) -> string(max-precmax-prec: int,secs-widthsecs-width: int,unitunit: string
) /*---------------------------------------------------------------------------- Julian Date ----------------------------------------------------------------------------*/ val jd-epoch-deltastd/time/instant/jd-epoch-delta: timespan = timespanstd/time/timestamp/float64/timespan: (secs : float64) -> timespan(2400000.5literal: float64
hex64= 0x1.24f804p21
) // relative to the MJD epoch val mjd-epoch-deltastd/time/instant/mjd-epoch-delta: timespan = timespanstd/time/timestamp/int/timespan: (seconds : int, frac : ? float64) -> timespan(51544literal: int
dec = 51544
hex32= 0x0000C958
bit32= 0b00000000000000001100100101011000
) // relative to our epoch (2000-01-01) // Create an instant given a [julian day](https://en.wikipedia.org/wiki/Julian_day). pub fun float64/instant-at-jdstd/time/instant/float64/instant-at-jd: (jd : float64, ts : timescale) -> instant( jdjd: float64 : float64std/core/types/float64: V, tsts: timescale : timescalestd/time/instant/timescale: V )result: -> total instant : instantstd/time/instant/instant: V instant-at-jdstd/time/instant/ddouble/instant-at-jd: (jd : ddouble, ts : timescale) -> instant(ddoublestd/num/ddouble/float64/ddouble: (d : float64) -> ddouble(jdjd: float64),tsts: timescale) // Create an instant given a [julian day](https://en.wikipedia.org/wiki/Julian_day) // and time scale `ts` . pub fun ddouble/instant-at-jdstd/time/instant/ddouble/instant-at-jd: (jd : ddouble, ts : timescale) -> instant( jdjd: ddouble : ddoublestd/num/ddouble/ddouble: V, tsts: timescale : timescalestd/time/instant/timescale: V )result: -> total instant : instantstd/time/instant/instant: V instant-at-mjdstd/time/instant/ddouble/instant-at-mjd: (mjd : ddouble, ts : timescale) -> instant( jdjd: ddouble -std/num/ddouble/(-): (x : ddouble, y : ddouble) -> ddouble jd-epoch-deltastd/time/instant/jd-epoch-delta: timespan, tsts: timescale ) // Create an instant given a [modified julian day](https://en.wikipedia.org/wiki/Julian_day). // and time scale `ts`.\ // `modified-julian-day = julian-day - 2400000.5` pub fun float64/instant-at-mjdstd/time/instant/float64/instant-at-mjd: (mjd : float64, ts : timescale) -> instant( mjdmjd: float64 : float64std/core/types/float64: V, tsts: timescale : timescalestd/time/instant/timescale: V )result: -> total instant : instantstd/time/instant/instant: V instant-at-mjdstd/time/instant/ddouble/instant-at-mjd: (mjd : ddouble, ts : timescale) -> instant(ddoublestd/num/ddouble/float64/ddouble: (d : float64) -> ddouble(mjdmjd: float64),tsts: timescale) // Create an instant given a [modified julian day](https://en.wikipedia.org/wiki/Julian_day). // and time scale `ts`.\ // `modified-julian-day = julian-day - 2400000.5` pub fun ddouble/instant-at-mjdstd/time/instant/ddouble/instant-at-mjd: (mjd : ddouble, ts : timescale) -> instant( mjdmjd: ddouble : ddoublestd/num/ddouble/ddouble: V, tsts: timescale : timescalestd/time/instant/timescale: V )result: -> total instant : instantstd/time/instant/instant: V val dd: ddouble = mjdmjd: ddouble -std/num/ddouble/(-): (x : ddouble, y : ddouble) -> ddouble mjd-epoch-deltastd/time/instant/mjd-epoch-delta: timespan // since 2000-01-01 val daysdays: ddouble = dd: ddouble.floorstd/num/ddouble/floor: (x : ddouble) -> ddouble val fracfrac: ddouble = dd: ddouble -std/num/ddouble/(-): (x : ddouble, y : ddouble) -> ddouble daysdays: ddouble val idaysidays: int = daysdays: ddouble.intstd/num/ddouble/int: (x : ddouble, nonfin : ? int) -> int match tsts: timescale.mb-from-mjd2000std/time/instant/timescale/mb-from-mjd2000: (timescale : timescale) -> maybe<(days : int, frac : ddouble) -> timestamp> Nothingstd/core/types/Nothing: forall<a> maybe<a> -> tsts: timescale.instantstd/time/instant/date/instant: (ts : timescale, days : int, secs : timespan, leap : ? int) -> instant( idaysidays: int, fracfrac: ddouble*std/num/ddouble/(*): (x : ddouble, y : ddouble) -> ddoublesolar-secs-per-daystd/time/timestamp/solar-secs-per-day: timespan ) Juststd/core/types/Just: forall<a> (value : a) -> maybe<a>(from-mjd2000from-mjd2000: (days : int, frac : ddouble) -> timestamp) -> tsts: timescale.instantstd/time/instant/timescale/instant: (ts : timescale, t : timestamp) -> instant( from-mjd2000from-mjd2000: (days : int, frac : ddouble) -> timestamp(idaysidays: int,fracfrac: ddouble) ) /* Return the julian day in a given time scale `ts` for an instant `i`. Properly takes leap seconds into account when calculating the fraction of the day in a UTC calendar. For example: ```` > time(2014,12,31,23,59,59).jd 2457023.499988425925926 > time(2015,12,31,23,59,59).jd 2457388.499988425925926 > time(2016,12,31,23,59,59).jd 2457754.499976852119767 > time(2016,12,31,23,59,60).jd 2457754.499988426059884 ```` . */ pub fun jdstd/time/instant/jd: (i : instant, ts : timescale) -> ddouble( ii: instant : instantstd/time/instant/instant: V, tsts: timescale : timescalestd/time/instant/timescale: V )result: -> total ddouble : ddoublestd/num/ddouble/ddouble: V ii: instant.mjdstd/time/instant/mjd: (i : instant, tscale : timescale, tzdelta : ? timespan) -> ddouble(tsts: timescale) +std/num/ddouble/(+): (x : ddouble, y : ddouble) -> ddouble jd-epoch-deltastd/time/instant/jd-epoch-delta: timespan // Return the modified julian day in a given time scale `ts` for an instant `i`. // Can also pass an optional `delta` (=`timespan0`) that is added to the raw timestamp of `i` // before conversion (used in `std/time/time` to take timezones into account) pub fun mjdstd/time/instant/mjd: (i : instant, tscale : timescale, tzdelta : ? timespan) -> ddouble( ii: instant : instantstd/time/instant/instant: V, tscaletscale: timescale : timescalestd/time/instant/timescale: V, tzdeltatzdelta: ? timespan : timespanstd/time/timestamp/timespan: V = timespan0std/time/timestamp/timespan0: timespan )result: -> total ddouble : ddoublestd/num/ddouble/ddouble: V val i0i0: instant = ii: instant.use-timescalestd/time/instant/use-timescale: (i : instant, tscale : timescale) -> instant(tscaletscale: timescale) val mjdmjd: ddouble = match tscaletscale: timescale.mb-to-mjd2000std/time/instant/timescale/mb-to-mjd2000: (timescale : timescale) -> maybe<(t : timestamp, tzdelta : timespan) -> ddouble> Nothingstd/core/types/Nothing: forall<a> maybe<a> -> val i1i1: instant = i0i0: instant.add-duration-instd/time/instant/add-duration-in: (i : instant, tscale : timescale, t : timespan) -> instant(tscaletscale: timescale,tzdeltatzdelta: timespan) val daysdays: ddouble = i1i1: instant.daysstd/time/instant/days: (i : instant) -> int.ddoublestd/num/ddouble/int/ddouble: (i : int) -> ddouble val fracfrac: ddouble = i1i1: instant.sincestd/time/instant/instant/since: (instant : instant) -> timestamp.seconds-into-daystd/time/timestamp/seconds-into-day: (ts : timestamp) -> ddouble /std/num/ddouble/(/): (x : ddouble, y : ddouble) -> ddouble solar-secs-per-daystd/time/timestamp/solar-secs-per-day: timespan (daysdays: ddouble +std/num/ddouble/(+): (x : ddouble, y : ddouble) -> ddouble fracfrac: ddouble) Juststd/core/types/Just: forall<a> (value : a) -> maybe<a>(to-mjdto-mjd: (t : timestamp, tzdelta : timespan) -> ddouble) -> to-mjdto-mjd: (t : timestamp, tzdelta : timespan) -> ddouble( i0i0: instant.sincestd/time/instant/instant/since: (instant : instant) -> timestamp, tzdeltatzdelta: timespan ) (mjdmjd: ddouble +std/num/ddouble/(+): (x : ddouble, y : ddouble) -> ddouble mjd-epoch-deltastd/time/instant/mjd-epoch-delta: timespan)