openhab-core
openhab-core copied to clipboard
[core] Use `Instant` internally for `DateTimeType`
Draft proposal for switching DateTimeType to use Instant internally rather than ZonedDateTime.
This will effectively strip time-zone information from the source of the DateTimeType and leave it to consumers to apply time-zone at the moment of presentation, according to the configured time-zone in openHAB regional settings or in the browser.
Example DSL rule:
var dt = ZonedDateTime.of(2024, 4, 26, 0, 0, 0, 0, ZoneId.systemDefault())
DateTimeTest1.postUpdate(new DateTimeType(dt))
DateTimeTest2.postUpdate(new DateTimeType(dt.toInstant().atZone(ZoneId.of("UTC"))))
DateTimeTest3.postUpdate(new DateTimeType(dt.toInstant()))
Previous result with system time-zone CET/DST:
[openhab.event.ItemStateChangedEvent ] - Item 'DateTimeTest1' changed from NULL to 2024-04-26T00:00:00.000+0200
[openhab.event.ItemStateChangedEvent ] - Item 'DateTimeTest2' changed from NULL to 2024-04-25T22:00:00.000+0000
New result with same system time-zone:
[openhab.event.ItemStateChangedEvent ] - Item 'DateTimeTest1' changed from NULL to 2024-04-26T00:00:00.000+0200
[openhab.event.ItemStateChangedEvent ] - Item 'DateTimeTest2' changed from NULL to 2024-04-26T00:00:00.000+0200
[openhab.event.ItemStateChangedEvent ] - Item 'DateTimeTest3' changed from NULL to 2024-04-26T00:00:00.000+0200
Resolves #2898
I hit a wall with this when realizing that toFullString() and toString() should probably format as UTC for consistency. However, I believe one of these is used by Main UI for display purposes, so to improve the display with correct time-zone rather breaking it by raw UTC format, we would need UI changes - see also https://github.com/openhab/openhab-core/issues/2898#issuecomment-1370230276.
I don't know if any @openhab/webui-maintainers can throw some light at what may be a possible way forward?
@mherwege - seeing your work in #4169 I'm wondering if you can advise how to accomplish decoupling the time-zone + formatting of DateTimeType. The general idea is to reduce it to be only an Instant without time-zone information. Therefore the UI should no longer display the raw output of toString() / toFullString(). Instead it must use the configured time-zone from TimeZoneProvider for formatting the DateTime in local time.
Currently it's formatted like this: 2024-04-10T20:55:01.000+0200. The problem is that "+0200" is the time-zone provided when updating the value, not the current time-zone. I don't know how this formatting works in Main UI.
@jlaur Main UI works with what it gets from the REST API.
On the Items screen (items list), it will show the state exactly as it is received from the REST API /items endpoint.
Here is an extract of such a response:
{
"link": "http://openhabian.local:8080/rest/items/PMD",
"state": "2024-04-11T00:00:00.000+0200",
"stateDescription": {
"pattern": "%1$td-%1$tm-%1$tY",
"readOnly": true,
"options": []
},
"editable": true,
"type": "DateTime",
"name": "PMD",
"label": "PMD",
"category": "calendar",
"tags": [],
"groupNames": [
"Afval"
]
}
state is what gets shown in the items list.
The formatted state comes from the states event stream in the displayState field. It is a result of applying the stateDescription pattern, but that is done in core.
Event stream extract:
data: {"Afval":{"state":"2024-04-10T00:00:00.000+0200","displayState":"10-04-2024","type":"DateTime"},"Papier":{"state":"2024-04-10T00:00:00.000+0200","displayState":"10-04-2024","type":"DateTime"},"Restafval":{"state":"2024-04-18T00:00:00.000+0200","displayState":"18-04-2024","type":"DateTime"},"PMD":{"state":"2024-04-11T00:00:00.000+0200","displayState":"11-04-2024","type":"DateTime"}}
displayState gets used in widgets when available.
So, to understand where state and displayState come from, one needs to look at the REST API code. According to https://github.com/openhab/openhab-core/blob/cbb458e0c3c35f353954f82031c5cd1b3943759c/bundles/org.openhab.core.io.rest.core/src/main/java/org/openhab/core/io/rest/core/internal/item/ItemResource.java#L953
state is added through the EnrichedItemDTOMapper here: https://github.com/openhab/openhab-core/blob/cbb458e0c3c35f353954f82031c5cd1b3943759c/bundles/org.openhab.core.io.rest.core/src/main/java/org/openhab/core/io/rest/core/item/EnrichedItemDTOMapper.java#L81
So it is simply using the toFullString() method on the state of the item.
@mherwege - many thanks for your insights. I will have a closer look at this soon.