I’ve been doing some date math at work and I came across something I thought was wack.
Check this out:
Calendar cal1 = Calendar.getInstance(); Thread.sleep(500); Calendar cal2 = Calendar.getInstance(); Thread.sleep(500); Date now = new Date(); System.out.println(cal1.before(cal2)); System.out.println(cal1.before(now));
What do you think this snippet prints (It compiles, I promise!)?
Looking at the code, it shows that we are getting three snapshots in time, waiting half a second between snapshots, and assigning those values to cal1,cal2, and now, respectively. I put in the Thread.sleep() to illustrate the point more clearly. The first print statement compares the first and second snapshots in time, returning true if the first is before the second. The second print statement returns true if the first is before the third snapshot.
Logically, we would expect both print statements to prints true. However, this outputs:
true false
But, how could the first snapshot be before the second snapshot but not the third?
Putting up the javadocs, gives us our answer. The Calendar before and after methods always returns false if you don’t pass it a Calendar object. Why? I have no idea. Why not just have the method signature take a Calendar object? I mean, I guess this allows you to extend Calendar to be able to call after/before on whatever kind of classes you want to support…but does it really make sense to compare a Calendar to a Monkey class? This is what I call a Java WTF.
9 Responses
Gareth
07|Mar|2008 1Here is the code behind Calendar.before(Object when)
public boolean before(Object when) {
return when instanceof Calendar &&
getTimeInMillis()
Gareth
07|Mar|2008 2Taken from the javadocs
“if and only if when is a Calendar instance. Otherwise, the method returns false.”
Theo
07|Mar|2008 3I’m interested in hearing the Java API designers rationale on why they designed the Calendar API like this. I understand the implementation. Don’t you think it’s kind of strange the Date class before/after takes a Date object and performs as expected, while the Calendar class’s after/before takes any ol’ Object AND only operates on other Calendar objects?
Asd
07|Mar|2008 4The Calendar code was “donated” by IBM. Accepting it was the worst decision in the history of Java.
bhaskar
07|Mar|2008 5If you need a decent time API in Java use joda-time. Seriously you will never go back to the JDK time API mess.
David HM Spector
07|Mar|2008 6Joda-time is great, however for anything that requires a Date or Calendar object you’ll just wind up have to screw around with conversion back to Date and Calendar.
Sun needs to have a flag day at some point and just throw out both Date and Calendar. It’s one of the single worst aspects of Java programming.
whaley
07|Mar|2008 7Joda-time is being used as the basis for the date/time/whatever api in jdk7. David HM Spector, you are getting your wish.
Fabrizio Giudici
07|Mar|2008 8JSR-310 is a clean up of Joda-Time that will hopefully be part of Java 7, so it would be a good idea to start using it.
I didn’t know that Date/Calendar was an IBM contribution. Do you have a reference? It would explain many things (even though I’m not saying Sun does always perfect thing, of course).
Theo
07|Mar|2008 9check this out:
http://www.icu-project.org/docs/papers/international_calendars_in_java.html
Leave a reply
About
My name is Theodore Nguyen-Cao. I'm a software engineer and I blog my thoughts on technology and life.
Search
Categories
Archives
Links
Calendar
Theodore Nguyen-Cao's blog
Copyright © 2007 - A Noted Path
InSense 1.0 Theme by Design Disease