Implement from, toString, equals, getter of Temporal.ZonedDateTimeObject

Signed-off-by: Seonghyun Kim <sh8281.kim@samsung.com>
This commit is contained in:
Seonghyun Kim 2025-11-06 20:01:58 +09:00 committed by Patrick Kim
commit bb3c62e2cc
14 changed files with 780 additions and 317 deletions

View file

@ -1093,12 +1093,73 @@ static Value builtinTemporalZonedDateTimeFrom(ExecutionState& state, Value thisV
return Temporal::toTemporalZonedDateTime(state, argv[0], argc > 1 ? argv[1] : Value());
}
static Value builtinTemporalZonedDateTimeCalendarId(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional<Object*> newTarget)
{
RESOLVE_THIS_BINDING_TO_ZONEDDATETIME(zonedDateTime, CalendarId);
if (zonedDateTime->calendarID() == Calendar(Calendar::ID::ISO8601)) {
return state.context()->staticStrings().lazyISO8601().string();
} else {
return zonedDateTime->calendarID().toString();
}
}
static Value builtinTemporalZonedDateTimeMonthCode(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional<Object*> newTarget)
{
RESOLVE_THIS_BINDING_TO_ZONEDDATETIME(zonedDateTime, MonthCode);
return zonedDateTime->monthCode(state);
}
static Value builtinTemporalZonedDateTimeTimeZoneId(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional<Object*> newTarget)
{
RESOLVE_THIS_BINDING_TO_ZONEDDATETIME(zonedDateTime, TimeZoneId);
return zonedDateTime->timeZone().timeZoneName();
}
static Value builtinTemporalZonedDateTimeOffset(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional<Object*> newTarget)
{
RESOLVE_THIS_BINDING_TO_ZONEDDATETIME(zonedDateTime, Offset);
StringBuilder sb;
Temporal::formatOffsetTimeZoneIdentifier(state, (int)(zonedDateTime->timeZone().offset() / ISO8601::ExactTime::nsPerMinute), sb);
return sb.finalize();
}
static Value builtinTemporalZonedDateTimeOffsetNanoseconds(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional<Object*> newTarget)
{
RESOLVE_THIS_BINDING_TO_ZONEDDATETIME(zonedDateTime, OffsetNanoseconds);
return Value(zonedDateTime->timeZone().offset());
}
static Value builtinTemporalZonedDateTimeEpochNanoseconds(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional<Object*> newTarget)
{
RESOLVE_THIS_BINDING_TO_ZONEDDATETIME(zonedDateTime, EpochNanoseconds);
BigIntData bd(zonedDateTime->epochNanoseconds());
return Value(new BigInt(std::move(bd)));
}
static Value builtinTemporalZonedDateTimeEpochMilliseconds(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional<Object*> newTarget)
{
RESOLVE_THIS_BINDING_TO_ZONEDDATETIME(zonedDateTime, EpochMilliseconds);
return Value(ISO8601::ExactTime(zonedDateTime->epochNanoseconds()).epochMilliseconds());
}
static Value builtinTemporalZonedDateTimeHoursInDay(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional<Object*> newTarget)
{
RESOLVE_THIS_BINDING_TO_ZONEDDATETIME(zonedDateTime, HoursInDay);
return Value(zonedDateTime->hoursInDay(state));
}
static Value builtinTemporalZonedDateTimeToString(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional<Object*> newTarget)
{
RESOLVE_THIS_BINDING_TO_ZONEDDATETIME2(zonedDateTime, toString);
return zonedDateTime->toString(state, argc ? argv[0] : Value());
}
static Value builtinTemporalZonedDateTimeEquals(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional<Object*> newTarget)
{
RESOLVE_THIS_BINDING_TO_ZONEDDATETIME(zonedDateTime, Equals);
return Value(zonedDateTime->equals(state, argv[0]));
}
void GlobalObject::initializeTemporal(ExecutionState& state)
{
ObjectPropertyNativeGetterSetterData* nativeData = new ObjectPropertyNativeGetterSetterData(
@ -1622,7 +1683,7 @@ void GlobalObject::installTemporal(ExecutionState& state)
}
// Temporal.ZonedDateTime
m_temporalZonedDateTime = new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyCapitalPlainMonthDay(), builtinTemporalZonedDateTimeConstructor, 2), NativeFunctionObject::__ForBuiltinConstructor__);
m_temporalZonedDateTime = new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyCapitalZonedDateTime(), builtinTemporalZonedDateTimeConstructor, 2), NativeFunctionObject::__ForBuiltinConstructor__);
m_temporalZonedDateTime->setGlobalIntrinsicObject(state);
m_temporalZonedDateTime->directDefineOwnProperty(state, ObjectPropertyName(strings->from), ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->from, builtinTemporalZonedDateTimeFrom, 1, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent)));
@ -1631,6 +1692,136 @@ void GlobalObject::installTemporal(ExecutionState& state)
m_temporalZonedDateTimePrototype->directDefineOwnProperty(state, ObjectPropertyName(state.context()->vmInstance()->globalSymbols().toStringTag),
ObjectPropertyDescriptor(Value(strings->lazyTemporalDotZonedDateTime().string()), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::ConfigurablePresent)));
m_temporalZonedDateTimePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->toString), ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->toString, builtinTemporalZonedDateTimeToString, 0, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent)));
m_temporalZonedDateTimePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyEquals()), ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyEquals(), builtinTemporalZonedDateTimeEquals, 1, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent)));
{
AtomicString name(state.context(), "get calendarId");
JSGetterSetter gs(
new NativeFunctionObject(state, NativeFunctionInfo(name, builtinTemporalZonedDateTimeCalendarId, 0, NativeFunctionInfo::Strict)),
Value(Value::EmptyValue));
ObjectPropertyDescriptor desc(gs, ObjectPropertyDescriptor::ConfigurablePresent);
m_temporalZonedDateTimePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyCalendarId()), desc);
}
{
AtomicString name(state.context(), "get monthCode");
JSGetterSetter gs(
new NativeFunctionObject(state, NativeFunctionInfo(name, builtinTemporalZonedDateTimeMonthCode, 0, NativeFunctionInfo::Strict)),
Value(Value::EmptyValue));
ObjectPropertyDescriptor desc(gs, ObjectPropertyDescriptor::ConfigurablePresent);
m_temporalZonedDateTimePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyMonthCode()), desc);
}
{
AtomicString name(state.context(), "get timeZoneId");
JSGetterSetter gs(
new NativeFunctionObject(state, NativeFunctionInfo(name, builtinTemporalZonedDateTimeTimeZoneId, 0, NativeFunctionInfo::Strict)),
Value(Value::EmptyValue));
ObjectPropertyDescriptor desc(gs, ObjectPropertyDescriptor::ConfigurablePresent);
m_temporalZonedDateTimePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyTimeZoneId()), desc);
}
{
AtomicString name(state.context(), "get offset");
JSGetterSetter gs(
new NativeFunctionObject(state, NativeFunctionInfo(name, builtinTemporalZonedDateTimeOffset, 0, NativeFunctionInfo::Strict)),
Value(Value::EmptyValue));
ObjectPropertyDescriptor desc(gs, ObjectPropertyDescriptor::ConfigurablePresent);
m_temporalZonedDateTimePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyOffset()), desc);
}
{
AtomicString name(state.context(), "get offsetNanoseconds");
JSGetterSetter gs(
new NativeFunctionObject(state, NativeFunctionInfo(name, builtinTemporalZonedDateTimeOffsetNanoseconds, 0, NativeFunctionInfo::Strict)),
Value(Value::EmptyValue));
ObjectPropertyDescriptor desc(gs, ObjectPropertyDescriptor::ConfigurablePresent);
m_temporalZonedDateTimePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyOffsetNanoseconds()), desc);
}
{
AtomicString name = state.context()->staticStrings().lazyGetEpochNanoseconds();
JSGetterSetter gs(
new NativeFunctionObject(state, NativeFunctionInfo(name, builtinTemporalZonedDateTimeEpochNanoseconds, 0, NativeFunctionInfo::Strict)),
Value(Value::EmptyValue));
ObjectPropertyDescriptor desc(gs, ObjectPropertyDescriptor::ConfigurablePresent);
m_temporalZonedDateTimePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyEpochNanoseconds()), desc);
}
{
AtomicString name = state.context()->staticStrings().lazyGetEpochMilliseconds();
JSGetterSetter gs(
new NativeFunctionObject(state, NativeFunctionInfo(name, builtinTemporalZonedDateTimeEpochMilliseconds, 0, NativeFunctionInfo::Strict)),
Value(Value::EmptyValue));
ObjectPropertyDescriptor desc(gs, ObjectPropertyDescriptor::ConfigurablePresent);
m_temporalZonedDateTimePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyEpochMilliseconds()), desc);
}
{
AtomicString name(state.context(), "get hoursInDay");
JSGetterSetter gs(
new NativeFunctionObject(state, NativeFunctionInfo(name, builtinTemporalZonedDateTimeHoursInDay, 0, NativeFunctionInfo::Strict)),
Value(Value::EmptyValue));
ObjectPropertyDescriptor desc(gs, ObjectPropertyDescriptor::ConfigurablePresent);
m_temporalZonedDateTimePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyHoursInDay()), desc);
}
#define DEFINE_ZONEDDATETIME_PROTOTYPE_GETTER_PROPERTY(name, stringName, Name) \
{ \
AtomicString name(state.context(), "get " stringName); \
auto getter = new NativeFunctionObject(state, NativeFunctionInfo(name, [](ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional<Object*> newTarget) -> Value { \
if (!thisValue.isObject() || !thisValue.asObject()->isTemporalZonedDateTimeObject()) { \
ErrorObject::throwBuiltinError(state, ErrorCode::TypeError, state.context()->staticStrings().lazyCapitalZonedDateTime().string(), true, String::fromASCII(stringName), ErrorObject::Messages::GlobalObject_CalledOnIncompatibleReceiver); \
} \
TemporalZonedDateTimeObject* s = thisValue.asObject()->asTemporalZonedDateTimeObject(); \
return Value(s->plainDate().name()); }, 0, NativeFunctionInfo::Strict)); \
JSGetterSetter gs(getter, Value()); \
ObjectPropertyDescriptor desc(gs, ObjectPropertyDescriptor::ConfigurablePresent); \
m_temporalZonedDateTimePrototype->directDefineOwnProperty(state, ObjectPropertyName(state, strings->lazy##Name()), desc); \
}
#define DEFINE_GETTER(name, Name) DEFINE_ZONEDDATETIME_PROTOTYPE_GETTER_PROPERTY(name, #name, Name)
PLAIN_DATE_UNITS(DEFINE_GETTER)
#undef DEFINE_GETTER
#undef DEFINE_ZONEDDATETIME_PROTOTYPE_GETTER_PROPERTY
#define DEFINE_ZONEDDATETIME_PROTOTYPE_EXTRA_GETTER_PROPERTY(name, stringName, Name) \
{ \
AtomicString name(state.context(), "get " stringName); \
AtomicString pName(state.context(), stringName); \
auto getter = new NativeFunctionObject(state, NativeFunctionInfo(name, [](ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional<Object*> newTarget) -> Value { \
if (!thisValue.isObject() || !thisValue.asObject()->isTemporalZonedDateTimeObject()) { \
ErrorObject::throwBuiltinError(state, ErrorCode::TypeError, state.context()->staticStrings().lazyCapitalZonedDateTime().string(), true, String::fromASCII(stringName), ErrorObject::Messages::GlobalObject_CalledOnIncompatibleReceiver); \
} \
TemporalZonedDateTimeObject* s = thisValue.asObject()->asTemporalZonedDateTimeObject(); \
return Value(s->name(state)); }, 0, NativeFunctionInfo::Strict)); \
JSGetterSetter gs(getter, Value()); \
ObjectPropertyDescriptor desc(gs, ObjectPropertyDescriptor::ConfigurablePresent); \
m_temporalZonedDateTimePrototype->directDefineOwnProperty(state, ObjectPropertyName(state, strings->lazy##Name()), desc); \
}
#define DEFINE_GETTER(name, Name) DEFINE_ZONEDDATETIME_PROTOTYPE_EXTRA_GETTER_PROPERTY(name, #name, Name)
PLAINDATE_EXTRA_PROPERTY(DEFINE_GETTER)
#undef DEFINE_GETTER
#undef DEFINE_ZONEDDATE_PROTOTYPE_EXTRA_GETTER_PROPERTY
#define DEFINE_ZONEDDATETIME_PROTOTYPE_GETTER_PROPERTY(name, stringName, Name) \
{ \
AtomicString name(state.context(), "get " stringName); \
auto getter = new NativeFunctionObject(state, NativeFunctionInfo(name, [](ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional<Object*> newTarget) -> Value { \
if (!thisValue.isObject() || !thisValue.asObject()->isTemporalZonedDateTimeObject()) { \
ErrorObject::throwBuiltinError(state, ErrorCode::TypeError, state.context()->staticStrings().lazyCapitalZonedDateTime().string(), true, String::fromASCII(stringName), ErrorObject::Messages::GlobalObject_CalledOnIncompatibleReceiver); \
} \
TemporalZonedDateTimeObject* s = thisValue.asObject()->asTemporalZonedDateTimeObject(); \
return Value(s->plainTime().name()); }, 0, NativeFunctionInfo::Strict)); \
JSGetterSetter gs(getter, Value()); \
ObjectPropertyDescriptor desc(gs, ObjectPropertyDescriptor::ConfigurablePresent); \
m_temporalZonedDateTimePrototype->directDefineOwnProperty(state, ObjectPropertyName(state, strings->lazy##Name()), desc); \
}
#define DEFINE_GETTER(name, Name) DEFINE_ZONEDDATETIME_PROTOTYPE_GETTER_PROPERTY(name, #name, Name)
PLAIN_TIME_UNITS(DEFINE_GETTER)
#undef DEFINE_GETTER
#undef DEFINE_ZONEDDATETIME_PROTOTYPE_GETTER_PROPERTY
m_temporal = new Object(state);
m_temporal->setGlobalIntrinsicObject(state);

View file

@ -72,6 +72,17 @@ BigIntData::BigIntData(const uint64_t& d)
bf_set_ui(&m_data, d);
}
BigIntData::BigIntData(const Int128& d)
{
if (d < std::numeric_limits<Int128>::max() && d > std::numeric_limits<Int128>::min()) {
bf_init(ThreadLocal::bfContext(), &m_data);
bf_set_si(&m_data, int64_t(d));
} else {
auto s = std::to_string(d);
init(s.data(), s.length(), 10);
}
}
BigIntData::BigIntData(String* src, int radix)
{
const auto& bd = src->bufferAccessData();

View file

@ -35,6 +35,7 @@ public:
BigIntData(const uint64_t& d = 0);
BigIntData(const int64_t& d);
BigIntData(const double& d);
BigIntData(const Int128& d);
BigIntData(String* src, int radix = 10);
BigIntData(const char* buf, size_t length, int radix = 10);
BigIntData(BigIntData&& src);

View file

@ -990,6 +990,7 @@ namespace Escargot {
F(FromEpochNanoseconds, "fromEpochNanoseconds") \
F(GetEpochMilliseconds, "get epochMilliseconds") \
F(GetEpochNanoseconds, "get epochNanoseconds") \
F(HoursInDay, "hoursInDay") \
F(Ignore, "ignore") \
F(InLeapYear, "inLeapYear") \
F(Instant, "instant") \
@ -1000,6 +1001,7 @@ namespace Escargot {
F(MonthsInYear, "monthsInYear") \
F(Negated, "negated") \
F(Offset, "offset") \
F(OffsetNanoseconds, "offsetNanoseconds") \
F(Overflow, "overflow") \
F(Reject, "reject") \
F(PlainDateISO, "plainDateISO") \

View file

@ -339,12 +339,16 @@ TemporalInstantObject* Temporal::toTemporalInstant(ExecutionState& state, Value
// If item is an Object, then
if (item.isObject()) {
// If item has an [[InitializedTemporalInstant]] or [[InitializedTemporalZonedDateTime]] internal slot, then
// TODO [[InitializedTemporalZonedDateTime]]
if (item.asObject()->isTemporalInstantObject()) {
// Return ! CreateTemporalInstant(item.[[EpochNanoseconds]]).
return new TemporalInstantObject(state, state.context()->globalObject()->temporalInstantPrototype(),
item.asObject()->asTemporalInstantObject()->epochNanoseconds());
}
if (item.asObject()->isTemporalZonedDateTimeObject()) {
// Return ! CreateTemporalInstant(item.[[EpochNanoseconds]]).
return new TemporalInstantObject(state, state.context()->globalObject()->temporalInstantPrototype(),
item.asObject()->asTemporalZonedDateTimeObject()->epochNanoseconds());
}
// NOTE: This use of ToPrimitive allows Instant-like objects to be converted.
// Set item to ? ToPrimitive(item, string).
item = item.toPrimitive(state, Value::PrimitiveTypeHint::PreferString);
@ -388,8 +392,28 @@ TemporalPlainTimeObject* Temporal::toTemporalTime(ExecutionState& state, Value i
return new TemporalPlainTimeObject(state, state.context()->globalObject()->temporalPlainTimePrototype(),
item.asObject()->asTemporalPlainTimeObject()->plainTime());
}
// TODO If item has an [[InitializedTemporalZonedDateTime]] internal slot, then...
// TODO If item has an [[InitializedTemporalDateTime]] internal slot, then...
// If item has an [[InitializedTemporalDateTime]] internal slot, then
if (item.asObject()->isTemporalPlainDateTimeObject()) {
// Let resolvedOptions be ? GetOptionsObject(options).
auto resolvedOptions = Intl::getOptionsObject(state, options);
// Perform ? GetTemporalOverflowOption(resolvedOptions).
Temporal::getTemporalOverflowOption(state, resolvedOptions);
// Return ! CreateTemporalTime(item.[[ISODateTime]].[[Time]]).
return new TemporalPlainTimeObject(state, state.context()->globalObject()->temporalPlainTimePrototype(),
item.asObject()->asTemporalPlainDateTimeObject()->plainTime());
}
// If item has an [[InitializedTemporalZonedDateTime]] internal slot, then
if (item.asObject()->isTemporalZonedDateTimeObject()) {
// Let isoDateTime be GetISODateTimeFor(item.[[TimeZone]], item.[[EpochNanoseconds]]).
auto isoDateTime = getISODateTimeFor(state, item.asObject()->asTemporalZonedDateTimeObject()->timeZone().operator Escargot::TimeZone(), item.asObject()->asTemporalZonedDateTimeObject()->epochNanoseconds());
// Let resolvedOptions be ? GetOptionsObject(options).
auto resolvedOptions = Intl::getOptionsObject(state, options);
// Perform ? GetTemporalOverflowOption(resolvedOptions).
Temporal::getTemporalOverflowOption(state, resolvedOptions);
// Return ! CreateTemporalTime(isoDateTime.[[Time]]).
return new TemporalPlainTimeObject(state, state.context()->globalObject()->temporalPlainTimePrototype(),
isoDateTime.plainTime());
}
// Let result be ? ToTemporalTimeRecord(item).
auto resultRecord = TemporalPlainTimeObject::toTemporalTimeRecord(state, item, NullOption);
// Let resolvedOptions be ? GetOptionsObject(options).
@ -445,8 +469,29 @@ TemporalPlainDateObject* Temporal::toTemporalDate(ExecutionState& state, Value i
return new TemporalPlainDateObject(state, state.context()->globalObject()->temporalPlainDatePrototype(),
item.asObject()->asTemporalPlainDateObject()->plainDate(), item.asObject()->asTemporalPlainDateObject()->calendarID());
}
// TODO If item has an [[InitializedTemporalZonedDateTime]] internal slot, then...
// TODO If item has an [[InitializedTemporalDateTime]] internal slot, then...
// If item has an [[InitializedTemporalZonedDateTime]] internal slot, then
if (item.asObject()->isTemporalZonedDateTimeObject()) {
// Let isoDateTime be GetISODateTimeFor(item.[[TimeZone]], item.[[EpochNanoseconds]]).
auto isoDateTime = getISODateTimeFor(state, item.asObject()->asTemporalZonedDateTimeObject()->timeZone().operator Escargot::TimeZone(), item.asObject()->asTemporalZonedDateTimeObject()->epochNanoseconds());
// Let resolvedOptions be ? GetOptionsObject(options).
auto resolvedOptions = Intl::getOptionsObject(state, options);
// Perform ? GetTemporalOverflowOption(resolvedOptions).
Temporal::getTemporalOverflowOption(state, resolvedOptions);
// Return ! CreateTemporalDate(isoDateTime.[[ISODate]], item.[[Calendar]]).
return new TemporalPlainDateObject(state, state.context()->globalObject()->temporalPlainDatePrototype(),
isoDateTime.plainDate(), item.asObject()->asTemporalZonedDateTimeObject()->calendarID());
}
// If item has an [[InitializedTemporalDateTime]] internal slot, then
if (item.asObject()->isTemporalPlainDateTimeObject()) {
// Let resolvedOptions be ? GetOptionsObject(options).
auto resolvedOptions = Intl::getOptionsObject(state, options);
// Perform ? GetTemporalOverflowOption(resolvedOptions).
Temporal::getTemporalOverflowOption(state, resolvedOptions);
// Return ! CreateTemporalDate(isoDateTime.[[ISODate]], item.[[Calendar]]).
auto isoDate = item.asObject()->asTemporalPlainDateTimeObject()->computeISODate(state);
return new TemporalPlainDateObject(state, state.context()->globalObject()->temporalPlainDatePrototype(),
isoDate, item.asObject()->asTemporalPlainDateTimeObject()->calendarID());
}
// Let calendar be ? GetTemporalCalendarIdentifierWithISODefault(item).
auto calendar = Temporal::getTemporalCalendarIdentifierWithISODefault(state, item);
@ -523,12 +568,17 @@ TemporalPlainDateTimeObject* Temporal::toTemporalDateTime(ExecutionState& state,
item.asObject()->asTemporalPlainDateTimeObject()->plainTime(),
item.asObject()->asTemporalPlainDateTimeObject()->calendarID());
} else if (item.asObject()->isTemporalZonedDateTimeObject()) {
// TODO If item has an [[InitializedTemporalZonedDateTime]] internal slot, then
// If item has an [[InitializedTemporalZonedDateTime]] internal slot, then
// Let isoDateTime be GetISODateTimeFor(item.[[TimeZone]], item.[[EpochNanoseconds]]).
auto isoDateTime = getISODateTimeFor(state, item.asObject()->asTemporalZonedDateTimeObject()->timeZone().operator Escargot::TimeZone(), item.asObject()->asTemporalZonedDateTimeObject()->epochNanoseconds());
// Let resolvedOptions be ? GetOptionsObject(options).
auto resolvedOptions = Intl::getOptionsObject(state, options);
// Perform ? GetTemporalOverflowOption(resolvedOptions).
Temporal::getTemporalOverflowOption(state, resolvedOptions);
// Return ! CreateTemporalDateTime(isoDateTime, item.[[Calendar]]).
ASSERT_NOT_REACHED();
return new TemporalPlainDateTimeObject(state, state.context()->globalObject()->temporalPlainDateTimePrototype(),
isoDateTime.plainDate(), isoDateTime.plainTime(),
item.asObject()->asTemporalZonedDateTimeObject()->calendarID());
} else if (item.asObject()->isTemporalPlainDateObject()) {
// If item has an [[InitializedTemporalDate]] internal slot, then
// Let resolvedOptions be ? GetOptionsObject(options).
@ -817,10 +867,270 @@ TemporalPlainMonthDayObject* Temporal::toTemporalMonthDay(ExecutionState& state,
plainDate, mayID.value());
}
Int128 Temporal::getStartOfDay(ExecutionState& state, TimeZone timeZone, ISO8601::PlainDate isoDate)
{
int64_t offset;
if (timeZone.hasOffset()) {
offset = timeZone.offset();
} else {
offset = Temporal::computeTimeZoneOffset(state, timeZone.timeZoneName(),
ISO8601::ExactTime::fromPlainDate(isoDate).epochMilliseconds());
}
auto epoch = ISO8601::ExactTime::fromISOPartsAndOffset(isoDate.year(), isoDate.month(), isoDate.day(),
0, 0, 0, 0, 0, 0, offset)
.epochNanoseconds();
if (!ISO8601::isValidEpochNanoseconds(epoch)) {
ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, "Out of range date-time");
}
return epoch;
}
Int128 Temporal::interpretISODateTimeOffset(ExecutionState& state, ISO8601::PlainDate isoDate, Optional<ISO8601::PlainTime> time,
TemporalOffsetBehaviour offsetBehaviour, int64_t offsetNanoseconds, TimeZone timeZone, bool hasUTCDesignator, TemporalDisambiguationOption disambiguation,
TemporalOffsetOption offsetOption, TemporalMatchBehaviour matchBehaviour)
{
// If time is start-of-day, then
if (!time) {
// Return ? GetStartOfDay(timeZone, isoDate).
return getStartOfDay(state, timeZone, isoDate);
}
// Let isoDateTime be CombineISODateAndTimeRecord(isoDate, time).
auto isoDateTime = ISO8601::PlainDateTime(isoDate, time.value());
// If offsetBehaviour is wall, or offsetBehaviour is option and offsetOption is ignore, then
if ((offsetBehaviour == TemporalOffsetBehaviour::Wall || offsetBehaviour == TemporalOffsetBehaviour::Option) && offsetOption == TemporalOffsetOption::Ignore) {
// Return ? GetEpochNanosecondsFor(timeZone, isoDateTime, disambiguation).
return Temporal::getEpochNanosecondsFor(state, timeZone, ISO8601::ExactTime::fromPlainDateTime(isoDateTime).epochNanoseconds(), disambiguation);
}
// If offsetBehaviour is exact, or offsetBehaviour is option and offsetOption is use, then
if ((offsetBehaviour == TemporalOffsetBehaviour::Exact || offsetBehaviour == TemporalOffsetBehaviour::Option) && offsetOption == TemporalOffsetOption::Use) {
// TODO Let balanced be BalanceISODateTime(isoDate.[[Year]], isoDate.[[Month]], isoDate.[[Day]], time.[[Hour]], time.[[Minute]], time.[[Second]], time.[[Millisecond]], time.[[Microsecond]], time.[[Nanosecond]] - offsetNanoseconds).
// TODO Perform ? CheckISODaysRange(balanced.[[ISODate]]).
// TODO Let epochNanoseconds be GetUTCEpochNanoseconds(balanced).
// TODO If IsValidEpochNanoseconds(epochNanoseconds) is false, throw a RangeError exception.
// Return epochNanoseconds.
return ISO8601::ExactTime::fromPlainDateTime(isoDateTime).epochNanoseconds() + offsetNanoseconds;
}
// TODO
// Assert: offsetBehaviour is option.
// Assert: offsetOption is prefer or reject.
// Perform ? CheckISODaysRange(isoDate).
// Let utcEpochNanoseconds be GetUTCEpochNanoseconds(isoDateTime).
// Let possibleEpochNs be ? GetPossibleEpochNanoseconds(timeZone, isoDateTime).
// For each element candidate of possibleEpochNs, do
// Let candidateOffset be utcEpochNanoseconds - candidate.
// If candidateOffset = offsetNanoseconds, then
// Return candidate.
// If matchBehaviour is match-minutes, then
// Let roundedCandidateNanoseconds be RoundNumberToIncrement(candidateOffset, 60 × 10**9, half-expand).
// If roundedCandidateNanoseconds = offsetNanoseconds, then
// Return candidate.
// If offsetOption is reject, throw a RangeError exception.
// Return ? DisambiguatePossibleEpochNanoseconds(possibleEpochNs, timeZone, isoDateTime, disambiguation).
Optional<int64_t> timeZoneOffsetNanoseconds;
if (timeZone.hasOffset()) {
timeZoneOffsetNanoseconds = timeZone.offset();
} else if (timeZone.hasTimeZoneName()) {
timeZoneOffsetNanoseconds = -Temporal::computeTimeZoneOffset(state, timeZone.timeZoneName(), ISO8601::ExactTime::fromPlainDateTime(isoDateTime).epochMilliseconds());
}
if (offsetOption == TemporalOffsetOption::Reject) {
if (offsetNanoseconds && timeZoneOffsetNanoseconds && offsetNanoseconds != timeZoneOffsetNanoseconds.value()) {
ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, "Invalid offset value");
} else if (offsetNanoseconds && timeZoneOffsetNanoseconds && offsetNanoseconds == timeZoneOffsetNanoseconds.value()) {
offsetNanoseconds = 0;
}
}
if (hasUTCDesignator) {
return ISO8601::ExactTime::fromPlainDateTime(isoDateTime).epochNanoseconds();
}
return ISO8601::ExactTime::fromPlainDateTime(isoDateTime).epochNanoseconds() - timeZoneOffsetNanoseconds.valueOr(0);
}
TemporalZonedDateTimeObject* Temporal::toTemporalZonedDateTime(ExecutionState& state, Value item, Value options)
{
RELEASE_ASSERT_NOT_REACHED();
return nullptr;
// If options is not present, set options to undefined.
// Let hasUTCDesignator be false.
bool hasUTCDesignator = false;
// Let matchBehaviour be match-exactly.
TemporalMatchBehaviour matchBehaviour = TemporalMatchBehaviour::MatchExactly;
ISO8601::PlainDate isoDate;
Optional<ISO8601::PlainTime> time;
Optional<String*> offsetString;
Optional<TimeZone> timeZone;
Calendar calendar;
TemporalDisambiguationOption disambiguation = TemporalDisambiguationOption::Compatible;
TemporalOffsetOption offsetOption = TemporalOffsetOption::Ignore;
TemporalOffsetBehaviour offsetBehaviour = TemporalOffsetBehaviour::Exact;
// If item is an Object, then
if (item.isObject()) {
// If item has an [[InitializedTemporalZonedDateTime]] internal slot, then
if (item.asObject()->isTemporalZonedDateTimeObject()) {
// NOTE: The following steps, and similar ones below, read options and perform independent validation in alphabetical order (GetTemporalDisambiguationOption reads "disambiguation", GetTemporalOffsetOption reads "offset", and GetTemporalOverflowOption reads "overflow").
// Let resolvedOptions be ? GetOptionsObject(options).
auto resolvedOptions = Intl::getOptionsObject(state, options);
// Perform ? GetTemporalDisambiguationOption(resolvedOptions).
Temporal::getTemporalDisambiguationOption(state, resolvedOptions);
// Perform ? GetTemporalOffsetOption(resolvedOptions, reject).
Temporal::getTemporalOffsetOption(state, resolvedOptions, TemporalOffsetOption::Reject);
// Perform ? GetTemporalOverflowOption(resolvedOptions).
Temporal::getTemporalOverflowOption(state, resolvedOptions);
// Return ! CreateTemporalZonedDateTime(item.[[EpochNanoseconds]], item.[[TimeZone]], item.[[Calendar]]).
return new TemporalZonedDateTimeObject(state, state.context()->globalObject()->temporalZonedDateTimePrototype(),
item.asObject()->asTemporalZonedDateTimeObject()->epochNanoseconds(),
item.asObject()->asTemporalZonedDateTimeObject()->timeZone(), item.asObject()->asTemporalZonedDateTimeObject()->calendarID());
}
// Let calendar be ? GetTemporalCalendarIdentifierWithISODefault(item).
calendar = Temporal::getTemporalCalendarIdentifierWithISODefault(state, item);
// Let fields be ? PrepareCalendarFields(calendar, item, « year, month, month-code, day », « hour, minute, second, millisecond, microsecond, nanosecond, offset, time-zone », « time-zone »).
CalendarField d[4] = { CalendarField::Year, CalendarField::Month, CalendarField::MonthCode, CalendarField::Day };
CalendarField t[8] = { CalendarField::Hour, CalendarField::Minute, CalendarField::Second, CalendarField::Millisecond,
CalendarField::Microsecond, CalendarField::Nanosecond, CalendarField::Offset, CalendarField::TimeZone };
CalendarField r[1] = { CalendarField::TimeZone };
auto fields = prepareCalendarFields(state, calendar, item.asObject(), d, 4, t, 8, r, 1);
// Let timeZone be fields.[[TimeZone]].
timeZone = fields.timeZone;
// Let offsetString be fields.[[OffsetString]].
offsetString = fields.offset;
// Let resolvedOptions be ? GetOptionsObject(options).
auto resolvedOptions = Intl::getOptionsObject(state, options);
// Let disambiguation be ? GetTemporalDisambiguationOption(resolvedOptions).
disambiguation = Temporal::getTemporalDisambiguationOption(state, resolvedOptions);
// Let offsetOption be ? GetTemporalOffsetOption(resolvedOptions, reject).
offsetOption = Temporal::getTemporalOffsetOption(state, resolvedOptions, TemporalOffsetOption::Reject);
// Let overflow be ? GetTemporalOverflowOption(resolvedOptions).
auto overflow = Temporal::getTemporalOverflowOption(state, resolvedOptions);
// Let result be ? InterpretTemporalDateTimeFields(calendar, fields, overflow).
auto result = Temporal::interpretTemporalDateTimeFields(state, calendar, fields, overflow);
// Let isoDate be result.[[ISODate]].
isoDate = result.plainDate();
// Let time be result.[[Time]].
time = result.plainTime();
} else {
// Else,
// If item is not a String, throw a TypeError exception.
constexpr auto msg = "The value you gave for ToTemporalZonedDateTime is invalid";
if (!item.isString()) {
ErrorObject::throwBuiltinError(state, ErrorCode::TypeError, msg);
}
// Let result be ? ParseISODateTime(item, « TemporalDateTimeString[+Zoned] »).
ISO8601::DateTimeParseOption option;
option.allowTimeZoneTimeWithoutTime = true;
auto result = ISO8601::parseCalendarDateTime(item.asString(), option);
if (!result || !std::get<2>(result.value())) {
ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, msg);
}
auto unwrappedResult = result.value();
// Let annotation be result.[[TimeZone]].[[TimeZoneAnnotation]].
// Assert: annotation is not empty.
// Let timeZone be ? ToTemporalTimeZoneIdentifier(annotation).
ISO8601::TimeZoneRecord tr = std::get<2>(result.value()).value();
// Let offsetString be result.[[TimeZone]].[[OffsetString]].
if (tr.m_offset) {
StringBuilder sb;
Temporal::formatOffsetTimeZoneIdentifier(state, (int)(tr.m_offset.value() / ISO8601::ExactTime::nsPerMinute), sb);
offsetString = sb.finalize();
}
// If result.[[TimeZone]].[[Z]] is true, then
if (tr.m_z) {
// Set hasUTCDesignator to true.
hasUTCDesignator = true;
}
if (tr.m_z) {
if (tr.m_nameOrOffset && tr.m_nameOrOffset.id().value() == 0) {
timeZone = TimeZone(tr.m_nameOrOffset.get<0>());
} else if (tr.m_nameOrOffset && tr.m_nameOrOffset.id().value() == 1) {
timeZone = TimeZone(tr.m_nameOrOffset.get<1>());
} else if (tr.m_offset) {
timeZone = TimeZone(int64_t(0));
} else {
ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, msg);
}
if (!std::get<1>(unwrappedResult)) {
ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, msg);
}
} else if (tr.m_nameOrOffset && tr.m_nameOrOffset.id().value() == 0) {
if (!std::get<1>(unwrappedResult)) {
ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, msg);
}
timeZone = TimeZone(tr.m_nameOrOffset.get<0>());
} else if (tr.m_nameOrOffset && tr.m_nameOrOffset.id().value() == 1) {
timeZone = TimeZone(tr.m_nameOrOffset.get<1>());
} else {
ASSERT(tr.m_offset);
ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, msg);
}
// Let calendar be result.[[Calendar]].
// If calendar is empty, set calendar to "iso8601".
// Set calendar to ? CanonicalizeCalendar(calendar).
if (std::get<3>(unwrappedResult)) {
auto mayCalendar = Calendar::fromString(std::get<3>(unwrappedResult).value());
if (!mayCalendar) {
ErrorObject::throwBuiltinError(state, ErrorCode::TypeError, msg);
}
calendar = mayCalendar.value();
}
// Set matchBehaviour to match-minutes.
matchBehaviour = TemporalMatchBehaviour::MatchMinutes;
// If offsetString is not empty, then
if (offsetString) {
// Let offsetParseResult be ParseText(StringToCodePoints(offsetString), UTCOffset[+SubMinutePrecision]).
// Assert: offsetParseResult is a Parse Node.
// If offsetParseResult contains more than one MinuteSecond Parse Node, set matchBehaviour to match-exactly.
if (tr.m_offset.value() % ISO8601::ExactTime::nsPerHour) {
matchBehaviour = TemporalMatchBehaviour::MatchExactly;
}
}
// Let resolvedOptions be ? GetOptionsObject(options).
auto resolvedOptions = Intl::getOptionsObject(state, options);
// Let disambiguation be ? GetTemporalDisambiguationOption(resolvedOptions).
disambiguation = Temporal::getTemporalDisambiguationOption(state, resolvedOptions);
// Let offsetOption be ? GetTemporalOffsetOption(resolvedOptions, reject).
offsetOption = Temporal::getTemporalOffsetOption(state, resolvedOptions, TemporalOffsetOption::Reject);
// Perform ? GetTemporalOverflowOption(resolvedOptions).
Temporal::getTemporalOverflowOption(state, resolvedOptions);
// Let isoDate be CreateISODateRecord(result.[[Year]], result.[[Month]], result.[[Day]]).
isoDate = std::get<0>(unwrappedResult);
// Let time be result.[[Time]].
time = std::get<1>(unwrappedResult);
}
// If hasUTCDesignator is true, then
if (hasUTCDesignator) {
// Let offsetBehaviour be exact.
offsetBehaviour = TemporalOffsetBehaviour::Exact;
} else if (!offsetString || offsetString.value()->length() == 0) {
// Else if offsetString is empty or offsetString is unset, then
// Let offsetBehaviour be wall.
offsetBehaviour = TemporalOffsetBehaviour::Wall;
} else {
// Else,
// Let offsetBehaviour be option.
offsetBehaviour = TemporalOffsetBehaviour::Option;
}
// Let offsetNanoseconds be 0.
int64_t offsetNanoseconds = 0;
// If offsetBehaviour is option, then
if (offsetBehaviour == TemporalOffsetBehaviour::Option) {
// Set offsetNanoseconds to ! ParseDateTimeUTCOffset(offsetString).
offsetNanoseconds = ISO8601::parseUTCOffset(offsetString.value(), ISO8601::DateTimeParseOption{}).value();
}
// Let epochNanoseconds be ? InterpretISODateTimeOffset(isoDate, time, offsetBehaviour, offsetNanoseconds, timeZone, disambiguation, offsetOption, matchBehaviour).
auto epochNanoseconds = interpretISODateTimeOffset(state, isoDate, time, offsetBehaviour, offsetNanoseconds, timeZone.value(), hasUTCDesignator, disambiguation, offsetOption, matchBehaviour);
// 12. Return ! CreateTemporalZonedDateTime(epochNanoseconds, timeZone, calendar).
return new TemporalZonedDateTimeObject(state, state.context()->globalObject()->temporalZonedDateTimePrototype(),
epochNanoseconds, timeZone.value(), calendar);
}
ISO8601::PlainTime Temporal::toTimeRecordOrMidnight(ExecutionState& state, Value item)
@ -1076,7 +1386,7 @@ TemporalOffsetOption Temporal::getTemporalOffsetOption(ExecutionState& state, Op
// Let stringValue be ? GetOption(options, "offset", string, « "prefer", "use", "ignore", "reject" », stringFallback).
Value values[4] = { state.context()->staticStrings().lazyPrefer().string(), state.context()->staticStrings().use.string(),
state.context()->staticStrings().lazyIgnore().string(), state.context()->staticStrings().reject.string() };
auto stringValue = Intl::getOption(state, options.value(), state.context()->staticStrings().lazyDisambiguation().string(), Intl::StringValue,
auto stringValue = Intl::getOption(state, options.value(), state.context()->staticStrings().lazyOffset().string(), Intl::StringValue,
values, 4, stringFallback)
.asString();
// If stringValue is "prefer", return prefer.
@ -1155,7 +1465,7 @@ TimeZone Temporal::parseTimeZone(ExecutionState& state, String* input)
if (complexTimeZone && std::get<2>(complexTimeZone.value())) {
ISO8601::TimeZoneRecord record = std::get<2>(complexTimeZone.value()).value();
if (record.m_z) {
return TimeZone(int64_t(0));
return TimeZone(state.context()->staticStrings().UTC.string());
} else if (record.m_nameOrOffset && record.m_nameOrOffset.id().value() == 0) {
return TimeZone(record.m_nameOrOffset.get<0>());
} else if (record.m_nameOrOffset && record.m_nameOrOffset.id().value() == 1) {
@ -1171,9 +1481,14 @@ TimeZone Temporal::parseTimeZone(ExecutionState& state, String* input)
TimeZone Temporal::toTemporalTimezoneIdentifier(ExecutionState& state, const Value& temporalTimeZoneLike)
{
// TODO If temporalTimeZoneLike is an Object, then
// TODO If temporalTimeZoneLike has an [[InitializedTemporalZonedDateTime]] internal slot, then
// TODO Return temporalTimeZoneLike.[[TimeZone]].
// If temporalTimeZoneLike is an Object, then
if (temporalTimeZoneLike.isObject()) {
// If temporalTimeZoneLike has an [[InitializedTemporalZonedDateTime]] internal slot, then
if (temporalTimeZoneLike.asObject()->isTemporalZonedDateTimeObject()) {
// Return temporalTimeZoneLike.[[TimeZone]].
return TimeZone(temporalTimeZoneLike.asObject()->asTemporalZonedDateTimeObject()->timeZone().timeZoneName());
}
}
// If temporalTimeZoneLike is not a String, throw a TypeError exception.
if (!temporalTimeZoneLike.isString()) {
@ -1669,13 +1984,20 @@ Calendar Temporal::getTemporalCalendarIdentifierWithISODefault(ExecutionState& s
Calendar Temporal::toTemporalCalendarIdentifier(ExecutionState& state, Value temporalCalendarLike)
{
// TODO [[InitializedTemporalDateTime]], [[InitializedTemporalMonthDay]], [[InitializedTemporalYearMonth]], or [[InitializedTemporalZonedDateTime]]
// If temporalCalendarLike is an Object, then
// If temporalCalendarLike has an [[InitializedTemporalDate]], [[InitializedTemporalDateTime]], [[InitializedTemporalMonthDay]], [[InitializedTemporalYearMonth]], or [[InitializedTemporalZonedDateTime]] internal slot, then
// Return temporalCalendarLike.[[Calendar]].
if (temporalCalendarLike.isObject()) {
if (temporalCalendarLike.asObject()->isTemporalPlainDateObject()) {
return temporalCalendarLike.asObject()->asTemporalPlainDateObject()->calendarID();
} else if (temporalCalendarLike.asObject()->isTemporalPlainDateTimeObject()) {
return temporalCalendarLike.asObject()->asTemporalPlainDateTimeObject()->calendarID();
} else if (temporalCalendarLike.asObject()->isTemporalPlainMonthDayObject()) {
return temporalCalendarLike.asObject()->asTemporalPlainMonthDayObject()->calendarID();
} else if (temporalCalendarLike.asObject()->isTemporalPlainYearMonthObject()) {
return temporalCalendarLike.asObject()->asTemporalPlainYearMonthObject()->calendarID();
} else if (temporalCalendarLike.asObject()->isTemporalZonedDateTimeObject()) {
return temporalCalendarLike.asObject()->asTemporalZonedDateTimeObject()->calendarID();
}
}
@ -1850,9 +2172,24 @@ void CalendarFieldsRecord::setValue(ExecutionState& state, CalendarField f, Valu
microsecond = value.toIntegerWithTruncation(state);
} else if (f == CalendarField::Nanosecond) {
nanosecond = value.toIntegerWithTruncation(state);
} else if (f == CalendarField::Offset) {
// to-offset-string
// Let offset be ? ToPrimitive(argument, string).
auto offset = value.toPrimitive(state, Value::PreferString);
// If offset is not a String, throw a TypeError exception.
if (!offset.isString()) {
ErrorObject::throwBuiltinError(state, ErrorCode::TypeError, "Invalid offset value");
}
// Perform ? ParseDateTimeUTCOffset(offset).
auto p = ISO8601::parseUTCOffset(offset.asString(), ISO8601::DateTimeParseOption{});
if (!p) {
ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, "Invalid offset value");
}
// Return offset.
this->offset = offset.asString();
} else {
// TODO
ASSERT_NOT_REACHED();
ASSERT(f == CalendarField::TimeZone);
timeZone = Temporal::toTemporalTimezoneIdentifier(state, value);
}
}
@ -1907,7 +2244,7 @@ CalendarFieldsRecord Temporal::prepareCalendarFields(ExecutionState& state, Cale
ErrorObject::throwBuiltinError(state, ErrorCode::TypeError, "Missing required field");
}
}
// TODO Set result's field whose name is given in the Field Name column of the same row to the corresponding Default value of the same row.
// Set result's field whose name is given in the Field Name column of the same row to the corresponding Default value of the same row.
}
}
@ -2612,7 +2949,7 @@ Int128 Temporal::getEpochNanosecondsFor(ExecutionState& state, Optional<TimeZone
{
const auto& date = isoDateTime.plainDate();
const auto& time = isoDateTime.plainTime();
auto epochNanoValue = ISO8601::ExactTime::fromISOPartsAndOffset(date.year(), date.month(), date.day(), time.hour(), time.minute(), time.second(), time.millisecond(), time.microsecond(), time.nanosecond(), 0).epochNanoseconds();
auto epochNanoValue = ISO8601::ExactTime::fromPlainDateTime(isoDateTime).epochNanoseconds();
return getEpochNanosecondsFor(state, timeZone, epochNanoValue, disambiguation);
}
@ -2623,12 +2960,12 @@ Int128 Temporal::getEpochNanosecondsFor(ExecutionState& state, Optional<TimeZone
}
if (timeZone.hasValue()) {
if (timeZone.value().hasOffset()) {
return epochNanoValue + timeZone.value().offset();
return epochNanoValue - timeZone.value().offset();
}
}
// TODO https://tc39.es/proposal-temporal/#sec-temporal-disambiguatepossibleepochnanoseconds
auto offset = computeTimeZoneOffset(state, timeZone.value().timeZoneName(), ISO8601::ExactTime(epochNanoValue).epochMilliseconds());
return epochNanoValue + Int128(offset) * 1000000;
return epochNanoValue - Int128(offset) * 1000000;
}
// https://tc39.es/proposal-temporal/#sec-applyunsignedroundingmode
@ -2936,15 +3273,9 @@ ISO8601::InternalDuration Temporal::differencePlainDateTimeWithRounding(Executio
return diff;
}
// Let originEpochNs be GetUTCEpochNanoseconds(isoDateTime1).
auto originEpochNs = ISO8601::ExactTime::fromISOPartsAndOffset(isoDateTime1.plainDate().year(), isoDateTime1.plainDate().month(), isoDateTime1.plainDate().day(),
isoDateTime1.plainTime().hour(), isoDateTime1.plainTime().minute(), isoDateTime1.plainTime().second(), isoDateTime1.plainTime().millisecond(), isoDateTime1.plainTime().microsecond(),
isoDateTime1.plainTime().nanosecond(), 0)
.epochNanoseconds();
auto originEpochNs = ISO8601::ExactTime::fromPlainDateTime(isoDateTime1).epochNanoseconds();
// Let destEpochNs be GetUTCEpochNanoseconds(isoDateTime2).
auto destEpochNs = ISO8601::ExactTime::fromISOPartsAndOffset(isoDateTime2.plainDate().year(), isoDateTime2.plainDate().month(), isoDateTime2.plainDate().day(),
isoDateTime2.plainTime().hour(), isoDateTime2.plainTime().minute(), isoDateTime2.plainTime().second(), isoDateTime2.plainTime().millisecond(), isoDateTime2.plainTime().microsecond(),
isoDateTime2.plainTime().nanosecond(), 0)
.epochNanoseconds();
auto destEpochNs = ISO8601::ExactTime::fromPlainDateTime(isoDateTime2).epochNanoseconds();
// Return ? RoundRelativeDuration(diff, originEpochNs, destEpochNs, isoDateTime1, unset, calendar, largestUnit, roundingIncrement, smallestUnit, roundingMode).
return roundRelativeDuration(state, diff, destEpochNs, isoDateTime1, NullOption, calendar, toTemporalUnit(largestUnit), roundingIncrement, toTemporalUnit(smallestUnit), roundingMode);
}
@ -3046,6 +3377,27 @@ void Temporal::formatOffsetTimeZoneIdentifier(ExecutionState& state, int offsetM
}
}
ISO8601::PlainDateTime Temporal::getISODateTimeFor(ExecutionState& state, Optional<TimeZone> timeZone, Int128 epochNs)
{
// Let offsetNanoseconds be GetOffsetNanosecondsFor(timeZone, epochNs).
// Let result be GetISOPartsFromEpoch((epochNs)).
// 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).
int64_t offsetNanoseconds = 0;
if (timeZone && timeZone.value().hasOffset()) {
offsetNanoseconds = timeZone.value().offset();
} else if (timeZone && timeZone.value().hasTimeZoneName()) {
offsetNanoseconds = Temporal::computeTimeZoneOffset(state, timeZone.value().timeZoneName(), ISO8601::ExactTime(epochNs).epochMilliseconds());
offsetNanoseconds *= 1000000;
}
epochNs += offsetNanoseconds;
DateObject::DateTimeInfo timeInfo;
DateObject::computeTimeInfoFromEpoch(ISO8601::ExactTime(epochNs).epochMilliseconds(), timeInfo);
auto d = Temporal::balanceTime(0, 0, 0, 0, 0, epochNs % ISO8601::ExactTime::nsPerDay);
return ISO8601::PlainDateTime(ISO8601::PlainDate(timeInfo.year, timeInfo.month + 1, timeInfo.mday),
ISO8601::PlainTime(d.hours(), d.minutes(), d.seconds(), d.milliseconds(), d.microseconds(), d.nanoseconds()));
}
} // namespace Escargot
#endif

View file

@ -191,7 +191,7 @@ struct MonthCode {
F(microsecond, Microsecond, Optional<unsigned>) \
F(nanosecond, Nanosecond, Optional<unsigned>) \
F(offset, Offset, Optional<String*>) \
F(timeZone, TimeZone, Optional<String*>)
F(timeZone, TimeZone, Optional<TimeZone>)
enum class CalendarField {
#define DEFINE_FIELD(name, Name, type) Name,
@ -244,6 +244,17 @@ enum class TemporalOffsetOption : uint8_t {
Reject,
};
enum class TemporalOffsetBehaviour : uint8_t {
Exact,
Wall,
Option
};
enum class TemporalMatchBehaviour : uint8_t {
MatchExactly,
MatchMinutes
};
class Temporal {
public:
static ISO8601::PlainDate computeISODate(ExecutionState& state, UCalendar* ucal);
@ -397,6 +408,14 @@ public:
// https://tc39.es/proposal-temporal/#sec-temporal-interprettemporaldatetimefields
static ISO8601::PlainDateTime interpretTemporalDateTimeFields(ExecutionState& state, Calendar calendar, const CalendarFieldsRecord& fields, TemporalOverflowOption overflow);
// https://tc39.es/proposal-temporal/#sec-temporal-interpretisodatetimeoffset
static Int128 interpretISODateTimeOffset(ExecutionState& state, ISO8601::PlainDate isoDate, Optional<ISO8601::PlainTime> time,
TemporalOffsetBehaviour offsetBehaviour, int64_t offsetNanoseconds, TimeZone timeZone, bool hasUTCDesignator, TemporalDisambiguationOption disambiguation,
TemporalOffsetOption offsetOption, TemporalMatchBehaviour matchBehaviour);
// https://tc39.es/proposal-temporal/#sec-temporal-getstartofday
static Int128 getStartOfDay(ExecutionState& state, TimeZone timeZone, ISO8601::PlainDate isoDate);
// https://tc39.es/proposal-temporal/#sec-temporal-gettemporalshowcalendarnameoption
static TemporalShowCalendarNameOption getTemporalShowCalendarNameOption(ExecutionState& state, Optional<Object*> options);
@ -447,6 +466,9 @@ public:
// https://tc39.es/proposal-temporal/#sec-temporal-formatoffsettimezoneidentifier
static void formatOffsetTimeZoneIdentifier(ExecutionState& state, int offsetMinutes, StringBuilder& sb, bool isSeparated = true);
// https://tc39.es/proposal-temporal/#sec-temporal-getisodatetimefor
static ISO8601::PlainDateTime getISODateTimeFor(ExecutionState& state, Optional<TimeZone> timeZone, Int128 epochNs);
};
} // namespace Escargot

View file

@ -45,7 +45,7 @@ TemporalPlainDateObject::TemporalPlainDateObject(ExecutionState& state, Object*
m_icuCalendar = calendar.createICUCalendar(state);
UErrorCode status = U_ZERO_ERROR;
ucal_setMillis(m_icuCalendar, ISO8601::ExactTime::fromISOPartsAndOffset(plainDate.year(), plainDate.month(), plainDate.day(), 0, 0, 0, 0, 0, 0, 0).epochMilliseconds(), &status);
ucal_setMillis(m_icuCalendar, ISO8601::ExactTime::fromPlainDate(plainDate).epochMilliseconds(), &status);
CHECK_ICU()
addFinalizer([](PointerValue* obj, void* data) {
@ -569,7 +569,7 @@ ISO8601::Duration TemporalPlainDateObject::differenceTemporalPlainDate(Execution
// Let isoDateTimeOther be CombineISODateAndTimeRecord(other.[[ISODate]], MidnightTimeRecord()).
auto isoDateTimeOther = other->computeISODate(state);
// Let destEpochNs be GetUTCEpochNanoseconds(isoDateTimeOther).
auto destEpochNs = ISO8601::ExactTime::fromISOPartsAndOffset(isoDateTimeOther.year(), isoDateTimeOther.month(), isoDateTimeOther.day(), 0, 0, 0, 0, 0, 0, 0).epochNanoseconds();
auto destEpochNs = ISO8601::ExactTime::fromPlainDate(isoDateTimeOther).epochNanoseconds();
duration = Temporal::roundRelativeDuration(state, duration, destEpochNs, ISO8601::PlainDateTime(isoDateTime, ISO8601::PlainTime()), NullOption, calendarID(), toTemporalUnit(settings.largestUnit), settings.roundingIncrement, toTemporalUnit(settings.smallestUnit), settings.roundingMode);
}

View file

@ -70,7 +70,7 @@ TemporalPlainDateTimeObject::TemporalPlainDateTimeObject(ExecutionState& state,
m_icuCalendar = calendar.createICUCalendar(state);
UErrorCode status = U_ZERO_ERROR;
ucal_setMillis(m_icuCalendar, ISO8601::ExactTime::fromISOPartsAndOffset(plainDate.year(), plainDate.month(), plainDate.day(), plainTime.hour(), plainTime.minute(), plainTime.second(), plainTime.millisecond(), plainTime.microsecond(), plainTime.microsecond(), 0).epochMilliseconds(), &status);
ucal_setMillis(m_icuCalendar, ISO8601::ExactTime::fromPlainDateTime(ISO8601::PlainDateTime(plainDate, plainTime)).epochMilliseconds(), &status);
CHECK_ICU()
addFinalizer([](PointerValue* obj, void* data) {

View file

@ -318,7 +318,7 @@ ISO8601::Duration TemporalPlainYearMonthObject::differenceTemporalPlainYearMonth
// Let isoDateTimeOther be CombineISODateAndTimeRecord(otherDate, MidnightTimeRecord()).
auto isoDateTimeOther = other->computeISODate(state);
// Let destEpochNs be GetUTCEpochNanoseconds(isoDateTimeOther).
auto destEpochNs = ISO8601::ExactTime::fromISOPartsAndOffset(isoDateTimeOther.year(), isoDateTimeOther.month(), isoDateTimeOther.day(), 0, 0, 0, 0, 0, 0, 0).epochNanoseconds();
auto destEpochNs = ISO8601::ExactTime::fromPlainDate(isoDateTimeOther).epochNanoseconds();
// Set duration to ? RoundRelativeDuration(duration, destEpochNs, isoDateTime, unset, calendar, settings.[[LargestUnit]], settings.[[RoundingIncrement]], settings.[[SmallestUnit]], settings.[[RoundingMode]]).
duration = Temporal::roundRelativeDuration(state, duration, destEpochNs, ISO8601::PlainDateTime(isoDateTime, ISO8601::PlainTime()), NullOption, calendar, toTemporalUnit(settings.largestUnit), settings.roundingIncrement, toTemporalUnit(settings.smallestUnit), settings.roundingMode);
}

View file

@ -33,6 +33,31 @@ namespace Escargot {
ErrorObject::throwBuiltinError(state, ErrorCode::TypeError, "failed to get value from ICU calendar"); \
}
// https://tc39.es/proposal-temporal/#sec-temporal-timezoneequals
static bool timeZoneEquals(const TemporalZonedDateTimeObject::ComputedTimeZone& one, const TemporalZonedDateTimeObject::ComputedTimeZone& two)
{
// If one is two, return true.
if (one.equals(two)) {
return true;
}
// Let offsetMinutesOne be ! ParseTimeZoneIdentifier(one).[[OffsetMinutes]].
// Let offsetMinutesTwo be ! ParseTimeZoneIdentifier(two).[[OffsetMinutes]].
// If offsetMinutesOne is empty and offsetMinutesTwo is empty, then
if (!one.hasOffsetTimeZoneName() && !two.hasOffsetTimeZoneName()) {
// Let recordOne be GetAvailableNamedTimeZoneIdentifier(one).
// Let recordTwo be GetAvailableNamedTimeZoneIdentifier(two).
// If recordOne is not empty and recordTwo is not empty and recordOne.[[PrimaryIdentifier]] is recordTwo.[[PrimaryIdentifier]], return true.
return one.timeZoneName()->equals(two.timeZoneName());
} else {
// Else,
// If offsetMinutesOne is not empty and offsetMinutesTwo is not empty and offsetMinutesOne = offsetMinutesTwo, return true.
if (one.hasOffsetTimeZoneName() && two.hasOffsetTimeZoneName()) {
return one.offset() == two.offset();
}
}
return false;
}
void TemporalZonedDateTimeObject::init(ExecutionState& state, ComputedTimeZone timeZone)
{
m_timeZone = timeZone;
@ -44,7 +69,7 @@ void TemporalZonedDateTimeObject::init(ExecutionState& state, ComputedTimeZone t
*m_plainDateTime = ISO8601::PlainDateTime(ISO8601::PlainDate(timeInfo.year, timeInfo.month + 1, timeInfo.mday),
ISO8601::PlainTime(d.hours(), d.minutes(), d.seconds(), d.milliseconds(), d.microseconds(), d.nanoseconds()));
if (!ISO8601::isoDateTimeWithinLimits(*m_epochNanoseconds)) {
if (!ISO8601::isValidEpochNanoseconds(*m_epochNanoseconds)) {
ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, "Out of range date-time");
}
@ -76,11 +101,11 @@ TemporalZonedDateTimeObject::TemporalZonedDateTimeObject(ExecutionState& state,
ComputedTimeZone computedTimeZone;
if (timeZone.hasTimeZoneName()) {
Int128 timezoneAppliedEpoch = Temporal::getEpochNanosecondsFor(state, timeZone, epochNanoseconds, TemporalDisambiguationOption::Compatible);
computedTimeZone = ComputedTimeZone(timeZone.timeZoneName(), int64_t(timezoneAppliedEpoch - epochNanoseconds));
computedTimeZone = ComputedTimeZone(false, timeZone.timeZoneName(), int64_t(epochNanoseconds - timezoneAppliedEpoch));
} else {
StringBuilder tz;
Temporal::formatOffsetTimeZoneIdentifier(state, int(timeZone.offset() / ISO8601::ExactTime::nsPerMinute), tz);
computedTimeZone = ComputedTimeZone(tz.finalize(), timeZone.offset());
computedTimeZone = ComputedTimeZone(true, tz.finalize(), timeZone.offset());
}
init(state, computedTimeZone);
@ -138,11 +163,11 @@ String* TemporalZonedDateTimeObject::toString(ExecutionState& state, Value optio
if (showTimeZone != TemporalShowTimeZoneNameOption::Never) {
// If showTimeZone is critical, let flag be "!"; else let flag be the empty String.
// Let timeZoneString be the string-concatenation of the code unit 0x005B (LEFT SQUARE BRACKET), flag, timeZone, and the code unit 0x005D (RIGHT SQUARE BRACKET).
sb.appendChar('[');
if (showTimeZone == TemporalShowTimeZoneNameOption::Critical) {
sb.appendChar('!');
}
// Let timeZoneString be the string-concatenation of the code unit 0x005B (LEFT SQUARE BRACKET), flag, timeZone, and the code unit 0x005D (RIGHT SQUARE BRACKET).
sb.appendChar('[');
sb.appendString(m_timeZone.timeZoneName());
sb.appendChar(']');
}
@ -152,6 +177,43 @@ String* TemporalZonedDateTimeObject::toString(ExecutionState& state, Value optio
return sb.finalize();
}
bool TemporalZonedDateTimeObject::equals(ExecutionState& state, Value otherInput)
{
// Let zonedDateTime be the this value.
// Perform ? RequireInternalSlot(zonedDateTime, [[InitializedTemporalZonedDateTime]]).
// Set other to ? ToTemporalZonedDateTime(other).
auto other = Temporal::toTemporalZonedDateTime(state, otherInput, Value());
// If zonedDateTime.[[EpochNanoseconds]] ≠ other.[[EpochNanoseconds]], return false.
if (epochNanoseconds() != other->epochNanoseconds()) {
return false;
}
// If TimeZoneEquals(zonedDateTime.[[TimeZone]], other.[[TimeZone]]) is false, return false.
if (!timeZoneEquals(timeZone(), other->timeZone())) {
return false;
}
// Return CalendarEquals(zonedDateTime.[[Calendar]], other.[[Calendar]]).
return calendarID() == other->calendarID();
}
int TemporalZonedDateTimeObject::hoursInDay(ExecutionState& state)
{
// Let timeZone be zonedDateTime.[[TimeZone]].
TimeZone timeZone = this->timeZone();
// Let isoDateTime be GetISODateTimeFor(timeZone, zonedDateTime.[[EpochNanoseconds]]).
auto isoDateTime = Temporal::getISODateTimeFor(state, timeZone, *m_epochNanoseconds);
// Let today be isoDateTime.[[ISODate]].
auto today = isoDateTime.plainDate();
// Let tomorrow be BalanceISODate(today.[[Year]], today.[[Month]], today.[[Day]] + 1).
auto tomorrow = Temporal::balanceISODate(state, today.year(), today.month(), today.day() + 1);
// Let todayNs be ? GetStartOfDay(timeZone, today).
auto todayNs = Temporal::getStartOfDay(state, timeZone, today);
// Let tomorrowNs be ? GetStartOfDay(timeZone, tomorrow).
auto tomorrowNs = Temporal::getStartOfDay(state, timeZone, tomorrow);
// Let diff be TimeDurationFromEpochNanosecondsDifference(tomorrowNs, todayNs).
// Return 𝔽(TotalTimeDuration(diff, hour)).
return (int32_t)((tomorrowNs - todayNs) / ISO8601::ExactTime::nsPerHour);
}
} // namespace Escargot
#endif

View file

@ -22,6 +22,7 @@
#define __EscargotTemporalZonedDateTimeObject__
#include "runtime/TemporalObject.h"
#include "runtime/TemporalPlainDateObject.h"
#include "util/ISO8601.h"
namespace Escargot {
@ -30,23 +31,45 @@ class TemporalZonedDateTimeObject : public DerivedObject {
public:
class ComputedTimeZone {
public:
ComputedTimeZone(String* timeZoneName = String::emptyString(), int64_t offset = 0)
: m_timeZoneName(timeZoneName)
ComputedTimeZone(bool hasOffsetTimeZoneName = false, String* timeZoneName = String::emptyString(), int64_t offset = 0)
: m_hasOffsetTimeZoneName(hasOffsetTimeZoneName)
, m_timeZoneName(timeZoneName)
, m_offset(offset)
{
}
String* timeZoneName()
bool hasOffsetTimeZoneName() const
{
return m_hasOffsetTimeZoneName;
}
String* timeZoneName() const
{
ASSERT(m_timeZoneName->length());
return m_timeZoneName;
}
int64_t offset()
int64_t offset() const
{
return m_offset;
}
bool equals(const ComputedTimeZone& src) const
{
return m_timeZoneName->equals(src.timeZoneName()) && offset() == src.offset();
}
operator TimeZone() const
{
if (hasOffsetTimeZoneName()) {
return TimeZone(offset());
} else {
return TimeZone(m_timeZoneName);
}
}
private:
bool m_hasOffsetTimeZoneName;
String* m_timeZoneName;
int64_t m_offset;
};
@ -89,9 +112,64 @@ public:
return m_timeZone;
}
// https://tc39.es/proposal-temporal/#sec-temporal.plaindatetime.prototype.tostring
Value era(ExecutionState& state)
{
return TemporalPlainDateGetter::era(state, plainDate(), calendarID(), m_icuCalendar);
}
Value eraYear(ExecutionState& state)
{
return TemporalPlainDateGetter::eraYear(state, plainDate(), calendarID(), m_icuCalendar);
}
Value dayOfWeek(ExecutionState& state)
{
return TemporalPlainDateGetter::dayOfWeek(state, plainDate(), calendarID(), m_icuCalendar);
}
Value dayOfYear(ExecutionState& state)
{
return TemporalPlainDateGetter::dayOfYear(state, plainDate(), calendarID(), m_icuCalendar);
}
Value weekOfYear(ExecutionState& state)
{
return TemporalPlainDateGetter::weekOfYear(state, plainDate(), calendarID(), m_icuCalendar);
}
Value yearOfWeek(ExecutionState& state)
{
return TemporalPlainDateGetter::yearOfWeek(state, plainDate(), calendarID(), m_icuCalendar);
}
Value daysInWeek(ExecutionState& state)
{
return TemporalPlainDateGetter::daysInWeek(state, plainDate(), calendarID(), m_icuCalendar);
}
Value daysInMonth(ExecutionState& state)
{
return TemporalPlainDateGetter::daysInMonth(state, plainDate(), calendarID(), m_icuCalendar);
}
Value daysInYear(ExecutionState& state)
{
return TemporalPlainDateGetter::daysInYear(state, plainDate(), calendarID(), m_icuCalendar);
}
Value monthsInYear(ExecutionState& state)
{
return TemporalPlainDateGetter::monthsInYear(state, plainDate(), calendarID(), m_icuCalendar);
}
Value inLeapYear(ExecutionState& state)
{
return TemporalPlainDateGetter::inLeapYear(state, plainDate(), calendarID(), m_icuCalendar);
}
Value monthCode(ExecutionState& state)
{
return TemporalPlainDateGetter::monthCode(state, plainDate(), calendarID(), m_icuCalendar);
}
// https://tc39.es/proposal-temporal/#sec-temporal.zoneddatetime.prototype.tostring
String* toString(ExecutionState& state, Value options);
// https://tc39.es/proposal-temporal/#sec-temporal.zoneddatetime.prototype.equals
bool equals(ExecutionState& state, Value otherInput);
// https://tc39.es/proposal-temporal/#sec-get-temporal.zoneddatetime.prototype.hoursinday
int hoursInDay(ExecutionState& state);
private:
void init(ExecutionState& state, ComputedTimeZone timeZone);
Int128* m_epochNanoseconds;

View file

@ -1652,6 +1652,17 @@ ExactTime ExactTime::fromISOPartsAndOffset(int32_t year, uint8_t month, uint8_t
return ExactTime{ utcNanoseconds - offset };
}
ExactTime ExactTime::fromPlainDate(const ISO8601::PlainDate& src)
{
return fromISOPartsAndOffset(src.year(), src.month(), src.day(), 0, 0, 0, 0, 0, 0, 0);
}
ExactTime ExactTime::fromPlainDateTime(const ISO8601::PlainDateTime& src)
{
return fromISOPartsAndOffset(src.plainDate().year(), src.plainDate().month(), src.plainDate().day(),
src.plainTime().hour(), src.plainTime().minute(), src.plainTime().second(), src.plainTime().millisecond(), src.plainTime().microsecond(), src.plainTime().nanosecond(), 0);
}
Int128 lengthInNanoseconds(DateTimeUnit unit)
{
if (unit == DateTimeUnit::Nanosecond) {

View file

@ -139,6 +139,9 @@ enum class UnsignedRoundingMode : uint8_t {
HalfEven
};
class PlainDate;
class PlainDateTime;
class ExactTime {
public:
static constexpr Int128 dayRangeSeconds{ 8640000000000 }; // 1e8 days
@ -163,6 +166,8 @@ public:
return ExactTime(Int128{ epochMilliseconds } * ExactTime::nsPerMillisecond);
}
static ExactTime fromISOPartsAndOffset(int32_t y, uint8_t mon, uint8_t d, unsigned h, unsigned min, unsigned s, unsigned ms, unsigned micros, unsigned ns, int64_t offset);
static ExactTime fromPlainDate(const ISO8601::PlainDate& src);
static ExactTime fromPlainDateTime(const ISO8601::PlainDateTime& src);
int64_t epochMilliseconds() const
{

View file

@ -359,9 +359,6 @@
<test id="built-ins/Temporal/Duration/prototype/total/unit-string-shorthand-string"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Duration/prototype/total/unit-wrong-type"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Duration/prototype/total/year-zero"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/compare/argument-zoneddatetime"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/from/argument-zoneddatetime"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/prototype/equals/argument-zoneddatetime"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/prototype/since/argument-zoneddatetime"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/prototype/toZonedDateTimeISO/branding"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/prototype/toZonedDateTimeISO/builtin"><reason>TODO</reason></test>
@ -427,22 +424,8 @@
<test id="built-ins/Temporal/Now/zonedDateTimeISO/timezone-string-sub-minute-offset"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Now/zonedDateTimeISO/timezone-string-year-zero"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Now/zonedDateTimeISO/timezone-wrong-type"><reason>TODO</reason></test>
<test id="built-ins/Temporal/PlainDate/compare/argument-plaindatetime"><reason>TODO</reason></test>
<test id="built-ins/Temporal/PlainDate/compare/argument-zoneddatetime"><reason>TODO</reason></test>
<test id="built-ins/Temporal/PlainDate/compare/argument-zoneddatetime-slots"><reason>TODO</reason></test>
<test id="built-ins/Temporal/PlainDate/compare/calendar-temporal-object"><reason>TODO</reason></test>
<test id="built-ins/Temporal/PlainDate/from/argument-plaindatetime"><reason>TODO</reason></test>
<test id="built-ins/Temporal/PlainDate/from/argument-zoneddatetime"><reason>TODO</reason></test>
<test id="built-ins/Temporal/PlainDate/from/argument-zoneddatetime-slots"><reason>TODO</reason></test>
<test id="built-ins/Temporal/PlainDate/from/calendar-temporal-object"><reason>TODO</reason></test>
<test id="built-ins/Temporal/PlainDate/from/order-of-operations"><reason>TODO</reason></test>
<test id="built-ins/Temporal/PlainDate/prototype/add/argument-duration-max"><reason>TODO</reason></test>
<test id="built-ins/Temporal/PlainDate/prototype/equals/argument-plaindatetime"><reason>TODO</reason></test>
<test id="built-ins/Temporal/PlainDate/prototype/equals/argument-zoneddatetime-slots"><reason>TODO</reason></test>
<test id="built-ins/Temporal/PlainDate/prototype/equals/calendar-temporal-object"><reason>TODO</reason></test>
<test id="built-ins/Temporal/PlainDate/prototype/since/argument-plaindatetime"><reason>TODO</reason></test>
<test id="built-ins/Temporal/PlainDate/prototype/since/argument-zoneddatetime-slots"><reason>TODO</reason></test>
<test id="built-ins/Temporal/PlainDate/prototype/since/calendar-temporal-object"><reason>TODO</reason></test>
<test id="built-ins/Temporal/PlainDate/prototype/subtract/argument-duration-max"><reason>TODO</reason></test>
<test id="built-ins/Temporal/PlainDate/prototype/toPlainDateTime/argument-object"><reason>TODO</reason></test>
<test id="built-ins/Temporal/PlainDate/prototype/toPlainDateTime/argument-string-calendar-annotation"><reason>TODO</reason></test>
@ -531,26 +514,8 @@
<test id="built-ins/Temporal/PlainDate/prototype/toZonedDateTime/timezone-wrong-type"><reason>TODO</reason></test>
<test id="built-ins/Temporal/PlainDate/prototype/toZonedDateTime/year-zero"><reason>TODO</reason></test>
<test id="built-ins/Temporal/PlainDate/prototype/until/argument-plaindatetime"><reason>TODO</reason></test>
<test id="built-ins/Temporal/PlainDate/prototype/until/argument-zoneddatetime-slots"><reason>TODO</reason></test>
<test id="built-ins/Temporal/PlainDate/prototype/until/calendar-temporal-object"><reason>TODO</reason></test>
<test id="built-ins/Temporal/PlainDate/prototype/with/overflow-undefined"><reason>TODO</reason></test>
<test id="built-ins/Temporal/PlainDate/prototype/with/plaindatelike-invalid"><reason>TODO</reason></test>
<test id="built-ins/Temporal/PlainDate/prototype/withCalendar/calendar-temporal-object"><reason>TODO</reason></test>
<test id="built-ins/Temporal/PlainDateTime/compare/argument-zoneddatetime-negative-epochnanoseconds"><reason>TODO</reason></test>
<test id="built-ins/Temporal/PlainDateTime/compare/calendar-temporal-object"><reason>TODO</reason></test>
<test id="built-ins/Temporal/PlainDateTime/from/argument-zoneddatetime-balance-negative-time-units"><reason>TODO</reason></test>
<test id="built-ins/Temporal/PlainDateTime/from/argument-zoneddatetime-negative-epochnanoseconds"><reason>TODO</reason></test>
<test id="built-ins/Temporal/PlainDateTime/from/calendar-temporal-object"><reason>TODO</reason></test>
<test id="built-ins/Temporal/PlainDateTime/from/options-wrong-type"><reason>TODO</reason></test>
<test id="built-ins/Temporal/PlainDateTime/from/order-of-operations"><reason>TODO</reason></test>
<test id="built-ins/Temporal/PlainDateTime/from/overflow-invalid-string"><reason>TODO</reason></test>
<test id="built-ins/Temporal/PlainDateTime/prototype/equals/argument-zoneddatetime-balance-negative-time-units"><reason>TODO</reason></test>
<test id="built-ins/Temporal/PlainDateTime/prototype/equals/argument-zoneddatetime-negative-epochnanoseconds"><reason>TODO</reason></test>
<test id="built-ins/Temporal/PlainDateTime/prototype/equals/calendar-temporal-object"><reason>TODO</reason></test>
<test id="built-ins/Temporal/PlainDateTime/prototype/since/argument-plaindate"><reason>TODO</reason></test>
<test id="built-ins/Temporal/PlainDateTime/prototype/since/argument-zoneddatetime-balance-negative-time-units"><reason>TODO</reason></test>
<test id="built-ins/Temporal/PlainDateTime/prototype/since/argument-zoneddatetime-negative-epochnanoseconds"><reason>TODO</reason></test>
<test id="built-ins/Temporal/PlainDateTime/prototype/since/calendar-temporal-object"><reason>TODO</reason></test>
<test id="built-ins/Temporal/PlainDateTime/prototype/since/order-of-operations"><reason>TODO</reason></test>
<test id="built-ins/Temporal/PlainDateTime/prototype/toString/calendarname-always"><reason>TODO</reason></test>
<test id="built-ins/Temporal/PlainDateTime/prototype/toString/calendarname-critical"><reason>TODO</reason></test>
@ -582,40 +547,9 @@
<test id="built-ins/Temporal/PlainDateTime/prototype/toZonedDateTime/two-digit-year"><reason>TODO</reason></test>
<test id="built-ins/Temporal/PlainDateTime/prototype/toZonedDateTime/year-zero"><reason>TODO</reason></test>
<test id="built-ins/Temporal/PlainDateTime/prototype/until/argument-plaindate"><reason>TODO</reason></test>
<test id="built-ins/Temporal/PlainDateTime/prototype/until/argument-zoneddatetime-balance-negative-time-units"><reason>TODO</reason></test>
<test id="built-ins/Temporal/PlainDateTime/prototype/until/argument-zoneddatetime-negative-epochnanoseconds"><reason>TODO</reason></test>
<test id="built-ins/Temporal/PlainDateTime/prototype/until/calendar-temporal-object"><reason>TODO</reason></test>
<test id="built-ins/Temporal/PlainDateTime/prototype/until/order-of-operations"><reason>TODO</reason></test>
<test id="built-ins/Temporal/PlainDateTime/prototype/with/calendar-temporal-object-throws"><reason>TODO</reason></test>
<test id="built-ins/Temporal/PlainDateTime/prototype/withCalendar/calendar-temporal-object"><reason>TODO</reason></test>
<test id="built-ins/Temporal/PlainDateTime/prototype/withPlainTime/argument-zoneddatetime-balance-negative-time-units"><reason>TODO</reason></test>
<test id="built-ins/Temporal/PlainDateTime/prototype/withPlainTime/argument-zoneddatetime-negative-epochnanoseconds"><reason>TODO</reason></test>
<test id="built-ins/Temporal/PlainMonthDay/from/calendar-temporal-object"><reason>TODO</reason></test>
<test id="built-ins/Temporal/PlainMonthDay/prototype/equals/calendar-temporal-object"><reason>TODO</reason></test>
<test id="built-ins/Temporal/PlainMonthDay/prototype/with/monthdaylike-invalid"><reason>TODO</reason></test>
<test id="built-ins/Temporal/PlainTime/compare/argument-zoneddatetime-negative-epochnanoseconds"><reason>TODO</reason></test>
<test id="built-ins/Temporal/PlainTime/from/argument-plaindatetime"><reason>TODO</reason></test>
<test id="built-ins/Temporal/PlainTime/from/argument-zoneddatetime-balance-negative-time-units"><reason>TODO</reason></test>
<test id="built-ins/Temporal/PlainTime/from/argument-zoneddatetime-negative-epochnanoseconds"><reason>TODO</reason></test>
<test id="built-ins/Temporal/PlainTime/from/order-of-operations"><reason>TODO</reason></test>
<test id="built-ins/Temporal/PlainTime/prototype/equals/argument-zoneddatetime-balance-negative-time-units"><reason>TODO</reason></test>
<test id="built-ins/Temporal/PlainTime/prototype/equals/argument-zoneddatetime-negative-epochnanoseconds"><reason>TODO</reason></test>
<test id="built-ins/Temporal/PlainTime/prototype/since/argument-zoneddatetime-balance-negative-time-units"><reason>TODO</reason></test>
<test id="built-ins/Temporal/PlainTime/prototype/since/argument-zoneddatetime-negative-epochnanoseconds"><reason>TODO</reason></test>
<test id="built-ins/Temporal/PlainTime/prototype/until/argument-zoneddatetime-balance-negative-time-units"><reason>TODO</reason></test>
<test id="built-ins/Temporal/PlainTime/prototype/until/argument-zoneddatetime-negative-epochnanoseconds"><reason>TODO</reason></test>
<test id="built-ins/Temporal/PlainTime/prototype/with/plaintimelike-invalid"><reason>TODO</reason></test>
<test id="built-ins/Temporal/PlainYearMonth/compare/calendar-temporal-object"><reason>TODO</reason></test>
<test id="built-ins/Temporal/PlainYearMonth/from/calendar-temporal-object"><reason>TODO</reason></test>
<test id="built-ins/Temporal/PlainYearMonth/prototype/add/argument-duration-max"><reason>TODO</reason></test>
<test id="built-ins/Temporal/PlainYearMonth/prototype/equals/calendar-temporal-object"><reason>TODO</reason></test>
<test id="built-ins/Temporal/PlainYearMonth/prototype/since/calendar-temporal-object"><reason>TODO</reason></test>
<test id="built-ins/Temporal/PlainYearMonth/prototype/subtract/argument-duration-max"><reason>TODO</reason></test>
<test id="built-ins/Temporal/PlainYearMonth/prototype/until/calendar-temporal-object"><reason>TODO</reason></test>
<test id="built-ins/Temporal/PlainYearMonth/prototype/with/yearmonthlike-invalid"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/calendar-case-insensitive"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/calendar-string"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/calendar-undefined"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/compare/argument-propertybag-calendar-case-insensitive"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/compare/argument-propertybag-calendar-invalid-iso-string"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/compare/argument-propertybag-calendar-iso-string"><reason>TODO</reason></test>
@ -662,78 +596,8 @@
<test id="built-ins/Temporal/ZonedDateTime/compare/zoneddatetime-string"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/compare/zoneddatetime-string-multiple-offsets"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/construction-and-properties"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/from/argument-propertybag-calendar-case-insensitive"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/from/argument-propertybag-calendar-invalid-iso-string"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/from/argument-propertybag-calendar-iso-string"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/from/argument-propertybag-calendar-leap-second"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/from/argument-propertybag-calendar-string"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/from/argument-propertybag-calendar-wrong-type"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/from/argument-propertybag-calendar-year-zero"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/from/argument-propertybag-empty-throws"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/from/argument-propertybag-function-object"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/from/argument-propertybag-ignores-incorrect-properties"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/from/argument-propertybag-invalid-offset-string"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/from/argument-propertybag-monthcode-month"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/from/argument-propertybag-offset-not-agreeing-with-timezone"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/from/argument-propertybag-required-correctly-spelled-properties"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/from/argument-propertybag-required-prop-undefined-throws"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/from/argument-propertybag-timezone-string"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/from/argument-propertybag-timezone-string-datetime"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/from/argument-propertybag-timezone-string-leap-second"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/from/argument-propertybag-timezone-string-multiple-offsets"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/from/argument-propertybag-timezone-string-sub-minute-offset"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/from/argument-propertybag-timezone-string-year-zero"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/from/argument-propertybag-timezone-wrong-type"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/from/argument-string-basic-and-extended-format"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/from/argument-string-calendar-annotation"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/from/argument-string-calendar-annotation-invalid-key"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/from/argument-string-critical-unknown-annotation"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/from/argument-string-date-with-utc-offset"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/from/argument-string-decimal-places"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/from/argument-string-limits"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/from/argument-string-minus-sign"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/from/argument-string-multiple-calendar"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/from/argument-string-multiple-time-zone"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/from/argument-string-negative-extended-year"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/from/argument-string-no-junk-at-end"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/from/argument-string-optional-parts"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/from/argument-string-start-of-day-not-valid-epoch-nanoseconds"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/from/argument-string-sub-minute-offset"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/from/argument-string-time-separators"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/from/argument-string-time-zone-annotation"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/from/argument-string-unknown-annotation"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/from/argument-string-variant-decimal-separator"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/from/argument-wrong-type"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/from/argument-zoneddatetime"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/from/bad-disambiguation"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/from/calendar-temporal-object"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/from/constrain-has-no-effect-on-invalid-iso-string"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/from/disambiguation-invalid-string"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/from/disambiguation-wrong-type"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/from/infinity-throws-rangeerror"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/from/leap-second"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/from/monthcode-invalid"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/from/observable-get-overflow-argument-primitive"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/from/observable-get-overflow-argument-string-invalid"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/from/offset-does-not-match-iana-time-zone"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/from/offset-invalid-string"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/from/offset-overrides-critical-flag"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/from/offset-string-invalid"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/from/offset-undefined"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/from/offset-wrong-type"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/from/options-object"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/from/options-wrong-type"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/from/order-of-operations"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/from/overflow-invalid-string"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/from/overflow-options"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/from/overflow-undefined"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/from/overflow-wrong-type"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/from/subclassing-ignored"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/from/timezone-case-insensitive"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/from/year-zero"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/from/zoneddatetime-string"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/from/zoneddatetime-string-multiple-offsets"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/name"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/add/add-duration"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/add/argument-duration-max"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/add/argument-duration-out-of-range"><reason>TODO</reason></test>
@ -766,82 +630,12 @@
<test id="built-ins/Temporal/ZonedDateTime/prototype/add/symmetrical-wrt-negative-durations-in-time-part"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/add/throw-when-ambiguous-result-with-reject"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/add/throw-when-intermediate-datetime-outside-valid-limits"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/calendarId/branding"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/calendarId/prop-desc"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/day/balance-negative-time-units"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/day/branding"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/day/prop-desc"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/dayOfWeek/branding"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/dayOfWeek/prop-desc"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/dayOfYear/branding"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/dayOfYear/prop-desc"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/daysInMonth/branding"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/daysInMonth/prop-desc"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/daysInWeek/branding"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/daysInWeek/prop-desc"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/daysInYear/basic"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/daysInYear/branding"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/daysInYear/prop-desc"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/epochMilliseconds/basic"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/epochMilliseconds/branding"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/epochMilliseconds/prop-desc"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/epochNanoseconds/basic"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/epochNanoseconds/branding"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/epochNanoseconds/prop-desc"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/equals/argument-object"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/equals/argument-propertybag-calendar-case-insensitive"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/equals/argument-propertybag-calendar-invalid-iso-string"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/equals/argument-propertybag-calendar-iso-string"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/equals/argument-propertybag-calendar-leap-second"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/equals/argument-propertybag-calendar-string"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/equals/argument-propertybag-calendar-year-zero"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/equals/argument-propertybag-invalid-offset-string"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/equals/argument-propertybag-offset-not-agreeing-with-timezone"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/equals/argument-propertybag-timezone-case-insensitive"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/equals/argument-propertybag-timezone-normalize-offset-strings"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/equals/argument-propertybag-timezone-string"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/equals/argument-propertybag-timezone-string-datetime"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/equals/argument-propertybag-timezone-string-leap-second"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/equals/argument-propertybag-timezone-string-multiple-offsets"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/equals/argument-propertybag-timezone-string-sub-minute-offset"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/equals/argument-propertybag-timezone-string-year-zero"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/equals/argument-propertybag-timezone-wrong-type"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/equals/argument-string-calendar-annotation"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/equals/argument-string-calendar-annotation-invalid-key"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/equals/argument-string-critical-unknown-annotation"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/equals/argument-string-date-with-utc-offset"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/equals/argument-string-limits"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/equals/argument-string-minus-sign"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/equals/argument-string-multiple-calendar"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/equals/argument-string-multiple-time-zone"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/equals/argument-string-sub-minute-offset"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/equals/argument-string-time-separators"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/equals/argument-string-time-zone-annotation"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/equals/argument-string-unknown-annotation"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/equals/argument-valid"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/equals/argument-wrong-type"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/equals/branding"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/equals/builtin"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/equals/calendar-temporal-object"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/equals/casts-argument"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/equals/constructed-from-equivalent-parameters-are-equal"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/equals/different-instant-not-equal"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/equals/different-time-zone-not-equal"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/equals/infinity-throws-rangeerror"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/equals/leap-second"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/equals/length"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/equals/name"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/equals/not-a-constructor"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/equals/order-of-operations"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/equals/prop-desc"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/equals/requires-properties"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/equals/year-zero"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/equals/zoneddatetime-string"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/equals/zoneddatetime-string-multiple-offsets"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/era/branding"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/era/prop-desc"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/eraYear/branding"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/eraYear/prop-desc"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/getTimeZoneTransition/branding"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/getTimeZoneTransition/builtin"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/getTimeZoneTransition/direction-undefined"><reason>TODO</reason></test>
@ -853,42 +647,6 @@
<test id="built-ins/Temporal/ZonedDateTime/prototype/getTimeZoneTransition/prop-desc"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/getTimeZoneTransition/utc-no-transitions"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/getTimeZoneTransition/wrong-string"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/hour/balance-negative-time-units"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/hour/branding"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/hour/prop-desc"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/hoursInDay/basic"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/hoursInDay/branding"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/hoursInDay/get-start-of-day-throws"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/hoursInDay/next-day-out-of-range"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/hoursInDay/prop-desc"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/inLeapYear/basic"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/inLeapYear/branding"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/inLeapYear/prop-desc"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/microsecond/balance-negative-time-units"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/microsecond/branding"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/microsecond/negative-epochnanoseconds"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/microsecond/prop-desc"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/millisecond/balance-negative-time-units"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/millisecond/branding"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/millisecond/negative-epochnanoseconds"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/millisecond/prop-desc"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/minute/balance-negative-time-units"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/minute/branding"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/minute/prop-desc"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/month/branding"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/month/prop-desc"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/monthCode/branding"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/monthCode/prop-desc"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/monthsInYear/branding"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/monthsInYear/prop-desc"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/nanosecond/branding"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/nanosecond/negative-epochnanoseconds"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/nanosecond/prop-desc"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/offset/basic"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/offset/branding"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/offset/prop-desc"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/offsetNanoseconds/branding"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/offsetNanoseconds/prop-desc"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/round/branding"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/round/builtin"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/round/day-rounding-out-of-range"><reason>TODO</reason></test>
@ -930,9 +688,6 @@
<test id="built-ins/Temporal/ZonedDateTime/prototype/round/throws-on-invalid-increments"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/round/throws-without-smallestunit"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/round/valid-increments"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/second/balance-negative-time-units"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/second/branding"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/second/prop-desc"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/since/argument-propertybag-calendar-case-insensitive"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/since/argument-propertybag-calendar-invalid-iso-string"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/since/argument-propertybag-calendar-iso-string"><reason>TODO</reason></test>
@ -1061,8 +816,6 @@
<test id="built-ins/Temporal/ZonedDateTime/prototype/subtract/symmetrical-wrt-negative-durations"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/subtract/throw-when-ambiguous-result-with-reject"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/subtract/throw-when-intermediate-datetime-outside-valid-limits"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/timeZoneId/branding"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/timeZoneId/prop-desc"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/toInstant/branding"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/toInstant/builtin"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/toInstant/length"><reason>TODO</reason></test>
@ -1112,9 +865,6 @@
<test id="built-ins/Temporal/ZonedDateTime/prototype/toPlainTime/negative-epochnanoseconds"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/toPlainTime/not-a-constructor"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/toPlainTime/prop-desc"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/toString/offset-auto"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/toString/offset-never"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/toString/timezonename-critical"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/until/argument-propertybag-calendar-case-insensitive"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/until/argument-propertybag-calendar-invalid-iso-string"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/until/argument-propertybag-calendar-iso-string"><reason>TODO</reason></test>
@ -1205,8 +955,6 @@
<test id="built-ins/Temporal/ZonedDateTime/prototype/valueOf/basic"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/valueOf/branding"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/valueOf/prop-desc"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/weekOfYear/branding"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/weekOfYear/prop-desc"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/with/basic"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/with/branding"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/with/builtin"><reason>TODO</reason></test>
@ -1301,15 +1049,7 @@
<test id="built-ins/Temporal/ZonedDateTime/prototype/withTimeZone/timezone-string-sub-minute-offset"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/withTimeZone/timezone-string-year-zero"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/withTimeZone/timezone-wrong-type"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/year/branding"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/year/prop-desc"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/yearOfWeek/basic"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/yearOfWeek/branding"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/prototype/yearOfWeek/prop-desc"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/subclass"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/timezone-case-insensitive"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/timezone-iso-string"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/timezone-string"><reason>TODO</reason></test>
<test id="built-ins/Temporal/ZonedDateTime/timezone-wrong-type"><reason>TODO</reason></test>
<test id="built-ins/ThrowTypeError/unique-per-realm-function-proto"><reason>TODO</reason></test>
<test id="built-ins/TypedArrayConstructors/internals/DefineOwnProperty/BigInt/tonumber-value-detached-buffer"><reason>TODO</reason></test>
@ -1491,31 +1231,25 @@
<test id="intl402/Temporal/PlainYearMonth/prototype/until/canonicalize-calendar"><reason>TODO</reason></test>
<test id="intl402/Temporal/PlainYearMonth/prototype/with/minimum-valid-year-month"><reason>TODO</reason></test>
<test id="intl402/Temporal/PlainYearMonth/prototype/with/non-iso-calendar-fields"><reason>TODO</reason></test>
<test id="intl402/Temporal/ZonedDateTime/canonicalize-calendar"><reason>TODO</reason></test>
<test id="intl402/Temporal/ZonedDateTime/compare/argument-propertybag-timezone-string-datetime"><reason>TODO</reason></test>
<test id="intl402/Temporal/ZonedDateTime/compare/disregards-calendar-if-exact-times-equal"><reason>TODO</reason></test>
<test id="intl402/Temporal/ZonedDateTime/compare/exhaustive"><reason>TODO</reason></test>
<test id="intl402/Temporal/ZonedDateTime/compare/infinity-throws-rangeerror"><reason>TODO</reason></test>
<test id="intl402/Temporal/ZonedDateTime/compare/sub-minute-offset"><reason>TODO</reason></test>
<test id="intl402/Temporal/ZonedDateTime/construct-non-utc-non-iso"><reason>TODO</reason></test>
<test id="intl402/Temporal/ZonedDateTime/etc-timezone"><reason>TODO</reason></test>
<test id="intl402/Temporal/ZonedDateTime/from/argument-propertybag-timezone-string-datetime"><reason>TODO</reason></test>
<test id="intl402/Temporal/ZonedDateTime/from/argument-valid"><reason>TODO</reason></test>
<test id="intl402/Temporal/ZonedDateTime/from/calendar-not-supporting-eras"><reason>TODO</reason></test>
<test id="intl402/Temporal/ZonedDateTime/from/canonicalize-calendar"><reason>TODO</reason></test>
<test id="intl402/Temporal/ZonedDateTime/from/canonicalize-era-codes"><reason>TODO</reason></test>
<test id="intl402/Temporal/ZonedDateTime/from/disambiguation-undefined"><reason>TODO</reason></test>
<test id="intl402/Temporal/ZonedDateTime/from/do-not-canonicalize-iana-identifiers"><reason>TODO</reason></test>
<test id="intl402/Temporal/ZonedDateTime/from/dst-skipped-cross-midnight"><reason>TODO</reason></test>
<test id="intl402/Temporal/ZonedDateTime/from/etc-timezone"><reason>TODO</reason></test>
<test id="intl402/Temporal/ZonedDateTime/from/infinity-throws-rangeerror"><reason>TODO</reason></test>
<test id="intl402/Temporal/ZonedDateTime/from/options-undefined"><reason>TODO</reason></test>
<test id="intl402/Temporal/ZonedDateTime/from/timezone-case-insensitive"><reason>TODO</reason></test>
<test id="intl402/Temporal/ZonedDateTime/from/zoneddatetime-sub-minute-offset"><reason>TODO</reason></test>
<test id="intl402/Temporal/ZonedDateTime/iana-legacy-names"><reason>TODO</reason></test>
<test id="intl402/Temporal/ZonedDateTime/links-africa"><reason>TODO</reason></test>
<test id="intl402/Temporal/ZonedDateTime/links-asia"><reason>TODO</reason></test>
<test id="intl402/Temporal/ZonedDateTime/links-australasia"><reason>TODO</reason></test>
<test id="intl402/Temporal/ZonedDateTime/links-backward"><reason>TODO</reason></test>
<test id="intl402/Temporal/ZonedDateTime/links-backzone"><reason>TODO</reason></test>
<test id="intl402/Temporal/ZonedDateTime/links-etcetera"><reason>TODO</reason></test>
@ -1527,12 +1261,9 @@
<test id="intl402/Temporal/ZonedDateTime/prototype/equals/argument-valid"><reason>TODO</reason></test>
<test id="intl402/Temporal/ZonedDateTime/prototype/equals/canonical-iana-names"><reason>TODO</reason></test>
<test id="intl402/Temporal/ZonedDateTime/prototype/equals/canonical-not-equal"><reason>TODO</reason></test>
<test id="intl402/Temporal/ZonedDateTime/prototype/equals/canonicalize-calendar"><reason>TODO</reason></test>
<test id="intl402/Temporal/ZonedDateTime/prototype/equals/canonicalize-iana-identifiers-before-comparing"><reason>TODO</reason></test>
<test id="intl402/Temporal/ZonedDateTime/prototype/equals/canonicalize-timezone"><reason>TODO</reason></test>
<test id="intl402/Temporal/ZonedDateTime/prototype/equals/canonicalize-utc-timezone"><reason>TODO</reason></test>
<test id="intl402/Temporal/ZonedDateTime/prototype/equals/different-calendar-not-equal"><reason>TODO</reason></test>
<test id="intl402/Temporal/ZonedDateTime/prototype/equals/infinity-throws-rangeerror"><reason>TODO</reason></test>
<test id="intl402/Temporal/ZonedDateTime/prototype/equals/offset-and-iana"><reason>TODO</reason></test>
<test id="intl402/Temporal/ZonedDateTime/prototype/equals/sub-minute-offset"><reason>TODO</reason></test>
<test id="intl402/Temporal/ZonedDateTime/prototype/equals/timezone-case-insensitive"><reason>TODO</reason></test>
@ -1546,8 +1277,6 @@
<test id="intl402/Temporal/ZonedDateTime/prototype/hoursInDay/dst-midnight"><reason>TODO</reason></test>
<test id="intl402/Temporal/ZonedDateTime/prototype/hoursInDay/dst-skipped-cross-midnight"><reason>TODO</reason></test>
<test id="intl402/Temporal/ZonedDateTime/prototype/hoursInDay/same-date-starts-twice"><reason>TODO</reason></test>
<test id="intl402/Temporal/ZonedDateTime/prototype/offset/basic-named-timezone"><reason>TODO</reason></test>
<test id="intl402/Temporal/ZonedDateTime/prototype/offsetNanoseconds/basic-named-timezone"><reason>TODO</reason></test>
<test id="intl402/Temporal/ZonedDateTime/prototype/offsetNanoseconds/nanoseconds-subtracted-or-added-at-dst-transition"><reason>TODO</reason></test>
<test id="intl402/Temporal/ZonedDateTime/prototype/round/dst-skipped-cross-midnight"><reason>TODO</reason></test>
<test id="intl402/Temporal/ZonedDateTime/prototype/since/argument-propertybag-timezone-string-datetime"><reason>TODO</reason></test>
@ -1595,7 +1324,6 @@
<test id="intl402/Temporal/ZonedDateTime/prototype/withCalendar/preserves-time-zone"><reason>TODO</reason></test>
<test id="intl402/Temporal/ZonedDateTime/prototype/withPlainTime/dst-skipped-cross-midnight"><reason>TODO</reason></test>
<test id="intl402/Temporal/ZonedDateTime/prototype/withTimeZone/preserves-calendar"><reason>TODO</reason></test>
<test id="intl402/Temporal/ZonedDateTime/supported-values-of"><reason>TODO</reason></test>
<test id="intl402/Temporal/ZonedDateTime/timezone-case-insensitive"><reason>TODO</reason></test>
<test id="intl402/Temporal/ZonedDateTime/timezone-ids-basic"><reason>TODO</reason></test>
<test id="intl402/TypedArray/prototype/toLocaleString/calls-toLocaleString-number-elements"><reason>TODO</reason></test>