/*----------------------------------------------------------------------------
   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 durations in SI seconds.

   Durations use SI seconds.
*/
module std/time/durationstd/time/duration

import std/num/ddoublestd/num/ddouble
import std/time/timestampstd/time/timestamp

/*----------------------------------------------------------------------------
  Durations
----------------------------------------------------------------------------*/

// A duration in time in (TAI) SI seconds (as measured on the earth's geoid).\
// A duration is represented by a `:ddouble` giving it a high range and precision (see the [`instant`](std_time_instant.html) module)
abstract value struct durationstd/time/duration/duration: V
  secsstd/time/duration/duration/secs: (duration : duration) -> timespan : timespanstd/time/timestamp/timespan: V


// A zero duration.
pub val zerostd/time/duration/zero: duration : durationstd/time/duration/duration: V = Durationstd/time/duration/Duration: (secs : timespan) -> duration(timespan0std/time/timestamp/timespan0: timespan)
pub val duration0std/time/duration/duration0: duration : durationstd/time/duration/duration: V = Durationstd/time/duration/Duration: (secs : timespan) -> duration(timespan0std/time/timestamp/timespan0: timespan)

// Convert a `:timespan` to a `:duration`. Be careful to only use
// use this on timespan's that are in TAI SI seconds!
pub fun durationstd/time/duration/duration: (t : timespan) -> duration( tt: timespan : timespanstd/time/timestamp/timespan: V )result: -> total duration : durationstd/time/duration/duration: V
  Durationstd/time/duration/Duration: (secs : timespan) -> duration(tt: timespan)


// Convert a `:timestamp` to a `:duration`. Be careful to only use
// use this on timestamp's that are in TAI SI seconds and do not
// contain leap seconds!
pub fun unsafe-durationstd/time/duration/unsafe-duration: (t : timestamp) -> duration( tt: timestamp : timestampstd/time/timestamp/timestamp: V )result: -> total duration : durationstd/time/duration/duration: V
  Durationstd/time/duration/Duration: (secs : timespan) -> duration(tt: timestamp.unsafe-timespan-withleapstd/time/timestamp/unsafe-timespan-withleap: (ts : timestamp) -> timespan)


