Skip to content

Commit fdac7ae

Browse files
committed
Implement Temporal.ZonedDateTime.round, startOfDay, getTimeZoneTransition, valueOf, compare
Signed-off-by: Seonghyun Kim <sh8281.kim@samsung.com>
1 parent dccf2f9 commit fdac7ae

File tree

12 files changed

+339
-147
lines changed

12 files changed

+339
-147
lines changed

src/builtins/BuiltinTemporal.cpp

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1089,7 +1089,7 @@ static Value builtinTemporalZonedDateTimeConstructor(ExecutionState& state, Valu
10891089

10901090
// If timeZone is not a String, throw a TypeError exception.
10911091
if (!argv[1].isString()) {
1092-
ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, "timeZone should be String");
1092+
ErrorObject::throwBuiltinError(state, ErrorCode::TypeError, "timeZone should be String");
10931093
}
10941094
// Let timeZoneParse be ? ParseTimeZoneIdentifier(timeZone).
10951095
// If timeZoneParse.[[OffsetMinutes]] is empty, then
@@ -1098,7 +1098,7 @@ static Value builtinTemporalZonedDateTimeConstructor(ExecutionState& state, Valu
10981098
// Set timeZone to identifierRecord.[[Identifier]].
10991099
// Else,
11001100
// Set timeZone to FormatOffsetTimeZoneIdentifier(timeZoneParse.[[OffsetMinutes]]).
1101-
auto timeZone = Temporal::parseTimeZone(state, argv[1].asString());
1101+
auto timeZone = Temporal::parseTimeZone(state, argv[1].asString(), false);
11021102

11031103
// If calendar is undefined, set calendar to "iso8601".
11041104
Value calendar = argc > 2 ? argv[2] : Value();
@@ -1123,6 +1123,11 @@ static Value builtinTemporalZonedDateTimeFrom(ExecutionState& state, Value thisV
11231123
return Temporal::toTemporalZonedDateTime(state, argv[0], argc > 1 ? argv[1] : Value());
11241124
}
11251125

1126+
static Value builtinTemporalZonedDateTimeCompare(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional<Object*> newTarget)
1127+
{
1128+
return Value(TemporalZonedDateTimeObject::compare(state, argv[0], argv[1]));
1129+
}
1130+
11261131
static Value builtinTemporalZonedDateTimeCalendarId(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional<Object*> newTarget)
11271132
{
11281133
RESOLVE_THIS_BINDING_TO_ZONEDDATETIME(zonedDateTime, CalendarId);
@@ -1274,6 +1279,24 @@ static Value builtinTemporalZonedDateTimeUntil(ExecutionState& state, Value this
12741279
return zonedDateTime->differenceTemporalZonedDateTime(state, TemporalZonedDateTimeObject::DifferenceTemporalZonedDateTime::Until, argv[0], argc > 1 ? argv[1] : Value());
12751280
}
12761281

1282+
static Value builtinTemporalZonedDateTimeRound(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional<Object*> newTarget)
1283+
{
1284+
RESOLVE_THIS_BINDING_TO_ZONEDDATETIME2(zonedDateTime, round);
1285+
return zonedDateTime->round(state, argv[0]);
1286+
}
1287+
1288+
static Value builtinTemporalZonedDateTimeGetTimeZoneTransition(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional<Object*> newTarget)
1289+
{
1290+
RESOLVE_THIS_BINDING_TO_ZONEDDATETIME(zonedDateTime, GetTimeZoneTransition);
1291+
return zonedDateTime->getTimeZoneTransition(state, argv[0]);
1292+
}
1293+
1294+
static Value builtinTemporalZonedDateTimeStartOfDay(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional<Object*> newTarget)
1295+
{
1296+
RESOLVE_THIS_BINDING_TO_ZONEDDATETIME(zonedDateTime, StartOfDay);
1297+
return zonedDateTime->startOfDay(state);
1298+
}
1299+
12771300
void GlobalObject::initializeTemporal(ExecutionState& state)
12781301
{
12791302
ObjectPropertyNativeGetterSetterData* nativeData = new ObjectPropertyNativeGetterSetterData(
@@ -1806,13 +1829,15 @@ void GlobalObject::installTemporal(ExecutionState& state)
18061829
m_temporalZonedDateTime->setGlobalIntrinsicObject(state);
18071830

18081831
m_temporalZonedDateTime->directDefineOwnProperty(state, ObjectPropertyName(strings->from), ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->from, builtinTemporalZonedDateTimeFrom, 1, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent)));
1832+
m_temporalZonedDateTime->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyCompare()), ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyCompare(), builtinTemporalZonedDateTimeCompare, 2, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent)));
18091833
m_temporalZonedDateTimePrototype = m_temporalZonedDateTime->getFunctionPrototype(state).asObject();
18101834

