webapp中的时区问题

May*_*dya 3 java timezone web-applications

我想知道在Web应用程序中处理时区的最佳实践.举个例子,Server是UTC时区,user1和user2都在不同的时区.什么是处理日期的正确方法?

  1. 当user1添加新日期时,它处于不同的时区,Server是UTC,那么我应该将日期转换为UTC并存储在数据库中吗?

  2. 显示UTC格式的日期获取日期,然后根据客户端时区进行转换并显示.这是正确的方法吗?

  3. 什么是DST问题?它会影响这个过程吗?

  4. 在某个地方,我以毫秒为单位阅读商店日期只是好主意吗?现在我存储日期/时间.

  5. 有没有适当的方法或库,请建议

我的问题是

GMT +5:30的客户创建记录并设置交付日期和时间让我们说2014年6月30日晚上11:30 GMT +5:30

因此GMT -3:00的运输商可以在GMT -3:00中看到客户选择的确切当地时间.怎么做到这一点?

Bas*_*que 7

1

是.通常,最佳做法是将所有日期时间值存储在UTC中.您的业​​务逻辑应该以UTC工作.

您可能还希望将用户输入的值或外部数据源存储为审计跟踪或调试辅助.但使用UTC作为官方记录.

是的,服务器的时区应设置为UTC(或者,如果不可能,则使用雷克雅未克冰岛).但是在编程中不要依赖于此.在代码中指定所需的时区,而不是依赖于默认值.

2

是.转换为本地化的演示时间.当然,除非用户更喜欢UTC.

将其视为本地化的一部分.进行国际化时,可以使用代码中的键值.然后在演示时,您使用键值来查找要显示给用户的本地化翻译字符串.

3

没问题.如果"DST"表示夏令时,则使用体面的日期时间库将自动处理夏令时的调整.警告:您需要保持图书馆使用的时区定义列表是最新的,因为政府经常更改规则.

如果调整DST(或时区)会导致您的用户产生混淆或错误信息,那么您应该在这种情况下显示UTC.

4

不可以.在大多数情况下,不要存储或工作毫秒.数据库和日期时间库可以在内部执行,但您不应该这样做.

一些书呆子类型会建议跟踪毫秒.但是使用日期时间作为毫秒就像使用文本作为字节数组一样.我们使用具有更高抽象级别的代码库来处理文本的所有复杂性(UTF-8,变音符号的Unicode规范化等)并添加有用的方法(搜索,替换等).所以它与日期时间有关.

此外,使用毫秒将导致混淆并使调试变得困难,因为您无法轻易理解它们的价值.日期时间工作本身就很棘手且容易出错.使用毫秒没有帮助.

并非所有数据库和其他库都在内部使用毫秒.有些使用整秒,或微秒,或纳秒.它们也都没有使用相同的时代.

在Java中,我们有两个很好的日期时间库:Joda-Timejava.time(Java 8).

java.time包的灵感来自Joda-Time,但是经过重新设计.他们有相似的概念,但不完全相同.只要您小心处理import语句,就可以在代码中使用它们.两者都有自己的优点和缺点.

避免使用juDate/.Calendar

不要使用与Java捆绑在一起的java.util.Date和.Calendar类.众所周知,它们在设计和实施方面都很麻烦,存在缺陷.它们已经被Sun/Oracle取代了新的java.time包.

Joda-Time和java.time都包含了一些方便的方法来转换为java.util.Date对象或从java.util.Date对象转换为其他类需要juDate对象.

奖金提示

关于文本格式:

  • 避免使用您在问题中使用的字符串格式.它难以理解且难以解析.
  • 了解如何使用ISO 8601标准定义的各种字符串格式进行日期时间值的文本表示.
  • 不要像在你的问题中那样在偏移中丢弃前导零.这将破坏库中的代码,并违反标准要求.总是写+05:30,永远不会 +5:30.即使在撰写散文时也要养成这种习惯,而不仅仅是编程代码.

示例代码

使用Joda-Time 2.3的示例代码.

实例化日期时间,本地到+05:30偏移量.我任意选择加尔各答时区.当然,你会用适当的替换.

DateTimeZone timeZoneKolkata = DateTimeZone.forID( "Asia/Kolkata" );
DateTime dateTimeKolkata = new DateTime( 2014, DateTimeConstants.JUNE, 30, 23, 30, 0, timeZoneKolkata );
Run Code Online (Sandbox Code Playgroud)

使用-03:00偏移将相同时刻调整到另一个时区.我随意选择了America/Buenos_Aires.

DateTimeZone timeZoneBuenos_Aires = DateTimeZone.forID( "America/Buenos_Aires" );
DateTime dateTimeBuenos_Aires = dateTimeKolkata.withZone( timeZoneBuenos_Aires );
Run Code Online (Sandbox Code Playgroud)

转换为UTC.

DateTime dateTimeUtc = dateTimeKolkata.withZone( DateTimeZone.UTC );
Run Code Online (Sandbox Code Playgroud)