4/3/2028 and Date Calculations

H

hbetts3

Recently working on an application that looks forward. When performing
the following:

cDays = (inputDate.getTime() - calendarStart.getTime())/(1000*60*60*24)


The resulting value is 1...

cDays is declared as double...
anyone care to explain this one?

Thanks
Hendry
 
M

Michael Borgwardt

hbetts3 said:
Recently working on an application that looks forward. When performing
the following:

cDays = (inputDate.getTime() - calendarStart.getTime())/(1000*60*60*24)

You're aware that this calculation may produce incorrect results if daylight
savings time is involved?
http://www.xmission.com/~goodhill/dates/deltaDates.html
The resulting value is 1...

What do you expect?
cDays is declared as double...

The calculation will still be performed as an integer division, since the
operands are integers.
 
H

hbetts3

Ok.. I need to revise this statement...

further investigation proves the following...
On the given statement

cDays = (inputDate.getTime() - calendarStart.getTime())/(1000*60*60*24)


Where input Date = 04/02/2028 and calendarStart = 02/03/1901

cDays = 46445

if you change the inputDate to 04/03/2028, cDays still equals 46445 and
the date count stays off until 10/30/2028.
Any ideas now?

Thanks again -- Hendry
 
J

Jacob

hbetts3 said:
further investigation proves the following...
On the given statement

cDays = (inputDate.getTime() - calendarStart.getTime())/(1000*60*60*24)


Where input Date = 04/02/2028 and calendarStart = 02/03/1901

cDays = 46445

if you change the inputDate to 04/03/2028, cDays still equals 46445 and
the date count stays off until 10/30/2028.
Any ideas now?

