Consider single era correctly in Temporal

Signed-off-by: Seonghyun Kim <sh8281.kim@samsung.com>
This commit is contained in:
Seonghyun Kim 2025-12-09 15:23:17 +09:00 committed by Patrick Kim
commit 7667784d79
5 changed files with 49 additions and 45 deletions

View file

@ -123,6 +123,19 @@ void Calendar::lookupICUEra(ExecutionState& state, const std::function<bool(size
return;
}
return;
} else if (id() == ID::Coptic) {
// for old-icu(~77)
// 0 is not AM
if (fn(1, "am")) {
return;
}
return;
} else if (id() == ID::EthiopianAmeteAlem) {
// for old-icu(~77)
if (fn(0, "aa")) {
return;
}
return;
}
std::string s = "root/calendar/";
@ -359,6 +372,9 @@ void Calendar::setYear(ExecutionState& state, UCalendar* icuCalendar, String* er
if (id() == Calendar::ID::Japanese && (era->equals("ad") || era->equals("bc") || era->equals("ce") || era->equals("bce"))) {
Calendar(ID::Gregorian).setYear(state, icuCalendar, era, year);
return;
} else if (id() == Calendar::ID::Buddhist && era->equals("be")) {
Calendar(ID::ISO8601).setYear(state, icuCalendar, year + epochISOYear());
return;
}
newCal.reset(createICUCalendar(state, "en@calendar=" + toICUString()));
icuCalendar = newCal.get();
@ -408,6 +424,9 @@ int32_t Calendar::year(ExecutionState& state, UCalendar* icuCalendar)
} else if (id() == ID::ROC) {
y -= 1911;
}
} else if (id() == ID::EthiopianAmeteAlem) {
// exceptional cases
y = ucal_get(icuCalendar, UCAL_YEAR, &status) - diffYearDueToICU4CAndSpecDiffer();
} else {
if (shouldUseICUExtendedYear()) {
y = ucal_get(icuCalendar, UCAL_EXTENDED_YEAR, &status) - diffYearDueToICU4CAndSpecDiffer();
@ -455,6 +474,14 @@ int32_t Calendar::eraYear(ExecutionState& state, UCalendar* icuCalendar)
if (y < 1) {
y = -(y - 1);
}
} else if (id() == ID::Coptic) {
UErrorCode status = U_ZERO_ERROR;
y = ucal_get(icuCalendar, UCAL_YEAR, &status);
CHECK_ICU_CALENDAR();
auto isoYear = Temporal::computeISODate(state, icuCalendar).year();
if (isoYear <= epochISOYear()) {
y = -(y - 1);
}
} else {
UErrorCode status = U_ZERO_ERROR;
y = ucal_get(icuCalendar, UCAL_YEAR, &status);
@ -501,33 +528,12 @@ String* Calendar::era(ExecutionState& state, UCalendar* icuCalendar)
} else {
return new ASCIIStringFromExternalMemory("ah");
}
/*
static int64_t islamicStartDay(Calendar::ID cal)
{
switch (cal) {
case Calendar::ID::IslamicTabular:
return ISO8601::ExactTime::fromPlainDate(ISO8601::PlainDate(622, 7, 29)).epochMilliseconds();
case Calendar::ID::Islamic:
case Calendar::ID::IslamicCivil:
case Calendar::ID::IslamicCivilLegacy:
case Calendar::ID::IslamicRGSA:
case Calendar::ID::IslamicUmmAlQura:
default:
return ISO8601::ExactTime::fromPlainDate(ISO8601::PlainDate(622, 7, 16)).epochMilliseconds();
}
}
int64_t startDate = islamicStartDay(id());
auto epochTime = ucal_getMillis(icuCalendar, &status);
if (startDate >= epochTime) {
return new ASCIIStringFromExternalMemory("ah");
} else {
return new ASCIIStringFromExternalMemory("bh");
}
*/
} else if (id() == ID::Coptic) {
// for old-icu(~77)
return new ASCIIStringFromExternalMemory("am");
} else if (id() == ID::EthiopianAmeteAlem) {
// for old-icu(~77)
return new ASCIIStringFromExternalMemory("aa");
}
auto ucalEra = ucal_get(icuCalendar, UCAL_ERA, &status);

