time/duration.fz
# This file is part of the Fuzion language implementation.
#
# The Fuzion language implementation is free software: you can redistribute it
# and/or modify it under the terms of the GNU General Public License as published
# by the Free Software Foundation, version 3 of the License.
#
# The Fuzion language implementation is distributed in the hope that it will be
# useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
# License for more details.
#
# You should have received a copy of the GNU General Public License along with The
# Fuzion language implementation. If not, see <https://www.gnu.org/licenses/>.
# -----------------------------------------------------------------------
#
# Tokiwa Software GmbH, Germany
#
# Source code of Fuzion standard library feature time.duration
#
# Author: Fridtjof Siebert (siebert@tokiwa.software)
#
# -----------------------------------------------------------------------
# time.duration -- value representing a duration, i.e., a time span
#
# This is intendend for high precision time specification and measurement, it
# uses a time resolution of 1ns.
#
# The maximum value is about 580 years, so this is not intended for use in
# calendars that may require time spans exceeding several centuries or millenia,
# nor astrological time spans.
#
private:public duration (
# the duration in nano seconds
#
public nanos u64
)
is
# this duration in micro seconds, omitting fractional part
#
public micros => nanos / units.nanos_per_micro
# this duration in milli seconds, omitting fractional part
#
public millis => nanos / units.nanos_per_milli
# this duration in whole seconds, omitting fractional part
#
public seconds => nanos / units.nanos_per_second
# this duration in whole minutes, omitting fractional part
#
public minutes => nanos / units.nanos_per_minute
# this duration in whole hours, omitting fractional part
#
public hours => nanos / units.nanos_per_hour
# this duration in whole days, omitting fractional part
#
public days => nanos / units.nanos_per_day
# this duration in whole weeks, omitting fractional part
#
public weeks => nanos / units.nanos_per_week
# this duration in whole Julian years, omitting fractional part
#
public years => nanos / units.nanos_per_year
# create a string representation of this duration. The string
# representation is not accurate, it consists of at least two
# and at most 4 decimal digits followed by a time unit string.
#
public redef as_string String =>
(f,u,_) := for
x := units.unit_names.first, n
n in units.unit_names.drop 1
nf := n.values.0
/* NYI this does not work yet, see #228:
*
while (!(nf = 0 || nanos / nf < 10)) else
x
*
* so use until .. then .. else instead, which works, but repeats 'x'
*/
until nf = u64 0 || nanos / nf < u64 10 then
x
else
x
n := $(nanos / f)
" "*(max 0 4-n.byte_length) + n + u
# time.durations -- unit type defining features related to duration but not requiring
# an instance
#
public durations : units is
# max value for a duration given in nanos
public max_duration_nanos => u64.max
# max value for a duration given in micros
public max_duration_micros => u64.max / nanos_per_micro
# max value for a duration given in millis
public max_duration_millis => u64.max / nanos_per_milli
# max value for a duration given in seconds
public max_duration_seconds => u64.max / nanos_per_second
# max value for a duration given in minutes
public max_duration_minutes => u64.max / nanos_per_minute
# max value for a duration given in hours
public max_duration_hours => u64.max / nanos_per_hour
# max value for a duration given in days
public max_duration_days => u64.max / nanos_per_day
# max value for a duration given in weeks
public max_duration_weeks => u64.max / nanos_per_week
# max value for a duration given in years
public max_duration_years => u64.max / nanos_per_year
# create duration of n ns
#
# NYI: Turn this into a 'postfix' call, see https://fuzion-lang.dev/design/postfix_calls
#
public ns (n u64)
pre
debug: n ≤ max_duration_nanos
=> duration n
# create duration of n µs
#
# NYI: Turn this into a 'postfix' call, see https://fuzion-lang.dev/design/postfix_calls
#
public µs (n u64)
pre
debug: n ≤ max_duration_micros
=> duration n*nanos_per_micro
# create duration of n ms
#
# NYI: Turn this into a 'postfix' call, see https://fuzion-lang.dev/design/postfix_calls
#
public ms (n u64)
pre
debug: n ≤ max_duration_millis
=> duration n*nanos_per_milli
# create duration of n seconds
#
# NYI: Turn this into a 'postfix' call, see https://fuzion-lang.dev/design/postfix_calls
#
public s (n u64)
pre
debug: n ≤ max_duration_seconds
=> duration n*nanos_per_second
# create duration of n seconds
#
# NYI: Turn this into a 'postfix' call, see https://fuzion-lang.dev/design/postfix_calls
#
public seconds (n u64)
pre
debug: n ≤ max_duration_seconds
=> s n
# create duration of n min
#
# NYI: Turn this into a 'postfix' call, see https://fuzion-lang.dev/design/postfix_calls
#
public min (n u64)
pre
debug: n ≤ max_duration_minutes
=> duration n*nanos_per_minute
# create duration of n min
#
# NYI: Turn this into a 'postfix' call, see https://fuzion-lang.dev/design/postfix_calls
#
public minutes (n u64)
pre
debug: n ≤ max_duration_minutes
=> min n
# create duration of n hours
#
# NYI: Turn this into a 'postfix' call, see https://fuzion-lang.dev/design/postfix_calls
#
public h (n u64)
pre
debug: n ≤ max_duration_hours
=> duration n*nanos_per_hour
# create duration of n hours
#
# NYI: Turn this into a 'postfix' call, see https://fuzion-lang.dev/design/postfix_calls
#
public hours (n u64)
pre
debug: n ≤ max_duration_hours
=> h n
# create duration of n days
#
# NYI: Turn this into a 'postfix' call, see https://fuzion-lang.dev/design/postfix_calls
#
public days (n u64)
pre
debug: n ≤ max_duration_days
=> duration n*nanos_per_day
# create duration of n weeks
#
# NYI: Turn this into a 'postfix' call, see https://fuzion-lang.dev/design/postfix_calls
#
public weeks (n u64)
pre
debug: n ≤ max_duration_weeks
=> duration n*nanos_per_week
# create duration of n years
#
# NYI: Turn this into a 'postfix' call, see https://fuzion-lang.dev/design/postfix_calls
#
public a (n u64)
pre
debug: n ≤ max_duration_years
=> duration n*nanos_per_year
# create duration of n years
#
# NYI: Turn this into a 'postfix' call, see https://fuzion-lang.dev/design/postfix_calls
#
public years (n u64)
pre
debug: n ≤ max_duration_years
=> a n
# time.duration.units -- unit time defining units used in duration
#
public units is
# factor converting nanos to nanos, just for completeness
public nanos_per_nano => u64 1
# factor converting micros to nanos
public nanos_per_micro => u64 1_000
# factor converting millis to nanos
public nanos_per_milli => nanos_per_micro * 1_000
# factor converting seconds to nanos
public nanos_per_second => nanos_per_milli * 1_000
# factor converting minutes to nanos
public nanos_per_minute => nanos_per_second * 60
# factor converting hours to nanos
public nanos_per_hour => nanos_per_minute * 60
# factor converting days to nanos
public nanos_per_day => nanos_per_hour * 24
# factor converting weeks to nanos
public nanos_per_week => nanos_per_day * 7
# factor converting years to nanos
public nanos_per_year => nanos_per_second * 31_557_600
# array of tuples consisting of the nanos_per_* conversion
# factors and an (mostly ISO) name of the corresponding unit.
#
# Entries are sorted by increasing duration size. The last
# entry is an ((u64 0), "--end marker--").
#
unit_names =>
[ (nanos_per_nano , "ns", "ns"),
(nanos_per_micro , "µs", "µs"),
(nanos_per_milli , "ms", "ms"),
(nanos_per_second , "s ", "sec"),
(nanos_per_minute , "m ", "min"),
(nanos_per_hour , "h ", "hours"),
(nanos_per_day , "d ", "days"),
(nanos_per_year , "a ", "years"),
((u64 0 ), "--end marker--", "--end marker--"),
]