0

I encountered really strange behaviour when constructing a Calendar object and then formating it in a particular style.

Let the code do the talking:

public class Test 
{
    public static void main(String[] args) 
    {
        SimpleDateFormat frmt = new SimpleDateFormat();
        frmt.applyPattern("yyyy-MM-dd");
        GregorianCalendar date = new GregorianCalendar(2012,1,1);
        System.out.println(frmt.format(date.getTime()));
    }
}

The output is:

2012-02-01

The expected output is of course:

2012-01-01

What am I doing wrong?

Nejc
  • 692
  • 6
  • 13
  • 3
    Months are zero based: January = 0, Feb = 1.... – duffymo Nov 07 '12 at 10:57
  • Thanks for the answers, but I really do not know why are months zero based? – Nejc Nov 07 '12 at 11:00
  • 1
    @Nejc the "why" has been answered here: http://stackoverflow.com/questions/344380/why-is-january-month-0-in-java-calendar – assylias Nov 07 '12 at 11:00
  • @assylias Thanks! But I really feel it as counter-intuitive. – Nejc Nov 07 '12 at 11:02
  • @Nejc It is hence my recommendation to use named constants - that way there is no ambiguity. – assylias Nov 07 '12 at 11:03
  • @assylias I am working on an interactive app, so the user inputs the year, month and day. I thought I would use the numerical representation to construct the date. Maybe I will create a new input method. – Nejc Nov 07 '12 at 11:08
  • @Nejc You can still use `input - 1` if you get a numerical input. – assylias Nov 07 '12 at 11:19
  • Ofcourse! But I am considering to have an String input, which is formated as yyyy-MM-dd, and then use the formatter to parse string and construct a Calendar object. – Nejc Nov 07 '12 at 11:23
  • 1
    You make this sound like it's such a big deal. java's been like this since 1995. Figure it out, like so many people before you have. Counter-intuitive? Not in C-world. – duffymo Nov 07 '12 at 11:36
  • Maybe I make it sound, like it is a big deal. It isn't to me. But nevertheless, I figured it out and now I know. At least I should expect something like this from java, because it mixes everything together (0-based and 1-based structures). – Nejc Nov 07 '12 at 12:56
  • I don't know why you brought C in the debate... I still think this is counter intuitieve (because in our world, january is the 1st month of the year, hence number 1). Because java is not as low-level as C, it would be simple to stick with the intuitive thing. Like this, it is also intuitive to me, that array indices start at 0. – Nejc Nov 07 '12 at 12:59

5 Answers5

3

Months start at 0, so new GregorianCalendar(2012,1,1); is the 1st of February. For 1st of January, you would use

new GregorianCalendar(2012,0,1);
// or even better 
new GregorianCalendar(2012,Calendar.JANUARY,1);
assylias
  • 321,522
  • 82
  • 660
  • 783
2

Month start with 0 in GregorianCalendar.

public static final int JANUARY = 0; 

It is declared in Clanedar class. and for February it is 1. So update code -

GregorianCalendar date = new GregorianCalendar(2012,Calendar.JANUARY,1);

or

GregorianCalendar date = new GregorianCalendar(2012,0,1);
Subhrajyoti Majumder
  • 40,646
  • 13
  • 77
  • 103
1

Month is 0-based. January == 0. From Calendar#MONTH javadoc:

Field number for get and set indicating the month. This is a calendar-specific value. The first month of the year is JANUARY which is 0; the last depends on the number of months in a year.

Aleksandr M
  • 24,264
  • 12
  • 69
  • 143
0

Try Joda time if you dont want Months that are indexed at 0

andy boot
  • 11,355
  • 3
  • 53
  • 66
0

It is documented behavior:

month - the value used to set the MONTH calendar field in the calendar. Month value is 0-based. e.g., 0 for January.

It is advisable to use the constants in Calendar, eg [Calendar.JANUARY][2] when using this constructor.

Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197