0

我正在使用 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

有任何想法吗?

4

3 回答 3

1

您可以使用 JodaTime >> http://joda-time.sourceforge.net/,它比 Java 日历更有效地实现时区计算

于 2013-04-27T00:38:55.070 回答
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 的建议。

于 2013-04-27T00:55:23.697 回答
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));
于 2013-04-27T01:02:07.123 回答