protocol

# `time_scales_protocol`

Time scales conversion protocol for UTC, TAI, TT, UT1, TDB, GPS, GST, TCG, and TCB.

Availability:
`logtalk_load(time_scales(loader))`
Author: Paulo Moura
Version: 1:0:0
Date: 2026-02-25
Compilation flags:
`static`
Dependencies:
(none)
Remarks:
(none)
Inherited public predicates:
(none)

## Public predicates

### `valid_scale/1`

True when the argument is a supported time scale (`utc`, `tai`, `tt`, `ut1`, `tdb`, `gps`, `gst`, `tcg`, or `tcb`).

Compilation flags:
`static`
Template:
`valid_scale(Scale)`
Mode and number of proofs:
`valid_scale(@atom)` - `zero_or_one`

### `supported_range/2`

Returns the supported UTC datetime range as `date_time(Year,Month,Day,Hour,Minute,Second)` terms.

Compilation flags:
`static`
Template:
`supported_range(StartUTC,EndUTC)`
Mode and number of proofs:
`supported_range(-compound,-compound)` - `one`

### `leap_second_date/2`

Enumerates UTC effective dates for `TAI-UTC` step changes and their resulting offset in SI seconds.

Compilation flags:
`static`
Template:
`leap_second_date(UTCDateTime,OffsetSeconds)`
Mode and number of proofs:
`leap_second_date(?compound,?integer)` - `zero_or_more`

### `load_leap_seconds_override/1`

Loads leap-second override data from a user-provided file containing `leap(UnixSeconds,OffsetSeconds).` terms.

Compilation flags:
`static`
Template:
`load_leap_seconds_override(File)`
Mode and number of proofs:
`load_leap_seconds_override(+atom)` - `one`

### `clear_leap_seconds_override/0`

Clears any previously loaded leap-second override data and reverts to bundled data.

Compilation flags:
`static`
Mode and number of proofs:
`clear_leap_seconds_override` - `one`

### `leap_seconds_source/1`

Returns the active leap-seconds data source as either `bundled` or `override`.

Compilation flags:
`static`
Template:
`leap_seconds_source(Source)`
Mode and number of proofs:
`leap_seconds_source(-atom)` - `one`

### `leap_seconds_entries/1`

Returns the active leap-seconds table as an ordered list of `leap(UnixSeconds,OffsetSeconds)` terms.

Compilation flags:
`static`
Template:
`leap_seconds_entries(Entries)`
Mode and number of proofs:
`leap_seconds_entries(-list)` - `one`

### `save_leap_seconds_entries/1`

Saves the active leap-seconds table to a file as `leap(UnixSeconds,OffsetSeconds).` terms.

Compilation flags:
`static`
Template:
`save_leap_seconds_entries(File)`
Mode and number of proofs:
`save_leap_seconds_entries(+atom)` - `one`

### `load_dut1_override/1`

Loads DUT1 override data from a user-provided file containing `dut1(UnixSeconds,Numerator,Denominator).` terms.

Compilation flags:
`static`
Template:
`load_dut1_override(File)`
Mode and number of proofs:
`load_dut1_override(+atom)` - `one`

### `clear_dut1_override/0`

Clears any previously loaded DUT1 override data and reverts to bundled data.

Compilation flags:
`static`
Mode and number of proofs:
`clear_dut1_override` - `one`

### `dut1_source/1`

Returns the active DUT1 data source as either `bundled` or `override`.

Compilation flags:
`static`
Template:
`dut1_source(Source)`
Mode and number of proofs:
`dut1_source(-atom)` - `one`

### `dut1_entries/1`

Returns the active DUT1 table as an ordered list of `dut1(UnixSeconds,Numerator,Denominator)` terms.

Compilation flags:
`static`
Template:
`dut1_entries(Entries)`
Mode and number of proofs:
`dut1_entries(-list)` - `one`

### `save_dut1_entries/1`

Saves the active DUT1 table to a file as `dut1(UnixSeconds,Numerator,Denominator).` terms.

Compilation flags:
`static`
Template:
`save_dut1_entries(File)`
Mode and number of proofs:
`save_dut1_entries(+atom)` - `one`

### `utc_date_time_to_instant/2`

Converts a UTC datetime term to an instant represented as `instant(utc,Seconds,fraction(Numerator,Denominator))` where `Seconds` are Unix epoch seconds and the fractional component is normalized.

