我想知道如何向不同时区的用户提供日期(没有时间元素)。假设日期存储在某个时区(例如UTC + 6)中运行的某个服务器上的某个数据库中,并且应用服务器在同一台机器上运行(或至少在同一时区)。该应用程序必须处理两种类型的时间值: A / DateTime (例如2013-08-20 08:00 UTC)和 B / Date (例如2013- 08-20)。
A / DateTime 很容易处理,因为它代表了历史中的某个特定点。例如Moon Landing。它存储在数据库中的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似乎很容易,并且不向用户显示时间组件。但转移后这将导致2013-08-19从时区UTC-x出现,这是错误的,因为我们并不真正知道世界的哪个部分在历史中被认为是昨天以及今天仍然在哪里。实际上,地球上有三个不同的日期(http://en.wikipedia.org/wiki/International_Date_Line)。
问题的一个好例子是发票到期日。当您在UTC + 6时区发布截止日期为2013-08-20的发票并将其存储在UTC中的服务器上时,中国的某个人应该付费吗?它是基于UTC的服务器上的2013-08-19还是2013-08-20?
制定问题:
如果没有存储和处理时间元素的日期应该如何能够从多个时区(包括超过12小时的差异)向客户提供服务?应该转移吗?它应该保持相同的日期吗?您如何在项目中处理这种情况?
非常感谢您阅读这一点。任何参考或想法表示赞赏。只有我能够达到的相关材料是之前提到的维基文章,但说实话,我不确定我的问题是否有答案。大多数文章与日期时间转移有关,但此时部分处理得很好。
P.S。应用程序服务器是用Java编写的,所以我正在标记这个问题Java,以鼓励Java特定的解决方案,如果有的话。
答案 0 :(得分:2)
首先,我很高兴看到你对此有所考虑!许多开发人员都会掩盖这些细节,这些细节可能非常重要,具体取决于您的应用程序要求。
在Java中,您应该使用Joda Time库来解决这些问题。它将帮助您分离您正在谈论的概念。
Joda Time中的第二个概念称为LocalDate
。
您还确定了DateMidnight
类型 - 我同意这种类型可能无法满足您的特定需求。
重要的是要意识到LocalDate
并非真正处于任何时区。这不是瞬间时间线上的一刻。它只是日历上的一个位置。它映射到一个真实的时间点取决于你如何解释它。
您可以将LocalDate
绑定到客户所在时区的当天结束时,这意味着您公司的每个客户都有不同的时刻。
您可以将LocalDate
绑定到公司时区的一天结束时,这意味着每个客户都有不同的时刻。
您可以制定公司政策,即工作日由UTC定义。
您应该考虑每个选项的实际含义。例如,由于您正在谈论发票到期日,因此您可能希望允许宽限期。
最后一点 - 您应始终确保您的代码不关心服务器的时区。您可以轻松部署到具有特定时区的服务器,并且您不希望它破坏任何内容。智能使用UTC或日期/时间/偏移类型将在特定时刻解决此问题。但由于LocalDate
不是确切的时刻 - 您必须小心从应用程序逻辑中的某些时区获取它。不要只是向服务器询问“现在”并假设这是正确的区域。