Skip to content

Commit c627a20

Browse files
committed
[GR-36828] Basic support for Temporal non-iso calendars.
PullRequest: js/3544
2 parents 21f373c + 529673e commit c627a20

21 files changed

+473
-562
lines changed

graal-js/src/com.oracle.truffle.js/src/com/oracle/truffle/js/builtins/temporal/TemporalPlainDatePrototypeBuiltins.java

Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,6 @@
7878
import com.oracle.truffle.js.nodes.temporal.TemporalMonthDayFromFieldsNode;
7979
import com.oracle.truffle.js.nodes.temporal.TemporalYearMonthFromFieldsNode;
8080
import com.oracle.truffle.js.nodes.temporal.ToTemporalCalendarIdentifierNode;
81-
import com.oracle.truffle.js.nodes.temporal.ToTemporalCalendarSlotValueNode;
8281
import com.oracle.truffle.js.nodes.temporal.ToTemporalDateNode;
8382
import com.oracle.truffle.js.nodes.temporal.ToTemporalDurationNode;
8483
import com.oracle.truffle.js.nodes.temporal.ToTemporalTimeNode;
@@ -88,6 +87,7 @@
8887
import com.oracle.truffle.js.runtime.JSContext;
8988
import com.oracle.truffle.js.runtime.JSRealm;
9089
import com.oracle.truffle.js.runtime.JSRuntime;
90+
import com.oracle.truffle.js.runtime.Strings;
9191
import com.oracle.truffle.js.runtime.builtins.BuiltinEnum;
9292
import com.oracle.truffle.js.runtime.builtins.JSDate;
9393
import com.oracle.truffle.js.runtime.builtins.temporal.ISODateTimeRecord;
@@ -105,12 +105,14 @@
105105
import com.oracle.truffle.js.runtime.builtins.temporal.NormalizedDurationRecord;
106106
import com.oracle.truffle.js.runtime.objects.JSDynamicObject;
107107
import com.oracle.truffle.js.runtime.objects.Undefined;
108+
import com.oracle.truffle.js.runtime.util.IntlUtil;
108109
import com.oracle.truffle.js.runtime.util.TemporalConstants;
109110
import com.oracle.truffle.js.runtime.util.TemporalErrors;
110111
import com.oracle.truffle.js.runtime.util.TemporalUtil;
111112
import com.oracle.truffle.js.runtime.util.TemporalUtil.Disambiguation;
112113
import com.oracle.truffle.js.runtime.util.TemporalUtil.ShowCalendar;
113114
import com.oracle.truffle.js.runtime.util.TemporalUtil.Unit;
115+
import org.graalvm.shadowed.com.ibm.icu.util.Calendar;
114116

