srawlins / timezone

Time zone database and time zone aware DateTime object for Dart.
BSD 2-Clause "Simplified" License
102 stars 54 forks source link

What is the Location of UTC? #80

Open glnjr opened 3 years ago

glnjr commented 3 years ago

I am trying to parse a UTC String to create a TZDateTime object. The TZDateTime.parse method requires (as do the regular constructors) a Location object which can be created using the getLocation(String) function. The IANA database shows 'Etc/UTC' as the proper database name for UTC time zone (understanding that time zone ≠ location); however, getLocation returns an exception with the following description:

Location with the name "Etc/UTC" doesn't exist

Does UTC have a proper Location?

Unless I missed it, I was not able to find this in the documentation.

Thanks!

IvanVishnevskiy commented 3 years ago

You should be pretty much safe with Accra, which uses UTC and does not use any kind of dst.

final utc = tz.getLocation('Africa/Accra'); final date = tz.TZDateTime.parse(utc, '2020-12-14T10:04:16.231Z');

armandojimenez commented 3 years ago

I'm getting this in a android emulator, how do I deal with this? LocationNotFoundException (Location with the name "GMT" doesn't exist)

IvanVishnevskiy commented 3 years ago

I'm getting this in a android emulator, how do I deal with this? LocationNotFoundException (Location with the name "GMT" doesn't exist)

Please, show the code you're using. You can't get "GMT" location, nor can you get an UTC. The "safe" bet is to use Africa/Accra, this location does not have any difference to UTC/GMT and doesn't have DST so it's kind of a best deal, I think.

armandojimenez commented 3 years ago

Im using this code at main:

Future _configureLocalTimeZone() async { tz.initializeTimeZones(); final String timeZoneName = await FlutterNativeTimezone.getLocalTimezone(); print('TimeZone name: $timeZoneName'); tz.setLocalLocation(tz.getLocation(timeZoneName)); }

And getting this error: Exception has occurred. LocationNotFoundException (Location with the name "GMT" doesn't exist) it's thrown at tz.getLocation(timeZoneName),

I'm using https://androidstudio.googleblog.com/2020/12/android-emulator-apple-silicon-preview.html since I'm using a m1 mac, I can't test with any other simulator, works fine on my physical android.

So I need to wrap the code in a try/catch and verify if the timezome is GMT or UTC and then use Africa/Accra as the timezone? I'm a little scared this will happen in PROD to an user, since the app crash here, and if I wrap it in a try/catch, then I need to assign something since I use timezone instance anywhere I need a DateTime.

lalomartins commented 3 years ago

The problem here is that it doesn't round-trip. Let's say I have client-server code, and the server is in another language entirely. The UTC object is a Location, so for a variable loc in the client, it's possible that for whatever reason it has the value UTC at some point. If I send this to the server with loc.name, then later in a different session I get this value from the server and try to rebuild it with getLocation(locName), I get an exception. That's not cricket. Currently I have to wrap it in a helper:

tz.TimeZone Location(String locationName) =>
    locationName == 'UTC' ? tz.UTC : tz.getLocation(locationName);

If IANA says Etc/UTC, then I'd suggest that's a valid fix for this situation. UTC.name can return 'Etc/UTC' (breaking change, but what can you do), and getLocation('Etc/UTC') can return the UTC object.

kpozin commented 2 years ago

Does this library support TZDB links (aliases)? "UTC" is a known alias for "Etc/UTC" in TZDB (see the bottom of the backward file).

Rossi1337 commented 2 years ago

The code for Etc/UTC is not in all databases included. If you use import 'package:timezone/data/latest_all.dart' as tz;

then that location should be recognized. The latest_10y.dart and latest.dart only contain a subset of the time zones. Unfortunately they miss this important one.

To fix this "Etc/UTC" and some others should be added in https://github.com/srawlins/timezone/blob/master/lib/src/tools.dart into the commonLocations there. I would suggest to extend that list with these codes:

Etc/GMT Etc/GMT+0 Etc/GMT+1 Etc/GMT+10 Etc/GMT+11 Etc/GMT+12 Etc/GMT+2 Etc/GMT+3 Etc/GMT+4 Etc/GMT+5 Etc/GMT+6 Etc/GMT+7 Etc/GMT+8 Etc/GMT+9 Etc/GMT-0 Etc/GMT-1 Etc/GMT-10 Etc/GMT-11 Etc/GMT-12 Etc/GMT-13 Etc/GMT-14 Etc/GMT-2 Etc/GMT-3 Etc/GMT-4 Etc/GMT-5 Etc/GMT-6 Etc/GMT-7 Etc/GMT-8 Etc/GMT-9 Etc/GMT0 Etc/Greenwich Etc/UCT Etc/UTC Etc/Universal Etc/Zulu