Skip to content

Commit b76f13e

Browse files
authored
[time] toZDT: Add support for Instant & toInstant: Add support for epoch millis (#422)
Closes #420. Signed-off-by: Florian Hotze <[email protected]>
1 parent 067a054 commit b76f13e

File tree

7 files changed

+57
-12
lines changed

7 files changed

+57
-12
lines changed

README.md

+12-10
Original file line numberDiff line numberDiff line change
@@ -978,6 +978,7 @@ The following rules are used during the conversion:
978978
| `null` or `undefined` | `time.ZonedDateTime.now()` | `time.toZDT();` |
979979
| `time.ZonedDateTime` | passed through unmodified | |
980980
| `java.time.ZonedDateTime` | converted to the `time.ZonedDateTime` equivalent | |
981+
| `time.Instant`, `java.time.Instant` | converted to the `time.ZonedDateTime` equivalent using `SYSTEM` as the timezone | `time.toZDT(time.toInstant(500));` (epoch milli 500 to ZDT) |
981982
| JavaScript native `Date` | converted to the `time.ZonedDateTime` equivalent using `SYSTEM` as the timezone | |
982983
| `number`, `bingint`, `java.lang.Number`, `DecimalType` | rounded to the nearest integer and added to `now` as milliseconds | `time.toZDT(1000);` |
983984
| [`Quantity`](#quantity) or `QuantityType` | if the unit is time-compatible, added to `now` | `time.toZDT(item.getItem('MyTimeItem').rawState);`, `time.toZDT(Quantity('10 min'));` |
@@ -1100,16 +1101,17 @@ console.log(timestamp.getMillisFromNow());
11001101
11011102
The following rules are used during the conversion:
11021103
1103-
| Argument Type | Rule | Examples |
1104-
|-----------------------------------------------|------------------------------------------------------------------------------------------|----------------------------------------------|
1105-
| `null` or `undefined` | `time.Instant.now()` | `time.toInstant();` |
1106-
| `time.Instant` | passed through unmodified | |
1107-
| `java.time.Instant` | converted to the `time.Instant` equivalent | |
1108-
| `java.time.ZonedDateTime` | converted to the `time.Instant` equivalent | |
1109-
| JavaScript native `Date` | converted to the `time.Instant` equivalent | |
1110-
| `items.Item` or `org.openhab.core.types.Item` | if the state is supported (see the `*Type` rules in this table), the state is converted | `time.toInstant(items.getItem('MyItem'));` |
1111-
| `String`, `java.lang.String`, `StringType` | parsed | `time.toInstant('2019-10-12T07:20:50.52Z');` |
1112-
| `DateTimeType` | converted to the `time.Instant` equivalent | |
1104+
| Argument Type | Rule | Examples |
1105+
|--------------------------------------------------------|-----------------------------------------------------------------------------------------|----------------------------------------------|
1106+
| `null` or `undefined` | `time.Instant.now()` | `time.toInstant();` |
1107+
| `time.Instant` | passed through unmodified | |
1108+
| `java.time.Instant` | converted to the `time.Instant` equivalent | |
1109+
| `number`, `bingint`, `java.lang.Number`, `DecimalType` | handled as epoch milliseconds and converted to the `time.Instant` equivalent | `time.toInstant(500);` |
1110+
| `java.time.ZonedDateTime` | converted to the `time.Instant` equivalent | |
1111+
| JavaScript native `Date` | converted to the `time.Instant` equivalent | |
1112+
| `items.Item` or `org.openhab.core.types.Item` | if the state is supported (see the `*Type` rules in this table), the state is converted | `time.toInstant(items.getItem('MyItem'));` |
1113+
| `String`, `java.lang.String`, `StringType` | parsed | `time.toInstant('2019-10-12T07:20:50.52Z');` |
1114+
| `DateTimeType` | converted to the `time.Instant` equivalent | |
11131115
11141116
When a type or string that cannot be handled is encountered, an error is thrown.
11151117

src/time.js

+23
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,7 @@ function javaZDTToJsZDT (zdt) {
246246
* - null, undefined: time.ZonedDateTime.now()
247247
* - time.ZonedDateTime: unmodified
248248
* - Java ZonedDateTime, DateTimeType: converted to time.ZonedDateTime equivalent
249+
* - time.Instant, Java Instant: converted to time.ZonedDateTime equivalent
249250
* - JavaScript native {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date Date}: converted to a `time.ZonedDateTime` using configured timezone
250251
* - number, bigint, Java Number, DecimalType: rounded and added to `time.ZonedDateTime.now()` as milliseconds
251252
* - {@link Quantity} & QuantityType: if the unit is time-compatible, added to `time.ZonedDateTime.now()`
@@ -279,6 +280,18 @@ function toZDT (when) {
279280
return javaZDTToJsZDT(when);
280281
}
281282

283+
// Convert time.Instant
284+
if (_isInstant(when)) {
285+
log.debug('toZDT: Converting time.Instant ' + when);
286+
return when.atZone(time.ZoneId.systemDefault());
287+
}
288+
289+
// Convert Java Instant
290+
if (when instanceof javaInstant) {
291+
log.debug('toZDT: Converting Java Instant ' + when);
292+
return javaInstantToJsInstant(when).atZone(time.ZoneId.systemDefault());
293+
}
294+
282295
// String or StringType
283296
if (typeof when === 'string' || when instanceof javaString || when instanceof StringType) {
284297
log.debug('toZDT: Parsing string ' + when);
@@ -360,6 +373,7 @@ time.ZonedDateTime.prototype.toToday = function () {
360373
* - time.ZonedDateTime: converted to the time.Instant equivalent
361374
* - Java Instant, DateTimeType: converted to time.Instant equivalent
362375
* - JavaScript native {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date Date}: converted to a `time.Instant`
376+
* - number, bigint, Java Number, DecimalType: assumed to be epoch milliseconds and converted to a `time.Instant`
363377
* - Item: converts the state of the Item based on the *Type rules described here
364378
* - String, Java String, StringType: parsed
365379
* @memberof time
@@ -405,6 +419,15 @@ function toInstant (when) {
405419
return time.Instant.from(native);
406420
}
407421

422+
// Convert epoch milliseconds
423+
if (typeof when === 'number' || typeof when === 'bigint') {
424+
log.debug('toInstant: Converting epoch milli ' + when);
425+
return time.Instant.ofEpochMilli(when);
426+
} else if (when instanceof javaNumber || when instanceof DecimalType) {
427+
log.debug('toInstant: Converting Java number or DecimalType ' + when);
428+
return time.Instant.ofEpochMilli(when.floatValue());
429+
}
430+
408431
// DateTimeType, extract the javaInstant and convert to time.Instant
409432
if (when instanceof DateTimeType) {
410433
log.debug('toInstant: Converting DateTimeType ' + when);

test/java.mock.js

+6
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,11 @@ class Class {
1313
}
1414
}
1515

16+
// java.lang.String (https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/String.html)
17+
class String {
18+
toString () {}
19+
}
20+
1621
// java.math.BigDecimal (https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/math/BigDecimal.html)
1722
class BigDecimal {}
1823
BigDecimal.valueOf = jest.fn(() => new BigDecimal());
@@ -76,6 +81,7 @@ class FrameworkUtil {
7681

7782
module.exports = {
7883
Class,
84+
String,
7985
ArrayList,
8086
BigDecimal,
8187
Instant,

test/jest.setup.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
const { ModuleBuilder, Configuration, QuantityType, JavaScriptExecution, JavaTransformation, JavaNotificationAction } = require('./openhab.mock');
2-
const { Class, BigDecimal, ArrayList, HashSet, Hashtable, UUID, FrameworkUtil, LoggerFactory, Instant, ZonedDateTime } = require('./java.mock');
2+
const { Class, String, BigDecimal, ArrayList, HashSet, Hashtable, UUID, FrameworkUtil, LoggerFactory, Instant, ZonedDateTime } = require('./java.mock');
33

44
const TYPES = {
55
'java.lang.Class': Class,
6+
'java.lang.String': String,
67
'java.math.BigDecimal': BigDecimal,
78
'java.time.Instant': Instant,
89
'java.time.ZonedDateTime': ZonedDateTime,

test/time.spec.js

+11
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,11 @@ describe('time.js', () => {
2020
expect(time.toZDT(zdt)).toBe(zdt);
2121
});
2222

23+
it('converts if when is a time.Instant', () => {
24+
const instant = time.Instant.now();
25+
expect(time.toZDT(instant)).toStrictEqual(instant.atZone(time.ZoneId.systemDefault()));
26+
});
27+
2328
it('delegates to parseString', () => {
2429
const when = 'when';
2530
expect(() => time.toZDT(when)).toThrow('Failed to parse string when: DateTimeParseException: Text cannot be parsed to a Duration: when, at index: 0');
@@ -45,6 +50,12 @@ describe('time.js', () => {
4550
expect(time.toInstant(string)).toStrictEqual(instant);
4651
});
4752

53+
it('converts if when is epoch millis', () => {
54+
const instant = time.Instant.now();
55+
const millis = instant.toEpochMilli();
56+
expect(time.toInstant(millis)).toStrictEqual(instant);
57+
});
58+
4859
// TODO: Add remaining possible cases for when
4960
});
5061

types/time.d.ts

+2
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ declare function javaZDTToJsZDT(zdt: JavaZonedDateTime): time.ZonedDateTime;
9999
* - null, undefined: time.ZonedDateTime.now()
100100
* - time.ZonedDateTime: unmodified
101101
* - Java ZonedDateTime, DateTimeType: converted to time.ZonedDateTime equivalent
102+
* - time.Instant, Java Instant: converted to time.ZonedDateTime equivalent
102103
* - JavaScript native {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date Date}: converted to a `time.ZonedDateTime` using configured timezone
103104
* - number, bigint, Java Number, DecimalType: rounded and added to `time.ZonedDateTime.now()` as milliseconds
104105
* - {@link Quantity} & QuantityType: if the unit is time-compatible, added to `time.ZonedDateTime.now()`
@@ -124,6 +125,7 @@ declare function toZDT(when?: any): time.ZonedDateTime;
124125
* - time.ZonedDateTime: converted to the time.Instant equivalent
125126
* - Java Instant, DateTimeType: converted to time.Instant equivalent
126127
* - JavaScript native {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date Date}: converted to a `time.Instant`
128+
* - number, bigint, Java Number, DecimalType: assumed to be epoch milliseconds and converted to a `time.Instant`
127129
* - Item: converts the state of the Item based on the *Type rules described here
128130
* - String, Java String, StringType: parsed
129131
* @memberof time

types/time.d.ts.map

+1-1
Original file line numberDiff line numberDiff line change

0 commit comments

Comments
 (0)