Reputation: 453
I'm working on a security signature in java that also verifies the date and time the call is being made. The POST call arrives with something like
String date = "Sat, 27 Apr 2013 01:11:30 GMT"
SimpleDateFormat RFC1123Format = new SimpleDateFormat("EEE, dd MMM yyyyy HH:mm:ss z", Locale.US);
And I'm able to parse it
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()));
However the printout I get differs by 1 entire hour.
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
Any ideas?
Upvotes: 0
Views: 248
Reputation: 453
Fixed it myself by adding an extra verification to check if Daylight Savings is being observed. This is the final code:
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>
}
Thanks @gangqinlaohu for your suggestion.
Upvotes: 0
Reputation: 10084
You don't give your formatter the calendar that you are using to represent your timestamps.
In this case, your calendar is set to represent timestamps in GMT. GMT is a synonym for UTC and UTC never observes any adjustment for DST. Your formatter, however, by default must convert your supplied string with the system default calendar as the basis, which likely does observe DST.
If this is the case, you can get consistent reporting by making sure that your formatter is using the same calendar that you are using to represent your date/times. Try this:
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));
Upvotes: 0
Reputation: 113
You can use JodaTime >> http://joda-time.sourceforge.net/ that implements TimeZone Calculations more efficiently than Java calendar
Upvotes: 1