Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Java > GregorianCalendar - it's a bomb ;-) [code insight]

Reply
Thread Tools

GregorianCalendar - it's a bomb ;-) [code insight]

 
 
Xandau
Guest
Posts: n/a
 
      06-22-2004
on the beginning i have to say that i use SDK 1.3.1_11


public void m() {
Integer scanInterval = new Integer(581);
try {
Date d;
GregorianCalendar gc = new GregorianCalendar();
GregorianCalendar gc2 = new GregorianCalendar();
System.out.println("GC = "+ gc.getTime().toString());

gc.set(gc.HOUR_OF_DAY, gc.get(gc.HOUR_OF_DAY) +
scanInterval.intValue());
System.out.println("GC = "+ gc.getTime().toString());
gc2.add(GregorianCalendar.HOUR_OF_DAY, scanInterval.intValue());
System.out.println("GC2 = "+ gc2.getTime().toString());
System.out.println("XXX "+ gc.get(gc.HOUR_OF_DAY));
} catch (Exception ex) {
ex.printStackTrace();
}
}

and on standard output we can see:
GC = Tue Jun 22 15:03:42 CEST 2004
GC = Fri Jul 16 20:03:42 CEST 2004
GC2 = Fri Jul 16 20:03:42 CEST 2004
XXX 20

- so the results are excactrly the same as we have expected ...
but if we change a value of "scanInterval" to higher like 585 or more...

public void m() {
Integer scanInterval = new Integer(590);
try {
Date d;
GregorianCalendar gc = new GregorianCalendar();
GregorianCalendar gc2 = new GregorianCalendar();
System.out.println("GC = "+ gc.getTime().toString());

gc.set(gc.HOUR_OF_DAY, gc.get(gc.HOUR_OF_DAY)
+scanInterval.intValue());
System.out.println("GC = "+ gc.getTime().toString());
gc2.add(GregorianCalendar.HOUR_OF_DAY, scanInterval.intValue());
System.out.println("GC2 = "+ gc2.getTime().toString());
System.out.println("XXX "+ gc.get(gc.HOUR_OF_DAY));
} catch (Exception ex) {
ex.printStackTrace();
}
}


the results are unbelivible :
GC = Tue Jun 22 15:07:37 CEST 2004
GC = Fri May 28 12:04:50 CEST 2004
^^^^^^^^^^^^^^^^^^^^^^^^^^
GC2 = Sat Jul 17 05:07:37 CEST 2004
XXX 12

i am wondering why 580 hours is counted corrected but 584 is counted
wrong...


regards,
Adam



 
Reply With Quote
 
 
 
 
=?UTF-8?B?IkRhcmlvIChkcmlua2luZyBjb++sgGVlIGluIHRoZSBv76yDY2XigKYpIg==?=
Guest
Posts: n/a
 
      06-22-2004
Xandau wrote:

> gc.set(gc.HOUR_OF_DAY, gc.get(gc.HOUR_OF_DAY) + scanInterval.intValue());
> ✄ ✄ ✄ ...
> i am wondering why 580 hours is counted corrected but 584 is counted wrong...


Bug is inside computeTime method of GregorianCalendar.
Here the following value
zzz * 60 *60 * 1000
is assigned to the millisInDay int variable,
where zzz is the value used in the invocation of:
gc.set(gc.HOUR_OF_DAY, zzz)

As you can note the int expression
zzz * 60 *60 * 1000
is OK when zzz <= 596, but it overflow when zzz >= 597.

So the bug!

Probably this bug must be submitted to Sun,
or, perhaps, the bug is already known by Sun.

- Dario
 
Reply With Quote
 
 
 
 
Thomas Weidenfeller
Guest
Posts: n/a
 
      06-22-2004
Xandau wrote:
> i am wondering why 580 hours is counted corrected but 584 is counted
> wrong...


You are working well out of the range of HOUR_OF_DAY. The set behavior
for values larger than 23 hours is not defined. You were just lucky that
it worked until 580 hours and that no little green gremlins came out of
your CD drive.

You would have to study the source code (comes with the SDK) to figure
out why it works for so long. As a guess, a variable overflows at that
point, is cut of, and you are thrown back in time. Interestingly, you
are thrown back something like 24 days. And 24 * 24 is 576, close to
your magic numbers. Yep, looks pretty much like an overflow to me.

/Thomas
 
Reply With Quote
 
Michael Borgwardt
Guest
Posts: n/a
 
      06-22-2004
