DateTime Conversion (openHAB 3.x)

Hello what I noticed is that java time doesn’t support parse.

1 Like

An alternative approach

val Differenz = ChronoType.SECONDS.between(Spater, Epoche)

Instead of importing org.joda.time.DateTime import java.time.ZonedDateTime.

And to get now use ZonedDateTime.now().

There is no more DateTime. You need to use ZonedDateTime. I think it might be as simple as changing the timestamp line to use ZonedDateTime instead of DateTime.

@AndreasK,

See Java Time API converting ISO 8601 to ZonedDateTime - Stack Overflow for a one liner to parse ISO8601 to get to a ZonedDateTime as well as a lot more description about how this all works.

The Rules DSL language tries really hard to figure out the types of things and when it needs to call toString on somethings. But it does so based on the current expression it’s in. For example:

“”+currentDateTimeType

would probably work. It sees you want a String because you are doing a String operations and all Objects have a toString method.

currentDateTimeType+""

Might not work because the first operand sets the type so it will probably complain that DateTimeType doesn’t have a + operator.

currentDateTimeType

all by itself doesn’t work because there is nothing else in the expression to tell it that it needs to be a String. The fact that the postUpdate method requires a String as the second argument isn’t enough.

@Malti1812 Note that I believe Easter and other similar religious holidays are implemented in and provided by Ephemeris. If it’s not there by default when you set your country and region then you can easily add it.

Create a DateTimeType

str(new DateTimeType(now.plusSeconds(timeout)))

Alternatively, use LocalDateTime (which is what DateTimeType does I think).

hello

can someone help me with my DateTime Problem?

