Skip to content

Commit cb6ca85

Browse files
committed
LibJS: Handle relativeTo ZDTs that fall within second DST wallclock time
This is a normative change in the Temporal proposal. See: tc39/proposal-temporal@1a089eb
1 parent 1ecb788 commit cb6ca85

File tree

9 files changed

+116
-60
lines changed

9 files changed

+116
-60
lines changed

Libraries/LibJS/Runtime/Temporal/Duration.cpp

Lines changed: 40 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -847,8 +847,8 @@ Crypto::BigFraction total_time_duration(TimeDuration const& time_duration, Unit
847847
return Crypto::BigFraction { time_duration } / Crypto::BigFraction { Crypto::SignedBigInteger { divisor } };
848848
}
849849

850-
// 7.5.33 NudgeToCalendarUnit ( sign, duration, destEpochNs, isoDateTime, timeZone, calendar, increment, unit, roundingMode ), https://tc39.es/proposal-temporal/#sec-temporal-nudgetocalendarunit
851-
ThrowCompletionOr<CalendarNudgeResult> nudge_to_calendar_unit(VM& vm, i8 sign, InternalDuration const& duration, Crypto::SignedBigInteger const& dest_epoch_ns, ISODateTime const& iso_date_time, Optional<StringView> time_zone, StringView calendar, u64 increment, Unit unit, RoundingMode rounding_mode)
850+
// 7.5.33 NudgeToCalendarUnit ( sign, duration, originEpochNs, destEpochNs, isoDateTime, timeZone, calendar, increment, unit, roundingMode ), https://tc39.es/proposal-temporal/#sec-temporal-nudgetocalendarunit
851+
ThrowCompletionOr<CalendarNudgeResult> nudge_to_calendar_unit(VM& vm, i8 sign, InternalDuration const& duration, Crypto::SignedBigInteger const& origin_epoch_ns, Crypto::SignedBigInteger const& dest_epoch_ns, ISODateTime const& iso_date_time, Optional<StringView> time_zone, StringView calendar, u64 increment, Unit unit, RoundingMode rounding_mode)
852852
{
853853
DateDuration start_duration;
854854
DateDuration end_duration;
@@ -947,35 +947,48 @@ ThrowCompletionOr<CalendarNudgeResult> nudge_to_calendar_unit(VM& vm, i8 sign, I
947947
else if (sign == -1)
948948
VERIFY(r1 <= 0 && r1 > r2);
949949

950-
// 7. Let start be ? CalendarDateAdd(calendar, isoDateTime.[[ISODate]], startDuration, CONSTRAIN).
951-
auto start = TRY(calendar_date_add(vm, calendar, iso_date_time.iso_date, start_duration, Overflow::Constrain));
950+
Crypto::SignedBigInteger start_epoch_ns;
951+
Crypto::SignedBigInteger end_epoch_ns;
952952

953-
// 8. Let end be ? CalendarDateAdd(calendar, isoDateTime.[[ISODate]], endDuration, CONSTRAIN).
954-
auto end = TRY(calendar_date_add(vm, calendar, iso_date_time.iso_date, end_duration, Overflow::Constrain));
953+
// 7. If r1 = 0, then
954+
if (r1 == 0) {
955+
// a. Let startEpochNs be originEpochNs.
956+
start_epoch_ns = origin_epoch_ns;
957+
}
958+
// 8. Else,
959+
else {
960+
// a. Let start be ? CalendarDateAdd(calendar, isoDateTime.[[ISODate]], startDuration, CONSTRAIN).
961+
auto start = TRY(calendar_date_add(vm, calendar, iso_date_time.iso_date, start_duration, Overflow::Constrain));
955962

956-
// 9. Let startDateTime be CombineISODateAndTimeRecord(start, isoDateTime.[[Time]]).
957-
auto start_date_time = combine_iso_date_and_time_record(start, iso_date_time.time);
963+
// b. Let startDateTime be CombineISODateAndTimeRecord(start, isoDateTime.[[Time]]).
964+
auto start_date_time = combine_iso_date_and_time_record(start, iso_date_time.time);
965+
966+
// c. If timeZone is UNSET, then
967+
if (!time_zone.has_value()) {
968+
// i. Let startEpochNs be GetUTCEpochNanoseconds(startDateTime).
969+
start_epoch_ns = get_utc_epoch_nanoseconds(start_date_time);
970+
}
971+
// d. Else,
972+
else {
973+
// i. Let startEpochNs be ? GetEpochNanosecondsFor(timeZone, startDateTime, COMPATIBLE).
974+
start_epoch_ns = TRY(get_epoch_nanoseconds_for(vm, *time_zone, start_date_time, Disambiguation::Compatible));
975+
}
976+
}
977+
978+
// 9. Let end be ? CalendarDateAdd(calendar, isoDateTime.[[ISODate]], endDuration, CONSTRAIN).
979+
auto end = TRY(calendar_date_add(vm, calendar, iso_date_time.iso_date, end_duration, Overflow::Constrain));
958980

959981
// 10. Let endDateTime be CombineISODateAndTimeRecord(end, isoDateTime.[[Time]]).
960982
auto end_date_time = combine_iso_date_and_time_record(end, iso_date_time.time);
961983

962-
Crypto::SignedBigInteger start_epoch_ns;
963-
Crypto::SignedBigInteger end_epoch_ns;
964-
965984
// 11. If timeZone is UNSET, then
966985
if (!time_zone.has_value()) {
967-
// a. Let startEpochNs be GetUTCEpochNanoseconds(startDateTime).
968-
start_epoch_ns = get_utc_epoch_nanoseconds(start_date_time);
969-
970-
// b. Let endEpochNs be GetUTCEpochNanoseconds(endDateTime).
986+
// a. Let endEpochNs be GetUTCEpochNanoseconds(endDateTime).
971987
end_epoch_ns = get_utc_epoch_nanoseconds(end_date_time);
972988
}
973989
// 12. Else,
974990
else {
975-
// a. Let startEpochNs be ? GetEpochNanosecondsFor(timeZone, startDateTime, COMPATIBLE).
976-
start_epoch_ns = TRY(get_epoch_nanoseconds_for(vm, *time_zone, start_date_time, Disambiguation::Compatible));
977-
978-
// b. Let endEpochNs be ? GetEpochNanosecondsFor(timeZone, endDateTime, COMPATIBLE).
991+
// a. Let endEpochNs be ? GetEpochNanosecondsFor(timeZone, endDateTime, COMPATIBLE).
979992
end_epoch_ns = TRY(get_epoch_nanoseconds_for(vm, *time_zone, end_date_time, Disambiguation::Compatible));
980993
}
981994

@@ -1319,8 +1332,8 @@ ThrowCompletionOr<InternalDuration> bubble_relative_duration(VM& vm, i8 sign, In
13191332
return duration;
13201333
}
13211334

1322-
// 7.5.37 RoundRelativeDuration ( duration, destEpochNs, isoDateTime, timeZone, calendar, largestUnit, increment, smallestUnit, roundingMode ), https://tc39.es/proposal-temporal/#sec-temporal-roundrelativeduration
1323-
ThrowCompletionOr<InternalDuration> round_relative_duration(VM& vm, InternalDuration duration, Crypto::SignedBigInteger const& dest_epoch_ns, ISODateTime const& iso_date_time, Optional<StringView> time_zone, StringView calendar, Unit largest_unit, u64 increment, Unit smallest_unit, RoundingMode rounding_mode)
1335+
// 7.5.37 RoundRelativeDuration ( duration, originEpochNs, destEpochNs, isoDateTime, timeZone, calendar, largestUnit, increment, smallestUnit, roundingMode ), https://tc39.es/proposal-temporal/#sec-temporal-roundrelativeduration
1336+
ThrowCompletionOr<InternalDuration> round_relative_duration(VM& vm, InternalDuration duration, Crypto::SignedBigInteger const& origin_epoch_ns, Crypto::SignedBigInteger const& dest_epoch_ns, ISODateTime const& iso_date_time, Optional<StringView> time_zone, StringView calendar, Unit largest_unit, u64 increment, Unit smallest_unit, RoundingMode rounding_mode)
13241337
{
13251338
// 1. Let irregularLengthUnit be false.
13261339
auto irregular_length_unit = false;
@@ -1340,8 +1353,8 @@ ThrowCompletionOr<InternalDuration> round_relative_duration(VM& vm, InternalDura
13401353

13411354
// 5. If irregularLengthUnit is true, then
13421355
if (irregular_length_unit) {
1343-
// a. Let record be ? NudgeToCalendarUnit(sign, duration, destEpochNs, isoDateTime, timeZone, calendar, increment, smallestUnit, roundingMode).
1344-
auto record = TRY(nudge_to_calendar_unit(vm, sign, duration, dest_epoch_ns, iso_date_time, time_zone, calendar, increment, smallest_unit, rounding_mode));
1356+
// a. Let record be ? NudgeToCalendarUnit(sign, duration, originEpochNs, destEpochNs, isoDateTime, timeZone, calendar, increment, smallestUnit, roundingMode).
1357+
auto record = TRY(nudge_to_calendar_unit(vm, sign, duration, origin_epoch_ns, dest_epoch_ns, iso_date_time, time_zone, calendar, increment, smallest_unit, rounding_mode));
13451358

13461359
// b. Let nudgeResult be record.[[NudgeResult]].
13471360
nudge_result = move(record.nudge_result);
@@ -1373,16 +1386,16 @@ ThrowCompletionOr<InternalDuration> round_relative_duration(VM& vm, InternalDura
13731386
return duration;
13741387
}
13751388

1376-
// 7.5.38 TotalRelativeDuration ( duration, destEpochNs, isoDateTime, timeZone, calendar, unit ), https://tc39.es/proposal-temporal/#sec-temporal-totalrelativeduration
1377-
ThrowCompletionOr<Crypto::BigFraction> total_relative_duration(VM& vm, InternalDuration const& duration, Crypto::SignedBigInteger const& dest_epoch_ns, ISODateTime const& iso_date_time, Optional<StringView> time_zone, StringView calendar, Unit unit)
1389+
// 7.5.38 TotalRelativeDuration ( duration, originEpochNs, destEpochNs, isoDateTime, timeZone, calendar, unit ), https://tc39.es/proposal-temporal/#sec-temporal-totalrelativeduration
1390+
ThrowCompletionOr<Crypto::BigFraction> total_relative_duration(VM& vm, InternalDuration const& duration, Crypto::SignedBigInteger const& origin_epoch_ns, Crypto::SignedBigInteger const& dest_epoch_ns, ISODateTime const& iso_date_time, Optional<StringView> time_zone, StringView calendar, Unit unit)
13781391
{
13791392
// 1. If IsCalendarUnit(unit) is true, or timeZone is not UNSET and unit is DAY, then
13801393
if (is_calendar_unit(unit) || (time_zone.has_value() && unit == Unit::Day)) {
13811394
// a. If InternalDurationSign(duration) < 0, let sign be -1; else let sign be 1.
13821395
auto sign = internal_duration_sign(duration) < 0 ? -1 : 1;
13831396

1384-
// b. Let record be ? NudgeToCalendarUnit(sign, duration, destEpochNs, isoDateTime, timeZone, calendar, 1, unit, TRUNC).
1385-
auto record = TRY(nudge_to_calendar_unit(vm, sign, duration, dest_epoch_ns, iso_date_time, time_zone, calendar, 1, unit, RoundingMode::Trunc));
1397+
// b. Let record be ? NudgeToCalendarUnit(sign, duration, originEpochNs, destEpochNs, isoDateTime, timeZone, calendar, 1, unit, TRUNC).
1398+
auto record = TRY(nudge_to_calendar_unit(vm, sign, duration, origin_epoch_ns, dest_epoch_ns, iso_date_time, time_zone, calendar, 1, unit, RoundingMode::Trunc));
13861399

13871400
// c. Return record.[[Total]].
13881401
return record.total;

Libraries/LibJS/Runtime/Temporal/Duration.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -137,12 +137,12 @@ i8 time_duration_sign(TimeDuration const&);
137137
ThrowCompletionOr<double> date_duration_days(VM&, DateDuration const&, PlainDate const&);
138138
ThrowCompletionOr<TimeDuration> round_time_duration(VM&, TimeDuration const&, Crypto::UnsignedBigInteger const& increment, Unit, RoundingMode);
139139
Crypto::BigFraction total_time_duration(TimeDuration const&, Unit);
140-
ThrowCompletionOr<CalendarNudgeResult> nudge_to_calendar_unit(VM&, i8 sign, InternalDuration const&, Crypto::SignedBigInteger const& dest_epoch_ns, ISODateTime const&, Optional<StringView> time_zone, StringView calendar, u64 increment, Unit, RoundingMode);
140+
ThrowCompletionOr<CalendarNudgeResult> nudge_to_calendar_unit(VM&, i8 sign, InternalDuration const&, Crypto::SignedBigInteger const& origin_epoch_ns, Crypto::SignedBigInteger const& dest_epoch_ns, ISODateTime const&, Optional<StringView> time_zone, StringView calendar, u64 increment, Unit, RoundingMode);
141141
ThrowCompletionOr<DurationNudgeResult> nudge_to_zoned_time(VM&, i8 sign, InternalDuration const&, ISODateTime const&, StringView time_zone, StringView calendar, u64 increment, Unit, RoundingMode);
142142
ThrowCompletionOr<DurationNudgeResult> nudge_to_day_or_time(VM&, InternalDuration const&, Crypto::SignedBigInteger const& dest_epoch_ns, Unit largest_unit, u64 increment, Unit smallest_unit, RoundingMode);
143143
ThrowCompletionOr<InternalDuration> bubble_relative_duration(VM&, i8 sign, InternalDuration, Crypto::SignedBigInteger const& nudged_epoch_ns, ISODateTime const&, Optional<StringView> time_zone, StringView calendar, Unit largest_unit, Unit smallest_unit);
144-
ThrowCompletionOr<InternalDuration> round_relative_duration(VM&, InternalDuration, Crypto::SignedBigInteger const& dest_epoch_ns, ISODateTime const&, Optional<StringView> time_zone, StringView calendar, Unit largest_unit, u64 increment, Unit smallest_unit, RoundingMode);
145-
ThrowCompletionOr<Crypto::BigFraction> total_relative_duration(VM&, InternalDuration const&, TimeDuration const&, ISODateTime const&, Optional<StringView> time_zone, StringView calendar, Unit);
144+
ThrowCompletionOr<InternalDuration> round_relative_duration(VM&, InternalDuration, Crypto::SignedBigInteger const& origin_epoch_ns, Crypto::SignedBigInteger const& dest_epoch_ns, ISODateTime const&, Optional<StringView> time_zone, StringView calendar, Unit largest_unit, u64 increment, Unit smallest_unit, RoundingMode);
145+
ThrowCompletionOr<Crypto::BigFraction> total_relative_duration(VM&, InternalDuration const&, Crypto::SignedBigInteger const& origin_epoch_ns, Crypto::SignedBigInteger const& dest_epoch_ns, ISODateTime const&, Optional<StringView> time_zone, StringView calendar, Unit);
146146
String temporal_duration_to_string(Duration const&, Precision);
147147
ThrowCompletionOr<GC::Ref<Duration>> add_durations(VM&, ArithmeticOperation, Duration const&, Value);
148148

Libraries/LibJS/Runtime/Temporal/DurationPrototype.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -369,7 +369,7 @@ JS_DEFINE_NATIVE_FUNCTION(DurationPrototype::round)
369369
// f. Set internalDuration to ? DifferenceZonedDateTimeWithRounding(relativeEpochNs, targetEpochNs, timeZone, calendar, largestUnit, roundingIncrement, smallestUnit, roundingMode).
370370
internal_duration = TRY(difference_zoned_date_time_with_rounding(vm, relative_epoch_nanoseconds, target_epoch_nanoseconds, time_zone, calendar, largest_unit_value, rounding_increment, smallest_unit_value, rounding_mode));
371371

372-
// g. If TemporalUnitCategory(largestUnit) is date, set largestUnit to hour.
372+
// g. If TemporalUnitCategory(largestUnit) is DATE, set largestUnit to HOUR.
373373
if (temporal_unit_category(largest_unit_value) == UnitCategory::Date)
374374
largest_unit_value = Unit::Hour;
375375

Libraries/LibJS/Runtime/Temporal/PlainDate.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -413,14 +413,17 @@ ThrowCompletionOr<GC::Ref<Duration>> difference_temporal_plain_date(VM& vm, Dura
413413
// a. Let isoDateTime be CombineISODateAndTimeRecord(temporalDate.[[ISODate]], MidnightTimeRecord()).
414414
auto iso_date_time = combine_iso_date_and_time_record(temporal_date.iso_date(), midnight_time_record());
415415

416-
// b. Let isoDateTimeOther be CombineISODateAndTimeRecord(other.[[ISODate]], MidnightTimeRecord()).
416+
// b. Let originEpochNs be GetUTCEpochNanoseconds(isoDateTime).
417+
auto origin_epoch_ns = get_utc_epoch_nanoseconds(iso_date_time);
418+
419+
// c. Let isoDateTimeOther be CombineISODateAndTimeRecord(other.[[ISODate]], MidnightTimeRecord()).
417420
auto iso_date_time_other = combine_iso_date_and_time_record(other->iso_date(), midnight_time_record());
418421

419-
// c. Let destEpochNs be GetUTCEpochNanoseconds(isoDateTimeOther).
422+
// d. Let destEpochNs be GetUTCEpochNanoseconds(isoDateTimeOther).
420423
auto dest_epoch_ns = get_utc_epoch_nanoseconds(iso_date_time_other);
421424

422-
// d. Set duration to ? RoundRelativeDuration(duration, destEpochNs, isoDateTime, UNSET, temporalDate.[[Calendar]], settings.[[LargestUnit]], settings.[[RoundingIncrement]], settings.[[SmallestUnit]], settings.[[RoundingMode]]).
423-
duration = TRY(round_relative_duration(vm, move(duration), dest_epoch_ns, iso_date_time, {}, temporal_date.calendar(), settings.largest_unit, settings.rounding_increment, settings.smallest_unit, settings.rounding_mode));
425+
// e. Set duration to ? RoundRelativeDuration(duration, originEpochNs, destEpochNs, isoDateTime, UNSET, temporalDate.[[Calendar]], settings.[[LargestUnit]], settings.[[RoundingIncrement]], settings.[[SmallestUnit]], settings.[[RoundingMode]]).
426+
duration = TRY(round_relative_duration(vm, move(duration), origin_epoch_ns, dest_epoch_ns, iso_date_time, {}, temporal_date.calendar(), settings.largest_unit, settings.rounding_increment, settings.smallest_unit, settings.rounding_mode));
424427
}
425428

426429
// 9. Let result be ! TemporalDurationFromInternal(duration, DAY).

Libraries/LibJS/Runtime/Temporal/PlainDateTime.cpp

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -369,11 +369,14 @@ ThrowCompletionOr<InternalDuration> difference_plain_date_time_with_rounding(VM&
369369
if (smallest_unit == Unit::Nanosecond && rounding_increment == 1)
370370
return diff;
371371

372-
// 5. Let destEpochNs be GetUTCEpochNanoseconds(isoDateTime2).
372+
// 5. Let originEpochNs be GetUTCEpochNanoseconds(isoDateTime1).
373+
auto origin_epoch_ns = get_utc_epoch_nanoseconds(iso_date_time1);
374+
375+
// 6. Let destEpochNs be GetUTCEpochNanoseconds(isoDateTime2).
373376
auto dest_epoch_ns = get_utc_epoch_nanoseconds(iso_date_time2);
374377

375-
// 6. Return ? RoundRelativeDuration(diff, destEpochNs, isoDateTime1, UNSET, calendar, largestUnit, roundingIncrement, smallestUnit, roundingMode).
376-
return TRY(round_relative_duration(vm, diff, dest_epoch_ns, iso_date_time1, {}, calendar, largest_unit, rounding_increment, smallest_unit, rounding_mode));
378+
// 7. Return ? RoundRelativeDuration(diff, originEpochNs, destEpochNs, isoDateTime1, UNSET, calendar, largestUnit, roundingIncrement, smallestUnit, roundingMode).
379+
return TRY(round_relative_duration(vm, diff, origin_epoch_ns, dest_epoch_ns, iso_date_time1, {}, calendar, largest_unit, rounding_increment, smallest_unit, rounding_mode));
377380
}
378381

379382
// 5.5.14 DifferencePlainDateTimeWithTotal ( isoDateTime1, isoDateTime2, calendar, unit ), https://tc39.es/proposal-temporal/#sec-temporal-differenceplaindatetimewithtotal
@@ -397,11 +400,14 @@ ThrowCompletionOr<Crypto::BigFraction> difference_plain_date_time_with_total(VM&
397400
if (unit == Unit::Nanosecond)
398401
return move(diff.time);
399402

400-
// 5. Let destEpochNs be GetUTCEpochNanoseconds(isoDateTime2).
403+
// 5. Let originEpochNs be GetUTCEpochNanoseconds(isoDateTime1).
404+
auto origin_epoch_ns = get_utc_epoch_nanoseconds(iso_date_time1);
405+
406+
// 6. Let destEpochNs be GetUTCEpochNanoseconds(isoDateTime2).
401407
auto dest_epoch_ns = get_utc_epoch_nanoseconds(iso_date_time2);
402408

403-
// 6. Return ? TotalRelativeDuration(diff, destEpochNs, isoDateTime1, UNSET, calendar, unit).
404-
return TRY(total_relative_duration(vm, diff, dest_epoch_ns, iso_date_time1, {}, calendar, unit));
409+
// 7. Return ? TotalRelativeDuration(diff, originEpochNs, destEpochNs, isoDateTime1, UNSET, calendar, unit).
410+
return TRY(total_relative_duration(vm, diff, origin_epoch_ns, dest_epoch_ns, iso_date_time1, {}, calendar, unit));
405411
}
406412

407413
// 5.5.15 DifferenceTemporalPlainDateTime ( operation, dateTime, other, options ), https://tc39.es/proposal-temporal/#sec-temporal-differencetemporalplaindatetime

Libraries/LibJS/Runtime/Temporal/PlainYearMonth.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -254,14 +254,17 @@ ThrowCompletionOr<GC::Ref<Duration>> difference_temporal_plain_year_month(VM& vm
254254
// a. Let isoDateTime be CombineISODateAndTimeRecord(thisDate, MidnightTimeRecord()).
255255
auto iso_date_time = combine_iso_date_and_time_record(this_date, midnight_time_record());
256256

257-
// b. Let isoDateTimeOther be CombineISODateAndTimeRecord(otherDate, MidnightTimeRecord()).
257+
// b. Let originEpochNs be GetUTCEpochNanoseconds(isoDateTime).
258+
auto origin_epoch_ns = get_utc_epoch_nanoseconds(iso_date_time);
259+
260+
// c. Let isoDateTimeOther be CombineISODateAndTimeRecord(otherDate, MidnightTimeRecord()).
258261
auto iso_date_time_other = combine_iso_date_and_time_record(other_date, midnight_time_record());
259262

260-
// c. Let destEpochNs be GetUTCEpochNanoseconds(isoDateTimeOther).
263+
// d. Let destEpochNs be GetUTCEpochNanoseconds(isoDateTimeOther).
261264
auto dest_epoch_ns = get_utc_epoch_nanoseconds(iso_date_time_other);
262265

263-
// d. Set duration to ? RoundRelativeDuration(duration, destEpochNs, isoDateTime, UNSET, calendar, settings.[[LargestUnit]], settings.[[RoundingIncrement]], settings.[[SmallestUnit]], settings.[[RoundingMode]]).
264-
duration = TRY(round_relative_duration(vm, move(duration), dest_epoch_ns, iso_date_time, {}, calendar, settings.largest_unit, settings.rounding_increment, settings.smallest_unit, settings.rounding_mode));
266+
// e. Set duration to ? RoundRelativeDuration(duration, originEpochNs, destEpochNs, isoDateTime, UNSET, calendar, settings.[[LargestUnit]], settings.[[RoundingIncrement]], settings.[[SmallestUnit]], settings.[[RoundingMode]]).
267+
duration = TRY(round_relative_duration(vm, move(duration), origin_epoch_ns, dest_epoch_ns, iso_date_time, {}, calendar, settings.largest_unit, settings.rounding_increment, settings.smallest_unit, settings.rounding_mode));
265268
}
266269

267270
// 17. Let result be ! TemporalDurationFromInternal(duration, DAY).

0 commit comments

Comments
 (0)