18111835
m_temporalZonedDateTimePrototype->directDefineOwnProperty(state, ObjectPropertyName(state.context()->vmInstance()->globalSymbols().toStringTag),
18121836
ObjectPropertyDescriptor(Value(strings->lazyTemporalDotZonedDateTime().string()), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::ConfigurablePresent)));
18131837
m_temporalZonedDateTimePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->toString), ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->toString, builtinTemporalZonedDateTimeToString, 0, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent)));
18141838
m_temporalZonedDateTimePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->toJSON), ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->toJSON, builtinTemporalZonedDateTimeToJSON, 0, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent)));
18151839
m_temporalZonedDateTimePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->toLocaleString), ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->toLocaleString, builtinTemporalZonedDateTimeToLocaleString, 0, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent)));
1840+
m_temporalZonedDateTimePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->valueOf), ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->valueOf, builtinTemporalAnyInstanceValueOf, 0, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent)));
18161841
m_temporalZonedDateTimePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyEquals()), ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyEquals(), builtinTemporalZonedDateTimeEquals, 1, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent)));
18171842
m_temporalZonedDateTimePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyToInstant()), ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyToInstant(), builtinTemporalZonedDateTimeToInstant, 0, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent)));
18181843
m_temporalZonedDateTimePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyToPlainDate()), ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyToPlainDate(), builtinTemporalZonedDateTimeToPlainDate, 0, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent)));
@@ -1826,7 +1851,9 @@ void GlobalObject::installTemporal(ExecutionState& state)
18261851
m_temporalZonedDateTimePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazySubtract()), ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->lazySubtract(), builtinTemporalZonedDateTimeSubtract, 1, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent)));
18271852
m_temporalZonedDateTimePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyUntil()), ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyUntil(), builtinTemporalZonedDateTimeUntil, 1, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent)));
18281853
m_temporalZonedDateTimePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazySince()), ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->lazySince(), builtinTemporalZonedDateTimeSince, 1, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent)));
1829-
1854+
m_temporalZonedDateTimePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->round), ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->round, builtinTemporalZonedDateTimeRound, 1, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent)));
1855+
m_temporalZonedDateTimePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyStartOfDay()), ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyStartOfDay(), builtinTemporalZonedDateTimeStartOfDay, 0, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent)));
1856+
m_temporalZonedDateTimePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyGetTimeZoneTransition()), ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyGetTimeZoneTransition(), builtinTemporalZonedDateTimeGetTimeZoneTransition, 1, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent)));
18301857

18311858
{
18321859
AtomicString name(state.context(), "get calendarId");

src/intl/Intl.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2895,7 +2895,7 @@ Optional<Object*> Intl::getOptionsObject(ExecutionState& state, const Value& opt
28952895
return resolvedOptions;
28962896
}
28972897

2898-
Value Intl::getOption(ExecutionState& state, Object* options, Value property, Intl::OptionValueType type, Value* values, size_t valuesLength, const Value& fallback)
2898+
Value Intl::getOption(ExecutionState& state, Object* options, Value property, Intl::OptionValueType type, Value* values, size_t valuesLength, Optional<Value> fallback)
28992899
{
29002900
// http://www.ecma-international.org/ecma-402/1.0/index.html#sec-9.2.9
29012901
// Let value be the result of calling the [[Get]] internal method of options with argument property.
@@ -2927,8 +2927,13 @@ Value Intl::getOption(ExecutionState& state, Object* options, Value property, In
29272927
// Return value.
29282928
return value;
29292929
} else {
2930-
// Else return fallback.
2931-
return fallback;
2930+
// If default is required, throw a RangeError exception.
2931+
if (!fallback) {
2932+
ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, "got invalid value");
2933+
}
2934+
2935+
// return fallback.
2936+
return fallback.value();
29322937
}
29332938
}
29342939

