From b6580ea895213fa6b69834263230859c4937560f Mon Sep 17 00:00:00 2001 From: "Guillaume W. Bres" Date: Sun, 28 May 2023 11:57:47 +0200 Subject: [PATCH] introducing to_time_scale Signed-off-by: Guillaume W. Bres --- src/deprecated.rs | 36 ++++--- src/efmt/formatter.rs | 4 +- src/epoch.rs | 222 +++++++++++++++++++----------------------- tests/epoch.rs | 66 +++++++++---- 4 files changed, 165 insertions(+), 163 deletions(-) diff --git a/src/deprecated.rs b/src/deprecated.rs index 4b6e3685..f40b6eb8 100644 --- a/src/deprecated.rs +++ b/src/deprecated.rs @@ -78,14 +78,16 @@ impl Epoch { self.to_duration_since_j1900() } - #[must_use] - #[deprecated( - note = "Prefix for this function is now `to_` instead of `as_`.", - since = "3.5.0" - )] - pub fn as_duration_since_j1900_in_time_scale(&self, time_scale: TimeScale) -> Duration { - self.to_duration_since_j1900_in_time_scale(time_scale) - } + /* + #[must_use] + #[deprecated( + note = "Prefix for this function is now `to_` instead of `as_`.", + since = "3.5.0" + )] + pub fn as_duration_since_j1900_in_time_scale(&self, time_scale: TimeScale) -> Duration { + self.to_duration_since_j1900_in_time_scale(time_scale) + } + */ #[must_use] #[deprecated( @@ -96,14 +98,16 @@ impl Epoch { self.to_tai_seconds() } - #[must_use] - #[deprecated( - note = "Prefix for this function is now `to_` instead of `as_`.", - since = "3.5.0" - )] - pub const fn as_tai_duration(&self) -> Duration { - self.to_tai_duration() - } + /* + #[must_use] + #[deprecated( + note = "Prefix for this function is now `to_` instead of `as_`.", + since = "3.5.0" + )] + pub const fn as_tai_duration(&self) -> Duration { + self.to_tai_duration() + } + */ #[must_use] #[deprecated( diff --git a/src/efmt/formatter.rs b/src/efmt/formatter.rs index 3922910a..974b7dd8 100644 --- a/src/efmt/formatter.rs +++ b/src/efmt/formatter.rs @@ -99,8 +99,8 @@ impl Formatter { } } - pub fn in_time_scale(epoch: Epoch, format: Format, time_scale: TimeScale) -> Self { - Self::new(epoch.in_time_scale(time_scale), format) + pub fn to_time_scale(epoch: Epoch, format: Format, time_scale: TimeScale) -> Self { + Self::new(epoch.to_time_scale(time_scale), format) } pub fn set_timezone(&mut self, offset: Duration) { diff --git a/src/epoch.rs b/src/epoch.rs index 8e5b00dd..4c9fc3a2 100644 --- a/src/epoch.rs +++ b/src/epoch.rs @@ -13,9 +13,9 @@ use crate::leap_seconds::{LatestLeapSeconds, LeapSecondProvider}; use crate::parser::Token; use crate::{ Errors, MonthName, TimeScale, BDT_REF_EPOCH, DAYS_PER_YEAR_NLD, ET_EPOCH_S, GPST_REF_EPOCH, - GST_REF_EPOCH, J1900_OFFSET, J2000_TO_J1900_DURATION, MJD_OFFSET, NANOSECONDS_PER_DAY, - NANOSECONDS_PER_MICROSECOND, NANOSECONDS_PER_MILLISECOND, NANOSECONDS_PER_SECOND_U32, - UNIX_REF_EPOCH, + GST_REF_EPOCH, J1900_OFFSET, J2000_REF_EPOCH, J2000_TO_J1900_DURATION, MJD_OFFSET, + NANOSECONDS_PER_DAY, NANOSECONDS_PER_MICROSECOND, NANOSECONDS_PER_MILLISECOND, + NANOSECONDS_PER_SECOND_U32, UNIX_REF_EPOCH, }; use crate::efmt::format::Format; @@ -138,7 +138,7 @@ impl Sub for Epoch { type Output = Duration; fn sub(self, other: Self) -> Duration { - self.duration - other.duration + self.duration - other.to_time_scale(self.time_scale).duration } } @@ -152,7 +152,10 @@ impl Sub for Epoch { type Output = Self; fn sub(self, duration: Duration) -> Self { - self.set(self.to_duration() - duration) + Self { + duration: self.to_duration() - duration, + time_scale: self.time_scale, + } } } @@ -162,7 +165,10 @@ impl Add for Epoch { type Output = Self; fn add(self, seconds: f64) -> Self { - self.set(self.to_duration() + seconds * Unit::Second) + Self { + duration: self.to_duration() + seconds * Unit::Second, + time_scale: self.time_scale, + } } } @@ -170,7 +176,10 @@ impl Add for Epoch { type Output = Self; fn add(self, duration: Duration) -> Self { - self.set(self.to_duration() + duration) + Self { + duration: self.to_duration() + duration, + time_scale: self.time_scale, + } } } @@ -193,7 +202,10 @@ impl Sub for Epoch { #[allow(clippy::identity_op)] fn sub(self, unit: Unit) -> Self { - self.set(self.to_duration() - unit * 1) + Self { + duration: self.to_duration() - unit * 1, + time_scale: self.time_scale, + } } } @@ -202,7 +214,10 @@ impl Add for Epoch { #[allow(clippy::identity_op)] fn add(self, unit: Unit) -> Self { - self.set(self.to_duration() + unit * 1) + Self { + duration: self.to_duration() + unit * 1, + time_scale: self.time_scale, + } } } @@ -215,7 +230,7 @@ impl AddAssign for Epoch { /// Equality only checks the duration since J1900 match in TAI, because this is how all of the epochs are referenced. impl PartialEq for Epoch { fn eq(&self, other: &Self) -> bool { - self.duration == other.duration + self.duration == other.to_time_scale(self.time_scale).duration } } @@ -229,7 +244,7 @@ impl PartialOrd for Epoch { fn partial_cmp(&self, other: &Self) -> Option { Some( self.duration - .cmp(&other.duration), + .cmp(&other.to_time_scale(self.time_scale).duration), ) } } @@ -237,7 +252,7 @@ impl PartialOrd for Epoch { impl Ord for Epoch { fn cmp(&self, other: &Self) -> Ordering { self.duration - .cmp(&other.duration) + .cmp(&other.to_time_scale(self.time_scale).duration) } } @@ -266,59 +281,56 @@ impl Epoch { /// Creates an epoch from given duration expressed in given timescale. /// In case of ET, TDB Timescales, a duration since J2000 is expected. #[must_use] - pub fn from_duration(new_duration: Duration, ts: TimeScale) -> Self { + pub fn from_duration(duration: Duration, ts: TimeScale) -> Self { + Self { + duration, + time_scale: ts, + } + } + + pub fn to_duration_since_j1900(&self) -> Duration { + self.to_time_scale(TimeScale::TAI).duration + } + + #[must_use] + /// Converts self to another time scale + pub fn to_time_scale(&self, ts: TimeScale) -> Self { match ts { - TimeScale::TAI => Self { - duration: new_duration, - time_scale: TimeScale::TAI, - }, - TimeScale::ET => { - // Run a Newton Raphston to convert find the correct value of the - let mut seconds_j2000 = new_duration.to_seconds(); - for _ in 0..5 { - seconds_j2000 += -NAIF_K - * (NAIF_M0 - + NAIF_M1 * seconds_j2000 - + NAIF_EB * (NAIF_M0 + NAIF_M1 * seconds_j2000).sin()) - .sin(); - } - // At this point, we have a good estimate of the number of seconds of this epoch. - // Reverse the algorithm: - let delta_et_tai = Self::delta_et_tai( - seconds_j2000 - (TT_OFFSET_MS * Unit::Millisecond).to_seconds(), - ); - // Match SPICE by changing the UTC definition. - Self { - duration: (new_duration.to_seconds() - delta_et_tai) - * Unit::Second - + J2000_TO_J1900_DURATION, - time_scale: TimeScale::ET, - } + TimeScale::TAI => { + // conversion to TAI: remove time scale reference point + let mut new_epoch = self.clone(); + new_epoch.duration -= ts.tai_reference_epoch().duration; + new_epoch.with_time_scale(TimeScale::TAI) } TimeScale::TDB => { - let gamma = Self::inner_g(new_duration.to_seconds()); + // first convert back to TAI + let mut tai_epoch = self.to_time_scale(TimeScale::TAI); + // seconds past J2000 + //TODO: this operation is not feasible is Self is not PAST J2000 + let duration_since_j2000 = tai_epoch - J2000_REF_EPOCH; + let seconds_since_j2000 = duration_since_j2000.to_seconds(); + let gamma = Self::inner_g(seconds_since_j2000); let delta_tdb_tai = gamma * Unit::Second + TT_OFFSET_MS * Unit::Millisecond; - // Offset back to J1900. - Self { - duration: new_duration - delta_tdb_tai - + J2000_TO_J1900_DURATION, - time_scale: TimeScale::TDB, - } + tai_epoch += delta_tdb_tai; + tai_epoch -= J2000_TO_J1900_DURATION; // TDB time scale is expressed past J2000 + tai_epoch.with_time_scale(TimeScale::TDB) } ts => { - let mut tai_epoch = ts.tai_reference_epoch(); - tai_epoch += new_duration; + // first convert back to TAI + let mut tai_epoch = self.to_time_scale(TimeScale::TAI); + // leap second management + if ts.uses_leap_seconds() { + // TAI = UTC + leap_seconds <=> UTC = TAI - leap_seconds + tai_epoch += tai_epoch.leap_seconds(true).unwrap_or(0.0) * Unit::Second; + } + // time scale specificities match ts { TimeScale::TT => { tai_epoch -= TT_OFFSET_MS * Unit::Millisecond; } _ => {} } - // leap second management - if ts.uses_leap_seconds() { - tai_epoch += tai_epoch.leap_seconds(true).unwrap_or(0.0) * Unit::Second; - } - tai_epoch.with_timescale(ts) + tai_epoch.with_time_scale(ts) } } } @@ -761,15 +773,11 @@ impl Epoch { duration_wrt_1900 -= Unit::Second; } - // NOTE: For ET and TDB, we make sure to offset the duration back to J2000 since those functions expect a J2000 input. - Ok(match time_scale { - TimeScale::ET => Self::from_et_duration(duration_wrt_1900 - J2000_TO_J1900_DURATION), - TimeScale::TDB => Self::from_tdb_duration(duration_wrt_1900 - J2000_TO_J1900_DURATION), - ts => Self::from_duration( - duration_wrt_1900 - ts.tai_reference_epoch().to_tai_duration(), - ts, - ), - }) + Ok(Self { + duration: duration_wrt_1900, + time_scale: TimeScale::TAI, + } + .to_time_scale(time_scale)) } #[must_use] @@ -1756,24 +1764,14 @@ impl Epoch { /// 2. If an epoch was initialized as Epoch::from_..._tdb(...) then the duration will be the UTC duration from J2000 because the TDB reference epoch is J2000. #[must_use] pub fn to_duration(&self) -> Duration { - self.to_duration_in_time_scale(self.time_scale) + self.duration } #[must_use] /// Returns this epoch with respect to the provided time scale. /// This is needed to correctly perform duration conversions in dynamical time scales (e.g. TDB). - pub fn to_duration_in_time_scale(&self, time_scale: TimeScale) -> Duration { - match time_scale { - TimeScale::TAI => self.duration, - TimeScale::TT => self.to_tt_duration(), - TimeScale::ET => self.to_et_duration(), - TimeScale::TDB => self.to_tdb_duration(), - TimeScale::UTC => self.to_utc_duration(), - TimeScale::BDT => self.to_bdt_duration(), - TimeScale::GST => self.to_gst_duration(), - // GPST and QZSST share the same properties - TimeScale::GPST | TimeScale::QZSST => self.to_gpst_duration(), - } + pub fn to_duration_in_time_scale(&self, ts: TimeScale) -> Duration { + self.to_time_scale(ts).duration } /// Attempts to return the number of nanoseconds since the reference epoch of the provided time scale. @@ -1790,46 +1788,23 @@ impl Epoch { } } - /// Returns this epoch in duration since J1900 in the time scale this epoch was created in. - #[must_use] - pub fn to_duration_since_j1900(&self) -> Duration { - self.to_duration_since_j1900_in_time_scale(self.time_scale) - } - - /// Returns this epoch in duration since J1900 with respect to the provided time scale. - #[must_use] - pub fn to_duration_since_j1900_in_time_scale(&self, time_scale: TimeScale) -> Duration { - match time_scale { - TimeScale::ET => self.to_et_duration_since_j1900(), - TimeScale::TAI => self.duration, - TimeScale::TT => self.to_tt_duration(), - TimeScale::TDB => self.to_tdb_duration_since_j1900(), - TimeScale::UTC => self.to_utc_duration(), - // GPST and QZSST share the same properties - TimeScale::GPST | TimeScale::QZSST => { - self.to_gpst_duration() + GPST_REF_EPOCH.to_tai_duration() + /* + /// Makes a copy of self and sets the duration and time scale appropriately given the new duration + #[must_use] + pub fn set(&self, new_duration: Duration) -> Self { + match self.time_scale { + TimeScale::TAI => Self::from_tai_duration(new_duration), + TimeScale::TT => Self::from_tt_duration(new_duration), + TimeScale::ET => Self::from_et_duration(new_duration), + TimeScale::TDB => Self::from_tdb_duration(new_duration), + TimeScale::UTC => Self::from_utc_duration(new_duration), + // GPST and QZSST share the same properties + TimeScale::GPST | TimeScale::QZSST => Self::from_gpst_duration(new_duration), + TimeScale::GST => Self::from_gst_duration(new_duration), + TimeScale::BDT => Self::from_bdt_duration(new_duration), } - TimeScale::GST => self.to_gst_duration() + GST_REF_EPOCH.to_tai_duration(), - TimeScale::BDT => self.to_bdt_duration() + BDT_REF_EPOCH.to_tai_duration(), - } - } - - /// Makes a copy of self and sets the duration and time scale appropriately given the new duration - #[must_use] - pub fn set(&self, new_duration: Duration) -> Self { - match self.time_scale { - TimeScale::TAI => Self::from_tai_duration(new_duration), - TimeScale::TT => Self::from_tt_duration(new_duration), - TimeScale::ET => Self::from_et_duration(new_duration), - TimeScale::TDB => Self::from_tdb_duration(new_duration), - TimeScale::UTC => Self::from_utc_duration(new_duration), - // GPST and QZSST share the same properties - TimeScale::GPST | TimeScale::QZSST => Self::from_gpst_duration(new_duration), - TimeScale::GST => Self::from_gst_duration(new_duration), - TimeScale::BDT => Self::from_bdt_duration(new_duration), } - } - + */ #[must_use] /// Returns the number of TAI seconds since J1900 pub fn to_tai_seconds(&self) -> f64 { @@ -1838,8 +1813,8 @@ impl Epoch { #[must_use] /// Returns this time in a Duration past J1900 counted in TAI - pub const fn to_tai_duration(&self) -> Duration { - self.duration + pub fn to_tai_duration(&self) -> Duration { + self.to_time_scale(TimeScale::TAI).duration } #[must_use] @@ -1869,8 +1844,7 @@ impl Epoch { #[must_use] /// Returns this time in a Duration past J1900 counted in UTC pub fn to_utc_duration(&self) -> Duration { - // TAI = UTC + leap_seconds <=> UTC = TAI - leap_seconds - self.duration - self.leap_seconds(true).unwrap_or(0.0) * Unit::Second + self.to_time_scale(TimeScale::UTC).duration } #[must_use] @@ -2051,8 +2025,7 @@ impl Epoch { #[must_use] /// Returns `Duration` past QZSS time Epoch. pub fn to_qzsst_duration(&self) -> Duration { - // GPST and QZSST share the same reference epoch - self.duration - GPST_REF_EPOCH.to_tai_duration() + self.to_time_scale(TimeScale::QZSST).duration } /// Returns nanoseconds past QZSS Time Epoch, defined as UTC midnight of January 5th to 6th 1980 (cf. ). @@ -2425,7 +2398,7 @@ impl Epoch { #[must_use] /// Copies this epoch and sets it to the new time scale provided. - pub fn in_time_scale(&self, new_time_scale: TimeScale) -> Self { + pub fn with_time_scale(&self, new_time_scale: TimeScale) -> Self { let mut me = *self; me.time_scale = new_time_scale; me @@ -2636,7 +2609,7 @@ impl Epoch { let (sign, days, _, _, _, milliseconds, microseconds, nanoseconds) = self.to_duration().decompose(); // Shadow other with the provided other epoch but in the correct time scale. - let other = other.in_time_scale(self.time_scale); + let other = other.to_time_scale(self.time_scale); Self::from_duration( Duration::compose( sign, @@ -2717,7 +2690,7 @@ impl Epoch { /// ``` pub fn with_hms_strict_from(&self, other: Self) -> Self { let (sign, days, _, _, _, _, _, _) = self.to_duration().decompose(); - let other = other.in_time_scale(self.time_scale); + let other = other.to_time_scale(self.time_scale); Self::from_duration( Duration::compose( sign, @@ -3003,7 +2976,7 @@ impl fmt::Debug for Epoch { /// Print this epoch in Gregorian in the time scale used at initialization fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { let (y, mm, dd, hh, min, s, nanos) = - Self::compute_gregorian(self.to_duration_since_j1900()); + Self::compute_gregorian(self.to_time_scale(TimeScale::TAI).duration); if nanos == 0 { write!( f, @@ -3265,7 +3238,8 @@ fn cumulative_days_for_month() { #[cfg(feature = "serde")] fn test_serdes() { let e = Epoch::from_gregorian_utc(2020, 01, 01, 0, 0, 0, 0); - let content = r#"{"duration":{"centuries":1,"nanoseconds":631065637000000000},"time_scale":"UTC"}"#; + let content = + r#"{"duration":{"centuries":1,"nanoseconds":631065637000000000},"time_scale":"UTC"}"#; assert_eq!(content, serde_json::to_string(&e).unwrap()); let parsed: Epoch = serde_json::from_str(content).unwrap(); assert_eq!(e, parsed); diff --git a/tests/epoch.rs b/tests/epoch.rs index 63adeb50..0488d46f 100644 --- a/tests/epoch.rs +++ b/tests/epoch.rs @@ -4,8 +4,8 @@ extern crate core; use hifitime::{ is_gregorian_valid, Duration, Epoch, Errors, ParsingErrors, TimeScale, TimeUnits, Unit, Weekday, BDT_REF_EPOCH, DAYS_GPS_TAI_OFFSET, GPST_REF_EPOCH, GST_REF_EPOCH, J1900_OFFSET, - J1900_REF_EPOCH, J2000_OFFSET, MJD_OFFSET, SECONDS_BDT_TAI_OFFSET, SECONDS_GPS_TAI_OFFSET, - SECONDS_GST_TAI_OFFSET, SECONDS_PER_DAY, + J1900_REF_EPOCH, J2000_OFFSET, J2000_REF_EPOCH, J2000_TO_J1900_DURATION, MJD_OFFSET, + SECONDS_BDT_TAI_OFFSET, SECONDS_GPS_TAI_OFFSET, SECONDS_GST_TAI_OFFSET, SECONDS_PER_DAY, }; use hifitime::efmt::{Format, Formatter}; @@ -563,11 +563,11 @@ fn unix() { let unix_epoch = Epoch::from_gregorian_utc_at_midnight(1970, 1, 1); assert_eq!( - format!("{}", unix_epoch.in_time_scale(TimeScale::UTC)), + format!("{}", unix_epoch.to_time_scale(TimeScale::UTC)), "1970-01-01T00:00:00 UTC" ); assert_eq!( - format!("{:x}", unix_epoch.in_time_scale(TimeScale::TAI)), + format!("{:x}", unix_epoch.to_time_scale(TimeScale::TAI)), "1970-01-01T00:00:00 TAI" ); // Print as UNIX seconds @@ -1240,7 +1240,6 @@ fn regression_test_gh_145() { fn test_timescale_recip() { // The general test function used throughout this verification. let recip_func = |utc_epoch: Epoch| { - assert_eq!(utc_epoch, utc_epoch.set(utc_epoch.to_duration())); // Test that we can convert this epoch into another time scale and re-initialize it correctly from that value. for ts in &[ //TimeScale::TAI, @@ -1326,7 +1325,7 @@ fn test_add_durations_over_leap_seconds() { // Noon UTC after the first leap second is in fact ten seconds _after_ noon TAI. // Hence, there are as many TAI seconds since Epoch between UTC Noon and TAI Noon + 10s. let pre_ls_utc = Epoch::from_gregorian_utc_at_noon(1971, 12, 31); - let pre_ls_tai = pre_ls_utc.in_time_scale(TimeScale::TAI); + let pre_ls_tai = pre_ls_utc.to_time_scale(TimeScale::TAI); // Before the first leap second, there is no time difference between both epochs (because only IERS announced leap seconds are accounted for by default). assert_eq!(pre_ls_utc - pre_ls_tai, Duration::ZERO); @@ -1427,7 +1426,7 @@ fn test_weekday() { TimeScale::TT, TimeScale::UTC, ] { - let e_ts = e.in_time_scale(new_time_scale); + let e_ts = e.to_time_scale(new_time_scale); assert_eq!(e_ts.weekday(), expect, "error with {new_time_scale}"); } }; @@ -1507,7 +1506,7 @@ fn test_get_time() { let epoch = Epoch::from_gregorian_utc(2022, 12, 01, 10, 11, 12, 13); let other_utc = Epoch::from_gregorian_utc(2024, 12, 01, 20, 21, 22, 23); - let other = other_utc.in_time_scale(TimeScale::TDB); + let other = other_utc.to_time_scale(TimeScale::TDB); assert_eq!( epoch.with_hms_from(other), @@ -1565,7 +1564,7 @@ fn test_time_of_week() { assert_eq!(epoch.to_time_of_week(), (0, 10 * 1_000_000_000 + 10)); // TAI<=>UTC - let epoch_utc = epoch.in_time_scale(TimeScale::UTC); + let epoch_utc = epoch.to_time_scale(TimeScale::UTC); let (week, tow) = epoch_utc.to_time_of_week(); assert_eq!( Epoch::from_time_of_week(week, tow, TimeScale::UTC), @@ -1585,7 +1584,7 @@ fn test_time_of_week() { assert_eq!(epoch.to_gregorian_utc(), (2022, 12, 01, 00, 00, 00, 00)); assert_eq!(epoch.to_time_of_week(), (2238, 345_618_000_000_000)); - let epoch_utc = epoch.in_time_scale(TimeScale::UTC); + let epoch_utc = epoch.to_time_scale(TimeScale::UTC); let (utc_wk, utc_tow) = epoch_utc.to_time_of_week(); assert_eq!( Epoch::from_time_of_week(utc_wk, utc_tow, TimeScale::UTC), @@ -1593,7 +1592,7 @@ fn test_time_of_week() { ); // GPST and QZSST share the same properties at all times - let epoch_qzsst = epoch.in_time_scale(TimeScale::QZSST); + let epoch_qzsst = epoch.to_time_scale(TimeScale::QZSST); assert_eq!(epoch.to_gregorian_utc(), epoch_qzsst.to_gregorian_utc()); let gps_qzss_offset = @@ -1605,7 +1604,7 @@ fn test_time_of_week() { assert_eq!(epoch.to_gregorian_utc(), (1980, 01, 06, 01, 00, 0 + 18, 00)); assert_eq!(epoch.to_time_of_week(), (0, 3_618_000_000_000)); - let epoch_utc = epoch.in_time_scale(TimeScale::UTC); + let epoch_utc = epoch.to_time_scale(TimeScale::UTC); let (utc_wk, utc_tow) = epoch_utc.to_time_of_week(); assert_eq!( Epoch::from_time_of_week(utc_wk, utc_tow, TimeScale::UTC), @@ -1626,7 +1625,7 @@ fn test_time_of_week() { assert_eq!(epoch.to_time_of_week(), (24, 306_457_000_000_000)); // <=>UTC - let epoch_utc = epoch.in_time_scale(TimeScale::UTC); + let epoch_utc = epoch.to_time_scale(TimeScale::UTC); let (week, tow) = epoch_utc.to_time_of_week(); assert_eq!( Epoch::from_time_of_week(week, tow, TimeScale::UTC), @@ -1638,7 +1637,7 @@ fn test_time_of_week() { assert_eq!(epoch.to_gregorian_utc(), (2022, 12, 01, 00, 00, 00, 01)); // <=>UTC - let epoch_utc = epoch.in_time_scale(TimeScale::UTC); + let epoch_utc = epoch.to_time_scale(TimeScale::UTC); let (week, tow) = epoch_utc.to_time_of_week(); assert_eq!( Epoch::from_time_of_week(week, tow, TimeScale::UTC), @@ -1650,7 +1649,7 @@ fn test_time_of_week() { assert_eq!(epoch.to_gregorian_utc(), (2022, 12, 02, 12, 00, 00, 00)); // <=>UTC - let epoch_utc = epoch.in_time_scale(TimeScale::UTC); + let epoch_utc = epoch.to_time_scale(TimeScale::UTC); let (week, tow) = epoch_utc.to_time_of_week(); assert_eq!( Epoch::from_time_of_week(week, tow, TimeScale::UTC), @@ -1662,7 +1661,7 @@ fn test_time_of_week() { assert_eq!(epoch.to_gregorian_utc(), (2022, 12, 02, 15, 27, 19, 10)); // <=>UTC - let epoch_utc = epoch.in_time_scale(TimeScale::UTC); + let epoch_utc = epoch.to_time_scale(TimeScale::UTC); let (week, tow) = epoch_utc.to_time_of_week(); assert_eq!( Epoch::from_time_of_week(week, tow, TimeScale::UTC), @@ -1676,7 +1675,7 @@ fn test_time_of_week() { assert_eq!(epoch.to_time_of_week(), (0, 3_600_000_000_000)); // <=>UTC - let epoch_utc = epoch.in_time_scale(TimeScale::UTC); + let epoch_utc = epoch.to_time_scale(TimeScale::UTC); let (week, tow) = epoch_utc.to_time_of_week(); assert_eq!( Epoch::from_time_of_week(week, tow, TimeScale::UTC), @@ -1692,7 +1691,7 @@ fn test_time_of_week() { assert_eq!(epoch.to_time_of_week(), (1, 128 * 3600 * 1_000_000_000)); // <=>UTC - let epoch_utc = epoch.in_time_scale(TimeScale::UTC); + let epoch_utc = epoch.to_time_scale(TimeScale::UTC); let (week, tow) = epoch_utc.to_time_of_week(); assert_eq!( Epoch::from_time_of_week(week, tow, TimeScale::UTC), @@ -1713,7 +1712,7 @@ fn test_time_of_week() { ); // <=>UTC - let epoch_utc = epoch.in_time_scale(TimeScale::UTC); + let epoch_utc = epoch.to_time_scale(TimeScale::UTC); let (week, tow) = epoch_utc.to_time_of_week(); assert_eq!( Epoch::from_time_of_week(week, tow, TimeScale::UTC), @@ -1736,7 +1735,7 @@ fn test_time_of_week() { ); // <=>UTC - let epoch_utc = epoch.in_time_scale(TimeScale::UTC); + let epoch_utc = epoch.to_time_scale(TimeScale::UTC); let (week, tow) = epoch_utc.to_time_of_week(); assert_eq!( Epoch::from_time_of_week(week, tow, TimeScale::UTC), @@ -1757,7 +1756,7 @@ fn test_day_of_year() { TimeScale::ET, TimeScale::TDB, ] { - let epoch = utc_epoch.in_time_scale(*ts); + let epoch = utc_epoch.to_time_scale(*ts); let (year, days) = epoch.year_days_of_year(); let rebuilt = Epoch::from_day_of_year(year, days, *ts); if *ts == TimeScale::ET || *ts == TimeScale::TDB { @@ -1879,6 +1878,31 @@ fn test_epoch_formatter() { ); } +#[test] +fn test_to_tai_time_scale() { + let j1900_ref = J1900_REF_EPOCH; + assert_eq!(j1900_ref, j1900_ref.to_time_scale(TimeScale::TAI)); + let j2000_ref = J2000_REF_EPOCH; + assert_eq!(j2000_ref, j2000_ref.to_time_scale(TimeScale::TAI)); + let j2000_to_j1900 = j2000_ref - j1900_ref; + assert_eq!(j2000_to_j1900, J2000_TO_J1900_DURATION); +} + +#[test] +fn test_to_utc_time_scale() { + let gpst_tai_ref = TimeScale::GPST.tai_reference_epoch(); + // there were 19 leap seconds on the day GPST was "started" + let gpst_utc_delta = 19.0; // leaps + let gpst_utc_ref = gpst_tai_ref.to_time_scale(TimeScale::UTC); + assert_eq!((gpst_utc_ref - gpst_tai_ref).to_seconds(), gpst_utc_delta); + + let bdt_tai_ref = TimeScale::BDT.tai_reference_epoch(); + // there were 33 leap seconds on the day BDT was "started" + let bdt_utc_delta = 33.0; // leaps + let bdt_utc_ref = bdt_tai_ref.to_time_scale(TimeScale::UTC); + assert_eq!((bdt_utc_ref - bdt_tai_ref).to_seconds(), bdt_utc_delta); +} + #[cfg(feature = "std")] #[test] fn test_leap_seconds_file() {