Skip to main content

gstreamer/
time_offsets.rs

1// Take a look at the license at the top of the repository in the LICENSE file.
2
3// rustdoc-stripper-ignore-next
4//! Time offset collection, useful when working with reference clock.
5//!
6//! See also the constants implemented on [`crate::ClockTime`].
7
8use std::sync::LazyLock;
9
10// rustdoc-stripper-ignore-next
11/// Number of seconds to add to UNIX time to convert to NTP time.
12///
13/// * NTP time epoch:  01/01/1900 00:00:00.00
14/// * UNIX time epoch: 01/01/1970 00:00:00.00
15/// * 17 leap years between 1900 & 1970
16pub const UNIX_TO_NTP_TIME_OFFSET_SECONDS: u64 = (365 * 70 + 17) * 24 * 60 * 60;
17
18// rustdoc-stripper-ignore-next
19/// Number of seconds to add to UNIX time to convert to PTP time.
20///
21/// * UNIX time and PTP time use the same epoch: 01/01/1970 00:00:00.00
22/// * UNIX time follows UTC in the sense that neither add leap seconds.
23/// * PTP time follows TAI with regard to leap seconds.
24pub static UNIX_TO_PTP_TIME_OFFSET_SECONDS: LazyLock<u64> =
25    LazyLock::new(|| *UTC_TO_TAI_LEAP_SECONDS);
26
27// rustdoc-stripper-ignore-next
28/// Number of seconds to subtract from NTP time to convert to PTP time.
29///
30/// * PTP time epoch is the same as UNIX time: 01/01/1970 00:00:00.00
31/// * NTP time follows UTC in the sense that neither add leap seconds.
32/// * PTP time follows TAI with regard to leap seconds.
33pub static NTP_TO_PTP_TIME_OFFSET_SECONDS: LazyLock<u64> =
34    LazyLock::new(|| UNIX_TO_NTP_TIME_OFFSET_SECONDS - *UTC_TO_TAI_LEAP_SECONDS);
35
36// rustdoc-stripper-ignore-next
37/// Env var for the number of leap seconds applicable to UTC compared to TAI
38/// See [`UTC_TO_TAI_LEAP_SECONDS`] for more details.
39pub const UTC_TO_TAI_LEAP_SECONDS_ENV_VAR: &str = "GST_UTC_TO_TAI_LEAP_SECONDS";
40
41// rustdoc-stripper-ignore-next
42/// Number of current leap seconds applicable to UTC compared to TAI
43///
44/// This is the variable part of the offset between:
45///
46/// * TAI (also PTP time)
47/// * and UTC (also NTP time, UNIX time).
48///
49/// Note that this doesn't account for the constant difference in epochs.
50/// See: [`UNIX_TO_NTP_TIME_OFFSET_SECONDS`], [`UNIX_TO_PTP_TIME_OFFSET_SECONDS`] &
51/// [`NTP_TO_PTP_TIME_OFFSET_SECONDS`].
52///
53/// Defaults to `UTC_TO_TAI_LEAP_SECONDS_DEFAULT` if the environment variable
54/// named by [`UTC_TO_TAI_LEAP_SECONDS_ENV_VAR`] is not defined or invalid.
55pub static UTC_TO_TAI_LEAP_SECONDS: LazyLock<u64> = LazyLock::new(|| {
56    const {
57        assert!(
58            UTC_TO_TAI_LEAP_SECONDS_DEFAULT <= UNIX_TO_NTP_TIME_OFFSET_SECONDS,
59            "NTP time to PTP time code assumes UTC_TO_TAI_LEAP_SECONDS_DEFAULT <= UNIX_TO_NTP_TIME_OFFSET_SECONDS"
60        );
61    }
62
63    match std::env::var(UTC_TO_TAI_LEAP_SECONDS_ENV_VAR) {
64        Ok(val) => match val.parse() {
65            Ok(val) => {
66                if val > UNIX_TO_NTP_TIME_OFFSET_SECONDS {
67                    crate::warning!(
68                        crate::CAT_RUST,
69                        "{UTC_TO_TAI_LEAP_SECONDS_ENV_VAR}: invalid value \
70                         greater than UNIX to NTP epoch ({UNIX_TO_NTP_TIME_OFFSET_SECONDS}) \
71                         => using default: {UTC_TO_TAI_LEAP_SECONDS_DEFAULT}"
72                    );
73
74                    UTC_TO_TAI_LEAP_SECONDS_DEFAULT
75                } else {
76                    crate::info!(
77                        crate::CAT_RUST,
78                        "{UTC_TO_TAI_LEAP_SECONDS_ENV_VAR} defined: {val}",
79                    );
80                    val
81                }
82            }
83            Err(err) => {
84                crate::warning!(
85                    crate::CAT_RUST,
86                    "{UTC_TO_TAI_LEAP_SECONDS_ENV_VAR}: invalid value '{val}' ({err}) \
87                     => using default: {UTC_TO_TAI_LEAP_SECONDS_DEFAULT}",
88                );
89                UTC_TO_TAI_LEAP_SECONDS_DEFAULT
90            }
91        },
92        Err(std::env::VarError::NotPresent) => {
93            crate::info!(
94                crate::CAT_RUST,
95                "{UTC_TO_TAI_LEAP_SECONDS_ENV_VAR} undefined \
96                 => using default: {UTC_TO_TAI_LEAP_SECONDS_DEFAULT}",
97            );
98            UTC_TO_TAI_LEAP_SECONDS_DEFAULT
99        }
100        Err(err) => {
101            crate::warning!(
102                crate::CAT_RUST,
103                "{UTC_TO_TAI_LEAP_SECONDS_ENV_VAR}: invalid value ({err}) \
104                 => using default: {UTC_TO_TAI_LEAP_SECONDS_DEFAULT}",
105            );
106            UTC_TO_TAI_LEAP_SECONDS_DEFAULT
107        }
108    }
109});
110
111// rustdoc-stripper-ignore-next
112/// Current variable number of leap seconds applicable to UTC compared to TAI
113/// as of 07/2026, since 01/01/2017 00:00:00 UTC
114///
115/// WARNING: this must remain private, everyone must use [`UTC_TO_TAI_LEAP_SECONDS`] instead.
116const UTC_TO_TAI_LEAP_SECONDS_DEFAULT: u64 = 37;