Skip to content

Commit 8c0ae66

Browse files
committed
Basic support for Temporal non-iso calendars.
1 parent 454d722 commit 8c0ae66

12 files changed

+327
-102
lines changed

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

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@
8787
import com.oracle.truffle.js.runtime.JSContext;
8888
import com.oracle.truffle.js.runtime.JSRealm;
8989
import com.oracle.truffle.js.runtime.JSRuntime;
90+
import com.oracle.truffle.js.runtime.Strings;
9091
import com.oracle.truffle.js.runtime.builtins.BuiltinEnum;
9192
import com.oracle.truffle.js.runtime.builtins.JSDate;
9293
import com.oracle.truffle.js.runtime.builtins.temporal.ISODateTimeRecord;
@@ -104,12 +105,14 @@
104105
import com.oracle.truffle.js.runtime.builtins.temporal.NormalizedDurationRecord;
105106
import com.oracle.truffle.js.runtime.objects.JSDynamicObject;
106107
import com.oracle.truffle.js.runtime.objects.Undefined;
108+
import com.oracle.truffle.js.runtime.util.IntlUtil;
107109
import com.oracle.truffle.js.runtime.util.TemporalConstants;
108110
import com.oracle.truffle.js.runtime.util.TemporalErrors;
109111
import com.oracle.truffle.js.runtime.util.TemporalUtil;
110112
import com.oracle.truffle.js.runtime.util.TemporalUtil.Disambiguation;
111113
import com.oracle.truffle.js.runtime.util.TemporalUtil.ShowCalendar;
112114
import com.oracle.truffle.js.runtime.util.TemporalUtil.Unit;
115+
import org.graalvm.shadowed.com.ibm.icu.util.Calendar;
113116

114117
public class TemporalPlainDatePrototypeBuiltins extends JSBuiltinsContainer.SwitchEnum<TemporalPlainDatePrototypeBuiltins.TemporalPlainDatePrototype> {
115118

@@ -256,38 +259,46 @@ protected JSTemporalPlainDateGetterNode(JSContext context, JSBuiltin builtin, Te
256259
}
257260

258261
@Specialization
259-
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+
}
260271
switch (property) {
261272
case era:
262273
return Undefined.instance;
263274
case eraYear:
264275
return Undefined.instance;
265276
case year:
266-
return temporalDT.getYear();
277+
return isoCalendar ? temporalDT.getYear() : IntlUtil.getCalendarField(cal, Calendar.YEAR);
267278
case month:
268-
return temporalDT.getMonth();
279+
return isoCalendar ? temporalDT.getMonth() : (IntlUtil.getCalendarField(cal, Calendar.MONTH) + 1);
269280
case day:
270-
return temporalDT.getDay();
281+
return isoCalendar ? temporalDT.getDay() : IntlUtil.getCalendarField(cal, Calendar.DAY_OF_MONTH);
271282
case dayOfWeek:
272-
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);
273284
case dayOfYear:
274-
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);
275286
case monthCode:
276-
return TemporalUtil.buildISOMonthCode(temporalDT.getMonth());
287+
return isoCalendar ? TemporalUtil.buildISOMonthCode(temporalDT.getMonth()) : Strings.fromJavaString(IntlUtil.getTemporalMonthCode(cal));
277288
case weekOfYear:
278-
return TemporalUtil.weekOfToISOWeekOfYear(temporalDT.getYear(), temporalDT.getMonth(), temporalDT.getDay());
289+
return isoCalendar ? TemporalUtil.weekOfToISOWeekOfYear(temporalDT.getYear(), temporalDT.getMonth(), temporalDT.getDay()) : Undefined.instance;
279290
case yearOfWeek:
280-
return TemporalUtil.yearOfToISOWeekOfYear(temporalDT.getYear(), temporalDT.getMonth(), temporalDT.getDay());
291+
return isoCalendar ? TemporalUtil.yearOfToISOWeekOfYear(temporalDT.getYear(), temporalDT.getMonth(), temporalDT.getDay()) : Undefined.instance;
281292
case daysInWeek:
282-
return 7;
293+
return isoCalendar ? 7 : IntlUtil.getCalendarFieldMax(cal, Calendar.DAY_OF_WEEK);
283294
case daysInMonth:
284-
return TemporalUtil.isoDaysInMonth(temporalDT.getYear(), temporalDT.getMonth());
295+
return isoCalendar ? TemporalUtil.isoDaysInMonth(temporalDT.getYear(), temporalDT.getMonth()) : IntlUtil.getCalendarFieldMax(cal, Calendar.DAY_OF_MONTH);
285296
case daysInYear:
286-
return TemporalUtil.isoDaysInYear(temporalDT.getYear());
297+
return isoCalendar ? TemporalUtil.isoDaysInYear(temporalDT.getYear()) : IntlUtil.getCalendarFieldMax(cal, Calendar.DAY_OF_YEAR);
287298
case monthsInYear:
288-
return 12;
299+
return isoCalendar ? 12 : (IntlUtil.getCalendarFieldMax(cal, Calendar.MONTH) + 1);
289300
case inLeapYear:
290-
return JSDate.isLeapYear(temporalDT.getYear());
301+
return isoCalendar ? JSDate.isLeapYear(temporalDT.getYear()) : IntlUtil.isLeapYear(cal);
291302
}
292303
throw Errors.shouldNotReachHere();
293304
}

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

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -116,13 +116,15 @@
116116
import com.oracle.truffle.js.runtime.objects.JSDynamicObject;
117117
import com.oracle.truffle.js.runtime.objects.JSObject;
118118
import com.oracle.truffle.js.runtime.objects.Undefined;
119+
import com.oracle.truffle.js.runtime.util.IntlUtil;
119120
import com.oracle.truffle.js.runtime.util.TemporalConstants;
120121
import com.oracle.truffle.js.runtime.util.TemporalErrors;
121122
import com.oracle.truffle.js.runtime.util.TemporalUtil;
122123
import com.oracle.truffle.js.runtime.util.TemporalUtil.Disambiguation;
123124
import com.oracle.truffle.js.runtime.util.TemporalUtil.RoundingMode;
124125
import com.oracle.truffle.js.runtime.util.TemporalUtil.ShowCalendar;
125126
import com.oracle.truffle.js.runtime.util.TemporalUtil.Unit;
127+
import org.graalvm.shadowed.com.ibm.icu.util.Calendar;
126128

