Skip to content

Commit

Permalink
Breaking change: renamed the following constants
Browse files Browse the repository at this point in the history
- J1900_NAIF -> JD_J1900
- J2000_NAIF -> JD_J2000
- J1900_OFFSET -> MJD_J1900
- J2000_OFFSET -> MJD_J12000

Removed constants (unused):
- J2000_TO_J1900_DURATION
- JDE_OFFSET_DAYS
- JDE_OFFSET_SECONDS
  • Loading branch information
ChristopherRabotin committed Jun 9, 2024
1 parent d2bc5c0 commit 36be207
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 60 deletions.
37 changes: 11 additions & 26 deletions src/epoch/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,7 @@ use crate::leap_seconds::{LatestLeapSeconds, LeapSecondProvider};
use crate::Weekday;
use crate::{
EpochError, MonthName, TimeScale, TimeUnits, BDT_REF_EPOCH, ET_EPOCH_S, GPST_REF_EPOCH,
GST_REF_EPOCH, J1900_OFFSET, J2000_TO_J1900_DURATION, MJD_OFFSET, NANOSECONDS_PER_DAY,
QZSST_REF_EPOCH, UNIX_REF_EPOCH,
GST_REF_EPOCH, MJD_J1900, MJD_OFFSET, NANOSECONDS_PER_DAY, QZSST_REF_EPOCH, UNIX_REF_EPOCH,
};
use core::cmp::Eq;
use core::str::FromStr;
Expand Down Expand Up @@ -356,7 +355,7 @@ impl Epoch {
days.is_finite(),
"Attempted to initialize Epoch with non finite number"
);
Self::from_tai_duration((days - J1900_OFFSET) * Unit::Day)
Self::from_tai_duration((days - MJD_J1900) * Unit::Day)
}

fn from_mjd_in_time_scale(days: f64, time_scale: TimeScale) -> Self {
Expand Down Expand Up @@ -396,7 +395,7 @@ impl Epoch {
days.is_finite(),
"Attempted to initialize Epoch with non finite number"
);
Self::from_tai_duration((days - J1900_OFFSET - MJD_OFFSET) * Unit::Day)
Self::from_tai_duration((days - MJD_J1900 - MJD_OFFSET) * Unit::Day)
}

