首页 > 解决方案 > Dart DateTime.parse timeZoneOffset 始终为 0

问题描述

DateTime.parse 创建的 DateTime 似乎总是为“timeZoneOffset”返回 0

  1. 我在非 UTC 时区创建了一个 ISO8601 字符串:https ://timestampgenerator.com/1610010318/+09:00

  2. 我将该字符串传递给 DateTime.parse:

  DateTime date = DateTime.parse("2021-01-07T18:05:18+0900");
  1. 问题:当我期待 +0900 时,timeZoneOffset 为 0。
  print(date.timeZoneOffset);  --> 0:00:00.000000
  print(date.timeZoneName); --> UTC 
  print(date); --> 2021-01-07 09:05:18.000Z

Dart 日期时间文档(https://api.dart.dev/stable/2.10.4/dart-core/DateTime/parse.html):

结果始终为当地时间或 UTC。如果指定了 UTC 以外的时区偏移量,则时间将转换为等效的 UTC 时间。

为什么 timeZoneOffset 为 0?我需要将什么字符串传递给 DateTime.parse 以使其以本地时间存储时间,而不是将其转换为等效的 UTC 时间?

标签: flutterdatetimedartiso

解决方案


Dart SDK 并没有真正处理不同的时区,这就是为什么parse需要本地时区(即运行程序的系统上的时区)或 UTC 的原因。

如果您尝试在没有任何时区信息的情况下解析时间戳,Dart 将假定时间在本地时区(我在丹麦,使用的是浪漫标准时区):

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
}

您可以使用时间戳将您的 UTC 时间戳转换为本地.toLocal()时间。但同样,这只会将其转换为您自己系统上的时区,而不是您解析时的时区:

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

如果您想使用时区数据处理时间,您应该查看包时区:https ://pub.dev/packages/timezone

关于保存时区偏移的一些注意事项

您应该知道,在大多数情况下,以可以再次获得原始偏移量的形式节省时间并没有真正意义。问题是大多数国家/地区都有 DST 之类的规则,或者用户正在旅行,并且确实希望系统能够正确处理时间。

所以在很多情况下,用户并不真的希望再次获得相同的偏移量,而是希望时间与当前基于位置和时间的偏移量保持一致。

例如,时区包不允许您解析时间戳并将偏移量与它一起保存(因为偏移量与位置不同)。相反,它希望您指定时间戳用于的位置,以便它可以计算该位置的当前偏移量。

因此,总的来说,我建议您始终将存储时间保存为 UTC。当要使用数据时,您应该有一些方法可以知道接收器的位置(例如,以某种形式的配置文件询问用户)并使用 timezone 包将时间转换为该位置。如果应用程序在数据接收者拥有的设备上运行,您可以使用.toLocale().


推荐阅读