127129
public class TemporalPlainDateTimePrototypeBuiltins extends JSBuiltinsContainer.SwitchEnum<TemporalPlainDateTimePrototypeBuiltins.TemporalPlainDateTimePrototype> {
128130

@@ -295,7 +297,15 @@ public JSTemporalPlainDateTimeGetterNode(JSContext context, JSBuiltin builtin, T
295297
}
296298

297299
@Specialization
298-
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+
}
299309
switch (property) {
300310
case era:
301311
return Undefined.instance;
@@ -314,31 +324,31 @@ protected Object dateTimeGetter(JSTemporalPlainDateTimeObject temporalDT) {
314324
case nanosecond:
315325
return temporalDT.getNanosecond();
316326
case year:
317-
return temporalDT.getYear();
327+
return isoCalendar ? temporalDT.getYear() : IntlUtil.getCalendarField(cal, Calendar.YEAR);
318328
case month:
319-
return temporalDT.getMonth();
329+
return isoCalendar ? temporalDT.getMonth() : (IntlUtil.getCalendarField(cal, Calendar.MONTH) + 1);
320330
case day:
321-
return temporalDT.getDay();
331+
return isoCalendar ? temporalDT.getDay() : IntlUtil.getCalendarField(cal, Calendar.DAY_OF_MONTH);
322332
case dayOfWeek:
323-
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);
324334
case dayOfYear:
325-
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);
326336
case monthCode:
327-
return TemporalUtil.buildISOMonthCode(temporalDT.getMonth());
337+
return isoCalendar ? TemporalUtil.buildISOMonthCode(temporalDT.getMonth()) : Strings.fromJavaString(IntlUtil.getTemporalMonthCode(cal));
328338
case weekOfYear:
329-
return TemporalUtil.weekOfToISOWeekOfYear(temporalDT.getYear(), temporalDT.getMonth(), temporalDT.getDay());
339+
return isoCalendar ? TemporalUtil.weekOfToISOWeekOfYear(temporalDT.getYear(), temporalDT.getMonth(), temporalDT.getDay()) : Undefined.instance;
330340
case yearOfWeek:
331-
return TemporalUtil.yearOfToISOWeekOfYear(temporalDT.getYear(), temporalDT.getMonth(), temporalDT.getDay());
341+
return isoCalendar ? TemporalUtil.yearOfToISOWeekOfYear(temporalDT.getYear(), temporalDT.getMonth(), temporalDT.getDay()) : Undefined.instance;
332342
case daysInWeek:
333-
return 7;
343+
return isoCalendar ? 7 : IntlUtil.getCalendarFieldMax(cal, Calendar.DAY_OF_WEEK);
334344
case daysInMonth:
335-
return TemporalUtil.isoDaysInMonth(temporalDT.getYear(), temporalDT.getMonth());
345+
return isoCalendar ? TemporalUtil.isoDaysInMonth(temporalDT.getYear(), temporalDT.getMonth()) : IntlUtil.getCalendarFieldMax(cal, Calendar.DAY_OF_MONTH);
336346
case daysInYear:
337-
return TemporalUtil.isoDaysInYear(temporalDT.getYear());
347+
return isoCalendar ? TemporalUtil.isoDaysInYear(temporalDT.getYear()) : IntlUtil.getCalendarFieldMax(cal, Calendar.DAY_OF_YEAR);
338348
case monthsInYear:
339-
return 12;
349+
return isoCalendar ? 12 : (IntlUtil.getCalendarFieldMax(cal, Calendar.MONTH) + 1);
340350
case inLeapYear:
341-
return JSDate.isLeapYear(temporalDT.getYear());
351+
return isoCalendar ? JSDate.isLeapYear(temporalDT.getYear()) : IntlUtil.isLeapYear(cal);
342352

