Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix conversion to Gregorian #303

Merged
merged 17 commits into from
May 20, 2024
Merged

Conversation

ChristopherRabotin
Copy link
Member

@ChristopherRabotin ChristopherRabotin commented May 19, 2024

Issue #261 made it clear that there were bugs in the conversion from a duration in a given time scale into its Gregorian representation. This PR solves this by rewriting that algorithm and extending the tests to include many reciprocal tests.

One of the complications I had was correcting for the leap years when converting a duration to its Gregorian representation. Specifically, the number of leap days in the "current year" is handled by the array of cumulative number of days. But if there were more leap years between 1900 and the current year was greater than the number of days left in a given year, then the modulo operation would incorrectly say that we were one year later (e.g. 1988-12-25 was computed as 1989-01-...). The number of days in the year was trivially fixed, but that fix failed if the previous year (e.g. 1988) was a leap year, since the code would incorrectly subtract one day to that year when that fix was in fact handled by the array of cumulative number of days.

None => {
return Err(EpochError::Duration {
source: DurationError::Overflow,
})
}
Some(days) => Unit::Day * i64::from(days),
},
} - time_scale.gregorian_epoch_offset();
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved to the end of the function to make it easier to write the reverse algorithm.

@@ -269,45 +251,43 @@ impl Epoch {
source: DurationError::Underflow,
})
}
Some(years_since_ref) => match years_since_ref.checked_mul(365) {
Some(years_since_ref) => match years_since_ref.checked_mul(DAYS_PER_YEAR_NLD as i32) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Replace magic number with the constant.

duration_wrt_ref += Unit::Day;
}
}
// Remove ref hours from duration to correct for the time scale not starting at midnight
// duration_wrt_ref -= Unit::Hour * time_scale.ref_hour() as i64;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This had been replaced with the time_scale.gregorian_offset()

@@ -1370,9 +1370,14 @@ fn div_rem_f64(me: f64, rhs: f64) -> (i32, f64) {
fn div_euclid_f64(lhs: f64, rhs: f64) -> f64 {
let q = (lhs / rhs).trunc();
if lhs % rhs < 0.0 {
return if rhs > 0.0 { q - 1.0 } else { q + 1.0 };
if rhs > 0.0 {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Exact same code, just more idiomatic Rust.

@ChristopherRabotin ChristopherRabotin changed the title DRAFT -- Fix conversion to Gregorian Fix conversion to Gregorian May 20, 2024
@ChristopherRabotin ChristopherRabotin linked an issue May 20, 2024 that may be closed by this pull request
@@ -692,7 +690,15 @@ impl fmt::Display for Duration {
}

let values = [days, hours, minutes, seconds, milli, us, nano];
let units = ["days", "h", "min", "s", "ms", "μs", "ns"];
let units = [
if days > 1 { "days" } else { "day" },
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Super minor but it was driving me crazy that a duration of one day was printed in plural form.

@ChristopherRabotin ChristopherRabotin merged commit cb55ba9 into master May 20, 2024
29 checks passed
@ChristopherRabotin ChristopherRabotin deleted the bug/261-jde_utc_days-error branch May 20, 2024 14:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

jde_utc_days Error
1 participant