Sunday, February 22, 2009

Difference in two Dates, Daylight saving issue and fixing

Calculating the number of days between two dates is not straight forward if
you are in a Time Zone which has daylight saving. Most of the programmers miss this
point and waits until it get caught up by the testing team or by the public user.

The worst case is sometimes this issue will continue to stay even without noticing as this happens only when the dates which are chosen are inside a period of daylight saving and may cost a lot at the end of the year.

The simplest way of calculating the number of days between two dates is
get the UTC time difference of the two dates and divide it by number of milliseconds per day. But this is incorrect as this can give false results if daylight saving is active on that particular dates.

Try the following example in Java.

Date d = new Date(2009, 2, 28, 12, 0, 0);
System.out.println(d + " local <=> GMT " + d.toGMTString());

Here we have created a Date object for 28 March 2009 and set the time to 12:00. Assume your time zone is GMT. But if you run this code you will notice the GMT time shows as 11:00. That means if you use getTime() function to get the time it is 1 hour less than what you expect.



There are few methods to fix this in Java.

1/ Add 2 hours to the difference that is 3600000 * 2 milliseconds.

Date d1 = new Date(year, month-1, day, 12, 0, 0);
Date d2 = new Date(year, month-1, day, 12, 0, 0);
int dif = (int)((d1.getTime() - d2.getTime() + 3600000 * 2 ) / 86400000);

Since 3600000 * 2 / 86400000 is a fraction it will be eliminated when casting to int. So this method will work when you are in daylight saving or not. This method can be used in any language Java, C, VB, PHP etc. or even JavaScript.

2/ Remove the offset value from the time component

Date d1 = new Date(year, month-1, day, 12, 0, 0);Date d2 = new Date(year, month-1, day, 12, 0, 0);

int dif = (int)((d.getTime() - d.getTimezoneOffset() * 60000 - (td.getTime() - td.getTimezoneOffset() * 60000) ) / 86400000);

Here the d.getTimezoneOffset() * 60000 is used because the offset is given in minutes. This is not required if you use the Calendar Object instead.

3/ You can pass a Custom TimeZone object to the Calendar object which doesn’t have anything in method bodies.

=============

No comments:

Post a Comment

Subscribe