简体   繁体   中英

Help with Java Calendar — it is giving some strange output

I'm newish to Java and am trying to do somethings with dates. First I started using the Date class, which I found out was mostly deprecated so I switched over to Calendar.

Now I am getting weird values. for example the Month value for December is 0, not 12. And on those Calendars where it is giving me 0 for December it is also moving the year ahead one year.

It's weird!

What am I missing?

Thanks for your help.

-GG

EDIT FOR AN EXAMPLE:

So I am reading some line sin from a file such as this: Johnny Graham HF 12-2-1973 Black

I parse it, and then for the Calendar I set:

int year = Integer.parseInt(stringVersionOfYear); // this value is 1973

Then later when I go to get the year back with a line like this:

calendar.get(Calendar.YEAR)

the value is 1974... And the month is 0 for cal.get(Calendar.MONTH)

EDIT 2:

I am creating the Calendar like this:

Calendar outputCalendar = Calendar.getInstance();
outputCalendar.set(year, month, day);

The java.util.Date and Calendar classes are poorly designed (eg, the first day in a month is day 1 but the first month in a year is month 0). Many projects use the Joda Time package instead.

Months values are 0 thru 11; set a month to 12 and the date gets "normalized", incrementing the year by one and setting the month to 0. This makes it easy to "add a month" without having to worry about handling the overflow at year end.

EDIT: January=0, February=1,... December=11. When you set the month value to 12 you were asking for the 13th month, which got normalized to the first month of the following year.

Note that this normalization process happens in general -- Try to set the date to December 32nd and you'll get back January 1 of the following year. This means it's important to be careful when modifying individual fields of a Calendar object. If you create a default Calendar on, say, January 31st and then want to modify it to contain, say February 5th, the order in which you set the fields is important. If you change the month first you'll be creating February 31st, which will get normalized to March 2nd or 3rd (depending on the leap year) and then when you set the day to 5 the result is March 5th, not February 5th. You have the opposite problem in other cases, such as starting from any date in February and modifying to the 30th or 31st of any other month. In that case doing the month first results in the same type of problem.

The only safe way to modify a date is to use a method that sets all three values simultaneously, such as the set(int,int,int) method.

See this line?

outputCalendar.set(year, month, day);

Just change it like this:

outputCalendar.set(year, month - 1, day);

and then when you want to get the month, don't use this:

cal.get(Calendar.MONTH)

instead, use this:

(1+(cal.get(Calendar.MONTH)))

It's a pain, but it will fix the problem (I think).

The main piece of advice I have for you is: read the API! Calendar is indeed not the pinnacle of intuitive API design, but it is definitely usable if you take the time to read the javadoc. Learn the difference between .add and .roll. Check out what happens when you set a year (1973) into a Calendar initialized with the current date (default Calendar.getInstance).

Whining about API is all fine (we all do it), but in the end to find solutions start off by reading what the authors provided to you before asking relatively obtuse questions on the Internet.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM