3

我想知道如何向不同时区的用户显示日期(没有时间元素)。假设日期存储在某个服务器上的某个数据库中,该服务器在某个时区(例如 UTC+6)中运行,并且应用程序服务器在同一台机器上运行(或至少在同一时区中)。应用程序必须处理两种类型的时间值:A/DateTime(例如 2013-08-20 08:00 UTC)和B/Date(例如 2013-08-20)。

A/ DateTime很容易处理,因为它代表了历史中的某个特定点。例如登月。它存储在数据库中的 UTC 中,每当它呈现给客户时,它就会转移到他的时区,以便适合他的现实。所以 2013-08-20 08:00 UTC = 2013-08-20 14:00 UTC+6 = 2013-08-19 22:00 UTC-10。每个客户都在看同一个时间点 = 从他的角度来看同一个事件,一切都很美好。

B/日期=问题。这种类型的时间值代表历史中的特定日期。由于它没有时间元素,它不能转移到不同的时区。将带有零时间分量的日期存储为 2013-08-20 00:00 UTC 并在没有时间分量的情况下向用户呈现它似乎很容易。但是在将其从 UTC-x 时区转移到 2013-08-19 之后,这是错误的,因为我们真的不知道历史上的这一点在世界的哪个地方被认为是昨天以及今天仍然在哪里。实际上,地球上的某些时间点有三个不同的日期(http://en.wikipedia.org/wiki/International_Date_Line)。

问题的一个很好的例子是发票的到期日。当您在 UTC+6 时区开具到期日为 2013 年 8 月 20 日的发票并将其存储在位于 UTC 的服务器上时,中国应该何时付款?在基于 UTC 的服务器上是 2013-08-19 还是仍然是 2013-08-20?

制定问题:

没有存储和处理时间元素的日期应该如何从多个时区(包括超过 12 小时的差异)向客户提供服务?应该转移吗?它应该保持相同的日期吗?您如何在项目中处理这种情况?

非常感谢您阅读到此为止。任何参考或想法表示赞赏。我能找到的唯一相关材料是前面提到的 wiki 文章,但老实说,我不确定我的问题是否有答案。大多数文章都与日期时间偏移有关,但此时该部分处理得很好。

PS 应用程序服务器是用 Java 编写的,所以我标记了这个 Java 相关问题,以鼓励 Java 特定的解决方案(如果有的话)。

4

1 回答 1

2

首先,我很高兴看到您对此有所考虑!许多开发人员忽略了这些细节,根据您的应用程序要求,这些细节可能非常重要。

在 Java 中,您应该使用Joda Time库来解决这些问题。它将帮助您区分您正在谈论的概念。

  • 您确定的第一个概念Instant在 Joda Time 中称为 an。当绑定到时区时,它被称为DateTime.

  • Joda Time 中的第二个概念称为LocalDate.

  • 您还确定了DateMidnight类型 - 我同意这可能不适用于您的特定需求。

重要的是要意识到 aLocalDate并不真正在任何时区。这不是瞬时时间线上的片刻。这只是日历上的一个位置。它映射到一个真实的时间点将取决于你如何解释它。

正如邓肯在评论中指出的那样——很难直接告诉你应该做什么,因为不同的企业在这方面有不同的要求。但这里有一些不同的方法:

  • 您可以将 绑定LocalDate到客户时区的一天结束,这意味着您公司的每个客户都有不同的时刻。

  • 您可以将 绑定LocalDate到公司时区的一天结束,这意味着每个客户的不同时刻。

  • 您可以有一个公司政策,即工作日由 UTC 定义。

您应该仔细考虑每个选项的实际含义。例如,由于您正在谈论发票到期日,您可能希望允许宽限期。

最后一点 - 您应该始终确保您的代码不关心服务器的时区是什么。您可以轻松地部署到具有特定时区的服务器,并且您不希望它破坏任何东西。巧妙地使用 UTC 或 Date/Time/Offset 类型将在特定时刻解决这个问题。但由于这LocalDate不是一个确切的时间 - 您必须小心从应用程序逻辑中的某个时区获取它。不要只向服务器询问“现在”并假设这是正确的区域。

于 2013-08-20T15:42:23.143 回答