i know that DateTime is not longer avaiable, but DateTimeType doesnt work.

 if (now.isBefore(new DateTime((next_event_at.state as DateTimeType).getZonedDateTime.toInstant.toEpochMilli).plusHours(24)) && 
        now.isAfter(new DateTime((next_event_at.state as DateTimeType).getZonedDateTime.toInstant.toEpochMilli).minusHours(8))) { 

Hi

Sorry, but the GUI should be easier and better than with OH2, but so far it is not. I would also like to move away from files and only do everything in the GUI. So I have a very simple question, what do I have to enter for metadata if I want to see the time stamp as follows: “hh: nn: ss dd.mm.yyyy”. Not everyone is a programmer or has 2 hours to test the date or to search in google. Help me please and others, simply naming a field with “pattern” isn’t helpfull or easy to normal openhab users. And there is no description available,or I am wrong? Thanks.

Hi,

try this if your time is ISO 8601 looks like this

2021-03-04T10:10:30

%1$tH:%1$tM:%1$tS %1$td.%1$tm.%1$tY

Hi,

Sorry, I am also stuck with the time format. I want to send a Date val via http-Binding to an influxdb. As this DateTime stamp is in the future (forecast), I cannot use the normal timestamp but must overwrite it. In OH2 it would have been as follows:

val ti24H00M = new DateTime(WestV48_DateTime.state.toString).millis.toString + "000000"

I tried it with EpochMilli but didn’t get it running. Just got the Error:

[ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID 'rule' failed: An error occurred during the script execution: null in rule

Any hints?

Thanks a lot, Christoph

As shown in #4 in the original post above to get the ZonedDateTime from a DateTime Item.

(WestV48_DateTime.state as DateTimeType).getZonedDateTime()

To get Epoch from a Java Time see #7.

(WestV48_DateTime.state as DateTimeType).getZonedDateTime.toInstant.toEpochMilli

or

(WestV48_DateTime.state as DateTimeType).getZonedDateTime.toEpochSecond * 1000

#8 variant B appears to have an error. There is no more DateTime in Java. @anfaenger, can you take a look at #8 variant B? That’s how it would work in the old OH 2.5 Joda DateTime type but won’t work with ZonedDateTime like that.

Over all I don’t think variant B there makes sense any more to get Epoch from a DateTimeType.

2 Likes

Thanks a lot! Both options seem to work. Now I just need to fix the rest and post it in the influxdb :slight_smile:

@anfaenger #3 needs to have ZonedDateTime -> DateTimeType

1 Like

I’m also converting my OH2 rules to OH3 and I’m stuggeling with my dates

For testing I’m just trying the get the current date and display it in a specific format

val ZonedDateTime today = ZonedDateTime.now()
logInfo("TestScript", today.format("%1$td.%1$tm.%1$ty %1$tH:%1$tM"))

But this second line gives this error:
Type mismatch: cannot convert from String to DateTimeFormatter; line 10, column 386, length 31

ZonedDateTime’s format expects a DateTimeFormatter. You’ve supplied a String formatter. They are two completely different things and work very different from each other. To do it like that you need something closer to

"".format("%1$td.%1$tm.%1$ty %1$tH:%1$tM", today)

Or you need to import DateTimeFormatter (Java SE 11 & JDK 11 ), create an instance with the formatting String that supports and pass that to today.format().

This is how it should have worked in OH 2 as well I think, though the source of the DateTimeFormatter for Joda DateTime was different I think.

1 Like

And what if I receive a String from an API request: 2021-03-04T20:49:29.000+0100
How can I convert this string to a format so I can extract dates, add days/months… ?
Sorry for these dumb questions, but I’m realy lost on this in OH3

Pretty much the same way as you always have. OH 3 has some new stuff but for everything else it’s pretty much the same.

That’s an ISO8601 formatted date time string. DateTimeType can be initialized by that type of String. So why not just link that to a DateTime Item in the first place? Then you don’t even have to mess with it in your rules?

If the string is coming from a call to a script or something in a rule, just postUpdate the String to the DateTime Item.

If you must parse this in your rules for some reason, just create a new DateTimeType("2021-03-04T20:49:29.000+0100") and it will parse it for you. Then to compare it to other DateTimes pull the zonedDateTime from the DateTimeType.

Sometimes I’m really amazed at how complicated people make this DateTime stuff. It’s franly easier now than it ever was with Joda DateTime because now our DateTimeType carries the ZonedDateTime version of the date time right there. No parsing or extra processing required. But even before in OH 3, as long as the DT String is ISO8601 compatible the only thing one has to do is create a new DT object passing the String unchanged.

I was almost there, I was just missing .zonedDateTime. Now I’m able to add hours, minutes and compare it with the current date. :slight_smile:
Thanks for helping once again!

1 Like

Thank you for your comment :+1:.
I will have a look later.

I have some problems in a rule with DateTime

I have an icalender item like this:

String   first_event_name_today         "first event [%s]"                              <calendar> { channel="icalendar:eventfilter:today:result_0#title" }

In my rule it is possible to do something like this:

if(first_event_name_today.state==UNDEF){

I then tried to shorten my code and save my item in a variable based on the day:

var String nachricht = ""
var DateTime event1
var DateTime event2
var DateTime event3

var Number hours = now.getHour

if (hours < 10){
    event1 = first_event_name_today
    event2 = second_event_name_today
    event3 = third_event_name_today
    nachricht = "Heute "

} else {
    event1 = first_event_name_tomorrow
    event2 = second_event_name_tomorrow
    event3 = third_event_name_tomorrow
    nachricht = "Morgen "
}

But when I now do the UNDEF check there is an error in the log

2021-03-16 08:00:26.104 [ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID 'Kalender-1' failed: 'state' is not a member of 'DateTime'; line 113, column 53, length 12 in Kalender

So what did I miss?

You have to use .state. Maybe consider to post the complete rule, not only snippets.

So my whole rule looks like this:

val logPrefix = "Kalender.rules: "
val telegramAction = getActions("telegram","telegram:telegramBot:FS6")


rule "Abfallkalender"
when
    Time cron "0 1 17 ? * * *" or  Time cron "0 0 20 ? * * *"

then   
var String nachricht = ""
var DateTime event1
var DateTime event2
var DateTime event3

var Number hours = now.getHour

if (hours < 10){
    event1 = first_event_name_today
    event2 = second_event_name_today
    event3 = third_event_name_today
    nachricht = "Heute "

} else {
    event1 = first_event_name_tomorrow
    event2 = second_event_name_tomorrow
    event3 = third_event_name_tomorrow
    nachricht = "Morgen "
 }

if(event1!=NULL && event1.state==UNDEF){
            logError("rules", logPrefix + "Event5 undef Heute kein muell {{}}", event1.state)

    return
} else {
        nachricht += "wird folgender Müll geholt: "
        var titel = event1.state.toString
        if(titel.length>=3 && titel.startsWith("EB ")){
            nachricht = nachricht + titel.substring(3, titel.length)   
        }
}

if(event2.state != UNDEF){
        var titel = event2.state.toString
        if(titel.length>=3 && titel.startsWith("EB ")){
            nachricht = nachricht + ", " + titel.substring(3, titel.length)   
        }
}


if(event3.state != UNDEF){
        var titel = event3.state.toString
        if(titel.length>=3 && titel.startsWith("EB ")){
            nachricht = nachricht + ", " + titel.substring(3, titel.length)   
        }
}


if (nachricht != ""){
    logError("rules", logPrefix + nachricht)
    telegramAction.sendTelegram(nachricht)
    say(nachricht, "picotts:deDE", "sonos:One:Wohnzimmer")
}

end

The error is the following:

2021-03-16 17:05:30.907 [ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID ‘Kalender-1’ failed: ‘state’ is not a member of ‘DateTime’; line 30, column 4, length 12 in Kalender

Did you solve it? I’m quite interested, I’m struggling with the same rule :slight_smile:

Date is correct not (2021-04-04) but the error is

Script execution of rule with UID 'date-2' failed: Text '2021-4-4' could not be parsed at index 5 in date

this is a piece of the rule

    else if (dayOfYear==easterSunday.getDayOfYear-48) {
        LocalTime_Holiday.postUpdate(OFF)
        LocalTime_HolidayName.postUpdate("Carnevale")
    }

Any help will be appreciated :slight_smile:
Andrea

event1, event2,a nd event3 are of type DateTime.

  1. DateTime no longer exists in openHAB 3. It has been replaced with ZonedDateTime.
  2. DateTime is not an Item type, there is no state on a DateTime.
  3. It’s not clear what first_event_name_today, second_event_name_today, and third_event_name_today are. Items perhaps? All I can say is that they are almost certainly not a DateTime. Let’s assume that they are DateTime Items (which would be of type DateTimeItem).
  4. event1!=NULL && event1.state==UNDEF makes no sense. Why test event1 for one and event1.state for the other? Is this line 30 in your file?
  5. This isn’t directly related to your specific problem, but the line that is getting the telegramAction will most likely cause problems. You should move it inside the rule.

You can address the specific error by changing the definition of event1, 2, and 3 as DateTimeItem. Then you need to change all of your tests to test for the state (e.g. if(event1.state != NULL && ...).