diff --git a/js/src/builtin/temporal/Calendar.cpp b/js/src/builtin/temporal/Calendar.cpp index 524259094054..34287c02f16a 100644 --- a/js/src/builtin/temporal/Calendar.cpp +++ b/js/src/builtin/temporal/Calendar.cpp @@ -2045,6 +2045,44 @@ static UniqueICU4XDate CreateDateFrom(JSContext* cx, CalendarId calendar, return date; } +/** + * RegulateISODate ( year, month, day, overflow ) + */ +static bool RegulateISODate(JSContext* cx, int32_t year, double month, + double day, TemporalOverflow overflow, + ISODate* result) { + MOZ_ASSERT(IsInteger(month)); + MOZ_ASSERT(IsInteger(day)); + + // Step 1. + if (overflow == TemporalOverflow::Constrain) { + // Step 1.a. + int32_t m = int32_t(std::clamp(month, 1.0, 12.0)); + + // Step 1.b. + double daysInMonth = double(::ISODaysInMonth(year, m)); + + // Step 1.c. + int32_t d = int32_t(std::clamp(day, 1.0, daysInMonth)); + + // Step 1.d. + *result = {year, m, d}; + return true; + } + + // Step 2.a. + MOZ_ASSERT(overflow == TemporalOverflow::Reject); + + // Step 2.b. + if (!ThrowIfInvalidISODate(cx, year, month, day)) { + return false; + } + + // Step 2.b. (Inlined call to CreateISODateRecord.) + *result = {year, int32_t(month), int32_t(day)}; + return true; +} + /** * CalendarDateToISO ( calendar, fields, overflow ) */ @@ -3272,7 +3310,138 @@ bool js::temporal::CalendarMonthDayFromFields( } /** - * CalendarDateAdd ( date, duration, overflow ) + * Mathematical Operations, "modulo" notation. + */ +static int32_t NonNegativeModulo(int64_t x, int32_t y) { + MOZ_ASSERT(y > 0); + + int32_t result = mozilla::AssertedCast(x % y); + return (result < 0) ? (result + y) : result; +} + +/** + * RegulateISODate ( year, month, day, overflow ) + * + * With |overflow = "constrain"|. + */ +static ISODate ConstrainISODate(const ISODate& date) { + const auto& [year, month, day] = date; + + // Step 1.a. + int32_t m = std::clamp(month, 1, 12); + + // Step 1.b. + int32_t daysInMonth = ::ISODaysInMonth(year, m); + + // Step 1.c. + int32_t d = std::clamp(day, 1, daysInMonth); + + // Step 3. + return {year, m, d}; +} + +/** + * RegulateISODate ( year, month, day, overflow ) + */ +static bool RegulateISODate(JSContext* cx, const ISODate& date, + TemporalOverflow overflow, ISODate* result) { + // Step 1. + if (overflow == TemporalOverflow::Constrain) { + // Steps 1.a-c and 3. + *result = ConstrainISODate(date); + return true; + } + + // Step 2.a. + MOZ_ASSERT(overflow == TemporalOverflow::Reject); + + // Step 2.b. + if (!ThrowIfInvalidISODate(cx, date)) { + return false; + } + + // Step 3. (Inlined call to CreateISODateRecord.) + *result = date; + return true; +} + +struct BalancedYearMonth final { + int64_t year = 0; + int32_t month = 0; +}; + +/** + * BalanceISOYearMonth ( year, month ) + */ +static BalancedYearMonth BalanceISOYearMonth(int64_t year, int64_t month) { + MOZ_ASSERT(std::abs(year) < (int64_t(1) << 33), + "year is the addition of plain-date year with duration years"); + MOZ_ASSERT(std::abs(month) < (int64_t(1) << 33), + "month is the addition of plain-date month with duration months"); + + // Step 1. (Not applicable in our implementation.) + + // Step 2. + int64_t balancedYear = year + temporal::FloorDiv(month - 1, 12); + + // Step 3. + int32_t balancedMonth = NonNegativeModulo(month - 1, 12) + 1; + MOZ_ASSERT(1 <= balancedMonth && balancedMonth <= 12); + + // Step 4. + return {balancedYear, balancedMonth}; +} + +/** + * CalendarDateAdd ( calendar, isoDate, duration, overflow ) + */ +static bool AddISODate(JSContext* cx, const ISODate& isoDate, + const DateDuration& duration, TemporalOverflow overflow, + ISODate* result) { + MOZ_ASSERT(IsValidISODate(isoDate)); + MOZ_ASSERT(ISODateWithinLimits(isoDate)); + MOZ_ASSERT(IsValidDuration(duration)); + + // Step 1.a. + auto yearMonth = BalanceISOYearMonth(isoDate.year + duration.years, + isoDate.month + duration.months); + MOZ_ASSERT(1 <= yearMonth.month && yearMonth.month <= 12); + + auto balancedYear = mozilla::CheckedInt(yearMonth.year); + if (!balancedYear.isValid()) { + JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, + JSMSG_TEMPORAL_PLAIN_DATE_INVALID); + return false; + } + + // Step 1.b. + ISODate regulated; + if (!RegulateISODate(cx, {balancedYear.value(), yearMonth.month, isoDate.day}, + overflow, ®ulated)) { + return false; + } + if (!ISODateWithinLimits(regulated)) { + JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, + JSMSG_TEMPORAL_PLAIN_DATE_INVALID); + return false; + } + + // Step 1.c. + int64_t days = duration.days + duration.weeks * 7; + + // Step 1.d. + ISODate balanced; + if (!BalanceISODate(cx, regulated, days, &balanced)) { + return false; + } + MOZ_ASSERT(IsValidISODate(balanced)); + + *result = balanced; + return true; +} + +/** + * CalendarDateAdd ( calendar, isoDate, duration, overflow ) */ bool js::temporal::CalendarDateAdd(JSContext* cx, Handle calendar, @@ -3303,7 +3472,95 @@ bool js::temporal::CalendarDateAdd(JSContext* cx, } /** - * CalendarDateUntil ( one, two, largestUnit ) + * CalendarDateUntil ( calendar, one, two, largestUnit ) + */ +static DateDuration DifferenceISODate(const ISODate& one, const ISODate& two, + TemporalUnit largestUnit) { + MOZ_ASSERT(IsValidISODate(one)); + MOZ_ASSERT(IsValidISODate(two)); + + // Both inputs are also within the date limits. + MOZ_ASSERT(ISODateWithinLimits(one)); + MOZ_ASSERT(ISODateWithinLimits(two)); + + MOZ_ASSERT(TemporalUnit::Year <= largestUnit && + largestUnit <= TemporalUnit::Day); + + // Step 1.a. + int32_t sign = -CompareISODate(one, two); + + // Step 1.b. + if (sign == 0) { + return {}; + } + + // Step 1.c. + int32_t years = 0; + + // Step 1.e. (Reordered) + int32_t months = 0; + + // Steps 1.d and 1.f. + if (largestUnit == TemporalUnit::Year || largestUnit == TemporalUnit::Month) { + years = two.year - one.year; + months = two.month - one.month; + + auto intermediate = ISODate{one.year + years, one.month, one.day}; + if (CompareISODate(intermediate, two) * sign > 0) { + years -= sign; + months += 12 * sign; + } + + intermediate = ISODate{one.year + years, one.month + months, one.day}; + if (intermediate.month > 12) { + intermediate.month -= 12; + intermediate.year += 1; + } else if (intermediate.month < 1) { + intermediate.month += 12; + intermediate.year -= 1; + } + if (CompareISODate(intermediate, two) * sign > 0) { + months -= sign; + } + + if (largestUnit == TemporalUnit::Month) { + months += years * 12; + years = 0; + } + } + + // Step 1.g. + auto intermediate = BalanceISOYearMonth(one.year + years, one.month + months); + + // Step 1.h. + auto constrained = ConstrainISODate( + ISODate{int32_t(intermediate.year), intermediate.month, one.day}); + + // Step 1.i. + int64_t weeks = 0; + + // Steps 1.k-n. + int64_t days = MakeDay(two) - MakeDay(constrained); + + // Step 1.j. (Reordered) + if (largestUnit == TemporalUnit::Week) { + weeks = days / 7; + days %= 7; + } + + // Step 1.o. + auto result = DateDuration{ + int64_t(years), + int64_t(months), + int64_t(weeks), + int64_t(days), + }; + MOZ_ASSERT(IsValidDuration(result)); + return result; +} + +/** + * CalendarDateUntil ( calendar, one, two, largestUnit ) */ bool js::temporal::CalendarDateUntil(JSContext* cx, Handle calendar, diff --git a/js/src/builtin/temporal/Calendar.h b/js/src/builtin/temporal/Calendar.h index 4bab80cb933e..ce74180b5fe3 100644 --- a/js/src/builtin/temporal/Calendar.h +++ b/js/src/builtin/temporal/Calendar.h @@ -228,14 +228,14 @@ JSLinearString* ToTemporalCalendarIdentifier( JSContext* cx, JS::Handle calendar); /** - * CalendarDateAdd ( date, duration, overflow ) + * CalendarDateAdd ( calendar, isoDate, duration, overflow ) */ bool CalendarDateAdd(JSContext* cx, JS::Handle calendar, const ISODate& date, const DateDuration& duration, TemporalOverflow overflow, ISODate* result); /** - * CalendarDateUntil ( one, two, largestUnit ) + * CalendarDateUntil ( calendar, one, two, largestUnit ) */ bool CalendarDateUntil(JSContext* cx, JS::Handle calendar, const ISODate& one, const ISODate& two, diff --git a/js/src/builtin/temporal/PlainDate.cpp b/js/src/builtin/temporal/PlainDate.cpp index 7cf73ea3dbe8..d8617f80d49e 100644 --- a/js/src/builtin/temporal/PlainDate.cpp +++ b/js/src/builtin/temporal/PlainDate.cpp @@ -226,89 +226,6 @@ bool js::temporal::ThrowIfInvalidISODate(JSContext* cx, double year, return ::ThrowIfInvalidISODate(cx, year, month, day); } -/** - * RegulateISODate ( year, month, day, overflow ) - * - * With |overflow = "constrain"|. - */ -static ISODate ConstrainISODate(const ISODate& date) { - const auto& [year, month, day] = date; - - // Step 1.a. - int32_t m = std::clamp(month, 1, 12); - - // Step 1.b. - int32_t daysInMonth = temporal::ISODaysInMonth(year, m); - - // Step 1.c. - int32_t d = std::clamp(day, 1, daysInMonth); - - // Step 1.d. - return {year, m, d}; -} - -/** - * RegulateISODate ( year, month, day, overflow ) - */ -static bool RegulateISODate(JSContext* cx, const ISODate& date, - TemporalOverflow overflow, ISODate* result) { - // Step 1. - if (overflow == TemporalOverflow::Constrain) { - *result = ::ConstrainISODate(date); - return true; - } - - // Step 2.a. - MOZ_ASSERT(overflow == TemporalOverflow::Reject); - - // Step 2.b. - if (!ThrowIfInvalidISODate(cx, date)) { - return false; - } - - // Step 2.b. (Inlined call to CreateISODateRecord.) - *result = date; - return true; -} - -/** - * RegulateISODate ( year, month, day, overflow ) - */ -bool js::temporal::RegulateISODate(JSContext* cx, int32_t year, double month, - double day, TemporalOverflow overflow, - ISODate* result) { - MOZ_ASSERT(IsInteger(month)); - MOZ_ASSERT(IsInteger(day)); - - // Step 1. - if (overflow == TemporalOverflow::Constrain) { - // Step 1.a. - int32_t m = int32_t(std::clamp(month, 1.0, 12.0)); - - // Step 1.b. - double daysInMonth = double(ISODaysInMonth(year, m)); - - // Step 1.c. - int32_t d = int32_t(std::clamp(day, 1.0, daysInMonth)); - - // Step 1.d. - *result = {year, m, d}; - return true; - } - - // Step 2.a. - MOZ_ASSERT(overflow == TemporalOverflow::Reject); - - // Step 2.b. - if (!ThrowIfInvalidISODate(cx, year, month, day)) { - return false; - } - - // Step 2.b. (Inlined call to CreateISODateRecord.) - *result = {year, int32_t(month), int32_t(day)}; - return true; -} - /** * CreateTemporalDate ( isoDate, calendar [ , newTarget ] ) */ @@ -602,48 +519,6 @@ static bool ToTemporalDate(JSContext* cx, Handle item, return ToTemporalDate(cx, item, UndefinedHandleValue, result); } -/** - * Mathematical Operations, "modulo" notation. - */ -static int32_t NonNegativeModulo(int64_t x, int32_t y) { - MOZ_ASSERT(y > 0); - - int32_t result = mozilla::AssertedCast(x % y); - return (result < 0) ? (result + y) : result; -} - -struct BalancedYearMonth final { - int64_t year = 0; - int32_t month = 0; -}; - -/** - * BalanceISOYearMonth ( year, month ) - */ -static BalancedYearMonth BalanceISOYearMonth(int64_t year, int64_t month) { - MOZ_ASSERT(std::abs(year) < (int64_t(1) << 33), - "year is the addition of plain-date year with duration years"); - MOZ_ASSERT(std::abs(month) < (int64_t(1) << 33), - "month is the addition of plain-date month with duration months"); - - // Step 1. (Not applicable in our implementation.) - - // Note: If either abs(year) or abs(month) is greater than 2^53 (the double - // integral precision limit), the additions resp. subtractions below are - // imprecise. This doesn't matter for us, because the single caller to this - // function (AddISODate) will throw an error for large values anyway. - - // Step 2. - int64_t balancedYear = year + temporal::FloorDiv(month - 1, 12); - - // Step 3. - int32_t balancedMonth = NonNegativeModulo(month - 1, 12) + 1; - MOZ_ASSERT(1 <= balancedMonth && balancedMonth <= 12); - - // Step 4. - return {balancedYear, balancedMonth}; -} - static bool IsValidISODateEpochMilliseconds(int64_t epochMilliseconds) { // Epoch nanoseconds limits, adjusted to the range supported by ISODate. constexpr auto oneDay = @@ -710,142 +585,6 @@ ISODate js::temporal::BalanceISODate(const ISODate& date, int32_t days) { return result; } -static bool CanBalanceISOYear(int64_t year) { - // TODO: Export these values somewhere. - constexpr int32_t minYear = -271821; - constexpr int32_t maxYear = 275760; - - // If the year is below resp. above the min-/max-year, no value of |day| will - // make the resulting date valid. - return minYear <= year && year <= maxYear; -} - -/** - * AddISODate ( year, month, day, years, months, weeks, days, overflow ) - */ -bool js::temporal::AddISODate(JSContext* cx, const ISODate& date, - const DateDuration& duration, - TemporalOverflow overflow, ISODate* result) { - MOZ_ASSERT(IsValidISODate(date)); - MOZ_ASSERT(ISODateWithinLimits(date)); - MOZ_ASSERT(IsValidDuration(duration)); - - // Steps 1-2. (Not applicable in our implementation.) - - // Step 3. - auto yearMonth = BalanceISOYearMonth(date.year + duration.years, - date.month + duration.months); - MOZ_ASSERT(1 <= yearMonth.month && yearMonth.month <= 12); - - // FIXME: spec issue? - // new Temporal.PlainDate(2021, 5, 31).subtract({months:1, days:1}).toString() - // returns "2021-04-29", but "2021-04-30" seems more likely expected. - // Note: "2021-04-29" agrees with java.time, though. - // - // Example where this creates inconsistent results: - // - // clang-format off - // - // js> Temporal.PlainDate.from("2021-05-31").since("2021-04-30", {largestUnit:"months"}).toString() - // "P1M1D" - // js> Temporal.PlainDate.from("2021-05-31").subtract("P1M1D").toString() - // "2021-04-29" - // - // clang-format on - // - // Later: This now returns "P1M" instead "P1M1D", so the results are at least - // consistent. Let's add a test case for this behaviour. - // - // Revisit when has - // been addressed. - - // |yearMonth.year| can only exceed the valid years range when called from - // `Temporal.Calendar.prototype.dateAdd`. And because `dateAdd` uses the - // result of AddISODate to create a new Temporal.PlainDate, we can directly - // throw an error if the result isn't within the valid date-time limits. This - // in turn allows to work on integer values and we don't have to worry about - // imprecise double value computations. - if (!CanBalanceISOYear(yearMonth.year)) { - JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, - JSMSG_TEMPORAL_PLAIN_DATE_INVALID); - return false; - } - - // Step 4. - ISODate regulated; - if (!RegulateISODate(cx, {int32_t(yearMonth.year), yearMonth.month, date.day}, - overflow, ®ulated)) { - return false; - } - if (!ISODateWithinLimits(regulated)) { - JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, - JSMSG_TEMPORAL_PLAIN_DATE_INVALID); - return false; - } - - // Steps 5-6. - int64_t days = duration.days + duration.weeks * 7; - - // Step 7. - ISODate balanced; - if (!BalanceISODate(cx, regulated, days, &balanced)) { - return false; - } - MOZ_ASSERT(IsValidISODate(balanced)); - - *result = balanced; - return true; -} - -struct YearMonthDuration { - int32_t years = 0; - int32_t months = 0; -}; - -/** - * AddISODate ( year, month, day, years, months, weeks, days, overflow ) - * - * With |overflow = "constrain"|. - */ -static ISODate AddISODate(const ISODate& date, - const YearMonthDuration& duration) { - MOZ_ASSERT(IsValidISODate(date)); - MOZ_ASSERT(ISODateWithinLimits(date)); - - MOZ_ASSERT_IF(duration.years < 0, duration.months <= 0); - MOZ_ASSERT_IF(duration.years > 0, duration.months >= 0); - - // TODO: Export these values somewhere. - [[maybe_unused]] constexpr int32_t minYear = -271821; - [[maybe_unused]] constexpr int32_t maxYear = 275760; - - MOZ_ASSERT(std::abs(duration.years) <= (maxYear - minYear), - "years doesn't exceed the maximum duration between valid years"); - MOZ_ASSERT(std::abs(duration.months) <= 12, - "months duration is at most one year"); - - // Steps 1-2. (Not applicable) - - // Step 3. (Inlined BalanceISOYearMonth) - int32_t year = date.year + duration.years; - int32_t month = date.month + duration.months; - MOZ_ASSERT(-11 <= month && month <= 24); - - if (month > 12) { - month -= 12; - year += 1; - } else if (month <= 0) { - month += 12; - year -= 1; - } - - MOZ_ASSERT(1 <= month && month <= 12); - MOZ_ASSERT(CanBalanceISOYear(year)); - - // Steps 4-7. - return ::ConstrainISODate({year, month, date.day}); -} - /** * CompareISODate ( y1, m1, d1, y2, m2, d2 ) */ @@ -869,223 +608,6 @@ int32_t js::temporal::CompareISODate(const ISODate& one, const ISODate& two) { return 0; } -/** - * CreateDateDurationRecord ( years, months, weeks, days ) - */ -static DateDuration CreateDateDurationRecord(int32_t years, int32_t months, - int32_t weeks, int32_t days) { - MOZ_ASSERT(IsValidDuration( - Duration{double(years), double(months), double(weeks), double(days)})); - return {years, months, weeks, days}; -} - -/** - * DifferenceISODate ( y1, m1, d1, y2, m2, d2, largestUnit ) - */ -DateDuration js::temporal::DifferenceISODate(const ISODate& start, - const ISODate& end, - TemporalUnit largestUnit) { - // Steps 1-2. - MOZ_ASSERT(IsValidISODate(start)); - MOZ_ASSERT(IsValidISODate(end)); - - // Both inputs are also within the date limits. - MOZ_ASSERT(ISODateWithinLimits(start)); - MOZ_ASSERT(ISODateWithinLimits(end)); - - // Because both inputs are valid dates, we don't need to worry about integer - // overflow in any of the computations below. - - MOZ_ASSERT(TemporalUnit::Year <= largestUnit && - largestUnit <= TemporalUnit::Day); - - // Step 3. - if (largestUnit == TemporalUnit::Year || largestUnit == TemporalUnit::Month) { - // Step 3.a. - int32_t sign = -CompareISODate(start, end); - - // Step 3.b. - if (sign == 0) { - return CreateDateDurationRecord(0, 0, 0, 0); - } - - // FIXME: spec issue - results can be ambiguous, is this intentional? - // https://github.com/tc39/proposal-temporal/issues/2535 - // - // clang-format off - // js> var end = new Temporal.PlainDate(1970, 2, 28) - // js> var start = new Temporal.PlainDate(1970, 1, 28) - // js> start.calendar.dateUntil(start, end, {largestUnit:"months"}).toString() - // "P1M" - // js> var start = new Temporal.PlainDate(1970, 1, 29) - // js> start.calendar.dateUntil(start, end, {largestUnit:"months"}).toString() - // "P1M" - // js> var start = new Temporal.PlainDate(1970, 1, 30) - // js> start.calendar.dateUntil(start, end, {largestUnit:"months"}).toString() - // "P1M" - // js> var start = new Temporal.PlainDate(1970, 1, 31) - // js> start.calendar.dateUntil(start, end, {largestUnit:"months"}).toString() - // "P1M" - // - // Compare to java.time.temporal - // - // jshell> import java.time.LocalDate - // jshell> var end = LocalDate.of(1970, 2, 28) - // end ==> 1970-02-28 - // jshell> var start = LocalDate.of(1970, 1, 28) - // start ==> 1970-01-28 - // jshell> start.until(end) - // $27 ==> P1M - // jshell> var start = LocalDate.of(1970, 1, 29) - // start ==> 1970-01-29 - // jshell> start.until(end) - // $29 ==> P30D - // jshell> var start = LocalDate.of(1970, 1, 30) - // start ==> 1970-01-30 - // jshell> start.until(end) - // $31 ==> P29D - // jshell> var start = LocalDate.of(1970, 1, 31) - // start ==> 1970-01-31 - // jshell> start.until(end) - // $33 ==> P28D - // - // Also compare to: - // - // js> var end = new Temporal.PlainDate(1970, 2, 27) - // js> var start = new Temporal.PlainDate(1970, 1, 27) - // js> start.calendar.dateUntil(start, end, {largestUnit:"months"}).toString() - // "P1M" - // js> var start = new Temporal.PlainDate(1970, 1, 28) - // js> start.calendar.dateUntil(start, end, {largestUnit:"months"}).toString() - // "P30D" - // js> var start = new Temporal.PlainDate(1970, 1, 29) - // js> start.calendar.dateUntil(start, end, {largestUnit:"months"}).toString() - // "P29D" - // - // clang-format on - - // Steps 3.c-d. (Not applicable in our implementation.) - - // FIXME: spec issue - consistently use either |end.[[Year]]| or |y2|. - - // Step 3.e. - int32_t years = end.year - start.year; - - // TODO: We could inline this, because the AddISODate call is just a more - // complicated way to perform: - // mid = ConstrainISODate(end.year, start.month, start.day) - // - // The remaining computations can probably simplified similarily. - - // Step 3.f. - auto mid = ::AddISODate(start, {years, 0}); - - // Step 3.g. - int32_t midSign = -CompareISODate(mid, end); - - // Step 3.h. - if (midSign == 0) { - // Step 3.h.i. - if (largestUnit == TemporalUnit::Year) { - return CreateDateDurationRecord(years, 0, 0, 0); - } - - // Step 3.h.ii. - return CreateDateDurationRecord(0, years * 12, 0, 0); - } - - // Step 3.i. - int32_t months = end.month - start.month; - - // Step 3.j. - if (midSign != sign) { - // Step 3.j.i. - years -= sign; - - // Step 3.j.ii. - months += sign * 12; - } - - // Step 3.k. - mid = ::AddISODate(start, {years, months}); - - // Step 3.l. - midSign = -CompareISODate(mid, end); - - // Step 3.m. - if (midSign == 0) { - // Step 3.m.i. - if (largestUnit == TemporalUnit::Year) { - return CreateDateDurationRecord(years, months, 0, 0); - } - - // Step 3.m.ii. - return CreateDateDurationRecord(0, months + years * 12, 0, 0); - } - - // Step 3.n. - if (midSign != sign) { - // Step 3.n.i. - months -= sign; - - // Step 3.n.ii. - mid = ::AddISODate(start, {years, months}); - } - - // Steps 3.o-q. - int32_t days; - if (mid.month == end.month) { - MOZ_ASSERT(mid.year == end.year); - - days = end.day - mid.day; - } else if (sign < 0) { - days = -mid.day - (ISODaysInMonth(end.year, end.month) - end.day); - } else { - days = end.day + (ISODaysInMonth(mid.year, mid.month) - mid.day); - } - - // Step 3.r. - if (largestUnit == TemporalUnit::Month) { - // Step 3.r.i. - months += years * 12; - - // Step 3.r.ii. - years = 0; - } - - // Step 3.s. - return CreateDateDurationRecord(years, months, 0, days); - } - - // Step 4.a. - MOZ_ASSERT(largestUnit == TemporalUnit::Week || - largestUnit == TemporalUnit::Day); - - // Step 4.b. - int32_t epochDaysStart = MakeDay(start); - - // Step 4.c. - int32_t epochDaysEnd = MakeDay(end); - - // Step 4.d. - int32_t days = epochDaysEnd - epochDaysStart; - - // Step 4.e. - int32_t weeks = 0; - - // Step 4.f. - if (largestUnit == TemporalUnit::Week) { - // Step 4.f.i - weeks = days / 7; - - // Step 4.f.ii. - days = days % 7; - } - - // Step 4.g. - return CreateDateDurationRecord(0, 0, weeks, days); -} - /** * DifferenceTemporalPlainDate ( operation, temporalDate, other, options ) */ diff --git a/js/src/builtin/temporal/PlainDate.h b/js/src/builtin/temporal/PlainDate.h index 38d6bc492bff..4d4c25022491 100644 --- a/js/src/builtin/temporal/PlainDate.h +++ b/js/src/builtin/temporal/PlainDate.h @@ -126,25 +126,6 @@ bool CreateTemporalDate(JSContext* cx, const ISODate& isoDate, JS::Handle calendar, JS::MutableHandle result); -/** - * RegulateISODate ( year, month, day, overflow ) - */ -bool RegulateISODate(JSContext* cx, int32_t year, double month, double day, - TemporalOverflow overflow, ISODate* result); - -/** - * AddISODate ( year, month, day, years, months, weeks, days, overflow ) - */ -bool AddISODate(JSContext* cx, const ISODate& date, - const DateDuration& duration, TemporalOverflow overflow, - ISODate* result); - -/** - * DifferenceISODate ( y1, m1, d1, y2, m2, d2, largestUnit ) - */ -DateDuration DifferenceISODate(const ISODate& start, const ISODate& end, - TemporalUnit largestUnit); - /** * CompareISODate ( y1, m1, d1, y2, m2, d2 ) */