【发布时间】:2021-02-15 14:42:50
【问题描述】:
- 语言:Java
- 数据库:mySQL
我必须为将在特定时间发送通知的用户建立一个警报系统。例如,用户可以指定时间上午 7 点和日期 2020 年 5 月 1 日,这意味着必须在 2020 年 5 月 1 日上午 7 点发送警报。用户可以在世界的任何地方,所以我们必须考虑不同的时区。我最初认为我们必须将时间存储在 UTC 中。因此,如果我是 EST 时区的用户,例如,数据库将存储 2020 年 5 月 1 日作为日期,将 12 点作为时间(我计划将日期和时间存储在单独的列中)。但是,现在我很困惑,因为如果我存储了上周的日期,即在夏令时之前存储的 UTC 时间将是 2020 年 5 月 1 日上午 11 点。因此,当 DST 发生时,用户不会在正确的时间收到警报。如何存储时间以便用户始终在早上 7 点收到警报?我必须将日期存储在用户本地时区吗?顺便说一下,我有一个存储用户时区信息的表。
【问题讨论】:
-
您将值以 UTC 格式存储在数据库中,但您使用
ZonedDateTime和用户的时区计算该值。 -
@Khazana 对于
ZonedDateTime,没有“DST 之前”和“DST 之后”之分,因为ZonedDateTime知道任何给定的日期/时间是在夏令时还是标准时间,例如它知道 2020 年 5 月 1 日早上 7 点是夏令时。 那就是你应该使用ZonedDateTime的原因。 -
“将本地时间转换为 UTC 是一种有损操作” -- 如果您从本地日期/时间开始,转换为 UTC,然后再转换回来,这是不正确的使用相同的时区规范。让我们调用本地日期/时间
t。两种情况下使用的 DST 偏移将是在时间t生效的偏移,即使您在不同时间使用不同的当前 DST 偏移执行转换。 -
假设您的活动发生在 2020 年 10 月 31 日当地时间 07:00。您将其转换为应用用户当地时区的
Instant。假设它是美国太平洋时间。在那个时刻,PDT 应用,所以偏移量是 -0700,UTC 是2020-10-31 14:00Z。无论您何时进行转换,这永远不会改变。现在你想计算一周后的时间。您获取该日期/时间,转换为LocalDateTime,添加星期,然后转换回 UTC。添加一周后,新的本地值为2020-11-06 07:00,但由于 DST 未生效,偏移量为 -0800... -
... UTC 是
2020-11-06 15:00Z。同样,这永远不会改变。
标签: java mysql datetime timezone