Because openHAB 2.x rules use Jodatime instead of Java Time API, there is still the old DateTime Conversion thread for openHAB 2.x.
Overview
In openHab 3.x there are different ways to handle Date/Time values.
-
DateTimeType
A DateTime Item carries a DateTimeType. -
Java Time
By default openHAB 3.x Rules DSL use java.time API to represent date and time.
Principle java date-time concepts are LocalDateTime (date and time without any offset or time-zone) and ZonedDateTime (“full” date-time with time-zone and resolved offset from UTC/Greenwich). -
Epoch
The lowest common denominator when working with time is to get at the epoc value. Epoc is the number of milliseconds that has passed since 1 January 1970 GMT and stored in along
. With epoc, one can compare two dates together, convert a Joda DateTime to a DateTimeType and visa versa. With epoc you can represent a duration. -
String
In certain cases it is needed to convert date/time values to a human readable.
This flow chart is intended to help you finding the code needed for conversion.
The numbers of the flow chart refer to the numbers of the following list.
#1 Get DateTimeType from String
String must be ISO 8601 formatted like this: “yyyy-MM-dd’T’HH:mm:ss.SSSZ”
val DateTimeType MyDateTimeTypeFromString = DateTimeType.valueOf(MyString)
#2 Get DateTimeType from Epoch
(Preliminary: not yet tested)
Since no direct conversion is known, this code uses conversion #6 (Epoch to JavaTime) and then #3 (JavaTime to DateTimeType)
val long MyEpochMilliseconds = 999999000 // create a epoch value to work with`
val MyJavaTimeFromEpoch = Instant.ofEpochMilli(MyEpochMilliseconds).atZone(ZoneId.systemDefault()) // #6 convert epoch to JavaTime
val MyDateTimeTypeFromJavaTime = new DateTimeType(MyJavaTimeFromEpoch) // #3 convert JavaTime to DateTimeType
#3 Get DateTimeType from Java Time
Variant A (from LocalDateTime)
val LocalDateTime MyJavaLocalDateTime = new LocalDateTime() // create a LocalDateTime value to work with`
val DateTimeType MyDateTimeTypeFromJavaLocalDateTime = new DateTimeType(MyJavaLocalDateTime ) // conversion
Variant B
Because JavaTime and DateTimeType both accept ISO 8601 formatted date/time strings it is easy to convert from one to the other using their toString.
Regarding to the flow chart this code converts JavaTime => #11 => to String => #1 => to DateTimeType
val DateTimeType MyDateTimeTypeFromJavaTime = DateTimeType.valueOf(MyJavaTime.toLocalDateTime().toString())
Timestamp (DateTimeType)
val DateTimeType MyDateTimeTypeTimestamp = DateTimeType.valueOf(now.toLocalDateTime().toString())
#4 Get Java Time from DateTimeType
val MyJavaTimeFromDateTimeItem = (MyDateTimeItem.state as DateTimeType).getZonedDateTime()
More info about Java ZonedDateTime Class
#5 Get Java Time from String
String must be ISO 8601 formatted like this: “yyyy-MM-dd’T’HH:mm:ss.SSSZ”
val MyZonedDateTimeFromString = ZonedDateTime.parse("2020-12-25T00:00:00.000Z").withZoneSameInstant(ZoneId.systemDefault())
#6 Get Java Time from Epoch
(Preliminary: not yet tested)
Variant A
val long MyMilliseconds = 999999000 // create a value we can work with`
val MyJavaTimeFromEpoch_VariantA = Instant.ofEpochMilli(MyMilliseconds).atZone(ZoneId.systemDefault()) // #6
#7 Get Epoch from Java Time
(Preliminary: not yet tested)
Variant A
val MyEpochFromJavaTime_VariantA = MyJavaTime.toInstant.toEpochMilli
Variant B
val MyEpochFromJavaTime_VariantB = MyJavaTime.toEpochSecond * 1000
Timestamp
val MyEpochTimestamp_VariantA = now.toInstant.toEpochMilli
val MyEpochTimestamp_VariantB = now.toEpochSecond * 1000
#8 Get Epoch from DateTimeType
val Number MyEpochFromDateTimeTypeItem = (MyDateTimeTypeItem.state as DateTimeType).zonedDateTime.toInstant.toEpochMilli
#9 Get Epoch from String
String must be ISO 8601 formatted like this: “yyyy-MM-dd’T’HH:mm:ss.SSSZ”
val Number MyEpochFromString = new DateTime(MyDateTimeString).millis
#10 Get String from Epoch
Variant A
Regarding to the flow chart this code converts from Epoch => #6 => to Java Time => #11 => to String. This means formatting can be done like shown in #11
ToDo …
Variant B
Here is an option utilizing SimpleDateFormat:
import java.text.SimpleDateFormat
import java.util.Date
val SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ")
val String MyStringFromEpoch_VariantB = sdf.format(new Date(MyEpoch))
#11 Get String from Java Time
Variant A
val String MyStringFromJavaTime = MyJavaTime.toLocalDateTime().toString()
Timestamp (String)
val String MyStringTimestamp = now.toLocalDateTime().toString()
#12 Get String from DateTimeType
Formatting can be done like shown here.
For more details look at this.
val String MyStringFromDateTimeType = MyDateTimeType_item.state.format("%1$td.%1$tm.%1$ty %1$tH:%1$tM")