2016-03-07 71 views
1

使用UTC时区时,我遇到了Calendar和SimpleDateFormatter的一些意外行为。它看起来像SimpleDateFormatter给出了正确的结果,但日历不是。我不知道为什么。我使用下面的代码来生成日期使用日历:带日历的时区

Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC")); 
    cal.set(Calendar.YEAR, 2012); 
    cal.set(Calendar.MONTH, Calendar.MARCH); 
    cal.set(Calendar.DAY_OF_MONTH, 5); 
    cal.set(Calendar.HOUR, 0); 
    cal.set(Calendar.MINUTE, 0); 
    cal.set(Calendar.SECOND, 0); 

换句话说,2012年3月5日00:00 UTC。
当我在本地CST时区打印这个时候,我得到:

Mon Mar 05 06:00:00 CST 2012
这很奇怪,因为CST是UTC-6:00,所以我预计2012年3月4日星期日18:00 CST(即午夜前6小时前一天)。相反,我在UTC 6小时后得到

当我使用像这样一个SimpleDateFormatter:

DateFormat df = new SimpleDateFormat("yyyy-MM-dd"); 
    df.setTimeZone(TimeZone.getTimeZone("UTC")); 
    df.parse("2012-03-05"); 

我得到预期的 “星期日2012年3月4日18:00 CST”,这是UTC6小时,即UTC-6:00 。

为什么我的结果错了?

回答

1

Calendar.HOUR以12小时格式设置小时,因此您不会将其设置为午夜,而是设置为12点。

使用Calendar.HOUR_OF_DAY代替或确保还设置了AM/PM值:

cal.set(Calendar.AM_PM, Calendar.AM); 
+0

哇,这是微妙的和可怕的。感谢您指出了这一点。改变它之后,单元测试现在通过。大! – PatrickB

+0

它是。 Java 8之前的日期/时间函数确实存在问题。如果你打算和他们打交道,而且你不能使用Java 8,你可能需要查看一些特定的库,例如[JodaTime](http://www.joda.org/joda-time/)。 –