Skip to main content

astrotime/
standard.rs

1use std::fmt::Debug;
2
3#[cfg(feature = "serde")]
4use serde::{Deserialize, Serialize};
5
6use crate::duration::Duration;
7
8/// A standard of time
9pub trait Standard: Debug + Sized + Clone {
10    /// Short capital-letter abbreviation for the time standard (usually 2 or 3 letters)
11    fn abbrev() -> &'static str;
12
13    /// Offset from Tt  (This + offset = TT)
14    ///
15    /// This function is not meant to be called from outside the library.
16    /// But if you wish to create a new Standard that implements this trait, you'll need
17    /// access to this. This should not adjust for leap seconds.
18    fn tt_offset() -> Duration;
19
20    /// Linear scale factor from TT, usually None
21    fn tt_scale() -> Option<f64>;
22}
23
24/// Terrestrial Time (TT)
25///
26/// This is a continuous time standard for the surface of the Earth (Earth's geoid)
27/// See [Wikipedia](https://en.wikipedia.org/wiki/Terrestrial_Time)
28///
29/// This type is proleptic. TT was defined in 1976, and changed in 2000 very slightly.
30/// All dates before this extrapolate backwards.
31#[derive(Debug, Clone, Copy, PartialEq, Eq)]
32#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
33pub struct Tt;
34impl Standard for Tt {
35    fn abbrev() -> &'static str {
36        "TT"
37    }
38
39    fn tt_offset() -> Duration {
40        Duration::new(0, 0)
41    }
42
43    fn tt_scale() -> Option<f64> {
44        None
45    }
46}
47
48/// International Atomic Time (TAI)
49///
50/// This is a continuous time standard for the surface of the Earth (Earth's geoid)
51/// realized via atomic clocks.
52///
53/// This type is proleptic. TAI started on 1 January 1958, but we represent all dates
54/// before this as if TAI extends backwards.
55#[derive(Debug, Clone, Copy, PartialEq, Eq)]
56#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
57pub struct Tai;
58impl Standard for Tai {
59    fn abbrev() -> &'static str {
60        "TAI"
61    }
62
63    fn tt_offset() -> Duration {
64        Duration::new(32, 184_000_000_000_000_000)
65    }
66
67    fn tt_scale() -> Option<f64> {
68        None
69    }
70}
71
72/// Universal Coordinated Time (UTC)
73///
74/// This is civil time as usually reported.  It is discontinuous, having leap
75/// seconds inserted from time to time based on the Earth's rotation.
76///
77/// This type is proleptic. For all dates prior to 1 Jan 1972, we presume
78/// 9 seconds have elapsed (like leaps) offsetting from TAI permanently by 9
79/// seconds, even though that's not what happened at the time (what happened at
80/// the time was that UTC wasn't syncronized to TAI by integer leap seconds,
81/// but rather to other time sources and contained fractional leap seconds which
82/// are hard to reconstruct or even get a list of).  For all dates prior to
83/// 1 January 1960, UTC didn't exist, but we pretend it did, offset 9 seconds
84/// from TAI.
85#[derive(Debug, Clone, Copy, PartialEq, Eq)]
86#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
87pub struct Utc;
88impl Standard for Utc {
89    fn abbrev() -> &'static str {
90        "UTC"
91    }
92
93    fn tt_offset() -> Duration {
94        Duration::new(41, 184_000_000_000_000_000)
95    }
96
97    fn tt_scale() -> Option<f64> {
98        None
99    }
100}
101
102/// Geocentric Coordinate Time (TCG)
103///
104/// This is an Einsteinian-corrected time standard used for satellites
105/// of the Earth, which is also used to compute precession and nutation.
106/// It applies to objects taht move along with the Earth, but are outside
107/// of the Earth's gravity well.
108///
109/// TCG was synchronized with 1977-01-01T00:00:32.184 TT
110///
111/// Even though TCG was not defined until 1991, we use the standard
112/// prolepticly in the past.
113#[derive(Debug, Clone, Copy, PartialEq, Eq)]
114#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
115pub struct Tcg;
116impl Standard for Tcg {
117    fn abbrev() -> &'static str {
118        "TCG"
119    }
120
121    fn tt_offset() -> Duration {
122        Duration::new(0, 0)
123    }
124
125    fn tt_scale() -> Option<f64> {
126        Some(6.969_290_134e-10)
127    }
128}