OH3 Getting .zonedDateTime.toInstant.toEpochMilli from an existing Item

I’ve used this example below and it works when you .postUpdate a NEW date variable in the rule but the issue I’m having is I want to use a pre-existing Item that already has the date in there which it doesn’t work.

Item File:

DateTime	      OH_Uptime    "Up Time [%1$tm.%1$td.%1$tY %1$tH:%1$tM]"		<time>	

Rule File:

import java.time.ZonedDateTime

Rule1:
OH_Uptime.postUpdate(new DateTimeType())

Result:
OH_Uptime variable is 2021-11-18T13:22:50.251059-0600

Rule 2: (neither one works)
val Number item_millis = OH_Uptime.zonedDateTime.toInstant.toEpochMilli
val Number item_millis = OH_Uptime.state.zonedDateTime.toInstant.toEpochMilli

Any suggestions would be helpful.

Best, Jay

The example you pointed to shows

val Number item_millis = (My_Item.state as DateTimeType).zonedDateTime.toInstant.toEpochMilli

maybe you could try that.

Not sure what your import is about.

1 Like

Thank you so much, it was right in front of my face but I couldn’t see it.

2021-11-19 07:07:09.510 [INFO ] [g.openhab.core.model.script.OHUpTime] - Starting to set OH Uptime Difference Calculation.
2021-11-19 07:07:09.512 [INFO ] [g.openhab.core.model.script.OHUpTime] - OH_Uptime.state is 2021-11-19T07:07:09.492889-0600
2021-11-19 07:07:09.516 [INFO ] [g.openhab.core.model.script.OHUpTime] - item_millis variable is 1637327229492
2021-11-19 07:07:09.518 [INFO ] [g.openhab.core.model.script.OHUpTime] - now_millis variable is 1637327229517
2021-11-19 07:07:09.521 [INFO ] [g.openhab.core.model.script.OHUpTime] - diff variable is 0.00041667

Best, Jay

Behind the scenes, a state type object is not a DateTimeType type object (it could be ON/OFF or numeric or …), so it doesn’t have methods like .ZonedDateTime. You have to force it, using as

The error message logged should have hinted at this.

So why do you need to mess with milliseconds on the first place? It’s almost never the easiest nor more straight forward way to work with date times these days. If all you want to do is update a DateTime Item’s current state to another DateTime Item

OtherItem.postUpdate(CurrentItem.state)

You don’t need to mess with the fact that it’s a DateTimeType at all.

What if you want to move that date time before updating OtherItem?

OtherItem.postUpdate((CurrentItem.state as DateTimeType).getZonedDateTime().plusDays(1))

Again, there is no need to go all the way down to milliseconds.

If you want to get the difference between two DateTime Item’s states it’s more flexible to use Duration.

var diff = java.time.Duration((CurrentItem.state as DateTimeType).getZonedDateTime(), (OtherItem.state as DateTimeType).getZonedDateTime())
var diffSecs = diff.seconds()
var diffStr = diff.toString() // will be in the format DD HH:MM:SS.mmm

It’s about converting an uptime reporting OH 2.x rule to OH 3.x. Here’s the rule I have had in place for 3 years now that needed fixing.

I didn’t want to rewrite the logic, just wanted to fix the OH2 to OH3 conversion issue.

Show openHAB uptime - Tutorials & Examples - openHAB Community

Best, Jay

rule "Openhab Uptime"
when
	System started
then
    OH_Uptime.postUpdate(now)
end


rule "Openhab Uptime readable"
when
    Item OH_Uptime changed or
    Time cron "1 1 * * * ?"
then

    // Nothing to do when OH_Uptime doesn't have a usable state
    if(OH_Uptime.state == NULL || OH_Uptime.state == UNDEF){
        return;
    }
    var diff = java.time.Duration(now, (OH_Uptime.state as DateTimeType).getZonedDateTime())
    OH_Uptime_HumanReadable.postUpdate(diff.toString())
end
1 Like

Wow! Thank you - so much code reduced . . .

Best, Jay

That’s why I keep pushing alternatives to messing with milliseconds. The code is so much shorter and easier to understand when using the tools available like Duration.

NOTE: I just typed in the above. There might be errors. Let me know if it doesn’t work as expected.