DateTime Conversion

Tags: #<Tag:0x00007f014307d3e8> #<Tag:0x00007f014307ea90> #<Tag:0x00007f014307bf20>

(rud) #1


In openHab there are different ways to handle Date/Time values.

  • DateTimeType
    A DateTime Item carries a DateTimeType.

  • Joda DateTime
    By default Rules use a Joda DateTime class to represent time, most notably now.

  • 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 a long . With epoc, one can compare two dates together, convert a Joda DateTime to a DateTimeType and visa versa.

  • String
    In certain cases it is needed to convert date/time values to a human readable.

This flow chart is intended to help you easily find 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

Regarding to the flow chart this code converts from Epoch => #6 => to Joda => #11 => to String => #1 => to DateTimeType

val DateTimeType MyDateTimeTypeFromEpoch = new DateTimeType(new DateTime(MyEpoch).toString)

#3 Get DateTimeType from Joda

Variant A

val calendar = java.util.Calendar::getInstance
calendar.timeInMillis = now.millis
val MyDateTimeTypeFromJoda_VariantA = new DateTimeType(calendar)

Variant B

(probably less efficient but much easier to read and remember)

Because Joda DateTime 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 from Joda => #11 => to String => #1 => to DateTimeType

val MyDateTimeTypeFromJoda_VariantB = new DateTimeType(now.toString)

#4 Get Joda from DateTimeType

Varinat A

val MyJodaFromDateTimeType_VariantA = new DateTime((MyDateTimeItem.state as DateTimeType).zonedDateTime.toInstant.toEpochMilli)

Variant B

Because Joda DateTime 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 from DateTimeType => #12 => to String => #5 => to Joda

val MyJodaFromDateTimeType_VariantB = new DateTime(MyDateTimeItem.state.toString)

#5 Get Joda from String

String must be ISO 8601 formatted like this: “yyyy-MM-dd’T’HH:mm:ss.SSSZ”

val DateTime MyJodaFromString = new DateTime("2018-05-05T05:55:55.000-04:00")

#6 Get Joda from Epoch

val MyJodaFromEpoch = new DateTime(MyEpoch)

#7 Get Epoch from Joda

val Number MyEpochFromJoda = now.millis

#8 Get Epoch from DateTimeType

Varinat A

val Number MyEpochFromDateTimeTypeItem_VariantA = (MyDateTimeTypeItem.state as DateTimeType).zonedDateTime.toInstant.toEpochMilli

Varinat B

val Number MyEpochFromDateTimeTypeItem_VariantB = new DateTime(MyDateTimeTypeItem.state.toString).millis

#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

val String MyStringFromEpoch_VariantA = new DateTime(MyEpoch).toString

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 Joda

This will return a time in your local timezone.

val String MyStringFromJoda = now.toString("yyyy-MM-dd'T'HH:mm:ss.SSSZ")

#12 Get String from DateTimeType

val String MyStringFromDateTimeType = MyDateTimeType_item.state.format("%1$td.%1$tm.%1$ty %1$tH:%1$tM")

[SOLVED] DateTime Items compare against fixed DateTimes
OH2.4 #1428 Java 8 DateTime API
[SOLVED] createTimer (tomorrow noon) in a rule
Problem with MQTT - How to configure the item?
[SOLVED] Epoch time without milliseconds
How to format the persistence previousState().timestamp?
Type Conversions
[SOLVED] Rule question with multiple "whens" + "last seen option"
[SOLVED] DateTime functions cannot be invoked
Assign value from string to Joda time format
(Jerome Luckenbach) #2


That’s something we should definitely improve and contribute back to the docs when it has filled some of the todos.

(Rich Koshak) #3

A way to do it would be:

val DateTimeType timestamp = new DateTimeType(new DateTime(epoch).toString)

NOTE: Because Joda DateTime and DateTimeType both accept ISO8601 formatted date/time strings it is easy to convert from one to the other using their toString.

