【问题标题】:Storing event times, UTC issues when DST存储事件时间,DST 时的 UTC 问题
【发布时间】:2015-04-27 15:09:07
【问题描述】:

我在询问之前搜索了这个,但找不到任何有用的东西。我有一个使用 UTC 的服务器,客户端可以设置服务器每天执行的事件的时间(这是一个简化)。例如,法国的某个人希望在当地时间 23:00(22:00 UTC)发生事件。我将其转换为 UTC 并存储它;服务器每天 22:00 UTC 愉快地执行。然后到了夏天,现在与法国的偏移量是 +2h,服务器仍然在 22:00 UTC 执行,但对于用户来说这是错误的时间,因为法国的 22:00 UTC 现在是当地时间 00:00。

我以 UTC 存储,因为每个人都说要以 UTC 存储并在输出给用户时转换为本地时间,很好,但这对用户来说并不像预期的那样工作。我想我应该存储像法国时间 23:00 这样的东西,服务器应该接受它并说“好的,这是今天 22:00 UTC”或者好的,这是因为 DST 今天是 21:00 UTC”(我正在使用 Java与 JodaTime 顺便说一句),但这与每个人所说的我应该如何将它以 UTC 存储在数据库中的说法相矛盾......所以......我可以/应该做什么?

如果我存储带有偏移量的本地时间和日期,并且当我读取它时(在使用 UTC 的服务器上),我会这样做:

DateTime dbLocalHistoricDateTime = fromDB(); // suppose this 23:00 in France on the 01.01.2015 (UTC+1), 22:00 UTC on that date
DateTimeZone localZone = dbLocalHistoricDateTime.getZone();
DateTime currentLocalDateTime = DateTime.now().withZone(localZone);
DateTime localToday = dbLocalHistoricDateTime.withDate(currentLocalDateTime.getYear(), currentLocalDateTime.getMonthOfYear(), currentLocalDateTime.getDayOfMonth());
DateTime utcToday = localToday.withZone(DateTimeZone.UTC);

然后 utcToday 包含今天正确的 UTC 时间(21:00 UTC 是 27.04.2015 在法国的 23:00,然后服务器可以在该 UTC 时间执行此事件。

谢谢, 加布里埃尔

【问题讨论】:

标签: java database timezone utc


【解决方案1】:

如果你想代表一个重复事件,你肯定需要存储本地时间和时区,或者存储或者决定如果该时间变得无效时该怎么做的策略,或者模糊的。 (假设用户存储 02:30 - 在春季,当时钟向前走时,该值根本不会出现,而在秋季,当时钟向后走时,它会出现两次。)

但是,如果您有重复的事件,则无论如何都不应该存储 DateTime - 我会存储类似“开始日期”(它应该发生的第一个日期;LocalDate )、每天应该发生的时间(LocalTime)和时区 ID(例如 Europe/Paris)。

如果您要存储未来的事件,存储“本地日期/时间和时区”也很重要,请记住时区规则可能会在现在和那时之间发生变化。

在以下情况下存储 UTC 瞬间很有用:

  • 原来的时区不再相关(如果它甚至存在的话)
  • 事件不再重复
  • 您希望能够真正轻松地比较事件

这与时间戳特别相关。

但是是的,就像日期/时间处理中的大多数事情一样,不存在简单的“一刀切”的答案 - 您需要考虑您的上下文。

【讨论】:

    猜你喜欢
    • 2011-09-24
    • 2019-04-30
    • 2020-02-25
    • 2013-09-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-11
    • 2020-10-10
    相关资源
    最近更新 更多