I use the Day class (http://geosoft.no/software/day/Day.java.html)
as follows:

Day day1 = new Day (1901, 2, 3);
Day day2 = new Day (2028, 4, 2);
Day day3 = new Day (2028, 4, 3);
System.out.println (day1.daysBetween (day2));
System.out.println (day1.daysBetween (day3));

And get:

46447
46448
 
V

Virgil Green

hbetts3 said:
Ok.. I need to revise this statement...

further investigation proves the following...
On the given statement

cDays = (inputDate.getTime() -
calendarStart.getTime())/(1000*60*60*24)


Where input Date = 04/02/2028 and calendarStart = 02/03/1901

cDays = 46445

if you change the inputDate to 04/03/2028, cDays still equals 46445
and the date count stays off until 10/30/2028.
Any ideas now?

Provide a small, complete example. There are too many assumptions to be made
to give you an accurate answer. Of course, I'm not guaranteeing I could give
you an accurate answer even if you do provide the a complete example... but
it's fare more likely that someone subscribing to the group will be able to
do so once the example is provided.

- Virgil
 
T

Thomas Schodt

hbetts3 said:
Ok.. I need to revise this statement...

further investigation proves the following...
On the given statement

cDays = (inputDate.getTime() - calendarStart.getTime())/(1000*60*60*24)


Where input Date = 04/02/2028 and calendarStart = 02/03/1901

cDays = 46445

if you change the inputDate to 04/03/2028, cDays still equals 46445 and
the date count stays off until 10/30/2028.

I get

46446.958333333336
46447.958333333336
46658.0
46659.0

from this test


import java.util.Calendar;
import java.util.Date;

public class Hbetts3 {

public static void main(String[] arg) {
Calendar cs = Calendar.getInstance();
cs.set(1901,2,3);
Date calendarStart = cs.getTime();

cs.set(2028,4,2);
Date inputDate = cs.getTime();
cs.set(2028,4,3);
Date inputDate2 = cs.getTime();
cs.set(2028,10,29);
Date inputDate3 = cs.getTime();
cs.set(2028,10,30);
Date inputDate4 = cs.getTime();

double cDays,cDays2,cDays3,cDays4;

cDays = ( inputDate.getTime()-calendarStart.getTime())/
(1000D*60*60*24);
cDays2 = (inputDate2.getTime()-calendarStart.getTime())/
(1000D*60*60*24);
cDays3 = (inputDate3.getTime()-calendarStart.getTime())/
(1000D*60*60*24);
cDays4 = (inputDate4.getTime()-calendarStart.getTime())/
(1000D*60*60*24);

System.out.println(cDays);
System.out.println(cDays2);
System.out.println(cDays3);
System.out.println(cDays4);
}
}
 
P

P.Hill

hbetts3 said:
if you change the inputDate to 04/03/2028, cDays still equals 46445 and
the date count stays off until 10/30/2028.
Any ideas now?

That would be the Daylight Savings "fallback" date after which the 23
hour day in the spring (the "spring forward" date) is now perfectly
offset by an equal number of 25 hour fallback days, so that the
MILLIS_PER_DAY value is now good.

You COULD add just a little kludge to the calculation and add an hour.

-Paul
 
P

P.Hill

Jacob said:
I use the Day class (http://geosoft.no/software/day/Day.java.html)
as follows:

Day day1 = new Day (1901, 2, 3);
Day day2 = new Day (2028, 4, 2);
Day day3 = new Day (2028, 4, 3);
System.out.println (day1.daysBetween (day2));
System.out.println (day1.daysBetween (day3));

Hi Jacob,

Thank you very much for crediting me in your code at geosoft.no, but
you didn't read my article close enough or maybe you just run
into the same problems as I did. You still have a bug.
I tried your difference method and it is incorrect 'half' [:)]
the time. If you run the following code through a Daylight spring
forward date hence a 23 hour day you will see the problem.
Running the following results in:
Cal1 date is in daylight savings = false
diff is 0 in DLS false
diff is 1 in DLS false
diff is 2 in DLS false
diff is 3 in DLS false <--- same answer
diff is 3 in DLS true <--- for 2 diff. midnights
diff is 4 in DLS true
diff is 5 in DLS true

Note the diff stays at 3 for the midnight before and the
midnight after the Spring forward and then remains off
by one.

You can use the kludge where you add an hour because
you are always setting the underlying calendar at
midnight.

NOTE TO OTHERS, DO NOT JUST ADD ONE HOUR TO THE CALCULATION
WHEN SUBTRACTING ARBITRARY TIMES. Why? Because from
for example:
12:30 AM the morning before the DLS fall back day to
12:29 AM mornings (47:59 hours) later should
result in a value of 1 (it is more than 24 hours later, but less
than 48 hours later, but adding 1 hour results in a value
of 3.

-Paul


-Paul

import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.TimeZone;

/**
* @author Paul Hill
* @since 2005-01-05
*/
public class Scratch {

/**
* Return number of days between two days.
* The method always returns a positive number of days.
*
* @param date The day to compare to.
* @return Number of days between this and day.
*/
public static int daysBetween (Calendar cal1, Calendar cal2) {
long millisBetween = Math.abs (cal2.getTime().getTime() -
cal1.getTime().getTime());
return (int) Math.round (millisBetween / (1000 * 60 * 60 * 24));
}

public static void main(String args[]) {
Calendar cal1 = new GregorianCalendar( 2004, Calendar.APRIL, 1 );
Calendar cal2 = new GregorianCalendar( 2004, Calendar.APRIL, 1 );
TimeZone tz = cal1.getTimeZone();
System.out.println( "Cal1 date is in daylight savings = " +
tz.inDaylightTime( cal1.getTime() ));
for ( int i = 0; i < 7; i++ ) {
System.out.println( "diff is " + daysBetween( cal1, cal2 ) +
"\t in DLS " + tz.inDaylightTime( cal2.getTime() ) );
cal2.add( Calendar.DATE, 1);
}
}
}
 
H

hbetts3

Ok... actually, the fix was found in Greenwich, England.

The solution is not trivial, but I will try to encapsulate it here

Since I was only looking for a difference in days, and I knew they
would be in the thousands, I merely wanted to eliminate the DST
consideration.

By creating a GregorianCalendar and setting the timeZone to GMT I was
able to calculate the difference between days without concern for DST.
Michael, you were very correct that my problem was related to DST, but
it only cropped up every 147 years... so it wouldn't have shown up
until I was long gone. However, I prefer to write code that lasts
longer than I do :)

Thanks to Jacob, P.Hill, Virgil, and Thomas for all your input. It was
well received.

Sincerely

Hendry
 
J

Jacob

P.Hill said:
Hi Jacob,

Thank you very much for crediting me in your code at geosoft.no, but
you didn't read my article close enough or maybe you just run
into the same problems as I did. You still have a bug.

Do you have an actual example of two dates where the the
Day.java code fails?

In your example you take daysBetween() out of context and
prove it wrong. In Day.java it is always applied on two
Calendars of timezone GMT. That was the fix you were credited
for afterall :)
 
P

P.Hill

Jacob said:
In your example you take daysBetween() out of context and
prove it wrong. In Day.java it is always applied on two
Calendars of timezone GMT. That was the fix you were credited
for afterall :)

<slap location="forehead">
D'oh!
</slap>

Thanks for correcting that. I just looked right past the following in
your code.

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

That's why we should always re-use code that is shown to work instead
of making another "just like" the original and repeat the same mistakes,
even the same ones I've made myself in the past and told others not to make.

Solution 1: Use GMT/UTC
Solution 2: fudge an hour when ALWAYS using midnights
Solution 3: check the TZ offset.

Or a Rosanne Rosanna Danna used to say, "Never Mind!"

-Paul

p.s. See next note.
 
P

P.Hill

p.s. See next note.

Okay, now that I understand Jacob implementation for his Day class :)

Your day class is great, but I guess I wonder how useful
your Time class would be, because it assumes 24 hours in all days.
That is fine when you want to count days (as per your Day class), but I
usually expect counting hours to come out right for the actual local
time, not for people on the West Coast of Africa (where I believe some
countries (a) use UTC and (2) don't have DLS).

Do you, or anyone who is using Jacob's classes, have any thoughts on that?

hmm.

-Paul
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,777
Messages
2,569,604
Members
45,234
Latest member
SkyeWeems

Latest Threads

Top