Skip to content

Commit

Permalink
tests: improve qzss coverage
Browse files Browse the repository at this point in the history
Signed-off-by: Guillaume W. Bres <[email protected]>
  • Loading branch information
gwbres committed May 21, 2023
1 parent 26ba849 commit 4d0f6f0
Show file tree
Hide file tree
Showing 3 changed files with 167 additions and 21 deletions.
12 changes: 6 additions & 6 deletions src/asn1der.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,8 @@ impl<'a> Decode<'a> for Epoch {
TimeScale::ET => Self::from_et_duration(duration),
TimeScale::TDB => Self::from_tdb_duration(duration),
TimeScale::UTC => Self::from_utc_duration(duration),
// GPST and QZSST share the same properties
TimeScale::GPST | TimeScale::QZSST => Self::from_gpst_duration(duration),
TimeScale::GPST => Self::from_gpst_duration(duration),
TimeScale::QZSST => Self::from_qzsst_duration(duration),
TimeScale::GST => Self::from_gst_duration(duration),
TimeScale::BDT => Self::from_bdt_duration(duration),
})
Expand Down Expand Up @@ -93,7 +93,7 @@ impl<'a> Decode<'a> for Unit {
// Testing the encoding and decoding of an Epoch inherently also tests the encoding and decoding of a Duration
#[test]
fn test_encdec() {
for ts_u8 in 0..=7 {
for ts_u8 in 0..=8 {
let ts: TimeScale = ts_u8.into();

let epoch = if ts == TimeScale::UTC {
Expand All @@ -108,10 +108,10 @@ fn test_encdec() {
TimeScale::TT => epoch.to_tt_duration(),
TimeScale::TDB => epoch.to_tdb_duration(),
TimeScale::UTC => epoch.to_utc_duration(),
TimeScale::GPST => epoch.to_gpst_duration(),
TimeScale::GST => epoch.to_gst_duration(),
TimeScale::BDT => epoch.to_bdt_duration(),
// GPST and QZSST share the same properties
TimeScale::GPST | TimeScale::QZSST => epoch.to_gpst_duration(),
TimeScale::QZSST => epoch.to_qzsst_duration(),
};

let e_dur = epoch.to_duration();
Expand All @@ -132,7 +132,7 @@ fn test_encdec() {
// Check that the time scale used is preserved
assert_eq!(
encdec_epoch.time_scale, ts,
"Decoded time system incorrect {ts:?}"
"Decoded time system incorrect {ts:?}",
);
}

Expand Down
120 changes: 109 additions & 11 deletions src/epoch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -272,8 +272,8 @@ impl Epoch {
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::GPST => Self::from_gpst_duration(new_duration),
TimeScale::QZSST => Self::from_qzsst_duration(new_duration),
TimeScale::GST => Self::from_gst_duration(new_duration),
TimeScale::BDT => Self::from_bdt_duration(new_duration),
}
Expand Down Expand Up @@ -347,6 +347,15 @@ impl Epoch {
me
}

#[must_use]
/// Initialize an Epoch from the provided duration since 1980 January 6 at midnight
pub fn from_qzsst_duration(duration: Duration) -> Self {
// QZSST and GPST share the same reference epoch
let mut me = Self::from_tai_duration(GPST_REF_EPOCH.to_tai_duration() + duration);
me.time_scale = TimeScale::QZSST;
me
}

#[must_use]
/// Initialize an Epoch from the provided duration since August 21st 1999 midnight
pub fn from_gst_duration(duration: Duration) -> Self {
Expand Down Expand Up @@ -391,6 +400,10 @@ impl Epoch {
Self::from_mjd_in_time_scale(days, TimeScale::GPST)
}
#[must_use]
pub fn from_mjd_qzsst(days: f64) -> Self {
Self::from_mjd_in_time_scale(days, TimeScale::QZSST)
}
#[must_use]
pub fn from_mjd_gst(days: f64) -> Self {
Self::from_mjd_in_time_scale(days, TimeScale::GST)
}
Expand Down Expand Up @@ -427,6 +440,10 @@ impl Epoch {
Self::from_jde_in_time_scale(days, TimeScale::GPST)
}
#[must_use]
pub fn from_jde_qzsst(days: f64) -> Self {
Self::from_jde_in_time_scale(days, TimeScale::QZSST)
}
#[must_use]
pub fn from_jde_gst(days: f64) -> Self {
Self::from_jde_in_time_scale(days, TimeScale::GST)
}
Expand Down Expand Up @@ -573,6 +590,34 @@ impl Epoch {
)
}

#[must_use]
/// Initialize an Epoch from the number of seconds since the QZSS Time Epoch,
/// defined as UTC midnight of January 5th to 6th 1980 (cf. <https://gssc.esa.int/navipedia/index.php/Time_References_in_GNSS#GPS_Time_.28GPST.29>).
pub fn from_qzsst_seconds(seconds: f64) -> Self {
Self::from_duration(Duration::from_f64(seconds, Unit::Second), TimeScale::QZSST)
}

#[must_use]
/// Initialize an Epoch from the number of days since the QZSS Time Epoch,
/// defined as UTC midnight of January 5th to 6th 1980 (cf. <https://gssc.esa.int/navipedia/index.php/Time_References_in_GNSS#GPS_Time_.28GPST.29>).
pub fn from_qzsst_days(days: f64) -> Self {
Self::from_duration(Duration::from_f64(days, Unit::Day), TimeScale::QZSST)
}

#[must_use]
/// Initialize an Epoch from the number of nanoseconds since the QZSS Time Epoch,
/// defined as UTC midnight of January 5th to 6th 1980 (cf. <https://gssc.esa.int/navipedia/index.php/Time_References_in_GNSS#GPS_Time_.28GPST.29>).
/// This may be useful for time keeping devices that use QZSS as a time source.
pub fn from_qzsst_nanoseconds(nanoseconds: u64) -> Self {
Self::from_duration(
Duration {
centuries: 0,
nanoseconds,
},
TimeScale::QZSST,
)
}

#[must_use]
/// Initialize an Epoch from the number of seconds since the GST Time Epoch,
/// starting August 21st 1999 midnight (UTC)
Expand Down Expand Up @@ -729,10 +774,13 @@ impl Epoch {
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),
TimeScale::UTC => Self::from_utc_duration(duration_wrt_1900),
// GPST and QZSST share the same properties
TimeScale::GPST | TimeScale::QZSST => {
TimeScale::GPST => {
Self::from_gpst_duration(duration_wrt_1900 - GPST_REF_EPOCH.to_tai_duration())
}
// QZSS and GPST share the same reference epoch
TimeScale::QZSST => {
Self::from_qzsst_duration(duration_wrt_1900 - GPST_REF_EPOCH.to_tai_duration())
}
TimeScale::GST => {
Self::from_gst_duration(duration_wrt_1900 - GST_REF_EPOCH.to_tai_duration())
}
Expand Down Expand Up @@ -1426,6 +1474,31 @@ impl Epoch {
Self::from_gpst_nanoseconds(nanoseconds)
}

#[cfg(feature = "python")]
#[classmethod]
/// Initialize an Epoch from the number of seconds since the QZSS Time Epoch,
/// defined as UTC midnight of January 5th to 6th 1980 (cf. <https://gssc.esa.int/navipedia/index.php/Time_References_in_GNSS#GPS_Time_.28GPST.29>).
fn init_from_qzsst_seconds(_cls: &PyType, seconds: f64) -> Self {
Self::from_qzsst_seconds(seconds)
}

#[cfg(feature = "python")]
#[classmethod]
/// Initialize an Epoch from the number of days since the QZSS Time Epoch,
/// defined as UTC midnight of January 5th to 6th 1980 (cf. <https://gssc.esa.int/navipedia/index.php/Time_References_in_GNSS#GPS_Time_.28GPST.29>).
fn init_from_qzsst_days(_cls: &PyType, days: f64) -> Self {
Self::from_qzsst_days(days)
}

#[cfg(feature = "python")]
#[classmethod]
/// Initialize an Epoch from the number of nanoseconds since the QZSS Time Epoch,
/// defined as UTC midnight of January 5th to 6th 1980 (cf. <https://gssc.esa.int/navipedia/index.php/Time_References_in_GNSS#GPS_Time_.28GPST.29>).
/// This may be useful for time keeping devices that use QZSS as a time source.
fn init_from_qzsst_nanoseconds(_cls: &PyType, nanoseconds: u64) -> Self {
Self::from_qzsst_nanoseconds(nanoseconds)
}

#[cfg(feature = "python")]
#[classmethod]
/// Initialize an Epoch from the number of seconds since the Galileo Time Epoch,
Expand Down Expand Up @@ -1987,6 +2060,31 @@ impl Epoch {
self.to_gpst_duration().to_unit(Unit::Day)
}

#[must_use]
/// Returns seconds past QZSS Time Epoch, defined as UTC midnight of January 5th to 6th 1980 (cf. <https://gssc.esa.int/navipedia/index.php/Time_References_in_GNSS#GPS_Time_.28GPST.29>).
pub fn to_qzsst_seconds(&self) -> f64 {
self.to_qzsst_duration().to_seconds()
}

#[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_since_j1900_tai - GPST_REF_EPOCH.to_tai_duration()
}

/// Returns nanoseconds past QZSS Time Epoch, defined as UTC midnight of January 5th to 6th 1980 (cf. <https://gssc.esa.int/navipedia/index.php/Time_References_in_GNSS#GPS_Time_.28GPST.29>).
/// NOTE: This function will return an error if the centuries past QZSST time are not zero.
pub fn to_qzsst_nanoseconds(&self) -> Result<u64, Errors> {
self.to_nanoseconds_in_time_scale(TimeScale::QZSST)
}

#[must_use]
/// Returns days past QZSS Time Epoch, defined as UTC midnight of January 5th to 6th 1980 (cf. <https://gssc.esa.int/navipedia/index.php/Time_References_in_GNSS#GPS_Time_.28GPST.29>).
pub fn to_qzsst_days(&self) -> f64 {
self.to_gpst_duration().to_unit(Unit::Day)
}

#[must_use]
/// Returns seconds past GST (Galileo) Time Epoch
pub fn to_gst_seconds(&self) -> f64 {
Expand All @@ -1999,6 +2097,13 @@ impl Epoch {
self.duration_since_j1900_tai - GST_REF_EPOCH.to_tai_duration()
}

/// Returns nanoseconds past GST (Galileo) Time Epoch, starting on August 21st 1999 Midnight UT
/// (cf. <https://gssc.esa.int/navipedia/index.php/Time_References_in_GNSS>).
/// NOTE: This function will return an error if the centuries past GST time are not zero.
pub fn to_gst_nanoseconds(&self) -> Result<u64, Errors> {
self.to_nanoseconds_in_time_scale(TimeScale::GST)
}

#[must_use]
/// Returns days past GST (Galileo) Time Epoch,
/// starting on August 21st 1999 Midnight UT
Expand All @@ -2007,13 +2112,6 @@ impl Epoch {
self.to_gst_duration().to_unit(Unit::Day)
}

/// Returns nanoseconds past GST (Galileo) Time Epoch, starting on August 21st 1999 Midnight UT
/// (cf. <https://gssc.esa.int/navipedia/index.php/Time_References_in_GNSS>).
/// NOTE: This function will return an error if the centuries past GST time are not zero.
pub fn to_gst_nanoseconds(&self) -> Result<u64, Errors> {
self.to_nanoseconds_in_time_scale(TimeScale::GST)
}

#[must_use]
/// Returns seconds past BDT (BeiDou) Time Epoch
pub fn to_bdt_seconds(&self) -> f64 {
Expand Down
56 changes: 52 additions & 4 deletions tests/epoch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -335,12 +335,31 @@ fn gpst() {
let ref_gps = Epoch::from_gregorian_utc_at_midnight(1980, 01, 06);

// Test 1sec into GPS timescale
let gnss = Epoch::from_gpst_seconds(1.0);
assert_eq!(gnss, ref_gps + 1.0 * Unit::Second);
let gps_1sec = Epoch::from_gpst_seconds(1.0);
assert_eq!(gps_1sec, ref_gps + 1.0 * Unit::Second);

// 1sec into QZSS time scale returns the same date
let qzss_1sec = Epoch::from_qzsst_seconds(1.0);
assert_eq!(gps_1sec.to_utc_duration(), qzss_1sec.to_utc_duration());

// GPS and QZSS share the same properties at all times
assert_eq!(gps_1sec.to_gpst_seconds(), qzss_1sec.to_qzsst_seconds());
assert_eq!(
gps_1sec.to_gpst_nanoseconds(),
qzss_1sec.to_qzsst_nanoseconds()
);

// Test 1+1/2 day into GPS timescale
let gnss = Epoch::from_gpst_days(1.5);
assert_eq!(gnss, ref_gps + 1.5 * Unit::Day);
let gps = Epoch::from_gpst_days(1.5);
assert_eq!(gps, ref_gps + 1.5 * Unit::Day);

// 1sec into QZSS time scale returns the same date
let qzss = Epoch::from_qzsst_days(1.5);
assert_eq!(gps.to_utc_duration(), qzss.to_utc_duration());

// GPS and QZSS share the same properties at all times
assert_eq!(gps.to_gpst_seconds(), qzss.to_qzsst_seconds());
assert_eq!(gps.to_gpst_nanoseconds(), qzss.to_qzsst_nanoseconds());

let now = Epoch::from_gregorian_tai_hms(2019, 8, 24, 3, 49, 9);
assert_eq!(
Expand Down Expand Up @@ -390,6 +409,28 @@ fn gpst() {
let epoch = Epoch::from_gregorian_utc_at_midnight(1980, 1, 1);
assert!((epoch.to_gpst_seconds() + 5.0 * SECONDS_PER_DAY).abs() < EPSILON);
assert!((epoch.to_gpst_days() + 5.0).abs() < EPSILON);

// test other GPS / QZSS equalities
assert_eq!(
Epoch::from_mjd_gpst(0.77).to_utc_duration(),
Epoch::from_mjd_qzsst(0.77).to_utc_duration()
);
assert_eq!(
Epoch::from_jde_gpst(1.23).to_utc_duration(),
Epoch::from_jde_qzsst(1.23).to_utc_duration()
);
assert_eq!(
Epoch::from_qzsst_seconds(1024.768).to_utc_duration(),
Epoch::from_gpst_seconds(1024.768).to_utc_duration()
);
assert_eq!(
Epoch::from_qzsst_days(987.654).to_utc_duration(),
Epoch::from_gpst_days(987.654).to_utc_duration()
);
assert_eq!(
Epoch::from_qzsst_nanoseconds(543210987).to_utc_duration(),
Epoch::from_gpst_nanoseconds(543210987).to_utc_duration()
);
}

#[test]
Expand Down Expand Up @@ -1551,6 +1592,13 @@ fn test_time_of_week() {
epoch_utc
);

// GPST and QZSST share the same properties at all times
let epoch_qzsst = epoch.in_time_scale(TimeScale::QZSST);
assert_eq!(epoch.to_gregorian_utc(), epoch_qzsst.to_gregorian_utc());

let gps_qzss_offset = TimeScale::GPST.ref_epoch() - TimeScale::QZSST.ref_epoch();
assert_eq!(gps_qzss_offset.total_nanoseconds(), 0); // no offset

// 06/01/1980 01:00:00 = 1H into GPST <=> (0, 3_618_000_000_000)
let epoch = Epoch::from_time_of_week(0, 3_618_000_000_000, TimeScale::GPST);
assert_eq!(epoch.to_gregorian_utc(), (1980, 01, 06, 01, 00, 0 + 18, 00));
Expand Down

0 comments on commit 4d0f6f0

Please sign in to comment.