There are other ways I’m sure. For example, #3 is basically doing just that. Just replace now.millis with epoch that you got some other way.

I recommend:

val dtt = new DateTimeType(now.toString)

It is probably less efficient but much easier to read and remember.

val readableString = now.toString

Creates the same format as in #1.

val joda = new DateTime(epoch)

Another alternative:

val Number epochFromDateTimeType = new DateTime(MyDateTimeItem.state.toString).millis

Assuming it is ISO 8601 format:

val epoch = new DateTime(MyTimestampString).millis

If it is in ISO 8601 format (as illustrated in the example)

val String MyTimestampString = new DateTime(epoch).toString

Otherwise see 11 for how to adjust the outputted format.

See previous example. To format it:

val String MyTimestampString = now.toString("yyyy-MM-dd'T'HH:mm:ss.SSSZ")

See for full documentation on the format string which I think matches those for SimpleDateFormat.

I haven’t tested any of these but am pretty sure they are all correct. There may be a typo here and there though.

(rud) #4

Thank you very much!
I will test it.

(Hallo Ween) #5

Hi, i get the string from a webpage and can´t use it as datetime inside openhab:

2018-10-25 11:00

(The whole string is “2018-10-26 11:00 Uhr”, so i cutted out the charcters 0 to 16.)

How can i convert this into a datetime item?

My rule is:

rule "Pollen datetime"
    Item DWD_Pollen_last_update changed or
    System started
    PollenLastUpdateDateTime.postUpdate(DWD_Pollen_last_update.state.toString().substring(0, 16))

But this doesn´t work, because of the wrong string format, i think? The “T” is missing between date and time?

This is my error:

Cannot convert '2018-10-25 11:00' to a state type which item 'PollenLastUpdateDateTime' accepts: [DateTimeType, UnDefType].

(Vincent Regaud) #6

Could you make your OP a wiki, so that we can add the different solutions provided to the OP, please?

(David K.) #7

I am trying to convert from a Human-Readable String to epoch which I have troubles with to read as it does not seem to be in ISO format, how can I specify the format?

(Rich Koshak) #8

I’m not sure regular users have the permissions necessary to turn their post into a wiki. @anfaenger, if you don’t have that option under the three dots menu let me know and I can do it. As a moderator I have that power <evil laugh>.

(Rich Koshak) #9

I have much less experience with this. Personally I’d do some String manipulation to convert it to ISO8601 format. See for how to do it with Java core classes and for how to do it with Joda.

(rud) #10

This are the options I have:

I will insert all the suggestions to my first post on the weekend.

(Rich Koshak) #11

If you want I can make it a wiki for you.

(rud) #12

Yes please.
Maybe a stupid question: What does this mean?
Couldn’t find anything about it in the docs.

(Rich Koshak) #13

A wiki will make the posting editable by anyone.

I’ll make the change right now. I can always change it back.

(Jerome Luckenbach) #14

Feel free to ping me, when we are ready to move this to the documentation.

I will help then.
But @rlkoshak is already experienced with moving content to the docs anyway. :slight_smile:

(rud) #15

Hi @vzorglub,
Just realized, that I’ve been working on the first post and in the meantime you edited it too.
Sorry if I messed up something. I will try to fix it. How can I notice this in the future.

(Vincent Regaud) #16

Don’t worry go ahead

I don’t think one can…

(rud) #17

This is #11 instead of #5, right?

(Rich Koshak) #18

Looking back I see no difference between 5 and 11. Duplicates?

(rud) #19

#5 should get joda from string
#11 should get string from joda

(Scott Rushworth) #20

I like #5 :wink::

val DateTime dateTimeFromString = new DateTime("2018-05-05T05:55:55.000-04:00")

Be careful with #11, since it will return a time in your local timezone if done like dateTime.toString.

Here’s one that doesn’t really fit anywhere, but it’s very handy… and the easiest way I’ve found to manually define a specific Joda DateTime.

val DateTime fiveDay =,55,55,0)