Java中的时区

时间:2013-04-27 00:27:35

标签: java calendar

我正在研究java中的安全签名,它还会验证调用的日期和时间。 POST呼叫到达的内容类似于

String date = "Sat, 27 Apr 2013 01:11:30 GMT"
SimpleDateFormat RFC1123Format = new SimpleDateFormat("EEE, dd MMM yyyyy HH:mm:ss z", Locale.US);

我能够解析它

Calendar gmtTime = new GregorianCalendar(TimeZone.getTimeZone("GMT"));
Date dateHeader = RFC1123Format.parse(date);
gmtTime.setTime(dateHeader);

System.out.println("Date Header (GMT TIME): " + gmtTime.getTimeInMillis() + " ms");
System.out.println("Hour of day (GMT TIME): " + gmtTime.get(Calendar.HOUR_OF_DAY));

Calendar currentTime = new GregorianCalendar(TimeZone.getTimeZone("GMT"));
currentTime.setTimeInMillis(System.currentTimeMillis());

System.out.println("System Date (LA TIME): " + currentTime.getTimeInMillis() + " ms");
System.out.println("Hour of day (LA TIME): " + currentTime.get(Calendar.HOUR_OF_DAY));

currentTime.setTimeZone(TimeZone.getTimeZone("GMT"));

System.out.println("System Date (GMT TIME): " + currentTime.getTimeInMillis() + " ms");
System.out.println("Hour of day (GMT TIME): " + currentTime.get(Calendar.HOUR_OF_DAY));

System.out.println("Diff: " + Math.abs(gmtTime.getTimeInMillis() - currentTime.getTimeInMillis()));

然而,我得到的打印输出相差1小时。

Date Header (GMT TIME): 1367025090000 ms
Hour of day (GMT TIME): 1
System Date (LA TIME): 1367022298441 ms
Hour of day (LA TIME): 0
System Date (GMT TIME): 1367022298441 ms
Hour of day (GMT TIME): 0
Diff: 2791559

有什么想法吗?

3 个答案:

答案 0 :(得分:1)

您可以使用JodaTime>> {J}比Java日历更有效地实现TimeZone计算

答案 1 :(得分:0)

通过添加额外的验证来检查是否正在观察夏令时来修复此问题。这是最终的代码:

Calendar gmtTime = new GregorianCalendar(TimeZone.getTimeZone("GMT"));
Date dateHeader = RFC1123Format.parse(date);
gmtTime.setTime(dateHeader);

Calendar currentTime = Calendar.getInstance();
currentTime.setTimeInMillis(System.currentTimeMillis());
boolean DST = false;
if(currentTime.getTimeZone().inDaylightTime(currentTime.getTime())) {
    DST = true; 
}
currentTime.setTimeZone(TimeZone.getTimeZone("GMT"));
if(DST) { 
    currentTime.set(Calendar.HOUR_OF_DAY, currentTime.get(Calendar.HOUR_OF_DAY) + 1); 
    .
    .
    .
    <code to handle last day of month and month change as a result of the hour adjustment>
}

感谢@gangqinlaohu的建议。

答案 2 :(得分:0)

您不会向格式化程序提供用于表示时间戳的日历。

在这种情况下,您的日历设置为表示GMT中的时间戳。 GMT是UTC的同义词,UTC从未观察到对DST的任何调整。但是,默认情况下,格式化程序必须将提供的字符串转换为系统默认日历作为基础,这可能会观察到DST。

如果是这种情况,您可以通过确保格式化程序使用您用来表示日期/时间的相同日历来获得一致的报告。试试这个:

SimpleDateFormat RFC1123Format = new SimpleDateFormat();
GregorianCalendar gc - new GregorianCalendar(TimeZone.getTimeZone("GMT"));

RFC1123Format.setCalendar(gc);
RFC1123Format.applyPattern("EEE, dd MMM yyyyy HH:mm:ss z");

gc.setTime(RFC1123Format.parse(yourDateString));