Dario (drinking coffee in the office…) wrote:
> Bug is inside computeTime method of GregorianCalendar.
> Here the following value
> zzz * 60 *60 * 1000
> is assigned to the millisInDay int variable,
> where zzz is the value used in the invocation of:
> gc.set(gc.HOUR_OF_DAY, zzz)
>
> As you can note the int expression
> zzz * 60 *60 * 1000
> is OK when zzz <= 596, but it overflow when zzz >= 597.
>
> So the bug!
>
> Probably this bug must be submitted to Sun,
> or, perhaps, the bug is already known by Sun.


Actually, I wouldn't really call it a but. Note that the method is called*set*.
Setting HOUR_OF_DAY to such an extremely large value makes no sense. The *add*,
where it does make sense, works fine.

Of course, it shouldn't overflow silently. The parameter should be checked and
an exception thrown when it's too large, and the restriction documented
in the API.
 
Reply With Quote
 
Thomas Weidenfeller
Guest
Posts: n/a
 
      06-22-2004
Dario (drinking coffee in the office…) wrote:
> Bug is inside computeTime method of GregorianCalendar.

[...]
> So the bug!
>
> Probably this bug must be submitted to Sun,
> or, perhaps, the bug is already known by Sun.


I don't think it is a bug. Calendar's documentation indicates that the
field is for the 24-hour clock of the day. And I think we can agree that
there is no 580 hour in a day. The set is simply operated outside of the
specification.

The only change I would consider if I would be Sun would be to throw an
exception if someone tries to set the field to something outside the
range of [0..23].

/Thomas
 
Reply With Quote
 
Roedy Green
Guest
Posts: n/a
 
      06-22-2004
On Tue, 22 Jun 2004 17:31:12 +0200, Thomas Weidenfeller
<(E-Mail Removed)> wrote or quoted :

>The only change I would consider if I would be Sun would be to throw an
>exception if someone tries to set the field to something outside the
>range of [0..23].


the other way of thinking is, what timestamp represents 26 hours after
.... and getting what you want with illegal values.

In BigDate you have a choice.

--
Canadian Mind Products, Roedy Green.
Coaching, problem solving, economical contract programming.
See http://mindprod.com/jgloss/jgloss.html for The Java Glossary.
 
Reply With Quote
 
Michael Borgwardt
Guest
Posts: n/a
 
      06-23-2004
Roedy Green wrote:
>>The only change I would consider if I would be Sun would be to throw an
>>exception if someone tries to set the field to something outside the
>>range of [0..23].

>
>
> the other way of thinking is, what timestamp represents 26 hours after


That's what the add() method is for.
 
Reply With Quote
 
Xandau
Guest
Posts: n/a
 
      06-23-2004
Thanks all for answers,
however i think that even if i have used a set
methond with to large number i should got an exception....

have changed a call to add... a now is working well.

Adam


 
Reply With Quote
 
Michael Borgwardt
Guest
Posts: n/a
 
      06-23-2004
Xandau wrote:
> Thanks all for answers,
> however i think that even if i have used a set
> methond with to large number i should got an exception....


I think everyone agrees that the silent failure via integer overflow
and especially the lack of documentation of the allowable value range
is a serious flaw in the API.
 
Reply With Quote
 
=?UTF-8?B?IkRhcmlvIChkcmlua2luZyBjb++sgGVlIGluIHRoZSBv76yDY2XigKYpIg==?=
Guest
Posts: n/a
 
      06-25-2004
Michael Borgwardt wrote:

> Xandau wrote:
>
>> Thanks all for answers,
>> however i think that even if i have used a set
>> methond with to large number i should got an exception....

>
> I think everyone agrees that the silent failure via integer overflow
> and especially the lack of documentation of the allowable value range
> is a serious flaw in the API.


Bugs 4936355 and 5067733 are fixed in Tiger.Beta.

- Dario
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
What a mess: Date, milliseconds, GregorianCalendar Erwin Moller Java 80 08-27-2004 11:05 AM
Convert from java.sql.Date to GregorianCalendar TT \(Tom Tempelaere\) Java 17 02-01-2004 01:04 AM
GregorianCalendar Andreas N Rasmussen Java 5 12-06-2003 12:31 AM
GregorianCalendar applet and StreamCorruptedException Nigel Wade Java 10 11-24-2003 05:15 PM
GregorianCalendar and how to subtract MONTH from a date. Manoj Nair Java 4 09-04-2003 05:49 AM



Advertisments