Calendar returns wrong month

2019-01-02 20:37发布

Calendar rightNow = Calendar.getInstance();
String month = String.valueOf(rightNow.get(Calendar.MONTH));

After the execution of the above snippet, month gets a value of 10 instead of 11. How come?

标签: java calendar
9条回答
美炸的是我
2楼-- · 2019-01-02 21:04
cal.get(Calendar.MONTH) + 1;

The above statement gives the exact number of the month. As get(Calendar.Month) returns month starting from 0, adding 1 to the result would give the correct output. And keep in mind to subtract 1 when setting the month.

cal.set(Calendar.MONTH, (8 - 1));

Or use the constant variables provided.

cal.set(Calendar.MONTH, Calendar.AUGUST);
查看更多
无色无味的生活
3楼-- · 2019-01-02 21:08

tl;dr

LocalDate.now()            // Returns a date-only `LocalDate` object for the current month of the JVM’s current default time zone.
         .getMonthValue()  // Returns 1-12 for January-December.

Details

Other answers are correct but outdated.

The troublesome old date-time classes had many poor design choices and flaws. One was the zero-based counting of month numbers 0-11 rather than the obvious 1-12.

java.time

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

Now in maintenance mode, the Joda-Time project also advises migration to java.time.

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

Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport and further adapted to Android in ThreeTenABP.

The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time.

Months 1-12

In java.time the month number is indeed the expected 1-12 for January-December.

The LocalDate class represents a date-only value without time-of-day and without time zone.

Time zone

A time zone is crucial in determining a date. For any given moment, the date varies around the globe by zone. For example, a few minutes after midnight in Paris France is a new day while still “yesterday” in Montréal Québec.

Specify a proper time zone name in the format of continent/region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 3-4 letter abbreviation such as EST or IST as they are not true time zones, not standardized, and not even unique(!).

LocalDate today = LocalDate.now( ZoneId.of( "America/Montreal" ) );
int month = today.getMonthValue();  // Returns 1-12 as values.

If you want a date-time for a time zone, use ZonedDateTime object in the same way.

ZonedDateTime now = ZonedDateTime.now( ZoneId.of( "America/Montreal" ) );
int month = now.getMonthValue();  // Returns 1-12 as values.

Convert legacy classes

If you have a GregorianCalendar object in hand, convert to ZonedDateTime using new toZonedDateTime method added to the old class. For more conversion info, see Convert java.util.Date to what “java.time” type?

ZonedDateTime zdt = myGregorianCalendar.toZonedDateTime();
int month = zdt.getMonthValue();  // Returns 1-12 as values.

Month enum

The java.time classes include the handy Month enum, by the way. Use instances of this class in your code rather than mere integers to make your code more self-documenting, provide type-safety, and ensure valid values.

Month month = today.getMonth();  // Returns an instant of `Month` rather than integer.

The Month enum offers useful methods such as generating a String with the localized name of the month.


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.

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

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

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.

查看更多
一个人的天荒地老
4楼-- · 2019-01-02 21:16

As is clear by the many answers: the month starts with 0.

Here's a tip: you should be using SimpleDateFormat to get the String-representation of the month:

Calendar rightNow = Calendar.getInstance();
java.text.SimpleDateFormat df1 = new java.text.SimpleDateFormat("MM");
java.text.SimpleDateFormat df2 = new java.text.SimpleDateFormat("MMM");
java.text.SimpleDateFormat df3 = new java.text.SimpleDateFormat("MMMM");
System.out.println(df1.format(rightNow.getTime()));
System.out.println(df2.format(rightNow.getTime()));
System.out.println(df3.format(rightNow.getTime()));

Output:

11
Nov
November

Note: the output may vary, it is Locale-specific.

查看更多
何处买醉
5楼-- · 2019-01-02 21:17

They start from 0 - check the docs

查看更多
零度萤火
6楼-- · 2019-01-02 21:18

From the API:

The first month of the year is JANUARY which is 0; the last depends on the number of months in a year.

http://java.sun.com/j2se/1.5.0/docs/api/java/util/Calendar.html

查看更多
与风俱净
7楼-- · 2019-01-02 21:19

Months are indexed from 0 not 1 so 10 is November and 11 will be December.

查看更多
登录 后发表回答