Compilation flags:
`static`
Template:
`utc_date_time_to_instant(UTCDateTime,Instant)`
Mode and number of proofs:
`utc_date_time_to_instant(+compound,-compound)` - `zero_or_one`

### `valid_instant/1`

True when the argument is a valid supported instant term `instant(Scale,Seconds,fraction(Numerator,Denominator))`.

Compilation flags:
`static`
Template:
`valid_instant(Instant)`
Mode and number of proofs:
`valid_instant(+compound)` - `zero_or_one`

### `check_instant/1`

Checks an instant term and throws an error instead of failing on invalid input.

Compilation flags:
`static`
Template:
`check_instant(Instant)`
Mode and number of proofs:
`check_instant(+compound)` - `one_or_error`
Exceptions:
`Instant` is a variable:
`instantiation_error`
`Instant` is not a valid instant term:
`domain_error(instant,Instant)`
`Scale` in `Instant` is neither a variable nor an atom:
`type_error(atom,Scale)`
`Scale` in `Instant` is not supported:
`domain_error(time_scale,Scale)`
`Seconds` in `Instant` is neither a variable nor an integer:
`type_error(integer,Seconds)`
`Seconds` in `Instant` is before supported UTC epoch:
`domain_error(utc_unix_seconds,Seconds)`
Fraction term in `Instant` is not of the form `fraction(Numerator,Denominator)`:
`domain_error(fraction,Fraction)`
`Numerator` in `Instant` is neither a variable nor an integer:
`type_error(integer,Numerator)`
`Denominator` in `Instant` is neither a variable nor an integer:
`type_error(integer,Denominator)`
`Denominator` in `Instant` is not positive:
`domain_error(positive_denominator,Denominator)`
Normalized fraction in `Instant` is not in the `[0,1[` interval:
`domain_error(normalized_fraction,Fraction)`

### `valid_conversion/3`

True when an instant is valid for `FromScale` and conversion to `ToScale` is admissible.

Compilation flags:
`static`
Template:
`valid_conversion(Instant,FromScale,ToScale)`
Mode and number of proofs:
`valid_conversion(+compound,+atom,+atom)` - `zero_or_one`

### `check_conversion/3`

Checks a conversion request and throws an error instead of failing on invalid input.

Compilation flags:
`static`
Template:
`check_conversion(Instant,FromScale,ToScale)`
Mode and number of proofs:
`check_conversion(+compound,+atom,+atom)` - `one_or_error`
Exceptions:
`Instant`, `FromScale`, or `ToScale` is a variable:
`instantiation_error`
`FromScale` is neither a variable nor an atom:
`type_error(atom,FromScale)`
`ToScale` is neither a variable nor an atom:
`type_error(atom,ToScale)`
`FromScale` is not supported:
`domain_error(time_scale,FromScale)`
`ToScale` is not supported:
`domain_error(time_scale,ToScale)`
`Instant` is not a valid instant term:
`domain_error(instant,Instant)`
`Scale` in `Instant` is neither a variable nor an atom:
`type_error(atom,Scale)`
`Scale` in `Instant` is not supported:
`domain_error(time_scale,Scale)`
`Seconds` in `Instant` is neither a variable nor an integer:
`type_error(integer,Seconds)`
`Seconds` in `Instant` is before supported UTC epoch:
`domain_error(utc_unix_seconds,Seconds)`
Fraction term in `Instant` is not of the form `fraction(Numerator,Denominator)`:
`domain_error(fraction,Fraction)`
`Numerator` in `Instant` is neither a variable nor an integer:
`type_error(integer,Numerator)`
`Denominator` in `Instant` is neither a variable nor an integer:
`type_error(integer,Denominator)`
`Denominator` in `Instant` is not positive:
`domain_error(positive_denominator,Denominator)`
Normalized fraction in `Instant` is not in the `[0,1[` interval:
`domain_error(normalized_fraction,Fraction)`
`Instant` scale does not match `FromScale`:
`domain_error(scale_mismatch,instant_scale(InstantScale,FromScale))`

### `instant_to_utc_date_time/2`

Converts an UTC instant represented as `instant(utc,Seconds,fraction(Numerator,Denominator))` to a UTC datetime term. Requires zero fractional part.

