Scientific timekeeping in Julia
This package provides a flexibile interface to write Durations of time, and
functionality to keep track of instants of Time relative to specified
Clocks. The design is partially motivated by C++'s std::chrono template
library.
Current functionality includes storage of Durations using any number type
and in periods of any chosen fraction of a second, a smattering of Clocks
based on the International Atomic Time (TAI) standard such as UTC and
GPS time standards. The Time type wraps a Duration since the start time
(a.k.a. epoch) of a Clock.
julia> using Chrono
julia> t1 = Time(12hours + 3.0seconds, UTCDate(2016,7,25))
43203.0 seconds (since 2016-07-25 (UTC))
julia> t2 = Time(14hours + 2minutes + 1.0seconds, UTCDate(2016,8,2))
50521.0 seconds (since 2016-08-02 (UTC))
julia> t2 - t1
698518.0 seconds
julia> t3 = Time(5hours + 5minutes + 26.0nanoseconds, GPSWeek(2016,1,1))
1.8300000000026e13 nanoseconds (since GPS week 1877 (2015-12-27))
julia> t4 = Time(t3, UTCDate(2015,12,27))
1.8317000000026e13 nanoseconds (since 2015-12-27 (UTC))
julia> t3.duration - t4.duration
-1.7e10 nanoseconds
julia> t3.clock - t4.clock
17//1 secondsThe Duration type represents a period of time with user-specified storage
format T and units (as PeriodInSeconds seconds):
struct Duration{PeriodInSeconds, T}
value::T
endCommon durations including weeks, days, hours, minutes, seconds,
milliseconds, microseconds and nanoseconds are provided. One can add,
subtract, multiply an divide these as expected:
julia> 2.0weeks + 3.0days
17.0 days
julia> 2.0weeks / days
14.0
julia> div(19days, weeks)
2
julia> rem(19days, weeks)
5//1 daysis exactly 7 days in a week, etc. However, floating point arithmetic is also
As seen above, rational arithmetic will be used whenever possible, so that there
fully supported, as well as conversion to/from Base.Dates.Period types.
A clock represents a method of measuring time. In general, a clock will have
"time = 0" at a certain instance of time - that instance is called the epoch.
We will represent a times as Durations from a Clock's epoch.
In general, it is difficult (or maybe impossible) to relate the time read by two clocks. However, in some instances, the relationship may be known from measurement or by definition. For an example of latter, the International Atomic Time (TAI) standard is defined using a world-wide system of atomic clocks, while a variety of derived time standards such as UTC and GPS time are defined relative to TAI (and possibly some epoch date or dates).
Thus, the package includes support for abstract TAIClocks, which include as
subtypes a variety of time standards that are related:
TAIDate(date)is a TAI clock that starts at the beginning of a givendate.UTCDate(date)is a clock that starts at the beginning of a givendate, and the package includes a table of UTC leap-seconds to relate UTC to other TAI-based times.GPSEpoch()is a clock that starts on January 6, 1980 at 19 seconds behind TAI time.GPSWeek(n)is a clock with an epoch at the beginning of thenth Sunday after January 6, 1980 (and trails the corresponding TAI time by 19 seconds). The GPS system transmits time as a combination of the GPS week and time since the beginning of that Sunday.
The Duration separating the epoch of any two TAI-derived clocks can be
obtained by subtracting the Clocks. The gps_week(date) helper function
returns the GPS week number corresponding to any date and the epoch(clock)
function returns the Date of the corresponding epoch (assumed to be at the
beginning of that day, in the corresponding time system).
As mentioned above, we measure Time relative to a Clock's epoch. Our
definition of time is simply:
struct Time{C <: Clock, D <: Duration}
duration::D
clock::C # This might be singleton, or it might contain complex data
endWe can do all the obvious things to Times: we can subtract two Times to get
the Duration that separates them, or add/subtract a Duration to a Time.
The Time relative to a new clock can be created via the constructor
Time(old_time, new_clock).