It’s coming from an external source updating an item via the rest api. The date time is part of a longer text string that is received and I extract it from the string. I have no control over the input to change its format.
Ah… that makes sense. To go from a formatted string to a DateTimeType, the easiest thing will be to convert from your string to a LocalDateTime using a DateTimeFormatter. Then convert it to a ZonedDateTime by adding timezone information.
// add imports to the top of the rule file
import java.time.format.DateTimeFormatter
import java.time.LocalDateTime
import java.time.ZoneId
...
// in your rule
val initial_time = "December 7, 2020 at 02:22PM"
val zdt = LocalDateTime.parse(initial_time, DateTimeFormatter.ofPattern("MMMM d, yyyy 'at' hh:mma")).atZone(ZoneId.systemDefault())
My_Item.postUpdate(new DateTimeType(zdt).toString())
I’ve tried to use what you suggested but can’t get it to work.
The goal here is to read the latest date time and if it is later than the previous date time that was sent, then update it, otherwise ignore it.
Here’s my rule:
rule "test"
when
Item test_toggle changed
then
val extract_date_time = google_wifi_Glenn.state.toString.substring(8,google_wifi_Glenn.state.toString.length) // this extracts the date time from the string ie (Home at December 7, 2020 at 02:22PM)
val extract_date_time_formatted = LocalDateTime.parse(extract_date_time, DateTimeFormatter.ofPattern("MMMM d, yyyy 'at' hh:mma")).atZone(ZoneId.systemDefault())
val new_time_of_event = new DateTimeType(extract_date_time_formatted).toString()
if(new_time_of_event > google_wifi_Glenn_date_time )
{
logInfo("Glenn Wifi", "GREATER" )
postUpdate(google_wifi_Glenn_date_time, new_time_of_event) //save the new date time
}
else
{
logInfo("Glenn Wifi", "LESS") //ignore
}
end
But I get en error in the logos
2020-12-08 14:53:32.667 [ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule 'test': org.eclipse.smarthome.core.library.items.DateTimeItem cannot be cast to java.lang.String
If I just log the values of the two times im comparing I get this:
There were a few things not quite right… try this one…
rule "test"
when
Item test_toggle changed
then
val extract_date_time = google_wifi_Glenn.state.toString.substring(8,google_wifi_Glenn.state.toString.length) // this extracts the date time from the string ie (Home at December 7, 2020 at 02:22PM)
val extract_date_time_formatted = LocalDateTime.parse(extract_date_time, DateTimeFormatter.ofPattern("MMMM d, yyyy 'at' hh:mma")).atZone(ZoneId.systemDefault())
val new_time_of_event = new DateTimeType(extract_date_time_formatted).toString()
if (extract_date_time_formatted.isAfter(google_wifi_Glenn_date_time.getStateAs(DateTimeType).zonedDateTime)) {
logInfo("Glenn Wifi", "GREATER")
google_wifi_Glenn_date_time.postUpdate(new_time_of_event) //save the new date time
} else {
logInfo("Glenn Wifi", "LESS") //ignore
}
end
Thanks a lot, that’s done the job (with the addition of a missing ‘)’ at the end of the if statement)
Thanks for you help, dates are confusing for a novice!
rule "test"
when
Item test_toggle changed
then
val extract_date_time = google_wifi_Glenn.state.toString.substring(8,google_wifi_Glenn.state.toString.length) // this extracts the date time from the string ie (Home at December 7, 2020 at 02:22PM)
val extract_date_time_formatted = LocalDateTime.parse(extract_date_time, DateTimeFormatter.ofPattern("MMMM d, yyyy 'at' hh:mma")).atZone(ZoneId.systemDefault())
val new_time_of_event = new DateTimeType(extract_date_time_formatted).toString()
if (extract_date_time_formatted.isAfter(google_wifi_Glenn_date_time.getStateAs(DateTimeType).zonedDateTime))
{
logInfo("Glenn Wifi", "GREATER" )
google_wifi_Glenn_date_time.postUpdate(new_time_of_event) //save the new date time
}
else
{
logInfo("Glenn Wifi", "LESS") //ignore
}
end
Hi again Scott,
One thing I didn’t think of was if the date/times are the same, and this rule will move that to ignore, but I’d actually want that to process it. Is there something to use rather than …isAfter( ) that is equivalent to isAfter or isEqual?