time.Duration.between StackOverflow error with items

Hi!

Going further with the previous problem described here I bumped into another problem.

The following code is working (Generating two time values within approx 10 minutes difference and calculating the exact timespan with Duration.between):

var logger = (logger) ? logger : log('testECMA');
opened = time.ZonedDateTime.now().minusSeconds(12-Math.random()*2)
closed = time.ZonedDateTime.now().minusSeconds( 1+Math.random()*2)
logger.debug('Opened: {}, Closed: {}',opened.toString(), closed.toString());
intl = time.Duration.between(opened,closed);
logger.debug('Length: {}',intl.toString());
logger.debug('In milliseconds : {}',intl.toMillis());

log result:

2022-02-08 17:28:59.339 [DEBUG] [g.openhab.automation.script.testecma] - Opened: 2022-02-08T17:28:48.333+01:00[SYSTEM], Closed: 2022-02-08T17:28:57.336+01:00[SYSTEM]
2022-02-08 17:28:59.343 [DEBUG] [g.openhab.automation.script.testecma] - Length: PT9.003S
2022-02-08 17:28:59.345 [DEBUG] [g.openhab.automation.script.testecma] - In milliseconds : 9003.0

Which is absolutely correct.

Meanwhile the following code (getting time values from DateTime items):

var logger = (logger) ? logger : log('testECMA');
opened = items.getItem('MQGarageDoorOpen_Contact_Changed').rawState.getZonedDateTime();
closed = items.getItem('MQGarageDoorClosed_Contact_Changed').rawState.getZonedDateTime();
logger.debug('Opened: {}, Closed: {}',opened.toString(), closed.toString());
intl = time.Duration.between(opened,closed);
logger.debug('Length: {}',intl.toString());
logger.debug('In milliseconds : {}',intl.toMillis());

gives the following error:

2022-02-08 17:29:49.916 [DEBUG] [g.openhab.automation.script.testecma] - Opened: 2022-02-08T16:39:49.665966+01:00, Closed: 2022-02-08T16:40:07.710677+01:00
2022-02-08 17:29:50.081 [ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID ‘bfc6bfd271’ failed: java.lang.Exception: java.lang.StackOverflowError

The difference is only the source of time values. The dumped datetime string is different too ([SYSTEM] is attached to former). What am I missing here? I assume the closed and opened variables are not the same type. Any help would be appreciated?

This works:

opened = time.ZonedDateTime.parse(items.getItem('MQGarageDoorOpen_Contact_Changed').rawState.getZonedDateTime().toString());
closed = time.ZonedDateTime.parse(items.getItem('MQGarageDoorClosed_Contact_Changed').rawState.getZonedDateTime().toString());
logger.debug('Opened: {}, Closed: {}',opened.toString(), closed.toString());
intl = time.Duration.between(opened,closed);
logger.debug('Length: {}',intl.toString());
logger.debug('In milliseconds : {}',intl.toMillis());

2022-02-08 17:39:12.079 [DEBUG] [g.openhab.automation.script.testecma] - Opened: 2022-02-08T16:39:49.665966+01:00, Closed: 2022-02-08T16:40:07.710677+01:00
2022-02-08 17:39:12.090 [DEBUG] [g.openhab.automation.script.testecma] - Length: PT18.044711S
2022-02-08 17:39:12.104 [DEBUG] [g.openhab.automation.script.testecma] - In milliseconds : 18044.0

Is the double ‘conversion’ really needed?

An unfortunate type difference.

items.getItem('SomeDTItem').rawState.getZonedDateTime() will give you an Object of type java.time.ZonedDateTime. That’s right, it’s a Java Object.

time.ZonedDateTime will give you an @joda-js.ZonedDateTime. That’s pure JavaScript.

The two are very much not the same thing, though they are very similar in how they can be used.

You have two choices, either convert the java.time.ZonedDateTime Objects to become joda DTs, or use java.time.Duration instead of time.Duration.

I’m working on a PR to add this and similar conversions to the openhab-js library but that might take a week or so.

If you use java.time.Duration, you’ll need to import it using

var Duration = Java.type('java.time.Duration');

Thank you again. :smiley: