[SOLVED] DateTimeType is deprecated

I’ve seen a couple of posts on this but not really sure how to go about fixing it. I have some rules based off the Tutorials on Time Based Rules, and have this below in one of them.

val long morning_start = (SunmorningNight_Time.state as DateTimeType).calendar.timeInMillis
  val long day_start = (Sunrise_Time.state as DateTimeType).calendar.timeInMillis
  val long afternoon_start = (Sunnoon_Time.state as DateTimeType).calendar.timeInMillis
  val long evening_start = (SuneveningNight_Time.state as DateTimeType).calendar.timeInMillis
  val long night_start = (SuneveningNight_Time.state as DateTimeType).calendar.timeInMillis

But that is showing this in the log

2017-12-14 10:33:58.692 [INFO ] [el.core.internal.ModelRepositoryImpl] - Validation issues found in configuration model 'timeofday.rules', using it anyway:
The method getCalendar() from the type DateTimeType is deprecated
The method getCalendar() from the type DateTimeType is deprecated
The method getCalendar() from the type DateTimeType is deprecated
The method getCalendar() from the type DateTimeType is deprecated
The method getCalendar() from the type DateTimeType is deprecated

You can resolve this by changing

.calendar.timeInMillis

to

.zonedDateTime.toInstant.toEpochMilli

Edit: Note that .toEpochSecond * 1000 also works, but loses a bit of accuracy.

13 Likes

I swear I looked through the JavaDocs and I could not find toEpochMilli. Thanks for posting this!

Since zonedDateTime is also deprecated, you will still get the rule validation warning unless you use .getZonedDateTime.toInstant.toEpochMilli. Also, no need for empty () in the DSL.

[EDIT: oops… I was wrong. My test included .calendar.timeInMillis for comparision, which is why I was getting the validation warning. There’s no validation warning with .zoneDateTime and in looking at the code, is the better choice! ]

1 Like

Ditto! I didn’t think to look in Instant…

https://docs.oracle.com/javase/8/docs/api/java/time/Instant.html#toEpochMilli--

1 Like

Hmm. That’s odd. I’m not getting rule validation warnings on .zonedDateTime.toInstant().toEpochMilli

Nm. I just saw your edit.

I am getting the warning The method or field toEpochSecond is undefined for the type DatTimeType in Visual Studio Code.

My revised code looks like this
if ((now.millis/1000 - (screen_bureau_time.state as DateTimeType).toEpochSecond) > screen_bureau_runtime)

Is this ok ?

You left out the zonedDateTime method, so like this…

if ((now.millis/1000 - (screen_bureau_time.state as DateTimeType).zonedDateTime.toEpochSecond) > screen_bureau_runtime)

I’ve been having fun lately with using Intervals to do time comparisons (the Duration could just be 86400000, but then I end up recalculating in my head how many days that is when reading back through the rule)…

val Boolean totalSolarEclipseThisWeek = new Interval(new Duration(java.util.concurrent.TimeUnit.DAYS.toMillis(7)),new DateTime((Sun_Eclipse_Total.state as DateTimeType).zonedDateTime.toInstant.toEpochMilli)).contains(now)

Probably not helpful for you, but your line could be written to use an Interval like this…

if (new Interval(new Duration(screen_bureau_runtime * 1000),new DateTime((screen_bureau_time.state as DateTimeType).zonedDateTime.toInstant.toEpochMilli)).contains(now))

based on this gist https://gist.github.com/tparton42/3057fda9c62377b3e0d8
i would assume that the shortest way from Joda DateTime to OpenHab DateTimeType via Java’s ZonedDate is as follows (where now represents a Joda DateTime)

MyDateTimeItem.postUpdate(
	new DateTimeType(
		java.time.ZonedDateTime.ofInstant(
			java.time.Instant.ofEpochMilli(now.getMillis),
			java.time.ZoneId.of(now.getZone.getId, java.time.ZoneId.SHORT_IDS)
		)
	)
)
2 Likes

I could not get that to work. My rule just fails silently when it gets to that line. I tried replacing the . with :: for the proper way to access static methods and values. This is probably one of those cases where I’m willing to give up some CPU efficiency to gain some easier to read and understand the code:

MyDateTimeItem.postUpdate(now.toString)

I’m sure with a little work I could figure out what the error is, but for now I wouldn’t recommend that approach for converting from Joda to DateTimeType when the toString works so well, at least in the case where we are posting the update or sending a command.

The D in getID needs to be capitalized…

MyDateTimeItem.postUpdate(
	new DateTimeType(
		java.time.ZonedDateTime.ofInstant(
			java.time.Instant.ofEpochMilli(now.getMillis),
			java.time.ZoneId.of(now.getZone.getID, java.time.ZoneId.SHORT_IDS)
		)
	)
)

I also experienced the “deprecated-notification” today and wanted to code according to the new standards.
I however didn’t find how to convert the milliseconds back to a DateTimeType, as the wiki is also deprecated.
I want to post an update to a DateTime item.
How to do this?
My goal is to store the time when the wasing mashine starts and update another item when it finishes with the washing duration (starttime - now). Maybe you got a better idea of how to do this, if so, please let me know :slight_smile:

rule "test time difference"
when
	Time cron "*/10 * * * * ?"
then
	val calendar = java.util.Calendar::getInstance
	calendar.timeInMillis = now.millis - (Waschkueche_Waschmaschine_startZeit.state as DateTimeType).zonedDateTime.toInstant.toEpochMilli
	Waschkueche_Waschmaschine_letzteZykluszeit.postUpdate(new DateTimeType(calendar))
end

This works but I want to solve it according to the new standard.
Thanks for your help :slight_smile:

Maybe it is unusual to store time differences in a DateTime item.
I should maybe better use a Number item.
Can anyone show me how to format the Number item from milliseconds to hours and minutes in the sitemap?

Staying with a DateTime item will work for this. It makes the formatting easier, but you need to be mindful of the timezone…

Waschkueche_Waschmaschine_letzteZykluszeit.postUpdate(new DateTime(now.millis - (Waschkueche_Waschmaschine_startZeit.state as DateTimeType).zonedDateTime.toInstant.toEpochMilli, DateTimeZone.UTC).toString)

If you setup your item label to be formatted like this, it should display in HH:MM:SS…

DateTime Waschkueche_Waschmaschine_letzteZykluszeit "Dish Washing Time [%1$tT]"

More formatting options can be found in here though… https://docs.oracle.com/javase/8/docs/api/java/util/Formatter.html#syntax

1 Like

Thank you very much, I got it working as I wanted it :slight_smile:

1 Like

I’m also having trouble with the deprecation of DateTime in the latest build using JSR223,
Can you give me a hint what the new coding standards would be?

I will give you an example and hope it helps:

Items:

DateTime Waschkueche_Waschmaschine_startZeit "Waschmaschine Startzeit [%1$tH:%1$tM Uhr]" (Waschkueche, Zeit)
DateTime Waschkueche_Waschmaschine_letzteZykluszeit "Letzte Waschdauer [%1$tH:%1$tM h]" (Waschkueche, Zeit)

Update item with current time (no change):

Waschkueche_Waschmaschine_startZeit.postUpdate(now.toString)

Get millis from item:

(Waschkueche_Waschmaschine_startZeit.state as DateTimeType).zonedDateTime.toInstant.toEpochMilli

Calculate time difference between stored time and now and update item with result:

Waschkueche_Waschmaschine_letzteZykluszeit.postUpdate(new DateTime(now.millis - (Waschkueche_Waschmaschine_startZeit.state as DateTimeType).zonedDateTime.toInstant.toEpochMilli, DateTimeZone.UTC).toString)
1 Like

Thank you for your hint.
I came up with following solution to replace the deprecated DateTime.

from java.time import OffsetDateTime

events.postUpdate(_uitem, str(OffsetDateTime.now()))

Wouldn’t it be a good idea to update the documentation’s sample code? The sample code on the Rules page of the documentation is itself now deprecated… hardly a good start for those trying to fight their way through the absurd DateTimeType vs Joda DateTime wrangle for the first time.

1 Like

Yes, it would
You can do that yourself by following the link at the bottom of the docs page: