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}