// Create a duration from whole seconds `secs` and a fraction of seconds `frac`.
pub fun int/durationstd/time/duration/int/duration: (secs : int, frac : ? float64) -> duration( secssecs: int : intstd/core/types/int: V, fracfrac: ? float64 : float64std/core/types/float64: V = 0.0literal: float64
hex64= 0x0p+0
)result: -> total duration : durationstd/time/duration/duration: V Durationstd/time/duration/Duration: (secs : timespan) -> duration(timespanstd/time/timestamp/int/timespan: (seconds : int, frac : ? float64) -> timespan(secssecs: int,fracfrac: float64)
) // Create a duration from seconds as a `:float64`. pub fun float64/durationstd/time/duration/float64/duration: (secs : float64) -> duration( secssecs: float64 : float64std/core/types/float64: V )result: -> total duration : durationstd/time/duration/duration: V Durationstd/time/duration/Duration: (secs : timespan) -> duration(timespanstd/time/timestamp/float64/timespan: (secs : float64) -> timespan(secssecs: float64)) // Create a duration from seconds and a fraction as a `:float64`'s. pub fun float64frac/durationstd/time/duration/float64frac/duration: (secs : float64, frac : float64) -> duration( secssecs: float64 : float64std/core/types/float64: V, fracfrac: float64 : float64std/core/types/float64: V )result: -> total duration : durationstd/time/duration/duration: V Durationstd/time/duration/Duration: (secs : timespan) -> duration(timespanstd/time/timestamp/tuple64/timespan: (secs : float64, frac : float64) -> timespan(secssecs: float64,fracfrac: float64)) // Convert a duration to a `:timespan`. pub fun timespanstd/time/duration/timespan: (d : duration) -> timespan( dd: duration : durationstd/time/duration/duration: V )result: -> total timespan : timespanstd/time/timestamp/timespan: V dd: duration.secondsstd/time/duration/seconds: (d : duration) -> timespan // Convert a duration to a `:timespan`. pub fun timestampstd/time/duration/timestamp: (d : duration) -> timestamp( dd: duration : durationstd/time/duration/duration: V )result: -> total timestamp : timestampstd/time/timestamp/timestamp: V dd: duration.secondsstd/time/duration/seconds: (d : duration) -> timespan.timestampstd/time/timestamp/timestamp: (t : timespan, leap : ? int) -> timestamp // Return the duration in SI seconds. pub fun secondsstd/time/duration/seconds: (d : duration) -> timespan( dd: duration : durationstd/time/duration/duration: V )result: -> total timespan : timespanstd/time/timestamp/timespan: V dd: duration.secsstd/time/duration/duration/secs: (duration : duration) -> timespan // Return the duration in rounded SI milli-seconds. pub fun milli-secondsstd/time/duration/milli-seconds: (d : duration) -> int( dd: duration : durationstd/time/duration/duration: V )result: -> total int : intstd/core/types/int: V (dd: duration.secsstd/time/duration/duration/secs: (duration : duration) -> timespan *std/num/ddouble/(*): (x : ddouble, y : ddouble) -> ddouble 1000literal: int
dec = 1000
hex16= 0x03E8
bit16= 0b0000001111101000
.timespanstd/time/timestamp/int/timespan: (seconds : int, frac : ? float64) -> timespan).intstd/num/ddouble/int: (x : ddouble, nonfin : ? int) -> int
// Return the duration in rounded SI nano-seconds. pub fun nano-secondsstd/time/duration/nano-seconds: (d : duration) -> int( dd: duration : durationstd/time/duration/duration: V )result: -> total int : intstd/core/types/int: V (dd: duration.secsstd/time/duration/duration/secs: (duration : duration) -> timespan *std/num/ddouble/(*): (x : ddouble, y : ddouble) -> ddouble 1000000000literal: int
dec = 1000000000
hex32= 0x3B9ACA00
bit32= 0b00111011100110101100101000000000
.timespanstd/time/timestamp/int/timespan: (seconds : int, frac : ? float64) -> timespan).intstd/num/ddouble/int: (x : ddouble, nonfin : ? int) -> int
// The whole seconds (in some time unit) of the duration as `:int``. Rounds towards zero. pub fun truncatestd/time/duration/truncate: (d : duration) -> int( dd: duration : durationstd/time/duration/duration: V )result: -> total int : intstd/core/types/int: V dd: duration.secsstd/time/duration/duration/secs: (duration : duration) -> timespan.truncatestd/num/ddouble/truncate: (x : ddouble) -> ddouble.intstd/num/ddouble/int: (x : ddouble, nonfin : ? int) -> int // The fractional seconds of a duration as a `:float64`. // `d.seconds == d.truncate.fixed + d.fraction.fixed pub fun fractionstd/time/duration/fraction: (d : duration) -> float64( dd: duration : durationstd/time/duration/duration: V )result: -> total float64 : float64std/core/types/float64: V dd: duration.secsstd/time/duration/duration/secs: (duration : duration) -> timespan.fractionstd/num/ddouble/fraction: (x : ddouble) -> ddouble.float64std/num/ddouble/float64: (x : ddouble) -> float64 // Is this a negative duration? pub fun is-negstd/time/duration/is-neg: (d : duration) -> bool( dd: duration : durationstd/time/duration/duration: V )result: -> total bool : boolstd/core/types/bool: V dd: duration.secsstd/time/duration/duration/secs: (duration : duration) -> timespan.is-negstd/num/ddouble/is-neg: (x : ddouble) -> bool // Is this a zero duration? pub fun is-zerostd/time/duration/is-zero: (d : duration) -> bool( dd: duration : durationstd/time/duration/duration: V )result: -> total bool : boolstd/core/types/bool: V dd: duration.secsstd/time/duration/duration/secs: (duration : duration) -> timespan.is-zerostd/num/ddouble/is-zero: (x : ddouble) -> bool // Is this a positive duration? pub fun is-posstd/time/duration/is-pos: (d : duration) -> bool( dd: duration : durationstd/time/duration/duration: V )result: -> total bool : boolstd/core/types/bool: V dd: duration.secsstd/time/duration/duration/secs: (duration : duration) -> timespan.is-posstd/num/ddouble/is-pos: (x : ddouble) -> bool // Compare two `:duration`s. pub fun cmpstd/time/duration/cmp: (i : duration, j : duration) -> order( ii: duration : durationstd/time/duration/duration: V, jj: duration : durationstd/time/duration/duration: V )result: -> total order : orderstd/core/types/order: V cmpstd/num/ddouble/cmp: (x : ddouble, y : ddouble) -> order(ii: duration.secsstd/time/duration/duration/secs: (duration : duration) -> timespan,jj: duration.secsstd/time/duration/duration/secs: (duration : duration) -> timespan) pub fun (<)std/time/duration/(<): (i : duration, j : duration) -> bool( ii: duration : durationstd/time/duration/duration: V, jj: duration : durationstd/time/duration/duration: V )result: -> total bool : boolstd/core/types/bool: V { cmpstd/time/duration/cmp: (i : duration, j : duration) -> order(ii: duration,jj: duration) ==std/core/order/(==): (x : order, y : order) -> bool Ltstd/core/types/Lt: order } pub fun (<=)std/time/duration/(<=): (i : duration, j : duration) -> bool( ii: duration : durationstd/time/duration/duration: V, jj: duration : durationstd/time/duration/duration: V )result: -> total bool : boolstd/core/types/bool: V { cmpstd/time/duration/cmp: (i : duration, j : duration) -> order(ii: duration,jj: duration) !=std/core/order/(!=): (x : order, y : order) -> bool Gtstd/core/types/Gt: order } pub fun (>)std/time/duration/(>): (i : duration, j : duration) -> bool( ii: duration : durationstd/time/duration/duration: V, jj: duration : durationstd/time/duration/duration: V )result: -> total bool : boolstd/core/types/bool: V { cmpstd/time/duration/cmp: (i : duration, j : duration) -> order(ii: duration,jj: duration) ==std/core/order/(==): (x : order, y : order) -> bool Gtstd/core/types/Gt: order } pub fun (>=)std/time/duration/(>=): (i : duration, j : duration) -> bool( ii: duration : durationstd/time/duration/duration: V, jj: duration : durationstd/time/duration/duration: V )result: -> total bool : boolstd/core/types/bool: V { cmpstd/time/duration/cmp: (i : duration, j : duration) -> order(ii: duration,jj: duration) !=std/core/order/(!=): (x : order, y : order) -> bool Ltstd/core/types/Lt: order } pub fun (==)std/time/duration/(==): (i : duration, j : duration) -> bool( ii: duration : durationstd/time/duration/duration: V, jj: duration : durationstd/time/duration/duration: V )result: -> total bool : boolstd/core/types/bool: V { cmpstd/time/duration/cmp: (i : duration, j : duration) -> order(ii: duration,jj: duration) ==std/core/order/(==): (x : order, y : order) -> bool Eqstd/core/types/Eq: order } pub fun (!=)std/time/duration/(!=): (i : duration, j : duration) -> bool( ii: duration : durationstd/time/duration/duration: V, jj: duration : durationstd/time/duration/duration: V )result: -> total bool : boolstd/core/types/bool: V { cmpstd/time/duration/cmp: (i : duration, j : duration) -> order(ii: duration,jj: duration) !=std/core/order/(!=): (x : order, y : order) -> bool Eqstd/core/types/Eq: order } // The minimum of two durations. pub fun minstd/time/duration/min: (i : duration, j : duration) -> duration( ii: duration : durationstd/time/duration/duration: V, jj: duration : durationstd/time/duration/duration: V )result: -> total duration : durationstd/time/duration/duration: V if ii: duration <=std/time/duration/(<=): (i : duration, j : duration) -> bool jj: duration then ii: duration else jj: duration // The maximum of two durations. pub fun maxstd/time/duration/max: (i : duration, j : duration) -> duration( ii: duration : durationstd/time/duration/duration: V, jj: duration : durationstd/time/duration/duration: V )result: -> total duration : durationstd/time/duration/duration: V if ii: duration >=std/time/duration/(>=): (i : duration, j : duration) -> bool jj: duration then ii: duration else jj: duration // Add two durations. pub fun (+)std/time/duration/(+): (d : duration, e : duration) -> duration( dd: duration : durationstd/time/duration/duration: V, ee: duration : durationstd/time/duration/duration: V )result: -> total duration : durationstd/time/duration/duration: V Durationstd/time/duration/Duration: (secs : timespan) -> duration(dd: duration.secsstd/time/duration/duration/secs: (duration : duration) -> timespan +std/num/ddouble/(+): (x : ddouble, y : ddouble) -> ddouble ee: duration.secsstd/time/duration/duration/secs: (duration : duration) -> timespan) // Negate a duration. pub fun (~)std/time/duration/(~): (d : duration) -> duration( dd: duration : durationstd/time/duration/duration: V )result: -> total duration : durationstd/time/duration/duration: V Durationstd/time/duration/Duration: (secs : timespan) -> duration(~std/num/ddouble/(~): (x : ddouble) -> ddoubledd: duration.secsstd/time/duration/duration/secs: (duration : duration) -> timespan) // Subtract a duration from a duration. pub fun (-)std/time/duration/(-): (d : duration, e : duration) -> duration( dd: duration : durationstd/time/duration/duration: V, ee: duration : durationstd/time/duration/duration: V )result: -> total duration : durationstd/time/duration/duration: V dd: duration +std/time/duration/(+): (d : duration, e : duration) -> duration ~std/time/duration/(~): (d : duration) -> durationee: duration // Show a duration in SI seconds. pub fun showstd/time/duration/show: (d : duration, max-prec : ? int) -> string( dd: duration : durationstd/time/duration/duration: V, max-precmax-prec: ? int : intstd/core/types/int: V = 9literal: int
dec = 9
hex8 = 0x09
bit8 = 0b00001001
)result: -> total string : stringstd/core/types/string: V dd: duration.secsstd/time/duration/duration/secs: (duration : duration) -> timespan.show-fixedstd/num/ddouble/show-fixed: (x : ddouble, prec : ? int) -> string(~std/core/int/(~): (i : int) -> intmax-precmax-prec: int.absstd/core/int/abs: (i : int) -> int) ++std/core/types/(++): (x : string, y : string) -> string "s"literal: string
count= 1
// Create a `:duration` of `n` milli-seconds. pub fun int/milli-secondsstd/time/duration/int/milli-seconds: (n : int) -> duration( nn: int : intstd/core/types/int: V )result: -> total duration : durationstd/time/duration/duration: V { Durationstd/time/duration/Duration: (secs : timespan) -> duration(nn: int.timespanstd/time/timestamp/int/timespan: (seconds : int, frac : ? float64) -> timespan /std/num/ddouble/(/): (x : ddouble, y : ddouble) -> ddouble 1000literal: int
dec = 1000
hex16= 0x03E8
bit16= 0b0000001111101000
.timespanstd/time/timestamp/int/timespan: (seconds : int, frac : ? float64) -> timespan)
} // Create a `:duration` of `n` seconds. pub fun int/secondsstd/time/duration/int/seconds: (n : int) -> duration( nn: int : intstd/core/types/int: V )result: -> total duration : durationstd/time/duration/duration: V { durationstd/time/duration/int/duration: (secs : int, frac : ? float64) -> duration(nn: int) } // Create a `:duration` of `n` minutes. pub fun minutesstd/time/duration/minutes: (n : int) -> duration( nn: int : intstd/core/types/int: V )result: -> total duration : durationstd/time/duration/duration: V { durationstd/time/duration/int/duration: (secs : int, frac : ? float64) -> duration(nn: int*std/core/int/(*): (int, int) -> int60literal: int
dec = 60
hex8 = 0x3C
bit8 = 0b00111100
)
} // Create a `:duration` of `n` hours. pub fun hoursstd/time/duration/hours: (n : int) -> duration( nn: int : intstd/core/types/int: V )result: -> total duration : durationstd/time/duration/duration: V { durationstd/time/duration/int/duration: (secs : int, frac : ? float64) -> duration(nn: int*std/core/int/(*): (int, int) -> int3600literal: int
dec = 3600
hex16= 0x0E10
bit16= 0b0000111000010000
)
} // Create a `:duration` of `n` "days" (assuming 86400s in a day). pub fun daysstd/time/duration/days: (n : int) -> duration( nn: int : intstd/core/types/int: V )result: -> total duration : durationstd/time/duration/duration: V { durationstd/time/duration/int/duration: (secs : int, frac : ? float64) -> duration(nn: int*std/core/int/(*): (int, int) -> intisolar-secs-per-daystd/time/timestamp/isolar-secs-per-day: int) } // Create a `:duration` of `n` "weeks" (assuming 7 days of 86400s). pub fun weeksstd/time/duration/weeks: (n : int) -> duration( nn: int : intstd/core/types/int: V )result: -> total duration : durationstd/time/duration/duration: V { durationstd/time/duration/int/duration: (secs : int, frac : ? float64) -> duration(nn: int*std/core/int/(*): (int, int) -> int7literal: int
dec = 7
hex8 = 0x07
bit8 = 0b00000111
*std/core/int/(*): (int, int) -> intisolar-secs-per-daystd/time/timestamp/isolar-secs-per-day: int)
} // Create a `:duration` of `n` "years" (assuming 365 days of 86400s). pub fun yearsstd/time/duration/years: (n : int) -> duration( nn: int : intstd/core/types/int: V )result: -> total duration : durationstd/time/duration/duration: V { durationstd/time/duration/int/duration: (secs : int, frac : ? float64) -> duration(nn: int*std/core/int/(*): (int, int) -> int365literal: int
dec = 365
hex16= 0x016D
bit16= 0b0000000101101101
*std/core/int/(*): (int, int) -> intisolar-secs-per-daystd/time/timestamp/isolar-secs-per-day: int)
}