OH 3 isBefore and isAfter - not a member of org.openhab.core.library.types.DateTimeType

I’ve been struggling with this rule for over 2 months now. It only runs in the morning with the alarm, so I wait 24 hours to see my results of the change.

This rule looks at an Alexa alarm then turns lights on gradually based on being within X minutes of the alarm.

Here’s where I’m at rewriting the logic from OH 2.x to OH 3.x based on the date/time conversion issues with OH3. I’ve pieced meal the rule below to keep it simple.

var String alarmtime = 'NULL'
var String alarmdate = 'NULL'
var CurrentDT = new DateTimeType(now().plusDays(0))

alarmtime = transform("JSONPATH", "$.notifications[" + i + "].originalTime", json)
alarmdate = transform("JSONPATH", "$.notifications[" + i + "].originalDate", json)

var setAlarmTime = new DateTimeType(alarmdate + "T" + alarmtime)

Here’s the variable values after the logic above:

CurrentDT is    2021-12-29T05:00:49.454941-0600
Alexa alarm is  2021-12-29T07:15:00.000-0600

Here’s the problem line:

if (CurrentDT.isBefore(setAlarmTime) && CurrentDT.plusMinutes(20).isAfter(setAlarmTime))

Here’s the error I’m getting:

'isBefore' is not a member of 'org.openhab.core.library.types.DateTimeType'; line 11576, column 10, length 32 in default
				

Any help would be grateful.

Best, Jay

You will have noticed that the most powerful type of object to use to represent a date-time in rules is the Java ZonedDateTime
This has methods for offsets, before/after tests, etc.
The system variable now for example is a ZonedDateTime object in OH3

DateTime type Items have a state holding the less-useful DateTimeType. That’s because of history, but it is easy enough to get that info converted to the ZonedDateTime when required.
In the bit of code that you have shown us here - who cares about that anyway? There are no Item states involved at all.

So as now is already ZonedDateTime, let’s just use it as it is.

var CurrentZDT = now().plusDays(0)
// but really that's just 
var CurrentZDT = now

So the test becomes

if (CurrentZDT.isBefore(setAlarmTime) && ...

and the ZonedDateTime object has isBefore/isAfter methods.

But, of course, you need that setAlarmTime variable to be ZDT as well.
I think this should do that from your string fragments -

var setAlarmTime = ZonedDateTime.parse(alarmdate + "T" + alarmtime)
1 Like

Hi rossko57,

We are closer, here’s the error we have now.

Script execution of rule with UID ‘default-95’ failed: Text ‘2021-12-30T07:15:00.000’ could not be parsed at index 23 in default

My guess the error is tied to this line:

var setAlarmTime = ZonedDateTime.parse(alarmdate + “T” + alarmtime)

Here’s the value of “now” which includes the time zone.

CurrentDT is 2021-12-30T05:30:49.060368-06:00[America/Chicago]

Any ideas?

Best, Jay

May I should just append this to the time side of the string so they match?

000-06:00[America/Chicago]

Best, Jay

Oh yes, ZonedDateTime wants timezone info of course.
Let’s assume this imported timestamp is in our locale -

var setAlarmTime = LocalDateTime.parse(alarmdate + “T” + alarmtime)

More complicated approaches -

Everything is working again! Thank you so much @rossko57 !

Here’s what I changed per your recommendations:

var CurrentDT = now
var setAlarmTime = ZonedDateTime.parse(alarmdate + "T" + alarmtime + "000-06:00[America/Chicago]")

The rule logic stayed the same but now works:

if (CurrentDT.isBefore(setAlarmTime) && CurrentDT.plusMinutes(20).isAfter(setAlarmTime)) {

Best, Jay

1 Like