Skip to content

Commit f926a31

Browse files
committed
convert Temporal.ZonedDateTime asInstant(), asDate(), asTime(), asTimeZone(), and test
1 parent 8095f92 commit f926a31

File tree

2 files changed

+103
-25
lines changed

2 files changed

+103
-25
lines changed

graal-js/src/com.oracle.truffle.js.test/src/com/oracle/truffle/js/test/interop/TemporalInteropToJavaTest.java

Lines changed: 27 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,9 @@ private static Context getJSContext() {
6363
return JSTest.newContextBuilder(ID).option("js.temporal", "true").build();
6464
}
6565

66+
// Calendar, Duration, PlainMonthDay, PlainYearMonth cannot be converted to Instant, Date or
67+
// Time
68+
6669
@Test
6770
public void testInstant() {
6871
try (Context ctx = getJSContext()) {
@@ -101,16 +104,6 @@ public void testInstant() {
101104
}
102105
}
103106

104-
// TODO
105-
// @Test
106-
// public void testCalendar() {
107-
// }
108-
109-
// TODO
110-
// @Test
111-
// public void testDuration() {
112-
// }
113-
114107
@Test
115108
public void testPlainDate() {
116109
try (Context ctx = getJSContext()) {
@@ -122,7 +115,8 @@ public void testPlainDate() {
122115

123116
Assert.assertFalse(val.isTime());
124117
Assert.assertFalse(val.isTimeZone());
125-
}}
118+
}
119+
}
126120

127121
@Test
128122
public void testPlainTime() {
@@ -158,16 +152,6 @@ public void testPlainDateTime() {
158152
}
159153
}
160154

161-
// TODO
162-
// @Test
163-
// public void testPlainMonthDay() {
164-
// }
165-
166-
// TODO
167-
// @Test
168-
// public void testPlainYearMonth() {
169-
// }
170-
171155
@Test
172156
public void testTimeZone() {
173157
try (Context ctx = getJSContext()) {
@@ -191,9 +175,27 @@ public void testTimeZone() {
191175
}
192176
}
193177

194-
// TODO
195-
// @Test
196-
// public void testZonedDateTime() {
197-
// }
178+
@Test
179+
public void testZonedDateTime() {
180+
try (Context ctx = getJSContext()) {
181+
Value val = ctx.eval(ID, "new Temporal.ZonedDateTime(100_123_456_789n, Temporal.TimeZone.from('Europe/Vienna'));");
182+
Instant inst = val.asInstant();
183+
Assert.assertEquals(123_456_789L, inst.getNano());
184+
Assert.assertEquals(100, inst.getEpochSecond());
185+
186+
LocalDate ld = val.asDate();
187+
Assert.assertEquals(1970, ld.getYear());
188+
Assert.assertEquals(Month.JANUARY, ld.getMonth());
189+
Assert.assertEquals(1, ld.getDayOfYear());
198190

191+
LocalTime lt = val.asTime();
192+
Assert.assertEquals(1, lt.getHour()); // offset of +1 due to timezone
193+
Assert.assertEquals(1, lt.getMinute());
194+
Assert.assertEquals(40, lt.getSecond());
195+
Assert.assertEquals(123_456_789L, lt.getNano());
196+
197+
ZoneId zid = val.asTimeZone();
198+
Assert.assertEquals("Europe/Vienna", zid.getId());
199+
}
200+
}
199201
}

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

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,27 @@
4040
*/
4141
package com.oracle.truffle.js.runtime.builtins.temporal;
4242

43+
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
44+
import com.oracle.truffle.api.interop.InteropLibrary;
45+
import com.oracle.truffle.api.interop.UnsupportedMessageException;
46+
import com.oracle.truffle.api.library.ExportLibrary;
47+
import com.oracle.truffle.api.library.ExportMessage;
4348
import com.oracle.truffle.api.object.Shape;
49+
import com.oracle.truffle.api.strings.TruffleString;
4450
import com.oracle.truffle.js.runtime.BigInt;
4551
import com.oracle.truffle.js.runtime.objects.JSDynamicObject;
4652
import com.oracle.truffle.js.runtime.objects.JSNonProxyObject;
53+
import com.oracle.truffle.js.runtime.objects.JSObject;
54+
import com.oracle.truffle.js.runtime.util.TemporalConstants;
55+
import com.oracle.truffle.js.runtime.util.TemporalUtil;
4756

57+
import java.math.BigInteger;
58+
import java.time.Instant;
59+
import java.time.LocalDate;
60+
import java.time.LocalTime;
61+
import java.time.ZoneId;
62+
63+
@ExportLibrary(InteropLibrary.class)
4864
public class JSTemporalZonedDateTimeObject extends JSNonProxyObject implements TemporalCalendar {
4965

5066
private final BigInt nanoseconds; // 6.4. A BigInt value
@@ -70,4 +86,64 @@ public JSDynamicObject getCalendar() {
7086
public JSDynamicObject getTimeZone() {
7187
return timeZone;
7288
}
89+
90+
@ExportMessage
91+
@TruffleBoundary
92+
Instant asInstant() {
93+
BigInteger[] res = nanoseconds.bigIntegerValue().divideAndRemainder(TemporalUtil.BI_10_POW_9);
94+
return Instant.ofEpochSecond(res[0].longValue(), res[1].intValue());
95+
}
96+
97+
@ExportMessage
98+
final boolean isTimeZone() {
99+
return getZoneIdIntl() != null;
100+
}
101+
102+
@ExportMessage
103+
@TruffleBoundary
104+
final ZoneId asTimeZone() throws UnsupportedMessageException {
105+
ZoneId tzObj = getZoneIdIntl();
106+
if (tzObj == null) {
107+
throw UnsupportedMessageException.create();
108+
}
109+
return tzObj;
110+
}
111+
112+
@TruffleBoundary
113+
private ZoneId getZoneIdIntl() {
114+
if (timeZone instanceof JSTemporalTimeZoneObject) {
115+
JSTemporalTimeZoneObject tzObj = (JSTemporalTimeZoneObject) timeZone;
116+
return tzObj.asTimeZone();
117+
}
118+
Object tzID = JSObject.get(timeZone, TemporalConstants.TIME_ZONE);
119+
if (tzID instanceof TruffleString) {
120+
String id = ((TruffleString) tzID).toJavaStringUncached();
121+
return ZoneId.of(id);
122+
}
123+
return null;
124+
}
125+
126+
@ExportMessage
127+
final boolean isDate() {
128+
return isTimeZone();
129+
}
130+
131+
@ExportMessage
132+
@TruffleBoundary
133+
final LocalDate asDate() throws UnsupportedMessageException {
134+
LocalDate ld = LocalDate.ofInstant(asInstant(), asTimeZone());
135+
return ld;
136+
}
137+
138+
@ExportMessage
139+
final boolean isTime() {
140+
return isTimeZone();
141+
}
142+
143+
@ExportMessage
144+
@TruffleBoundary
145+
final LocalTime asTime() throws UnsupportedMessageException {
146+
LocalTime lt = LocalTime.ofInstant(asInstant(), asTimeZone());
147+
return lt;
148+
}
73149
}

0 commit comments

Comments
 (0)