Dart DateTime.parse timeZoneOffset 始终为 0

Dart DateTime.parse timeZoneOffset is always 0

DateTime.parse 创建的 DateTime 对于“timeZoneOffset”

似乎总是 returns 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):

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.

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

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

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

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
}

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

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

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

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

您应该知道,在大多数情况下,将时间保存在可以再次获得原始偏移量的表格中并没有多大意义。问题是大多数国家/地区都有像 DST 这样的规则,或者用户正在旅行并且希望系统能够正确处理时间。

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

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

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

将 UTC 转换为本地时间