343353
}
344354
throw Errors.shouldNotReachHere();

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
}

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

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@
8080
import com.oracle.truffle.js.runtime.JSContext;
8181
import com.oracle.truffle.js.runtime.JSRealm;
8282
import com.oracle.truffle.js.runtime.JSRuntime;
83+
import com.oracle.truffle.js.runtime.Strings;
8384
import com.oracle.truffle.js.runtime.builtins.BuiltinEnum;
8485
import com.oracle.truffle.js.runtime.builtins.JSDate;
8586
import com.oracle.truffle.js.runtime.builtins.temporal.ISODateRecord;
@@ -94,11 +95,13 @@
9495
import com.oracle.truffle.js.runtime.objects.JSDynamicObject;
9596
import com.oracle.truffle.js.runtime.objects.JSObject;
9697
import com.oracle.truffle.js.runtime.objects.Undefined;
98+
import com.oracle.truffle.js.runtime.util.IntlUtil;
9799
import com.oracle.truffle.js.runtime.util.TemporalConstants;
98100
import com.oracle.truffle.js.runtime.util.TemporalErrors;
99101
import com.oracle.truffle.js.runtime.util.TemporalUtil;
100102
import com.oracle.truffle.js.runtime.util.TemporalUtil.ShowCalendar;
101103
import com.oracle.truffle.js.runtime.util.TemporalUtil.Unit;
104+
import org.graalvm.shadowed.com.ibm.icu.util.Calendar;
102105

103106
public class TemporalPlainYearMonthPrototypeBuiltins extends JSBuiltinsContainer.SwitchEnum<TemporalPlainYearMonthPrototypeBuiltins.TemporalPlainYearMonthPrototype> {
104107

@@ -202,26 +205,34 @@ protected JSTemporalPlainYearMonthGetterNode(JSContext context, JSBuiltin builti
202205
}
203206

204207
@Specialization
205-
protected Object dateGetter(JSTemporalPlainYearMonthObject temporalYM) {
208+
protected Object dateGetter(JSTemporalPlainYearMonthObject temporalYM,
209+
@Cached TruffleString.EqualNode equalNode,
210+
@Cached InlinedConditionProfile isoCalendarProfile) {
211+
TruffleString calendar = temporalYM.getCalendar();
212+
boolean isoCalendar = isoCalendarProfile.profile(this, Strings.equals(equalNode, TemporalConstants.ISO8601, calendar));
213+
Calendar cal = null;
214+
if (!isoCalendar) {
215+
cal = IntlUtil.getCalendar(calendar, temporalYM.getYear(), temporalYM.getMonth(), temporalYM.getDay());
216+
}
206217
switch (property) {
207218
case era:
208219
return Undefined.instance;
209220
case eraYear:
210221
return Undefined.instance;
211222
case year:
212-
return temporalYM.getYear();
223+
return isoCalendar ? temporalYM.getYear() : IntlUtil.getCalendarField(cal, Calendar.YEAR);
213224
case month:
214-
return temporalYM.getMonth();
225+
return isoCalendar ? temporalYM.getMonth() : (IntlUtil.getCalendarField(cal, Calendar.MONTH) + 1);
215226
case monthCode:
216-
return TemporalUtil.buildISOMonthCode(temporalYM.getMonth());
227+
return isoCalendar ? TemporalUtil.buildISOMonthCode(temporalYM.getMonth()) : Strings.fromJavaString(IntlUtil.getTemporalMonthCode(cal));
217228
case daysInYear:
218-
return TemporalUtil.isoDaysInYear(temporalYM.getYear());
229+
return isoCalendar ? TemporalUtil.isoDaysInYear(temporalYM.getYear()) : IntlUtil.getCalendarFieldMax(cal, Calendar.DAY_OF_YEAR);
219230
case daysInMonth:
220-
return TemporalUtil.isoDaysInMonth(temporalYM.getYear(), temporalYM.getMonth());
231+
return isoCalendar ? TemporalUtil.isoDaysInMonth(temporalYM.getYear(), temporalYM.getMonth()) : IntlUtil.getCalendarFieldMax(cal, Calendar.DAY_OF_MONTH);
221232
case monthsInYear:
222-
return 12;
233+
return isoCalendar ? 12 : (IntlUtil.getCalendarFieldMax(cal, Calendar.MONTH) + 1);
223234
case inLeapYear:
224-
return JSDate.isLeapYear(temporalYM.getYear());
235+
return isoCalendar ? JSDate.isLeapYear(temporalYM.getYear()) : IntlUtil.isLeapYear(cal);
225236
}
226237
throw Errors.shouldNotReachHere();
227238
}

0 commit comments

Comments
 (0)