View file

@ -66,7 +66,7 @@ public:
F(Coptic, "coptic", "coptic", "coptic") \
F(Dangi, "dangi", "dangi", "dangi") \
F(Ethiopian, "ethiopic", "ethiopic", "ethiopic") \
F(EthiopianAmeteAlem, "ethioaa", "ethiopic-amete-alem", "ethiopic-amete-alem") \
F(EthiopianAmeteAlem, "ethioaa", "ethiopic-amete-alem", "ethioaa") \
F(Gregorian, "gregory", "gregorian", "gregory") \
F(Hebrew, "hebrew", "hebrew", "hebrew") \
F(Indian, "indian", "indian", "indian") \

View file

@ -38,21 +38,31 @@ namespace Escargot {
ErrorObject::throwBuiltinError(state, ErrorCode::TypeError, "failed to get value from ICU calendar"); \
}
TemporalPlainDateObject::TemporalPlainDateObject(ExecutionState& state, Object* proto, ISO8601::PlainDate plainDate, Calendar calendar, bool checkBoundery)
TemporalPlainDateObject::TemporalPlainDateObject(ExecutionState& state, Object* proto, ISO8601::PlainDate isoDate, Calendar calendar, bool checkBoundery)
: DerivedObject(state, proto)
, m_plainDate(new(PointerFreeGC) ISO8601::PlainDate(plainDate))
, m_plainDate(new(PointerFreeGC) ISO8601::PlainDate(isoDate))
, m_calendarID(calendar)
{
if (checkBoundery && !ISO8601::isoDateTimeWithinLimits(plainDate.year(), plainDate.month(), plainDate.day())) {
if (checkBoundery && !ISO8601::isoDateTimeWithinLimits(isoDate.year(), isoDate.month(), isoDate.day())) {
ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, "Out of range date");
}
m_icuCalendar = calendar.createICUCalendar(state);
UErrorCode status = U_ZERO_ERROR;
ucal_setMillis(m_icuCalendar, ISO8601::ExactTime::fromPlainDate(plainDate).floorEpochMilliseconds(), &status);
ucal_setMillis(m_icuCalendar, ISO8601::ExactTime::fromPlainDate(isoDate).floorEpochMilliseconds(), &status);
CHECK_ICU()
if (!calendar.isISO8601()) {
auto y = calendar.year(state, m_icuCalendar);
auto m = ucal_get(m_icuCalendar, UCAL_ORDINAL_MONTH, &status) + 1;
CHECK_ICU()
auto d = ucal_get(m_icuCalendar, UCAL_DAY_OF_MONTH, &status);
CHECK_ICU()
*m_plainDate = ISO8601::PlainDate(y, m, d);
}
addFinalizer([](PointerValue* obj, void* data) {
TemporalPlainDateObject* self = (TemporalPlainDateObject*)obj;
ucal_close(self->m_icuCalendar);

View file

@ -42,7 +42,7 @@ struct TemporalPlainDateGetter {
class TemporalPlainDateObject : public DerivedObject {
public:
TemporalPlainDateObject(ExecutionState& state, Object* proto, ISO8601::PlainDate plainDate, Calendar calendar, bool checkBoundery = true);
TemporalPlainDateObject(ExecutionState& state, Object* proto, ISO8601::PlainDate isoDate, Calendar calendar, bool checkBoundery = true);
TemporalPlainDateObject(ExecutionState& state, Object* proto, std::pair<UCalendar*, Optional<ISO8601::PlainDate>> fieldResolveResult, Calendar calendar, bool checkBoundery = true);
TemporalPlainDateObject(ExecutionState& state, Object* proto, UCalendar* icuCalendar, Calendar calendar);

View file

@ -412,16 +412,13 @@
<test id="intl402/Temporal/Instant/prototype/toLocaleString/era"><reason>TODO</reason></test>
<test id="intl402/Temporal/PlainDate/from/calc-epoch-year-hebrew"><reason>TODO</reason></test>
<test id="intl402/Temporal/PlainDate/from/extreme-dates"><reason>TODO</reason></test>
<test id="intl402/Temporal/PlainDate/from/from-iso-string-indian"><reason>TODO</reason></test>
<test id="intl402/Temporal/PlainDate/from/hebrew-keviah"><reason>TODO</reason></test>
<test id="intl402/Temporal/PlainDate/from/invalid-month-codes-hebrew"><reason>TODO</reason></test>
<test id="intl402/Temporal/PlainDate/from/islamic"><reason>TODO</reason></test>
<test id="intl402/Temporal/PlainDate/from/islamic-rgsa"><reason>TODO</reason></test>
<test id="intl402/Temporal/PlainDate/from/leap-months-hebrew"><reason>TODO</reason></test>
<test id="intl402/Temporal/PlainDate/from/leap-year-hebrew"><reason>TODO</reason></test>
<test id="intl402/Temporal/PlainDate/from/non-positive-single-era-year"><reason>TODO</reason></test>
<test id="intl402/Temporal/PlainDate/prototype/add/basic-chinese"><reason>TODO</reason></test>
<test id="intl402/Temporal/PlainDate/prototype/add/basic-coptic"><reason>TODO</reason></test>
<test id="intl402/Temporal/PlainDate/prototype/add/basic-dangi"><reason>TODO</reason></test>
<test id="intl402/Temporal/PlainDate/prototype/add/basic-ethioaa"><reason>TODO</reason></test>
<test id="intl402/Temporal/PlainDate/prototype/add/basic-hebrew"><reason>TODO</reason></test>
@ -459,9 +456,7 @@
<test id="intl402/Temporal/PlainDate/prototype/add/leap-year-roc"><reason>TODO</reason></test>
<test id="intl402/Temporal/PlainDate/prototype/add/month-boundary-buddhist"><reason>TODO</reason></test>
<test id="intl402/Temporal/PlainDate/prototype/add/month-boundary-chinese"><reason>TODO</reason></test>
<test id="intl402/Temporal/PlainDate/prototype/add/month-boundary-coptic"><reason>TODO</reason></test>
<test id="intl402/Temporal/PlainDate/prototype/add/month-boundary-dangi"><reason>TODO</reason></test>
<test id="intl402/Temporal/PlainDate/prototype/add/month-boundary-ethioaa"><reason>TODO</reason></test>
<test id="intl402/Temporal/PlainDate/prototype/add/month-boundary-gregory"><reason>TODO</reason></test>
<test id="intl402/Temporal/PlainDate/prototype/add/month-boundary-hebrew"><reason>TODO</reason></test>
<test id="intl402/Temporal/PlainDate/prototype/add/month-boundary-indian"><reason>TODO</reason></test>
@ -512,7 +507,6 @@
<test id="intl402/Temporal/PlainDate/prototype/since/wrapping-at-end-of-month-islamic-umalqura"><reason>TODO</reason></test>
<test id="intl402/Temporal/PlainDate/prototype/since/wrapping-at-end-of-month-persian"><reason>TODO</reason></test>
<test id="intl402/Temporal/PlainDate/prototype/subtract/basic-chinese"><reason>TODO</reason></test>
<test id="intl402/Temporal/PlainDate/prototype/subtract/basic-coptic"><reason>TODO</reason></test>
<test id="intl402/Temporal/PlainDate/prototype/subtract/basic-dangi"><reason>TODO</reason></test>
<test id="intl402/Temporal/PlainDate/prototype/subtract/basic-ethioaa"><reason>TODO</reason></test>
<test id="intl402/Temporal/PlainDate/prototype/subtract/basic-hebrew"><reason>TODO</reason></test>
@ -552,9 +546,7 @@
<test id="intl402/Temporal/PlainDate/prototype/subtract/leap-year-roc"><reason>TODO</reason></test>
<test id="intl402/Temporal/PlainDate/prototype/subtract/month-boundary-buddhist"><reason>TODO</reason></test>
<test id="intl402/Temporal/PlainDate/prototype/subtract/month-boundary-chinese"><reason>TODO</reason></test>
<test id="intl402/Temporal/PlainDate/prototype/subtract/month-boundary-coptic"><reason>TODO</reason></test>
<test id="intl402/Temporal/PlainDate/prototype/subtract/month-boundary-dangi"><reason>TODO</reason></test>
<test id="intl402/Temporal/PlainDate/prototype/subtract/month-boundary-ethioaa"><reason>TODO</reason></test>
<test id="intl402/Temporal/PlainDate/prototype/subtract/month-boundary-gregory"><reason>TODO</reason></test>
<test id="intl402/Temporal/PlainDate/prototype/subtract/month-boundary-hebrew"><reason>TODO</reason></test>
<test id="intl402/Temporal/PlainDate/prototype/subtract/month-boundary-indian"><reason>TODO</reason></test>
@ -654,7 +646,6 @@
<test id="intl402/Temporal/PlainDate/prototype/with/wrapping-at-end-of-month-ethioaa"><reason>TODO</reason></test>
<test id="intl402/Temporal/PlainDate/prototype/with/wrapping-at-end-of-month-ethiopic"><reason>TODO</reason></test>
<test id="intl402/Temporal/PlainDate/prototype/withCalendar/extreme-dates"><reason>TODO</reason></test>
<test id="intl402/Temporal/PlainDate/prototype/year/arithmetic-year"><reason>TODO</reason></test>
<test id="intl402/Temporal/PlainDate/prototype/year/epoch-year"><reason>TODO</reason></test>
<test id="intl402/Temporal/PlainDateTime/from/basic-hebrew"><reason>TODO</reason></test>
<test id="intl402/Temporal/PlainDateTime/from/calendar-not-supporting-eras"><reason>TODO</reason></test>
@ -975,7 +966,6 @@
<test id="intl402/Temporal/PlainYearMonth/prototype/until/chinese-calendar-dates"><reason>TODO</reason></test>
<test id="intl402/Temporal/PlainYearMonth/prototype/until/dangi-calendar-dates"><reason>TODO</reason></test>
<test id="intl402/Temporal/PlainYearMonth/prototype/with/non-iso-calendar-fields"><reason>TODO</reason></test>
<test id="intl402/Temporal/PlainYearMonth/prototype/year/arithmetic-year"><reason>TODO</reason></test>
<test id="intl402/Temporal/PlainYearMonth/prototype/year/epoch-year"><reason>TODO</reason></test>
<test id="intl402/Temporal/ZonedDateTime/from/basic-hebrew"><reason>TODO</reason></test>
<test id="intl402/Temporal/ZonedDateTime/from/canonicalize-era-codes"><reason>TODO</reason></test>
@ -1876,7 +1866,6 @@
<test id="staging/Temporal/v8/duration-constructor"><reason>TODO</reason></test>
<test id="staging/Temporal/v8/duration-to-json-boundary-cases"><reason>TODO</reason></test>
<test id="staging/Temporal/v8/plain-date-time-with-plain-time"><reason>TODO</reason></test>
<test id="staging/Temporal/v8/plain-date-with"><reason>TODO</reason></test>
<test id="staging/built-ins/Object/preventExtensions/preventExtensions-variable-length-typed-arrays"><reason>TODO</reason></test>
<test id="staging/built-ins/Object/seal/seal-variable-length-typed-arrays"><reason>TODO</reason></test>
<test id="staging/built-ins/Reflect/preventExtensions/preventExtensions-variable-length-typed-arrays"><reason>TODO</reason></test>
@ -1988,7 +1977,6 @@
<test id="staging/sm/Symbol/as-base-value"><reason>TODO</reason></test>
<test id="staging/sm/Symbol/property-nonwritable"><reason>TODO</reason></test>
<test id="staging/sm/Symbol/property-reflection"><reason>TODO</reason></test>
<test id="staging/sm/Temporal/PlainDate/from-indian"><reason>TODO</reason></test>
<test id="staging/sm/Temporal/PlainDate/from-islamic-umalqura"><reason>TODO</reason></test>
<test id="staging/sm/Temporal/PlainMonthDay/from-chinese-leap-month-uncommon"><reason>TODO</reason></test>
<test id="staging/sm/Temporal/ZonedDateTime/zones-and-links"><reason>TODO</reason></test>