请查看我是否可以告诉我如何处理DST问题。
首先,我的应用程序是一个物流系统,它适用于全球用户,因此它涉及时区问题,我将在设置用户本地预订日期时将其处理如下:
1.当用户登录应用程序时,我们可以根据登录IP获取用户的时区,但是只是一个偏移(我不记得这个东西的术语),例如“GMT + 08”(北京)或“GMT” -06“(芝加哥)。
2.在用户保存预订之前,我们需要设置预订当地日期,因为我无法直接获得用户本地日期。所以我将首先获得服务器日期(在我的情况下,它是北京时间),然后计算根据服务器日期和用户时区的本地日期,例如,如果用户时区为“GMT-08”,则服务器日期为2013-08-29 17:45:00。服务器时区是“GMT + 08”,然后我将使用服务器日期-8-8,结果将是2013-08-29 01:45:00。但由于我不考虑夏令时,计算的本地日期将与实际日期不同。现在在旧金山,实际的当地日期将比我用这种方式计算的结果提前一小时,
我发现java TimeZone已经考虑了DST问题,但我需要在构造TimeZone时提供“位置”名称(例如US / Alaska,Pacific / Apia)。虽然在我的情况下,我能得到的只是偏移量。你能告诉我如何在我的情况下解决DST问题吗?
答案 0 :(得分:5)
是的,您应该使用{8}中的Joda-Time或新的java.time包(受Joda-Time启发)。
偏移量是UTC(GMT)由特定日期时间值表示的小时数和分钟数。西海岸是-08:00(忽略夏令时废话),意味着比UTC晚8小时。
请注意,java.time在其初始版本中有一个小错误,它无法处理几分钟的偏移(例如+08
)而没有分钟(例如+08:00
)。
time zone是关于夏令时(DST)的偏移加规则,DST更改的历史记录以及有关其他异常的信息。
使用适当的time zone names(主要是大陆斜线城市)。避免使用3或4个字母代码,例如EST,它们既不是标准的也不是唯一的。
java.util.Date没有时区,而Joda-Time DateTime没有时区。
要获取网络浏览器的时区,请参阅this question。但通常,这不会很好。正如您可能已经看到的,许多网站要求用户选择时区。
您确切的用例令人困惑。通常,最好的方法是使用UTC的日期时间值,然后根据需要调整用户的本地时间。通常最适合您的软件工作和存储日期时间为UTC。然后显示调整为适合用户的本地日期时间。换句话说,全局思考(UTC),在本地呈现(调整本地时区)。
通常,系统管理员将其服务器计算机设置为UTC(无时区偏移)。如果您的操作系统(如Mac OS X)不提供UTC,则使用Reykjavik
,因为冰岛全年使用UTC,没有任何夏令时。同样,数据库引擎几乎总是将日期时间值转换为UTC进行存储。
当您真正不关心时区或时间时,Joda-Time会提供LocalDate类。但通常最好使用日期时间(DateTime实例),并根据需要格式化仅限日期的字符串。
Joda-Time 2.3中的示例代码。
DateTimeZone timeZoneChina = DateTimeZone.forID( "Asia/Shanghai" );
DateTime dateTimeChina = new DateTime( 2013, 8, 29, 17, 45, 00, timeZoneChina );
DateTime dateTimeUtc = dateTimeChina.withZone( DateTimeZone.UTC );
DateTime dateTimeParis = dateTimeChina.withZone( DateTimeZone.forID( "Europe/Paris" ) );
DateTimeZone timeZoneUsWestCoast = DateTimeZone.forID( "America/Los_Angeles" );
DateTime dateTimeUnitedStatesWestCoast = dateTimeChina.withZone( timeZoneUsWestCoast );
DateTimeFormatter formatter = ISODateTimeFormat.date();
String outputDateOnlyForUnitedStatesWestCoast = formatter.withZone( timeZoneUsWestCoast ).print( dateTimeUtc );
转储到控制台...
System.out.println( "dateTimeChina: " + dateTimeChina );
System.out.println( "dateTimeUtc: " + dateTimeUtc );
System.out.println( "dateTimeParis: " + dateTimeParis );
System.out.println( "dateTimeUnitedStatesWestCoast: " + dateTimeUnitedStatesWestCoast );
System.out.println( "outputDateOnlyForUnitedStatesWestCoast: " + outputDateOnlyForUnitedStatesWestCoast );
跑步时......
dateTimeChina: 2013-08-29T17:45:00.000+08:00
dateTimeUtc: 2013-08-29T09:45:00.000Z
dateTimeParis: 2013-08-29T11:45:00.000+02:00
dateTimeUnitedStatesWestCoast: 2013-08-29T02:45:00.000-07:00
outputDateOnlyForUnitedStatesWestCoast: 2013-08-29
答案 1 :(得分:3)
这是头痛的常见原因
我用以下方法解决了类似的问题: 您将精确时区与服务器端数据库中的每个用户相关联。当用户填写预订表格时,您会显示一个TZ选择器,预先填充其默认TZ。所以他可以仔细检查它(恕我直言,比通过IP猜测更安全),在服务器端,日期可以安全地从本地转换为服务器时间和返回。
答案 2 :(得分:1)
Joda时间可能能够解决您的问题:
http://joda-time.sourceforge.net/apidocs/org/joda/time/DateTimeZone.html