115117
public class TemporalPlainDatePrototypeBuiltins extends JSBuiltinsContainer.SwitchEnum<TemporalPlainDatePrototypeBuiltins.TemporalPlainDatePrototype> {
116118

@@ -257,38 +259,46 @@ protected JSTemporalPlainDateGetterNode(JSContext context, JSBuiltin builtin, Te
257259
}
258260

259261
@Specialization
260-
protected final Object dateGetter(JSTemporalPlainDateObject temporalDT) {
262+
protected final Object dateGetter(JSTemporalPlainDateObject temporalDT,
263+
@Cached TruffleString.EqualNode equalNode,
264+
@Cached InlinedConditionProfile isoCalendarProfile) {
265+
TruffleString calendar = temporalDT.getCalendar();
266+
boolean isoCalendar = isoCalendarProfile.profile(this, Strings.equals(equalNode, TemporalConstants.ISO8601, calendar));
267+
Calendar cal = null;
268+
if (!isoCalendar) {
269+
cal = IntlUtil.getCalendar(calendar, temporalDT.getYear(), temporalDT.getMonth(), temporalDT.getDay());
270+
}
261271
switch (property) {
262272
case era:
263273
return Undefined.instance;
264274
case eraYear:
265275
return Undefined.instance;
266276
case year:
267-
return temporalDT.getYear();
277+
return isoCalendar ? temporalDT.getYear() : IntlUtil.getCalendarField(cal, Calendar.YEAR);
268278
case month:
269-
return temporalDT.getMonth();
279+
return isoCalendar ? temporalDT.getMonth() : (IntlUtil.getCalendarField(cal, Calendar.MONTH) + 1);
270280
case day:
271-
return temporalDT.getDay();
281+
return isoCalendar ? temporalDT.getDay() : IntlUtil.getCalendarField(cal, Calendar.DAY_OF_MONTH);
272282
case dayOfWeek:
273-
return TemporalUtil.toISODayOfWeek(temporalDT.getYear(), temporalDT.getMonth(), temporalDT.getDay());
283+
return isoCalendar ? TemporalUtil.toISODayOfWeek(temporalDT.getYear(), temporalDT.getMonth(), temporalDT.getDay()) : IntlUtil.getCalendarField(cal, Calendar.DAY_OF_WEEK);
274284
case dayOfYear:
275-
return TemporalUtil.toISODayOfYear(temporalDT.getYear(), temporalDT.getMonth(), temporalDT.getDay());
285+
return isoCalendar ? TemporalUtil.toISODayOfYear(temporalDT.getYear(), temporalDT.getMonth(), temporalDT.getDay()) : IntlUtil.getCalendarField(cal, Calendar.DAY_OF_YEAR);
276286
case monthCode:
277-
return TemporalUtil.buildISOMonthCode(temporalDT.getMonth());
287+
return isoCalendar ? TemporalUtil.buildISOMonthCode(temporalDT.getMonth()) : Strings.fromJavaString(IntlUtil.getTemporalMonthCode(cal));
278288
case weekOfYear:
279-
return TemporalUtil.weekOfToISOWeekOfYear(temporalDT.getYear(), temporalDT.getMonth(), temporalDT.getDay());
289+
return isoCalendar ? TemporalUtil.weekOfToISOWeekOfYear(temporalDT.getYear(), temporalDT.getMonth(), temporalDT.getDay()) : Undefined.instance;
280290
case yearOfWeek:
281-
return TemporalUtil.yearOfToISOWeekOfYear(temporalDT.getYear(), temporalDT.getMonth(), temporalDT.getDay());
291+
return isoCalendar ? TemporalUtil.yearOfToISOWeekOfYear(temporalDT.getYear(), temporalDT.getMonth(), temporalDT.getDay()) : Undefined.instance;
282292
case daysInWeek:
283-
return 7;
293+
return isoCalendar ? 7 : IntlUtil.getCalendarFieldMax(cal, Calendar.DAY_OF_WEEK);
284294
case daysInMonth:
285-
return TemporalUtil.isoDaysInMonth(temporalDT.getYear(), temporalDT.getMonth());
295+
return isoCalendar ? TemporalUtil.isoDaysInMonth(temporalDT.getYear(), temporalDT.getMonth()) : IntlUtil.getCalendarFieldMax(cal, Calendar.DAY_OF_MONTH);
286296
case daysInYear:
287-
return TemporalUtil.isoDaysInYear(temporalDT.getYear());
297+
return isoCalendar ? TemporalUtil.isoDaysInYear(temporalDT.getYear()) : IntlUtil.getCalendarFieldMax(cal, Calendar.DAY_OF_YEAR);
288298
case monthsInYear:
289-
return 12;
299+
return isoCalendar ? 12 : (IntlUtil.getCalendarFieldMax(cal, Calendar.MONTH) + 1);
290300
case inLeapYear:
291-
return JSDate.isLeapYear(temporalDT.getYear());
301+
return isoCalendar ? JSDate.isLeapYear(temporalDT.getYear()) : IntlUtil.isLeapYear(cal);
292302
}
293303
throw Errors.shouldNotReachHere();
294304
}
@@ -380,10 +390,10 @@ protected JSTemporalPlainDateWithCalendar(JSContext context, JSBuiltin builtin)
380390
}
381391

382392
@Specialization
383-
protected final JSTemporalPlainDateObject withCalendar(JSTemporalPlainDateObject date, Object calendarParam,
384-
@Cached ToTemporalCalendarSlotValueNode toCalendarSlotValue,
393+
protected final JSTemporalPlainDateObject withCalendar(JSTemporalPlainDateObject date, Object calendarLike,
394+
@Cached ToTemporalCalendarIdentifierNode toCalendarIdentifier,
385395
@Cached InlinedBranchProfile errorBranch) {
386-
TruffleString calendar = toCalendarSlotValue.execute(calendarParam);
396+
TruffleString calendar = toCalendarIdentifier.executeString(calendarLike);
387397
return JSTemporalPlainDate.create(getContext(), getRealm(), date.getYear(), date.getMonth(), date.getDay(), calendar, this, errorBranch);
388398
}
389399

graal-js/src/com.oracle.truffle.js/src/com/oracle/truffle/js/builtins/temporal/TemporalPlainDateTimePrototypeBuiltins.java

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,6 @@
8686
import com.oracle.truffle.js.nodes.temporal.TemporalGetOptionNode;
8787
import com.oracle.truffle.js.nodes.temporal.ToFractionalSecondDigitsNode;
8888
import com.oracle.truffle.js.nodes.temporal.ToTemporalCalendarIdentifierNode;
89-
import com.oracle.truffle.js.nodes.temporal.ToTemporalCalendarSlotValueNode;
9089
import com.oracle.truffle.js.nodes.temporal.ToTemporalDateTimeNode;
9190
import com.oracle.truffle.js.nodes.temporal.ToTemporalDurationNode;
9291
import com.oracle.truffle.js.nodes.temporal.ToTemporalTimeNode;
@@ -117,13 +116,15 @@
117116
import com.oracle.truffle.js.runtime.objects.JSDynamicObject;
118117
import com.oracle.truffle.js.runtime.objects.JSObject;
119118
import com.oracle.truffle.js.runtime.objects.Undefined;
119+
import com.oracle.truffle.js.runtime.util.IntlUtil;
120120
import com.oracle.truffle.js.runtime.util.TemporalConstants;
121121
import com.oracle.truffle.js.runtime.util.TemporalErrors;
122122
import com.oracle.truffle.js.runtime.util.TemporalUtil;
123123
import com.oracle.truffle.js.runtime.util.TemporalUtil.Disambiguation;
124124
import com.oracle.truffle.js.runtime.util.TemporalUtil.RoundingMode;
125125
import com.oracle.truffle.js.runtime.util.TemporalUtil.ShowCalendar;
126126
import com.oracle.truffle.js.runtime.util.TemporalUtil.Unit;
127+
import org.graalvm.shadowed.com.ibm.icu.util.Calendar;
127128

128129
public class TemporalPlainDateTimePrototypeBuiltins extends JSBuiltinsContainer.SwitchEnum<TemporalPlainDateTimePrototypeBuiltins.TemporalPlainDateTimePrototype> {
129130

@@ -296,7 +297,15 @@ public JSTemporalPlainDateTimeGetterNode(JSContext context, JSBuiltin builtin, T
296297
}
297298

298299
@Specialization
299-
protected Object dateTimeGetter(JSTemporalPlainDateTimeObject temporalDT) {
300+
protected Object dateTimeGetter(JSTemporalPlainDateTimeObject temporalDT,
301+
@Cached TruffleString.EqualNode equalNode,
302+
@Cached InlinedConditionProfile isoCalendarProfile) {
303+
TruffleString calendar = temporalDT.getCalendar();
304+
boolean isoCalendar = isoCalendarProfile.profile(this, Strings.equals(equalNode, TemporalConstants.ISO8601, calendar));
305+
Calendar cal = null;
306+
if (!isoCalendar) {
307+
cal = IntlUtil.getCalendar(calendar, temporalDT.getYear(), temporalDT.getMonth(), temporalDT.getDay());
308+
}
300309
switch (property) {
301310
case era:
302311
return Undefined.instance;
@@ -315,31 +324,31 @@ protected Object dateTimeGetter(JSTemporalPlainDateTimeObject temporalDT) {
315324
case nanosecond:
316325
return temporalDT.getNanosecond();
317326
case year:
318-
return temporalDT.getYear();
327+
return isoCalendar ? temporalDT.getYear() : IntlUtil.getCalendarField(cal, Calendar.YEAR);
319328
case month:
320-
return temporalDT.getMonth();
329+
return isoCalendar ? temporalDT.getMonth() : (IntlUtil.getCalendarField(cal, Calendar.MONTH) + 1);
321330
case day:
322-
return temporalDT.getDay();
331+
return isoCalendar ? temporalDT.getDay() : IntlUtil.getCalendarField(cal, Calendar.DAY_OF_MONTH);
323332
case dayOfWeek:
324-
return TemporalUtil.toISODayOfWeek(temporalDT.getYear(), temporalDT.getMonth(), temporalDT.getDay());
333+
return isoCalendar ? TemporalUtil.toISODayOfWeek(temporalDT.getYear(), temporalDT.getMonth(), temporalDT.getDay()) : IntlUtil.getCalendarField(cal, Calendar.DAY_OF_WEEK);
325334
case dayOfYear:
326-
return TemporalUtil.toISODayOfYear(temporalDT.getYear(), temporalDT.getMonth(), temporalDT.getDay());
335+
return isoCalendar ? TemporalUtil.toISODayOfYear(temporalDT.getYear(), temporalDT.getMonth(), temporalDT.getDay()) : IntlUtil.getCalendarField(cal, Calendar.DAY_OF_YEAR);
327336
case monthCode:
328-
return TemporalUtil.buildISOMonthCode(temporalDT.getMonth());
337+
return isoCalendar ? TemporalUtil.buildISOMonthCode(temporalDT.getMonth()) : Strings.fromJavaString(IntlUtil.getTemporalMonthCode(cal));
329338
case weekOfYear:
330-
return TemporalUtil.weekOfToISOWeekOfYear(temporalDT.getYear(), temporalDT.getMonth(), temporalDT.getDay());
339+
return isoCalendar ? TemporalUtil.weekOfToISOWeekOfYear(temporalDT.getYear(), temporalDT.getMonth(), temporalDT.getDay()) : Undefined.instance;
331340
case yearOfWeek:
332-
return TemporalUtil.yearOfToISOWeekOfYear(temporalDT.getYear(), temporalDT.getMonth(), temporalDT.getDay());
341+
return isoCalendar ? TemporalUtil.yearOfToISOWeekOfYear(temporalDT.getYear(), temporalDT.getMonth(), temporalDT.getDay()) : Undefined.instance;
333342
case daysInWeek:
334-
return 7;
343+
return isoCalendar ? 7 : IntlUtil.getCalendarFieldMax(cal, Calendar.DAY_OF_WEEK);
335344
case daysInMonth:
336-
return TemporalUtil.isoDaysInMonth(temporalDT.getYear(), temporalDT.getMonth());
345+
return isoCalendar ? TemporalUtil.isoDaysInMonth(temporalDT.getYear(), temporalDT.getMonth()) : IntlUtil.getCalendarFieldMax(cal, Calendar.DAY_OF_MONTH);
337346
case daysInYear:
338-
return TemporalUtil.isoDaysInYear(temporalDT.getYear());
347+
return isoCalendar ? TemporalUtil.isoDaysInYear(temporalDT.getYear()) : IntlUtil.getCalendarFieldMax(cal, Calendar.DAY_OF_YEAR);
339348
case monthsInYear:
340-
return 12;
349+
return isoCalendar ? 12 : (IntlUtil.getCalendarFieldMax(cal, Calendar.MONTH) + 1);
341350
case inLeapYear:
342-
return JSDate.isLeapYear(temporalDT.getYear());
351+
return isoCalendar ? JSDate.isLeapYear(temporalDT.getYear()) : IntlUtil.isLeapYear(cal);
343352

344353
}
345354
throw Errors.shouldNotReachHere();
@@ -808,9 +817,9 @@ protected JSTemporalPlainDateTimeWithCalendarNode(JSContext context, JSBuiltin b
808817

809818
@Specialization
810819
final JSTemporalPlainDateTimeObject withCalendar(JSTemporalPlainDateTimeObject temporalDateTime, Object calendarLike,
811-
@Cached ToTemporalCalendarSlotValueNode toCalendarSlotValue,
820+
@Cached ToTemporalCalendarIdentifierNode toCalendarIdentifier,
812821
@Cached InlinedBranchProfile errorBranch) {
813-
TruffleString calendar = toCalendarSlotValue.execute(calendarLike);
822+
TruffleString calendar = toCalendarIdentifier.executeString(calendarLike);
814823
return JSTemporalPlainDateTime.create(getContext(), getRealm(),
815824
temporalDateTime.getYear(), temporalDateTime.getMonth(), temporalDateTime.getDay(),
816825
temporalDateTime.getHour(), temporalDateTime.getMinute(), temporalDateTime.getSecond(),

graal-js/src/com.oracle.truffle.js/src/com/oracle/truffle/js/builtins/temporal/TemporalPlainMonthDayPrototypeBuiltins.java

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,15 +66,19 @@
6666
import com.oracle.truffle.js.nodes.temporal.ToTemporalMonthDayNode;
6767
import com.oracle.truffle.js.runtime.Errors;
6868
import com.oracle.truffle.js.runtime.JSContext;
69+
import com.oracle.truffle.js.runtime.Strings;
6970
import com.oracle.truffle.js.runtime.builtins.BuiltinEnum;
7071
import com.oracle.truffle.js.runtime.builtins.temporal.JSTemporalPlainDateObject;
7172
import com.oracle.truffle.js.runtime.builtins.temporal.JSTemporalPlainMonthDay;
7273
import com.oracle.truffle.js.runtime.builtins.temporal.JSTemporalPlainMonthDayObject;
7374
import com.oracle.truffle.js.runtime.objects.JSDynamicObject;
7475
import com.oracle.truffle.js.runtime.objects.Undefined;
76+
import com.oracle.truffle.js.runtime.util.IntlUtil;
77+
import com.oracle.truffle.js.runtime.util.TemporalConstants;
7578
import com.oracle.truffle.js.runtime.util.TemporalErrors;
7679
import com.oracle.truffle.js.runtime.util.TemporalUtil;
7780
import com.oracle.truffle.js.runtime.util.TemporalUtil.ShowCalendar;
81+
import org.graalvm.shadowed.com.ibm.icu.util.Calendar;
7882

7983
public class TemporalPlainMonthDayPrototypeBuiltins extends JSBuiltinsContainer.SwitchEnum<TemporalPlainMonthDayPrototypeBuiltins.TemporalPlainMonthDayPrototype> {
8084

@@ -170,12 +174,20 @@ protected JSTemporalPlainMonthDayGetterNode(JSContext context, JSBuiltin builtin
170174
}
171175

172176
@Specialization
173-
protected Object monthDayGetter(JSTemporalPlainMonthDayObject plainMD) {
177+
protected Object monthDayGetter(JSTemporalPlainMonthDayObject plainMD,
178+
@Cached TruffleString.EqualNode equalNode,
179+
@Cached InlinedConditionProfile isoCalendarProfile) {
180+
TruffleString calendar = plainMD.getCalendar();
181+
boolean isoCalendar = isoCalendarProfile.profile(this, Strings.equals(equalNode, TemporalConstants.ISO8601, calendar));
182+
Calendar cal = null;
183+
if (!isoCalendar) {
184+
cal = IntlUtil.getCalendar(calendar, plainMD.getYear(), plainMD.getMonth(), plainMD.getDay());
185+
}
174186
switch (property) {
175187
case day:
176-
return plainMD.getDay();
188+
return isoCalendar ? plainMD.getDay() : IntlUtil.getCalendarField(cal, Calendar.DAY_OF_MONTH);
177189
case monthCode:
178-
return TemporalUtil.buildISOMonthCode(plainMD.getMonth());
190+
return isoCalendar ? TemporalUtil.buildISOMonthCode(plainMD.getMonth()) : Strings.fromJavaString(IntlUtil.getTemporalMonthCode(cal));
179191
}
180192
throw Errors.shouldNotReachHere();
181193
}

0 commit comments

Comments
 (0)