For anyone following this thread, the mentioned PR is this one:
openhab:main
← jlaur:2898-datetimetype-instant
opened 10:09PM - 29 Apr 23 UTC
Proposal for switching `DateTimeType` to use `Instant` internally rather than `Z… onedDateTime`.
This will effectively discard 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.
Configured time-zone is now applied for:
- REST API
- SSE item state events
- Item UI registry (affecting e.g. sitemaps)
Consequential changes because `DateTimeType` is now "zone-less":
- Parameter `timezone` for `TimestampOffsetProfile` has been removed. openhab/openhab-docs#2403 has been prepared.
- Methods `toZone`, `toLocaleZone` and `getZonedDateTime` have been marked as deprecated and all usages have been refactored. I would suggest to remove them in 5.0 (or maybe even before when all bindings are refactored, see openhab/openhab-addons#17725).
- Method `getZonedDateTime(ZoneId)` has been introduced for convenience.
The following demonstrates the difference between old and new behavior.
REST API calls are for `http://localhost:8080/rest/items/DateTimeTest` and the returned `state` is shown in the comparison table:
```json
{
"link": "http://localhost:8080/rest/items/DateTimeTest",
"state": "2024-10-31T21:00:00.000+0100",
"stateDescription": {
"pattern": "%1$tY-%1$tm-%1$td %1$tH:%1$tM:%1$tS",
"readOnly": false,
"options": []
},
"editable": true,
"type": "DateTime",
"name": "DateTimeTest",
"label": "",
"category": "",
"tags": [],
"groupNames": []
}
```
Updates are made in Karaf using commands like:
```shell
openhab:update DateTimeTest 2024-10-31T21:00:00+01:00
```
| Step | Before | Now |
|------------------------------------------|------------------------------|----------------------------------|
| System time-zone: Europe/Copenhagen | | |
| Set openHAB time-zone: Europe/Copenhagen | | |
| Update to: 2024-10-01T20:00:00Z | | |
| Observe REST API result | 2024-10-01T20:00:00.000+0000 | 2024-10-01T**22:00:00.000+0200** |
| Observe /settings/items/ | 2024-10-01T20:00:00.000+0000 | 2024-10-01T**22:00:00.000+0200** |
| Observe /settings/items/DateTimeTest | 2024-10-01 22:00:00 | 2024-10-01 22:00:00 |
| Observe sitemap | 2024-10-01 22:00:00 | 2024-10-01 22:00:00 |
| Update to: 2024-10-31T20:00:00Z | | |
| Observe REST API result | 2024-10-31T20:00:00.000+0000 | 2024-10-31T**21:00:00.000+0100** |
| Observe /settings/items/ | 2024-10-31T20:00:00.000+0000 | 2024-10-31T**21:00:00.000+0100** |
| Observe /settings/items/DateTimeTest | 2024-10-31 21:00:00 | 2024-10-31 21:00:00 |
| Observe sitemap | 2024-10-31 21:00:00 | 2024-10-31 21:00:00 |
| Update to: 2024-10-31T21:00:00+01:00 | | |
| Observe REST API result | 2024-10-31T21:00:00.000+0100 | 2024-10-31T21:00:00.000+0100 |
| Observe /settings/items/ | 2024-10-31T21:00:00.000+0100 | 2024-10-31T21:00:00.000+0100 |
| Observe /settings/items/DateTimeTest | 2024-10-31 21:00:00 | 2024-10-31 21:00:00 |
| Observe sitemap | 2024-10-31 21:00:00 | 2024-10-31 21:00:00 |
| Set time-zone: US/Alaska | | |
| Observe REST API result | 2024-10-31T21:00:00.000+0100 | 2024-10-31T**12:00:00.000-0800** |
| Observe /settings/items/ | 2024-10-31T21:00:00.000+0100 | 2024-10-31T**12:00:00.000-0800** |
| Observe /settings/items/DateTimeTest | 2024-10-31 21:00:00 | 2024-10-31 **12:00:00** |
| Observe sitemap | 2024-10-31 21:00:00 | 2024-10-31 **12:00:00** |
| Update to: 2024-10-31T**12:00:00-0800** | | |
| Observe REST API result | 2024-10-31T12:00:00.000-0800 | 2024-10-31T12:00:00.000-0800 |
| Observe /settings/items/ | 2024-10-31T12:00:00.000-0800 | 2024-10-31T12:00:00.000-0800 |
| Observe /settings/items/DateTimeTest | 2024-10-31 21:00:00 | 2024-10-31 **12:00:00** |
| Observe sitemap | 2024-10-31 21:00:00 | 2024-10-31 **12:00:00** |
As it can be seen from the table, we now have consistent results.
Example DSL rule:
```java
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
```
Summary of benefits for developers:
- In cases where `TimeZoneProvider` is used only to generate a `DateTimeType` with the correct time-zone, this can now be completely removed. This simplifies the code. See openhab/openhab-addons#17725 for examples.
- The default `DateTimeType` constructor can now be used (without losing correct time-zone).
- In cases where the configured time-zone was not correctly applied, this will now work properly without any changes.
- The change is fully backwards compatible, although two methods have been deprecated: `toZone` and `toLocaleZone`. I will go through usages and remove them, since they no longer make sense. See openhab/openhab-addons#17725.
- Pull request reviews should be a bit smoother, since add-on maintainers will no longer have to assist contributors in constructing a proper `DateTimeType` using `TimeZoneProvider`.
And for users:
- There will now be consistent behavior across all bindings, where previously time-zone could differ between bindings and even within same binding: System time-zone or openHAB time-zone.
- There will now be consistent behavior across different parts of the UI, where previously some parts used the time-zone contained in the `DateTimeType` (which could be either depending on binding) and other parts used system time-zone.
- A change in time-zone will have immediate effect for the UI without requiring state updates for the items.
And finally limitations:
- It is no longer possible to send a `DateTimeType` command to a binding with a specified time-zone. The bindings will have to provide a time-zone if needed (e.g. time-zone from device, openHAB configuration or system time-zone). I have not found any bindings using this possibility, so I don't think this will cause any issues.
Resolves #2898
You are right that I didn’t anticipate that Rules DSL would log deprecation notices when loading rules. Unfortunately there is strong coupling between Rules DSL and core types.
I’m not sure if the deprecation itself is a mistake though, but I am somewhat divided. The issue is that previously you would get back the time-zone that was provided when creating the DateTimeType
. If the item was updated by a binding, this might be the configured time-zone in openHAB - or system time-zone or UTC, depending on the binding.
Now, you will get system time-zone, because that’s the only time-zone which is possible to obtain within the DateTimeType
instance. Therefore the functionality had to change, and IMHO this ambiguity is a good reason for deprecating the method, and instead promote getZonedDateTime(ZoneId)
in order to have consistent and predictable results. Especially for addons, this should lead to refactoring so that the desired time-zone is always explicitly provided. I already prepared a PR for that, so that we’ll no longer be using the deprecated methods:
openhab:main
← jlaur:datetimetype-instant
opened 10:21PM - 09 Nov 24 UTC
This is a cleanup only and does not change functionality when openhab/openhab-co… re#3583 has first been merged. The core PR discards time-zone from `DateTimeType`, thus binding code can be simplified:
- Instantiations from `ZonedDateTime` using either time-zone from `TimeZoneProvider` or `ZoneId.systemDefault()` have been simplified to use `Instant`. In some cases this entirely eliminated the need for `TimeZoneProvider`, which has then been removed.
- Usages of deprecated methods `toZone` and `toLocaleZone` have been removed.
- Usages of deprecated method `getZonedDateTime()` have been removed. In cases where time-zone is needed, `getZonedDateTime(ZoneId.systemDefault())` is now explicitly called.
Related to openhab/openhab-core#3583
On the other hand, it might be desirable to be less strict for Rules DSL since this is user-provided rules, and for most users the system time-zone will be the same as the time-zone configured in openHAB. However, fundamentally the problem is the same in rules as in addons, so in the long run, I still think it would be better to avoid relying implicitly on the time-zone, as it could lead to some unexpected behavior.
Unfortunately, because of the tight coupling, there is no way of deprecating the method for core/addons Java development, but not for Rules DSL. So I think not deprecating it now will just postpone the problem. And all DSL rules will still continue to work, even with the deprecation notices logged.
For completeness, this deprecation shouldn’t affect any other rule languages. It has been verified at least that JavaScript doesn’t log anything, and it will only require a small change in the beginning of the 5.0 development cycle to stop using the deprecated method, and instead use the time-zone configured in openHAB. This will lead to a more consistent behavior than prior to 4.3 (the “breaking change” label is misleading, it won’t be breaking):
opened 03:32PM - 11 Dec 24 UTC
breaking change
Due to https://github.com/openhab/openhab-core/pull/3583,
it is required to adj… ust
https://github.com/openhab/openhab-js/blob/5ebf646404b75de3c26b2d810f25520e3843ca12/src/time.js#L189
and
https://github.com/openhab/openhab-js/blob/5ebf646404b75de3c26b2d810f25520e3843ca12/src/time.js#L294
to `DateTimeType.getZonedDateTime(zoneId)`.
This however cannot be done without breaking backwards compatibility with openHAB < 4.3, so we have to postpone this change to the next breaking openhab-js release.