Click to See Complete Forum and Search --> : Java (1.2.2) Calendar Bug


3Wheels
02-01-2002, 03:11 PM
Hi All,

I've been running a Java scheduler application for several years, but ran into a problem this morning with the Calendar object. I use the after() method to determine if schedule entries are old. If they are older than today, I delete the entries. Today, Calendar seems to think 1/29/2002, 1/30/2002 and 1/31/2002 all come AFTER 2/1/2002. However, it correctly understands that 1/28/2002 comes BEFORE 2/1/2002.

Below is a code sample. I wonder if anyone can explain what I'm seeing. Any info is appreciated.


import java.io.*;
import java.net.*;
import java.util.*;
import java.text.*;
import java.lang.*;


// Here is the output of this program under jdk1.2.2:
//
// 2/1/2002 DOES NOT come after 1/31/2002??? BAD
// 2/1/2002 DOES NOT come after 1/30/2002??? BAD
// 2/1/2002 DOES NOT come after 1/29/2002??? BAD
// 2/1/2002 comes after 1/28/2002, good
//

public class BuggyCalendar {

public static void main (String[] args) {

Calendar calendar = Calendar.getInstance(); // For today, 2/2
Calendar calendar2 = Calendar.getInstance(); // For yesterday 1/31
Calendar calendar3 = Calendar.getInstance(); // 1/30
Calendar calendar4 = Calendar.getInstance(); // 1/29
Calendar calendar5 = Calendar.getInstance(); // 1/28


// Year: 2002 for all 5 dates
Integer Iyy = new Integer("2002");

// Month for today is "02", February
Integer Ifeb = new Integer("02");
// Month for all other dates is "01", January
Integer Ijan = new Integer("01");

// Today 2-1-2002
Integer Idd = new Integer("01");

// Yesterday 1-31-2002
Integer Idd2 = new Integer("31");

// Wednesday 1-30-2002
Integer Idd3 = new Integer("30");

// Tuesday 1-29-2002
Integer Idd4 = new Integer("29");

// Monday 1-28-2002
Integer Idd5 = new Integer("28");

// Calendar object to hold today's date: 2-1-2002
calendar.set(Iyy.intValue(), Ifeb.intValue(), Idd.intValue());

// Calendar object to hold yesterday, 1-31-2002
calendar2.set(Iyy.intValue(), Ijan.intValue(), Idd2.intValue());

// Calendar object to hold 1-30-2002
calendar3.set(Iyy.intValue(), Ijan.intValue(), Idd3.intValue());

// Calendar object to hold 1-29-2002
calendar4.set(Iyy.intValue(), Ijan.intValue(), Idd4.intValue());

// Calendar object to hold 1-28-2002
calendar5.set(Iyy.intValue(), Ijan.intValue(), Idd5.intValue());

if ( calendar.after(calendar2) ) {
System.out.println("2/1/2002 comes after 1/31/2002, good");
}
else {
System.out.println("2/1/2002 DOES NOT come after 1/31/2002??? BAD");
}

if ( calendar.after(calendar3) ) {
System.out.println("2/1/2002 comes after 1/30/2002, good");
}
else {
System.out.println("2/1/2002 DOES NOT come after 1/30/2002??? BAD");
}

if ( calendar.after(calendar4) ) {
System.out.println("2/1/2002 comes after 1/29/2002, good");
}
else {
System.out.println("2/1/2002 DOES NOT come after 1/29/2002??? BAD");
}

if ( calendar.after(calendar5) ) {
System.out.println("2/1/2002 comes after 1/28/2002, good");
}
else {
System.out.println("2/1/2002 DOES NOT come after 1/28/2002??? BAD");
}

}
}

Dru Lee Parsec
02-01-2002, 06:51 PM
I wish I had time to analyze it for you but I'm swamped at work right now.

My first thought is this, instead of using 1,2,3 for January, Feb, March etc. use predefined static attributes Calendar.JANUARY Calendar.FEBRUARY and so on.

Also, why are you setting your integers like this:

Integer Idd3 = new Integer("30");

And then using intValue() later on instead of just doing this:

int iDay30 = 30;

Or even simpler:

calendar.set(2002, 2, 1);
calendar2.set(2002, 1, 30);

??

Dru Lee Parsec
02-01-2002, 07:02 PM
You're right, this smaller code example demonstrates the same issue.


import java.util.*;

public class CalendarTest
{
public static void main(String args[])
{
Calendar today = Calendar.getInstance();
Calendar tomorrow = Calendar.getInstance();
Calendar yesterday = Calendar.getInstance();

today.set(2002,2,1);
tomorrow.set(2002,2,2);
yesterday.set(2002,1,30);

System.out.println("today is " + today);
System.out.println("tomorrow is " + tomorrow);
System.out.println("yesterday was " + yesterday);

System.out.println("Is today after yesterday ? " + today.after(yesterday));
System.out.println("Is today after tomorrow ? " + today.after(tomorrow));
System.out.println("Is tomorrow after yesterday ? " + tomorrow.after(yesterday));
System.out.println("Is tomorrow after today ? " + tomorrow.after(today));
}
}

Dru Lee Parsec
02-01-2002, 07:07 PM
Got it. Month is zero based, not one based. This modified example works fine:



import java.util.*;

public class CalendarTest
{
public static void main(String args[])
{
Calendar today = Calendar.getInstance();
Calendar tomorrow = Calendar.getInstance();
Calendar yesterday = Calendar.getInstance();

today.set(2002,Calendar.FEBRUARY,1);
tomorrow.set(2002,Calendar.FEBRUARY,2);
yesterday.set(2002,Calendar.JANUARY,30);

System.out.println("today is " + today);
System.out.println("tomorrow is " + tomorrow);
System.out.println("yesterday was " + yesterday);

System.out.println("Is today after yesterday ? " + today.after(yesterday));
System.out.println("Is today after tomorrow ? " + today.after(tomorrow));
System.out.println("Is tomorrow after yesterday ? " + tomorrow.after(yesterday));
System.out.println("Is tomorrow after today ? " + tomorrow.after(today));
}
}



Found the solution in Bug Id 4389937

3Wheels
02-02-2002, 06:06 PM
Thanks for the info! Since the program receives the date in a string representing mmddyy format (which, BTW, cannot be changed), and mm is in human form (01-12), I'll have to subtract a 1 from each month.
Thanks again.

[ 02 February 2002: Message edited by: mattmorrow ]

3Wheels
02-03-2002, 09:22 AM
Ya know, after a good night's sleep and a little thought, it occurs to me that the error happened because we mistakenly initialized February with 30 or 31 days - which it never has. (month 01 was actually Feb, but thinking in human terms, we treat it as Jan, and passed it values of 30 and 31).

This breaks the after() method. Strange that you can initialize the date with an invalid one. I even initialized it with "99" as the day of the month!

-mm