Search code examples
flutterdatetimedartiso

Dart DateTime.parse timeZoneOffset is always 0


The DateTime created by DateTime.parse seems to always returns 0 for "timeZoneOffset"

  1. I create a ISO8601 string here in a non UTC timezone: https://timestampgenerator.com/1610010318/+09:00

  2. I pass that string to DateTime.parse:

  DateTime date = DateTime.parse("2021-01-07T18:05:18+0900");
  1. Issue: timeZoneOffset is 0 when I was expecting +0900.
  print(date.timeZoneOffset);  --> 0:00:00.000000
  print(date.timeZoneName); --> UTC 
  print(date); --> 2021-01-07 09:05:18.000Z

Dart DateTime documentation (https://api.dart.dev/stable/2.10.4/dart-core/DateTime/parse.html):

The result is always in either local time or UTC. If a time zone offset other than UTC is specified, the time is converted to the equivalent UTC time.

Why is timeZoneOffset 0? What string do I need to pass to DateTime.parse to get it to store the time in local time instead of converting it to the equivalent UTC time?


Solution

  • The Dart SDK does not really handle different timezones which is the reason why the parse want local timezone (which is the timezone on the system running the program) or UTC.

    If you are trying to parse a timestamp without any timezone information, Dart will assume the time are in local timezone (I am in Denmark which are using the Romance Standard Timezone):

    void main() {
      print(DateTime.parse("2021-01-07T18:05:18").timeZoneName); // Romance Standard Time
      print(DateTime.parse("2021-01-07T18:05:18+0900").timeZoneName); // UTC
    }
    

    You can convert your UTC timestamp into localtime by using .toLocal() on the timestamp. But again, this will just convert it into the timezone which are on your own system and not the one coming from the time you have parsed:

    void main() {
      print(DateTime.parse("2021-01-07T18:05:18+0900").toLocal().timeZoneName); // Romance Standard Time
    }
    

    If you want to handle time with timezone data you should look into the package timezone: https://pub.dev/packages/timezone

    Some notes about saving timezone offset

    You should be aware that in most cases, it does not really makes sense to save the time in a form where you can get the original offset again. The problem is that most countries have rules like DST or the user are traveling and does expect the system to handle the time correctly.

    So in a lot of cases, the user does not really expect to get the same offset back again but want the time to be with the currently offset based on location and time right now.

    The timezone package does e.g. not allow you to parse a timestamp and save the offset together with it (because an offset is not the same as a location). Instead, it want you to specify the location the timestamp are used for so it can calculate the current offset for that location.

    So in general, I recommend you to always save time as UTC on storage. When the data are going to be used, you should have some way to know the location of the receiver (e.g. ask the user in some form of profile) and convert the time to that location using the timezone package. If the application are running on a device owned by the receiver of the data, you can convert the UTC to local time using .toLocale().