src/intl/Intl.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,11 @@ class Intl {
4848
StringValue,
4949
BooleanValue,
5050
};
51-
static Value getOption(ExecutionState& state, Object* options, Value property, OptionValueType type, Value* values, size_t valuesLength, const Value& fallback);
51+
static Value getOption(ExecutionState& state, Object* options, Value property, OptionValueType type, Value* values, size_t valuesLength, Optional<Value> fallback);
52+
static Value getOption(ExecutionState& state, Object* options, Value property, OptionValueType type, Value* values, size_t valuesLength, Value fallback)
53+
{
54+
return getOption(state, options, property, type, values, valuesLength, Optional<Value>(fallback));
55+
}
5256
template <typename T>
5357
static T getNumberOption(ExecutionState& state, Optional<Object*> options, String* property, double minimum, double maximum, const T& fallback);
5458
static std::string preferredLanguage(const std::string& language);

src/runtime/StaticStrings.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -980,6 +980,7 @@ namespace Escargot {
980980
F(DaysInMonth, "daysInMonth") \
981981
F(DaysInWeek, "daysInWeek") \
982982
F(DaysInYear, "daysInYear") \
983+
F(Direction, "direction") \
983984
F(Disambiguation, "disambiguation") \
984985
F(Earlier, "earlier") \
985986
F(EraYear, "eraYear") \
@@ -990,6 +991,7 @@ namespace Escargot {
990991
F(FromEpochNanoseconds, "fromEpochNanoseconds") \
991992
F(GetEpochMilliseconds, "get epochMilliseconds") \
992993
F(GetEpochNanoseconds, "get epochNanoseconds") \
994+
F(GetTimeZoneTransition, "getTimeZoneTransition") \
993995
F(HoursInDay, "hoursInDay") \
994996
F(Ignore, "ignore") \
995997
F(InLeapYear, "inLeapYear") \
@@ -1009,7 +1011,9 @@ namespace Escargot {
10091011
F(PlainTime, "plainTime") \
10101012
F(PlainTimeISO, "plainTimeISO") \
10111013
F(Prefer, "prefer") \
1014+
F(Previous, "previous") \
10121015
F(Since, "since") \
1016+
F(StartOfDay, "startOfDay") \
10131017
F(SmallestUnit, "smallestUnit") \
10141018
F(Subtract, "subtract") \
10151019
F(TemporalDotDuration, "Temporal.Duration") \

src/runtime/TemporalObject.cpp

Lines changed: 38 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1427,6 +1427,25 @@ TemporalOffsetOption Temporal::getTemporalOffsetOption(ExecutionState& state, Op
14271427
return TemporalOffsetOption::Reject;
14281428
}
14291429

1430+
TemporalDirectionOption Temporal::getTemporalDirectionOption(ExecutionState& state, Optional<Object*> resolvedOptions)
1431+
{
1432+
if (!resolvedOptions) {
1433+
ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, "Invalid direction option");
1434+
}
1435+
1436+
Value values[2] = {
1437+
state.context()->staticStrings().next.string(),
1438+
state.context()->staticStrings().lazyPrevious().string(),
1439+
};
1440+
auto stringValue = Intl::getOption(state, resolvedOptions.value(), state.context()->staticStrings().lazyDirection().string(), Intl::StringValue,
1441+
values, 2, NullOption)
1442+
.asString();
1443+
if (stringValue->equals("next")) {
1444+
return TemporalDirectionOption::Next;
1445+
}
1446+
return TemporalDirectionOption::Previous;
1447+
}
1448+
14301449
void Temporal::validateTemporalUnitValue(ExecutionState& state, Optional<TemporalUnit> value, ISO8601::DateTimeUnitCategory unitGroup, Optional<TemporalUnit*> extraValues, size_t extraValueSize)
14311450
{
14321451
// If value is unset, return unused.
@@ -1469,7 +1488,7 @@ void Temporal::validateTemporalUnitValue(ExecutionState& state, Optional<Tempora
14691488
ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, msg);
14701489
}
14711490

1472-
TimeZone Temporal::parseTimeZone(ExecutionState& state, String* input)
1491+
TimeZone Temporal::parseTimeZone(ExecutionState& state, String* input, bool allowISODateTimeString)
14731492
{
14741493
ISO8601::DateTimeParseOption option;
14751494
option.parseSubMinutePrecisionForTimeZone = false;
@@ -1483,17 +1502,19 @@ TimeZone Temporal::parseTimeZone(ExecutionState& state, String* input)
14831502
return TimeZone(identifier.value());
14841503
}
14851504

1486-
auto complexTimeZone = ISO8601::parseCalendarDateTime(input, option);
1487-
if (complexTimeZone && std::get<2>(complexTimeZone.value())) {
1488-
ISO8601::TimeZoneRecord record = std::get<2>(complexTimeZone.value()).value();
1489-
if (record.m_z) {
1490-
return TimeZone(state.context()->staticStrings().UTC.string());
1491-
} else if (record.m_nameOrOffset && record.m_nameOrOffset.id().value() == 0) {
1492-
return TimeZone(record.m_nameOrOffset.get<0>());
1493-
} else if (record.m_nameOrOffset && record.m_nameOrOffset.id().value() == 1) {
1494-
return TimeZone(record.m_nameOrOffset.get<1>());
1495-
} else if (record.m_offset) {
1496-
return TimeZone(record.m_offset.value());
1505+
if (allowISODateTimeString) {
1506+
auto complexTimeZone = ISO8601::parseCalendarDateTime(input, option);
1507+
if (complexTimeZone && std::get<2>(complexTimeZone.value())) {
1508+
ISO8601::TimeZoneRecord record = std::get<2>(complexTimeZone.value()).value();
1509+
if (record.m_z) {
1510+
return TimeZone(state.context()->staticStrings().UTC.string());
1511+
} else if (record.m_nameOrOffset && record.m_nameOrOffset.id().value() == 0) {
1512+
return TimeZone(record.m_nameOrOffset.get<0>());
1513+
} else if (record.m_nameOrOffset && record.m_nameOrOffset.id().value() == 1) {
1514+
return TimeZone(record.m_nameOrOffset.get<1>());
1515+
} else if (record.m_offset) {
1516+
return TimeZone(record.m_offset.value());
1517+
}
14971518
}
14981519
}
14991520

@@ -3413,14 +3434,15 @@ Int128 Temporal::addZonedDateTime(ExecutionState& state, Int128 epochNanoseconds
34133434
return addInstant(state, epochNanoseconds, duration.time());
34143435
}
34153436
// Let isoDateTime be GetISODateTimeFor(timeZone, epochNanoseconds).
3416-
auto isoDateTime = getISODateTimeFor(state, timeZone, epochNanoseconds);
3437+
// Pass NullOption to timeZone to get utc date time
3438+
auto isoDateTime = getISODateTimeFor(state, NullOption, epochNanoseconds);
34173439
// Let addedDate be ? CalendarDateAdd(calendar, isoDateTime.[[ISODate]], duration.[[Date]], overflow).
34183440
UErrorCode status = U_ZERO_ERROR;
34193441
LocalResourcePointer<UCalendar> newCal(calendar.createICUCalendar(state), [](UCalendar* r) {
34203442
ucal_close(r);
34213443
});
34223444
CHECK_ICU_CALENDAR();
3423-
ucal_setMillis(newCal.get(), ISO8601::ExactTime::fromPlainDate(isoDateTime.plainDate()).floorEpochMilliseconds(), &status);
3445+
ucal_setMillis(newCal.get(), ISO8601::ExactTime::fromPlainDateTime(isoDateTime).floorEpochMilliseconds(), &status);
34243446
CHECK_ICU_CALENDAR();
34253447
auto addedDate = calendarDateAdd(state, calendar, isoDateTime.plainDate(), newCal.get(), duration.dateDuration(), overflow);
34263448
// Let intermediateDateTime be CombineISODateAndTimeRecord(addedDate, isoDateTime.[[Time]]).
@@ -3431,7 +3453,8 @@ Int128 Temporal::addZonedDateTime(ExecutionState& state, Int128 epochNanoseconds
34313453
ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, "Invalid time value");
34323454
}
34333455
// Let intermediateNs be ! GetEpochNanosecondsFor(timeZone, intermediateDateTime, compatible).
3434-
auto intermediateNs = getEpochNanosecondsFor(state, timeZone, intermediateDateTime, TemporalDisambiguationOption::Compatible);
3456+
// Pass NullOption to timeZone to get utc date time
3457+
auto intermediateNs = getEpochNanosecondsFor(state, NullOption, intermediateDateTime, TemporalDisambiguationOption::Compatible);
34353458
// Return ? AddInstant(intermediateNs, duration.[[Time]]).
34363459
return addInstant(state, intermediateNs, duration.time());
34373460
}

0 commit comments

Comments
 (0)