Skip to content

Commit ed7c1af

Browse files
authored
Fix not adjusting fraction for duration unit (#228)
Fix for the regression showing up on boa-dev/boa#4193. During the last update, I forgot that fraction is now agnostic about it's unit, so it needs to be adjusted for the unit.
1 parent a1f5503 commit ed7c1af

File tree

2 files changed

+42
-13
lines changed

2 files changed

+42
-13
lines changed

src/builtins/core/duration.rs

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -922,15 +922,17 @@ impl FromStr for Duration {
922922

923923
let (hours, minutes, seconds, millis, micros, nanos) = match parse_record.time {
924924
Some(TimeDurationRecord::Hours { hours, fraction }) => {
925-
let ns = fraction.and_then(|x| x.to_nanoseconds()).unwrap_or(0) as u64;
926-
let minutes = ns.div_euclid(60 * 1_000_000_000);
927-
let rem = ns.rem_euclid(60 * 1_000_000_000);
925+
let unadjusted_fraction =
926+
fraction.and_then(|x| x.to_nanoseconds()).unwrap_or(0) as u64;
927+
let fractional_hours_ns = unadjusted_fraction * 3600;
928+
let minutes = fractional_hours_ns.div_euclid(60 * 1_000_000_000);
929+
let fractional_minutes_ns = fractional_hours_ns.rem_euclid(60 * 1_000_000_000);
928930

929-
let seconds = rem.div_euclid(1_000_000_000);
930-
let rem = rem.rem_euclid(1_000_000_000);
931+
let seconds = fractional_minutes_ns.div_euclid(1_000_000_000);
932+
let fractional_seconds = fractional_minutes_ns.rem_euclid(1_000_000_000);
931933

932-
let milliseconds = rem.div_euclid(1_000_000);
933-
let rem = rem.rem_euclid(1_000_000);
934+
let milliseconds = fractional_seconds.div_euclid(1_000_000);
935+
let rem = fractional_seconds.rem_euclid(1_000_000);
934936

935937
let microseconds = rem.div_euclid(1_000);
936938
let nanoseconds = rem.rem_euclid(1_000);
@@ -950,12 +952,14 @@ impl FromStr for Duration {
950952
minutes,
951953
fraction,
952954
}) => {
953-
let ns = fraction.and_then(|x| x.to_nanoseconds()).unwrap_or(0);
954-
let seconds = ns.div_euclid(1_000_000_000);
955-
let rem = ns.rem_euclid(1_000_000_000);
956-
957-
let milliseconds = rem.div_euclid(1_000_000);
958-
let rem = rem.rem_euclid(1_000_000);
955+
let unadjusted_fraction =
956+
fraction.and_then(|x| x.to_nanoseconds()).unwrap_or(0) as u64;
957+
let fractional_minutes_ns = unadjusted_fraction * 60;
958+
let seconds = fractional_minutes_ns.div_euclid(1_000_000_000);
959+
let fractional_seconds = fractional_minutes_ns.rem_euclid(1_000_000_000);
960+
961+
let milliseconds = fractional_seconds.div_euclid(1_000_000);
962+
let rem = fractional_seconds.rem_euclid(1_000_000);
959963

960964
let microseconds = rem.div_euclid(1_000);
961965
let nanoseconds = rem.rem_euclid(1_000);

src/builtins/core/duration/tests.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use core::str::FromStr;
2+
13
use crate::{
24
options::ToStringRoundingOptions, parsers::Precision, partial::PartialDuration,
35
primitive::FiniteF64,
@@ -186,3 +188,26 @@ fn preserve_precision_loss() {
186188

187189
assert_eq!(&result, "PT9016206453995.731991S");
188190
}
191+
192+
#[test]
193+
fn duration_from_str() {
194+
let duration = Duration::from_str("PT0.999999999H").unwrap();
195+
assert_eq!(duration.minutes(), FiniteF64(59.0));
196+
assert_eq!(duration.seconds(), FiniteF64(59.0));
197+
assert_eq!(duration.milliseconds(), FiniteF64(999.0));
198+
assert_eq!(duration.microseconds(), FiniteF64(996.0));
199+
assert_eq!(duration.nanoseconds(), FiniteF64(400.0));
200+
201+
let duration = Duration::from_str("PT0.000000011H").unwrap();
202+
assert_eq!(duration.minutes(), FiniteF64(0.0));
203+
assert_eq!(duration.seconds(), FiniteF64(0.0));
204+
assert_eq!(duration.milliseconds(), FiniteF64(0.0));
205+
assert_eq!(duration.microseconds(), FiniteF64(39.0));
206+
assert_eq!(duration.nanoseconds(), FiniteF64(600.0));
207+
208+
let duration = Duration::from_str("PT0.999999999M").unwrap();
209+
assert_eq!(duration.seconds(), FiniteF64(59.0));
210+
assert_eq!(duration.milliseconds(), FiniteF64(999.0));
211+
assert_eq!(duration.microseconds(), FiniteF64(999.0));
212+
assert_eq!(duration.nanoseconds(), FiniteF64(940.0));
213+
}

0 commit comments

Comments
 (0)