@@ -238,6 +238,16 @@ void Temporal::formatSecondsStringFraction(StringBuilder& builder, Int128 fracti
238238 }
239239}
240240
241+ ISO8601::PlainDateTime Temporal::toPlainDateTime (Int128 epochNanoseconds)
242+ {
243+ int64_t computedEpoch = ISO8601::ExactTime (epochNanoseconds).floorEpochMilliseconds ();
244+ DateObject::DateTimeInfo timeInfo;
245+ DateObject::computeTimeInfoFromEpoch (computedEpoch, timeInfo);
246+ auto d = Temporal::balanceTime (0 , 0 , 0 , 0 , 0 , epochNanoseconds % ISO8601::ExactTime::nsPerDay);
247+ return ISO8601::PlainDateTime (ISO8601::PlainDate (timeInfo.year , timeInfo.month + 1 , timeInfo.mday ),
248+ ISO8601::PlainTime (d.hours (), d.minutes (), d.seconds (), d.milliseconds (), d.microseconds (), d.nanoseconds ()));
249+ }
250+
241251int32_t Temporal::computeTimeZoneOffset (ExecutionState& state, String* name, int64_t epoch)
242252{
243253 auto u16 = name->toUTF16StringData ();
@@ -912,7 +922,11 @@ Int128 Temporal::interpretISODateTimeOffset(ExecutionState& state, ISO8601::Plai
912922 // TODO Let epochNanoseconds be GetUTCEpochNanoseconds(balanced).
913923 // TODO If IsValidEpochNanoseconds(epochNanoseconds) is false, throw a RangeError exception.
914924 // Return epochNanoseconds.
915- return ISO8601::ExactTime::fromPlainDateTime (isoDateTime).epochNanoseconds () + offsetNanoseconds;
925+ auto ns = ISO8601::ExactTime::fromPlainDateTime (isoDateTime).epochNanoseconds () + offsetNanoseconds;
926+ if (!ISO8601::isValidEpochNanoseconds (ns)) {
927+ ErrorObject::throwBuiltinError (state, ErrorCode::RangeError, " Invalid date-time value" );
928+ }
929+ return ns;
916930 }
917931
918932 // TODO
@@ -947,10 +961,18 @@ Int128 Temporal::interpretISODateTimeOffset(ExecutionState& state, ISO8601::Plai
947961 }
948962 }
949963
964+ Int128 ns;
950965 if (hasUTCDesignator) {
951- return ISO8601::ExactTime::fromPlainDateTime (isoDateTime).epochNanoseconds ();
966+ ns = ISO8601::ExactTime::fromPlainDateTime (isoDateTime).epochNanoseconds ();
967+ } else {
968+ ns = ISO8601::ExactTime::fromPlainDateTime (isoDateTime).epochNanoseconds () - timeZoneOffsetNanoseconds.valueOr (0 );
952969 }
953- return ISO8601::ExactTime::fromPlainDateTime (isoDateTime).epochNanoseconds () - timeZoneOffsetNanoseconds.valueOr (0 );
970+
971+ if (!ISO8601::isValidEpochNanoseconds (ns)) {
972+ ErrorObject::throwBuiltinError (state, ErrorCode::RangeError, " Invalid date-time value" );
973+ }
974+
975+ return ns;
954976}
955977
956978TemporalZonedDateTimeObject* Temporal::toTemporalZonedDateTime (ExecutionState& state, Value item, Value options)
@@ -1836,17 +1858,6 @@ bool Temporal::isPartialTemporalObject(ExecutionState& state, Value value)
18361858 return true ;
18371859}
18381860
1839- template <typename T>
1840- T nonNegativeModulo (T x, int y)
1841- {
1842- T result = x % y;
1843- if (!result)
1844- return 0 ;
1845- if (result < 0 )
1846- result += y;
1847- return result;
1848- }
1849-
18501861template <>
18511862double nonNegativeModulo (double x, int y)
18521863{
@@ -1858,19 +1869,6 @@ double nonNegativeModulo(double x, int y)
18581869 return result;
18591870}
18601871
1861- template <typename T>
1862- T intFloor (T x, int y)
1863- {
1864- if (x > 0 ) {
1865- return x / y;
1866- }
1867- if (x % y) {
1868- return x / y - 1 ;
1869- } else {
1870- return x / y;
1871- }
1872- }
1873-
18741872ISO8601::Duration Temporal::balanceTime (double hour, double minute, double second, double millisecond, double microsecond, double nanosecond)
18751873{
18761874 microsecond += std::floor (nanosecond / 1000 );
@@ -3286,12 +3284,7 @@ ISO8601::InternalDuration Temporal::differenceISODateTime(ExecutionState& state,
32863284 // Let timeDuration be DifferenceTime(isoDateTime1.[[Time]], isoDateTime2.[[Time]]).
32873285 auto timeDuration = differenceTime (isoDateTime1.plainTime (), isoDateTime2.plainTime ());
32883286 // Let timeSign be TimeDurationSign(timeDuration).
3289- int timeSign = 0 ;
3290- if (timeDuration < 0 ) {
3291- timeSign = -1 ;
3292- } else if (timeDuration > 0 ) {
3293- timeSign = 1 ;
3294- }
3287+ int timeSign = timeDurationSign (timeDuration);
32953288 // Let dateSign be CompareISODate(isoDateTime1.[[ISODate]], isoDateTime2.[[ISODate]]).
32963289 auto dateSign = isoDateTime1.plainDate ().compare (isoDateTime2.plainDate ());
32973290 // Let adjustedDate be isoDateTime2.[[ISODate]].
@@ -3384,11 +3377,7 @@ ISO8601::PlainDateTime Temporal::getISODateTimeFor(ExecutionState& state, Option
33843377 // Return BalanceISODateTime(result.[[ISODate]].[[Year]], result.[[ISODate]].[[Month]], result.[[ISODate]].[[Day]], result.[[Time]].[[Hour]], result.[[Time]].[[Minute]], result.[[Time]].[[Second]], result.[[Time]].[[Millisecond]], result.[[Time]].[[Microsecond]], result.[[Time]].[[Nanosecond]] + offsetNanoseconds).
33853378 int64_t offsetNanoseconds = timeZone ? getOffsetNanosecondsFor (state, timeZone.value (), epochNs) : 0 ;
33863379 epochNs += offsetNanoseconds;
3387- DateObject::DateTimeInfo timeInfo;
3388- DateObject::computeTimeInfoFromEpoch (ISO8601::ExactTime (epochNs).floorEpochMilliseconds (), timeInfo);
3389- auto d = Temporal::balanceTime (0 , 0 , 0 , 0 , 0 , epochNs % ISO8601::ExactTime::nsPerDay);
3390- return ISO8601::PlainDateTime (ISO8601::PlainDate (timeInfo.year , timeInfo.month + 1 , timeInfo.mday ),
3391- ISO8601::PlainTime (d.hours (), d.minutes (), d.seconds (), d.milliseconds (), d.microseconds (), d.nanoseconds ()));
3380+ return toPlainDateTime (epochNs);
33923381}
33933382
33943383int64_t Temporal::getOffsetNanosecondsFor (ExecutionState& state, TimeZone timeZone, Int128 epochNs)
0 commit comments