Hi! We've come across an odd thing when using a particular timezone.
We are using TeaVM 0.10.0 with java.util.TimeZone.autodetect set to true
My Windows timezone is set to (UTC+00:00) Dublin, Edinburgh, Lisbon, London (I am based in UK).
In our web app, the time returned by LocalTime.now() is behind by 114 minutes.
I think this is ultimately down to DateTimeZoneProvider.detectTimeZone(), which returns Atlantic/Azores.
This is the same whether or not I enable "Adjust for daylight saving time automatically" in Windows settings.
If I use any other UTC/UTC+00:00 timezones in Windows settings, TTimeZone.detectTimeZone() returns Europe/Prague, and the time returned by LocalTime.now() is as expected (don't quite understand this either as Prague is an hour ahead!).
This is repeatable in Chromium and Firefox browsers on Windows, and my colleague has replicated the same on Mac.
I am wondering if this is related to the timezone offsets, which DateTimeZoneProvider is scaling into minutes.
Most of them correspond to the UTC time differences, but some are irregular; for Atlantic/Azores, the offset is -114.
I made a copy of detectTimeZone() where I forced the Atlantic/Azores offset to -120; in this case, the default timezone returned was Europe/Prague.
Our workaround is to use another UTC/UTC+00:00 timezone but we'd like to understand whether this is an issue in TeaVM or somehow an issue with the OS - please can you shed any light on this?
Hi. Time zone detection is quite unreliable and was developed back 10 years ago when there was no API in JS to get system timezone. Now you can use Intl for this purpose. I'll implement proper time zone detection in TeaVM, but for now you can try to use following workaround:
Intl.DateTimeFormat().resolvedOptions().timeZone
Thanks so much for the quick response!
I've followed your suggestion and that's now setting the default time zone to Europe/London, which makes sense.
I'm still seeing an issue with how this formats times.I've created a ZonedDateTime myTime with a UTC time e.g. 2024-12-19T13:44:46.3433333ZI've created a DateTimeFormatter as follows:DateTimeFormatter dtf = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.SHORT).withZone(ZoneId.systemDefault());The formatted time returned by myTime.format(dtf) is an hour ahead e.g. 19/12/2024, 14:44It seems to be to do with the offset rules for Europe/London in particular.
Can you please provide the code, with default time zone set to some particular constant, so that it's easily reproducible? I did try following:
TimeZone.setDefault(TimeZone.getTimeZone("Europe/London")); System.out.println(ZoneId.systemDefault()); var dtf = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.SHORT).withZone(ZoneId.of("UTC")); var time = ZonedDateTime.of(2024, 12, 19, 13, 44, 46, 0, ZoneId.systemDefault()); System.out.println(time.format(dtf));
And got following result on JVM in JS respectively:
Europe/London 19.12.2024, 13:44 Europe/London 12/19/24, 1:44 PM
This is behaving as I'd expect in Java server code so I've been comparing StandardZoneRules with java.time.zone.ZoneRules - the only obvious difference I can see is when savingsInstantTransitions is instantiated - StandardZoneRules uses Instant.getEpochSecond whereas ZoneRules uses ZoneOffsetTransition.toEpochSecond - could that be having an effect?
Sorry, have no idea. I don't know well this thing with time zones and don't know java.time API. I just ported threeten code to TeaVM - without understanding how it works internally.
You can also use native JS code to format dates. In order you
want to share some code between client and server, hide
date-formatting routine behind some interface and provide either
JS-specific or JVM-specific implementation. Also, you can try to
update to 0.11.0
Thanks so much for the quick response!
I've followed your suggestion and that's now setting the default time zone to Europe/London, which makes sense.
I'm still seeing an issue with how this formats times.I've created a ZonedDateTime myTime with a UTC time e.g. 2024-12-19T13:44:46.3433333ZI've created a DateTimeFormatter as follows:DateTimeFormatter dtf = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.SHORT).withZone(ZoneId.systemDefault());The formatted time returned by myTime.format(dtf) is an hour ahead e.g. 19/12/2024, 14:44It seems to be to do with the offset rules for Europe/London in particular.
Can you please provide the code, with default time zone set to some particular constant, so that it's easily reproducible? I did try following:
TimeZone.setDefault(TimeZone.getTimeZone("Europe/London")); System.out.println(ZoneId.systemDefault()); var dtf = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.SHORT).withZone(ZoneId.of("UTC")); var time = ZonedDateTime.of(2024, 12, 19, 13, 44, 46, 0, ZoneId.systemDefault()); System.out.println(time.format(dtf));
And got following result on JVM in JS respectively:
Europe/London 19.12.2024, 13:44 Europe/London 12/19/24, 1:44 PM
This is behaving as I'd expect in Java server code so I've been comparing StandardZoneRules with java.time.zone.ZoneRules - the only obvious difference I can see is when savingsInstantTransitions is instantiated - StandardZoneRules uses Instant.getEpochSecond whereas ZoneRules uses ZoneOffsetTransition.toEpochSecond - could that be having an effect?
Sorry, have no idea. I don't know well this thing with time zones and don't know java.time API. I just ported threeten code to TeaVM - without understanding how it works internally.