Compilation flags:
`static`
Template:
`instant_to_utc_date_time(Instant,UTCDateTime)`
Mode and number of proofs:
`instant_to_utc_date_time(+compound,-compound)` - `zero_or_one`

### `convert/4`

Converts an `instant(Scale,Seconds,fraction(Numerator,Denominator))` from `FromScale` to `ToScale`.

Compilation flags:
`static`
Template:
`convert(Instant,FromScale,ToScale,ConvertedInstant)`
Mode and number of proofs:
`convert(+compound,+atom,+atom,-compound)` - `zero_or_one`

### `check_convert/4`

Converts an instant from `FromScale` to `ToScale` and throws an error instead of failing on invalid input.

Compilation flags:
`static`
Template:
`check_convert(Instant,FromScale,ToScale,ConvertedInstant)`
Mode and number of proofs:
`check_convert(+compound,+atom,+atom,-compound)` - `one_or_error`
Exceptions:
`Instant`, `FromScale`, or `ToScale` is a variable:
`instantiation_error`
`FromScale` is neither a variable nor an atom:
`type_error(atom,FromScale)`
`ToScale` is neither a variable nor an atom:
`type_error(atom,ToScale)`
`FromScale` is not supported:
`domain_error(time_scale,FromScale)`
`ToScale` is not supported:
`domain_error(time_scale,ToScale)`
`Instant` is not a valid instant term:
`domain_error(instant,Instant)`
`Scale` in `Instant` is neither a variable nor an atom:
`type_error(atom,Scale)`
`Scale` in `Instant` is not supported:
`domain_error(time_scale,Scale)`
`Seconds` in `Instant` is neither a variable nor an integer:
`type_error(integer,Seconds)`
`Seconds` in `Instant` is before supported UTC epoch:
`domain_error(utc_unix_seconds,Seconds)`
Fraction term in `Instant` is not of the form `fraction(Numerator,Denominator)`:
`domain_error(fraction,Fraction)`
`Numerator` in `Instant` is neither a variable nor an integer:
`type_error(integer,Numerator)`
`Denominator` in `Instant` is neither a variable nor an integer:
`type_error(integer,Denominator)`
`Denominator` in `Instant` is not positive:
`domain_error(positive_denominator,Denominator)`
Normalized fraction in `Instant` is not in the `[0,1[` interval:
`domain_error(normalized_fraction,Fraction)`
`Instant` scale does not match `FromScale`:
`domain_error(scale_mismatch,instant_scale(InstantScale,FromScale))`

### `offset/3`

Returns the offset required to convert an instant to a target scale as `rational(Numerator,Denominator)`.

Compilation flags:
`static`
Template:
`offset(Instant,ToScale,Offset)`
Mode and number of proofs:
`offset(+compound,+atom,-compound)` - `zero_or_one`

### `check_offset/3`

Returns the conversion offset and throws an error instead of failing on invalid input.

Compilation flags:
`static`
Template:
`check_offset(Instant,ToScale,Offset)`
Mode and number of proofs:
`check_offset(+compound,+atom,-compound)` - `one_or_error`
Exceptions:
`Instant` or `ToScale` is a variable:
`instantiation_error`
`ToScale` is neither a variable nor an atom:
`type_error(atom,ToScale)`
`ToScale` is not supported:
`domain_error(time_scale,ToScale)`
`Instant` is not a valid instant term:
`domain_error(instant,Instant)`
`Scale` in `Instant` is neither a variable nor an atom:
`type_error(atom,Scale)`
`Scale` in `Instant` is not supported:
`domain_error(time_scale,Scale)`
`Seconds` in `Instant` is neither a variable nor an integer:
`type_error(integer,Seconds)`
`Seconds` in `Instant` is before supported UTC epoch:
`domain_error(utc_unix_seconds,Seconds)`
Fraction term in `Instant` is not of the form `fraction(Numerator,Denominator)`:
`domain_error(fraction,Fraction)`
`Numerator` in `Instant` is neither a variable nor an integer:
`type_error(integer,Numerator)`
`Denominator` in `Instant` is neither a variable nor an integer:
`type_error(integer,Denominator)`
`Denominator` in `Instant` is not positive:
`domain_error(positive_denominator,Denominator)`
Normalized fraction in `Instant` is not in the `[0,1[` interval:
`domain_error(normalized_fraction,Fraction)`

## Protected predicates

(none)

## Private predicates

(none)

## Operators

(none)

See also

time_scales, date