java - 如何向来自不同时区的用户显示日期(没有时间元素)?

标签 java database date datetime timezone

我想知道如何向来自不同时区的用户显示日期(没有时间元素)。假设日期存储在某个服务器上的某个数据库中,该服务器在某个时区(例如 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-08-20 的发票并将其存储在位于 UTC 的服务器上时,中国人应该何时付款?在基于 UTC 的服务器上是 2013-08-19 还是仍然是 2013-08-20?

提出问题:

应该如何存储和处理没有时间元素的日期,才能将其提供给来自多个时区(包括超过 12 小时的时差)的客户?是否应该转移?它应该保持相同的日期吗?您如何在项目中处理这种情况?

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

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

最佳答案

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

在 Java 中,您应该使用 Joda Time这些问题的图书馆。它将帮助您区分所讨论的概念。

  • 您确定的第一个概念称为 Instant在乔达时间。当绑定(bind)到时区时,它被称为 DateTime .

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

  • 您还确定了 DateMidnight类型 - 我同意这可能无法满足您的特定需求。

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

正如 Duncan 在评论中指出的那样 - 很难直接建议您应该做什么,因为不同的企业在这方面有不同的要求。但这里有一些不同的方法:

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

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

  • 您可以制定工作日由 UTC 定义的公司政策。

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

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

关于java - 如何向来自不同时区的用户显示日期(没有时间元素)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18337199/

相关文章:

java - 单击菜单项时如何显示 JavaFX Web View ?

java - 使用不同的包名称跨不同应用程序反/序列化 java 对象

java - 为什么 NVL 函数称为 "NVL"?

php - 当数据位于不同行时,使用Where子句检索数据

javascript - 每 18 小时循环倒数计时器,并具有特定的开始日期

java - 定义接口(interface)和类的最佳/标准方法

java - Spring Boot 安全性 - java.lang.IllegalArgumentException : Cannot pass a null GrantedAuthority collection

sql - postgresql 中奇怪的间隔

javascript - (JavaScript) 每天比较时间戳(超过 2 年)

javascript - 日期时间过滤器 AngularJS 没有给出正确的日期?