fn from_jde_in_time_scale(days: f64, time_scale: TimeScale) -> Self {
Expand Down Expand Up @@ -820,7 +819,7 @@ impl Epoch {
#[must_use]
/// Returns this epoch as a duration in the requested units in MJD TAI
pub fn to_mjd_tai(&self, unit: Unit) -> f64 {
(self.to_tai_duration() + Unit::Day * J1900_OFFSET).to_unit(unit)
(self.to_tai_duration() + Unit::Day * MJD_J1900).to_unit(unit)
}

#[must_use]
Expand All @@ -832,7 +831,7 @@ impl Epoch {
#[must_use]
/// Returns the Modified Julian Date in the provided unit in UTC.
pub fn to_mjd_utc(&self, unit: Unit) -> f64 {
(self.to_utc_duration() + Unit::Day * J1900_OFFSET).to_unit(unit)
(self.to_utc_duration() + Unit::Day * MJD_J1900).to_unit(unit)
}

#[must_use]
Expand All @@ -858,7 +857,7 @@ impl Epoch {
#[must_use]
/// Returns the Julian Days from epoch 01 Jan -4713 12:00 (noon) as a Duration
pub fn to_jde_tai_duration(&self) -> Duration {
self.to_tai_duration() + Unit::Day * J1900_OFFSET + Unit::Day * MJD_OFFSET
self.to_tai_duration() + Unit::Day * MJD_J1900 + Unit::Day * MJD_OFFSET
}

#[must_use]
Expand All @@ -876,7 +875,7 @@ impl Epoch {
#[must_use]
/// Returns the Julian days in UTC as a `Duration`
pub fn to_jde_utc_duration(&self) -> Duration {
self.to_utc_duration() + Unit::Day * (J1900_OFFSET + MJD_OFFSET)
self.to_utc_duration() + Unit::Day * (MJD_J1900 + MJD_OFFSET)
}

#[must_use]
Expand Down Expand Up @@ -923,7 +922,7 @@ impl Epoch {

#[must_use]
pub fn to_jde_tt_duration(&self) -> Duration {
self.to_tt_duration() + Unit::Day * (J1900_OFFSET + MJD_OFFSET)
self.to_tt_duration() + Unit::Day * (MJD_J1900 + MJD_OFFSET)
}

#[must_use]
Expand All @@ -934,7 +933,7 @@ impl Epoch {

#[must_use]
pub fn to_mjd_tt_duration(&self) -> Duration {
self.to_tt_duration() + Unit::Day * J1900_OFFSET
self.to_tt_duration() + Unit::Day * MJD_J1900
}

#[must_use]
Expand Down Expand Up @@ -1075,13 +1074,6 @@ impl Epoch {
self.to_et_duration().to_seconds()
}

#[must_use]
/// Returns the Ephemeris Time in duration past 1900 JAN 01 at noon.
/// **Only** use this if the subsequent computation expect J1900 seconds.
pub fn to_et_duration_since_j1900(&self) -> Duration {
self.to_et_duration() + J2000_TO_J1900_DURATION
}

#[must_use]
/// Returns the duration between J2000 and the current epoch as per NAIF SPICE.
///
Expand Down Expand Up @@ -1120,13 +1112,6 @@ impl Epoch {
self.to_tdb_duration().to_seconds()
}

#[must_use]
/// Returns the Dynamics Barycentric Time (TDB) as a high precision Duration with reference epoch of 1900 JAN 01 at noon.
/// **Only** use this if the subsequent computation expect J1900 seconds.
pub fn to_tdb_duration_since_j1900(&self) -> Duration {
self.to_tdb_duration() + J2000_TO_J1900_DURATION
}

#[must_use]
/// Returns the Ephemeris Time JDE past epoch
pub fn to_jde_et_days(&self) -> f64 {
Expand All @@ -1136,7 +1121,7 @@ impl Epoch {
#[must_use]
pub fn to_jde_et_duration(&self) -> Duration {
self.to_et_duration()
+ Unit::Day * (J1900_OFFSET + MJD_OFFSET)
+ Unit::Day * (MJD_J1900 + MJD_OFFSET)
+ TimeScale::ET.prime_epoch_offset()
}

Expand All @@ -1148,7 +1133,7 @@ impl Epoch {
#[must_use]
pub fn to_jde_tdb_duration(&self) -> Duration {
self.to_tdb_duration()
+ Unit::Day * (J1900_OFFSET + MJD_OFFSET)
+ Unit::Day * (MJD_J1900 + MJD_OFFSET)
+ TimeScale::TDB.prime_epoch_offset()
}

Expand Down
29 changes: 8 additions & 21 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,25 +10,18 @@
* Documentation: https://nyxspace.com/
*/

pub const J1900_NAIF: f64 = 2_415_020.0;
pub const J2000_NAIF: f64 = 2_451_545.0;
/// `J1900_OFFSET` determines the offset in julian days between 01 Jan 1900 at midnight and the
/// Modified Julian Day at 17 November 1858.
/// NOTE: Julian days "start" at noon so that astronomical observations throughout the night
/// happen at the same Julian day. Note however that the Modified Julian Date (MJD) starts at
/// midnight, not noon, cf. <http://tycho.usno.navy.mil/mjd.html>.
pub const J1900_OFFSET: f64 = 15_020.0;
/// `J2000_OFFSET` determines the offset in julian days between 01 Jan 2000 at **noon** and the
/// Modified Julian Day at 17 November 1858.
pub const J2000_OFFSET: f64 = 51_544.5;
/// Julian date for the J1900 epoch, as per NAIF SPICE.
pub const JD_J1900: f64 = 2_415_020.0;
/// Julian date for the J2000 epoch, as per NAIF SPICE.
pub const JD_J2000: f64 = 2_451_545.0;
/// Julian days between 01 Jan 1900 at midnight and the Modified Julian Day at 17 November 1858.
pub const MJD_J1900: f64 = 15_020.0;
/// Julian days between 01 Jan 2000 at **noon** and the Modified Julian Day at 17 November 1858.
pub const MJD_J2000: f64 = 51_544.5;
/// The Ephemeris Time epoch, in seconds
pub const ET_EPOCH_S: i64 = 3_155_716_800;
/// Modified Julian Date in seconds as defined [here](http://tycho.usno.navy.mil/mjd.html). MJD epoch is Modified Julian Day at 17 November 1858 at midnight.
pub const MJD_OFFSET: f64 = 2_400_000.5;
/// The JDE offset in days
pub const JDE_OFFSET_DAYS: f64 = J1900_OFFSET + MJD_OFFSET;
/// The JDE offset in seconds
pub const JDE_OFFSET_SECONDS: f64 = JDE_OFFSET_DAYS * SECONDS_PER_DAY;
/// `DAYS_PER_YEAR` corresponds to the number of days per year in the Julian calendar.
pub const DAYS_PER_YEAR: f64 = 365.25;
/// `DAYS_PER_YEAR_NLD` corresponds to the number of days per year **without leap days**.
Expand All @@ -55,12 +48,6 @@ pub const SECONDS_PER_TROPICAL_YEAR: f64 = 31_556_925.974_7;
/// `SECONDS_PER_SIDEREAL_YEAR` corresponds to the number of seconds per sidereal year from [NIST](https://www.nist.gov/pml/special-publication-811/nist-guide-si-appendix-b-conversion-factors/nist-guide-si-appendix-b9#TIME).
pub const SECONDS_PER_SIDEREAL_YEAR: f64 = 31_558_150.0;

/// The duration between J2000 and J1900 is exactly one century, both references start at noon.
pub const J2000_TO_J1900_DURATION: Duration = Duration {
centuries: 1,
nanoseconds: 0,
};

// Epoch formatting module is called `efmt` to avoid collision with `std::fmt` and `core::fmt`.
pub mod efmt;
mod parser;
Expand Down
44 changes: 31 additions & 13 deletions tests/epoch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@ extern crate core;
use hifitime::{
is_gregorian_valid, Duration, Epoch, EpochError, ParsingError, TimeScale, TimeUnits, Unit,
Weekday, BDT_REF_EPOCH, DAYS_GPS_TAI_OFFSET, DAYS_PER_YEAR, GPST_REF_EPOCH, GST_REF_EPOCH,
J1900_OFFSET, 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,
J1900_REF_EPOCH, J2000_REF_EPOCH, JD_J2000, MJD_J1900, MJD_J2000, MJD_OFFSET,
SECONDS_BDT_TAI_OFFSET, SECONDS_GPS_TAI_OFFSET, SECONDS_GST_TAI_OFFSET, SECONDS_PER_DAY,
};

use hifitime::efmt::{Format, Formatter};
Expand All @@ -25,15 +24,15 @@ fn test_const_ops() {
// Tests that multiplying a constant with a unit returns the correct number in that same unit
let mjd_offset = MJD_OFFSET * Unit::Day;
assert!((mjd_offset.to_unit(Unit::Day) - MJD_OFFSET).abs() < f64::EPSILON);
let j2000_offset = J2000_OFFSET * Unit::Day;
assert!((j2000_offset.to_unit(Unit::Day) - J2000_OFFSET).abs() < f64::EPSILON);
let j2000_mjd = MJD_J2000 * Unit::Day;
assert!((j2000_mjd.to_unit(Unit::Day) - MJD_J2000).abs() < f64::EPSILON);
}

#[allow(clippy::float_equality_without_abs)]
#[test]
fn utc_epochs() {
assert!(Epoch::from_mjd_tai(J1900_OFFSET).to_tai_seconds() < EPSILON);
assert!((Epoch::from_mjd_tai(J1900_OFFSET).to_mjd_tai_days() - J1900_OFFSET).abs() < EPSILON);
assert!(Epoch::from_mjd_tai(MJD_J1900).to_tai_seconds() < EPSILON);
assert!((Epoch::from_mjd_tai(MJD_J1900).to_mjd_tai_days() - MJD_J1900).abs() < EPSILON);

// Tests are chronological dates.
// All of the following examples are cross validated against NASA HEASARC,
Expand Down Expand Up @@ -422,11 +421,6 @@ fn gpst() {
GPST_REF_EPOCH.duration
);

// assert_eq!(
// GPST_REF_EPOCH.to_utc_seconds(),
// Epoch::from_gregorian_utc_at_midnight(1980, 1, 6).to_tai_seconds()
// );

assert!(
GPST_REF_EPOCH.to_gpst_seconds().abs() < EPSILON,
"The number of seconds from the GPS epoch was not 0: {}",
Expand Down Expand Up @@ -1918,7 +1912,7 @@ fn test_to_tai_time_scale() {
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);
assert_eq!(j2000_to_j1900, Duration::from_parts(1, 0));
}

#[cfg(feature = "std")]
Expand Down Expand Up @@ -2044,3 +2038,27 @@ fn regression_test_gh_209() {
let t = Epoch::from_time_of_week(1982, 604800000000000 - 19000000000, TimeScale::GPST);
println!("{t}");
}

#[test]
fn regression_test_gh_282() {
assert_eq!(
"1900-01-01T00:00:00 UTC",
format!("{}", Epoch::from_utc_duration(0_f64.nanoseconds()))
);
// NOTE: Hifitime's prime epoch is midnight on 1900-01-01, but the Julian date J1900 is at noon.
// This explains why the calculation returns `0.5` with a zero duration UTC epoch.
assert_eq!(
"2415020.5",
format!(
"{}",
Epoch::from_utc_duration(0_f64.nanoseconds()).to_jde_utc_days()
)
);
assert_eq!(
"2000-01-01T12:00:00 TAI",
format!(
"{}",
Epoch::from_jde_tai(JD_J2000).to_gregorian_str(hifitime::TimeScale::TAI)
)
);
}

0 comments on commit 36be207

Please sign in to comment.