Greedy Coder
Greedy Coder

Reputation: 1326

Java Calendar giving wrong value after parsing month string

I know that Java month begins from 0 and we have to add an offset of 1 to it,but when I use the following code which has a CST time zone,I get value for february month as 6.

I am trying to convert month to its equivalent calendar value such as 1 for January and 2 for Feb and so on.

    Calendar cal = Calendar.getInstance();
    cal.setTime(new SimpleDateFormat("MMM").parse("FEB"));
    int monthInt = cal.get(Calendar.MONTH) + 1;
    System.out.println(monthInt);

But when I run it in a machine with time zone as Indian Standard Time(IST-GMT +5.30) I get the expected value as 2.

What is wrong here?Do I need to include any locale to my calendar.I am getting totally meaningless values for months with the above code.

Upvotes: 2

Views: 661

Answers (2)

Basil Bourque
Basil Bourque

Reputation: 340098

tl;dr

Month.JANUARY.getValue()

1

Wrong class

You are trying to represent a month using a class that represents a moment. Square peg, round hole.

But when I run it in a machine with time zone as Indian Standard Time(IST-GMT +5.30) I get the expected value as 2.

Again, this occurs because you used the wrong class, a class that represents a moment in the context of a time zone.

I know that Java month begins from 0

Again, you are using the wrong class. This crazy numbering is one of many reasons why the date-time classes bundled with the earliest versions of Java were supplanted by the java.time classes defined by JSR 310 and built into Java 8 and later. Do not use the legacy classes.

Month

The appropriate class for a month is Month. This modern java.time class has sane numbering, unlike the legacy date-time classes that you should avoid.

convert month to its equivalent calendar value such as 1 for January

Use the Month.JANUARY enum object. As for its number, 1-12 for January-December.

int monthNumber = Month.JANUARY.getValue() ;

1

But I suggest you avoid representing a month by a mere integer number. Instead, use Month enum objects throughout your codebase. This makes your code more self-documenting, ensures valid values, and provides type-safety.

Use this:

public void runMonthlyReport( Month month ) { … }

…instead of this:

public void runMonthlyReport( int monthNumber ) { … }

About java.time

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.

Where to obtain the java.time classes?

The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

Upvotes: 1

user987339
user987339

Reputation: 10727

You should instantiate your Calendar with appropriate locales:

Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("IST"),Locale.US);

Upvotes: 3

Related Questions