Skip to content

Commit d475808

Browse files
authored
Fix ComputeNudgeWindow startEpochNs computation to check full startDateDuration sign (#723)
1 parent c003cc9 commit d475808

3 files changed

Lines changed: 40 additions & 2 deletions

File tree

src/builtins/core/duration/normalized.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -707,7 +707,7 @@ impl InternalDurationRecord {
707707
|| (sign == NonZeroSign::Negative && r1 <= 0 && r1 > r2)
708708
);
709709

710-
let start_epoch_ns = if r1 == 0 {
710+
let start_epoch_ns = if start_duration.sign() == Sign::Zero {
711711
origin_epoch_ns
712712
} else {
713713
// 7. Let start be ? CalendarDateAdd(calendar, isoDateTime.[[ISODate]], startDuration, constrain).

src/builtins/core/duration/tests.rs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -605,3 +605,41 @@ fn out_of_bounds_duration_no_crash() {
605605

606606
assert!(duration.is_err());
607607
}
608+
609+
// https://github.com/tc39/test262/commit/a70493eb104948583a7928d50eac28b6c81114bf
610+
// https://github.com/tc39/proposal-temporal/issues/3316
611+
#[test]
612+
#[cfg(feature = "compiled_data")]
613+
fn test_exact_multiple_of_larger_unit_plaindate() {
614+
use crate::options::RoundingMode;
615+
use crate::PlainDate;
616+
617+
let relative_to = PlainDate::try_new_iso(2012, 1, 1).unwrap();
618+
619+
// Temporal.Duration(0, 0, 0, 31).round({ smallestUnit: "weeks", largestUnit: "months", roundingMode, relativeTo })
620+
// should be 0, 1, 0, 0, 0, 0, 0, 0, 0, 0
621+
let d1 = Duration::new(0, 0, 0, 31, 0, 0, 0, 0, 0, 0).unwrap();
622+
623+
for mode in [
624+
RoundingMode::Ceil,
625+
RoundingMode::Floor,
626+
RoundingMode::Expand,
627+
RoundingMode::HalfCeil,
628+
RoundingMode::HalfFloor,
629+
RoundingMode::HalfEven,
630+
RoundingMode::HalfExpand,
631+
RoundingMode::HalfTrunc,
632+
RoundingMode::Trunc,
633+
] {
634+
let options = RoundingOptions {
635+
smallest_unit: Some(Unit::Week),
636+
largest_unit: Some(Unit::Month),
637+
rounding_mode: Some(mode),
638+
..Default::default()
639+
};
640+
let res = d1.round(options, Some(relative_to.clone().into())).unwrap();
641+
assert_eq!(res.months(), 1, "P31D weeks..months {mode:?}");
642+
assert_eq!(res.weeks(), 0, "P31D weeks..months {mode:?}");
643+
assert_eq!(res.days(), 0, "P31D weeks..months {mode:?}");
644+
}
645+
}

src/iso.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -452,7 +452,7 @@ impl IsoDate {
452452
// c. Repeat, while ISODateSurpasses(sign, intermediate.[[Year]], intermediate.[[Month]], d1, y2, m2, d2) is false,
453453
// Safety: balance_iso_year_month should always return a month value from 1..=12
454454
while !iso_date_surpasses(
455-
&IsoDate::new_unchecked(intermediate.0, intermediate.1 as u8, self.day),
455+
&IsoDate::new_unchecked(intermediate.0, intermediate.1, self.day),
456456
other,
457457
sign,
458458
) {

0 commit comments

Comments
 (0)