Calendar rightNow = Calendar.getInstance();
String month = String.valueOf(rightNow.get(Calendar.MONTH));
执行上面的代码片段后,month得到的值为10而不是11.为什么?
答案 0 :(得分:124)
月份的索引是从0而不是1,因此10是11月,11是12月。
答案 1 :(得分:28)
他们从0开始 - 检查the docs
答案 2 :(得分:22)
许多答案清楚地表明:月份从0开始。
这是一个提示:您应该使用SimpleDateFormat来获取月份的字符串表示形式:
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()));
输出:
11
Nov
November
注意:输出可能会有所不同,它是特定于区域设置的。
答案 3 :(得分:18)
正如几位人士所指出的那样,Java中Calendar和Date类返回的月数是从0而不是1索引的。所以0是1月,当月是11月,10
你可能想知道为什么会这样。起源于POSIX标准函数ctime
,gmtime
和localtime
,它们接受或返回带有以下字段的time_t
结构(来自man 3 ctime):
int tm_mday; /* day of month (1 - 31) */
int tm_mon; /* month of year (0 - 11) */
int tm_year; /* year - 1900 */
这个API几乎完全复制到Java 1.0中的Java Date类中,并且从那里完全复制到Java 1.1中的Calendar类中。当他们介绍日历时,Sun解决了最明显的问题 - 格里高利历中的2001年由他们的日期类中的值101表示。但我不确定为什么他们没有将日期和月份值更改为至少两者在索引中保持一致,无论是从零还是一。到目前为止,这种不一致和相关的混淆仍然存在于Java(和C)中。
答案 4 :(得分:10)
月份从零开始,就像列表的索引一样。
因此Jan = 0,Feb = 1等
答案 5 :(得分:8)
来自API:
一年中的第一个月是1月 这是0;最后取决于 一年中的月数。
http://java.sun.com/j2se/1.5.0/docs/api/java/util/Calendar.html
答案 6 :(得分:7)
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.
其他答案是正确但过时的。
麻烦的旧日期时间课程有很多糟糕的设计选择和缺陷。一个是0-11月份的零点计数,而不是明显的1-12。
java.time框架内置于Java 8及更高版本中。这些类取代了旧的麻烦日期时间类,例如java.util.Date
,.Calendar
和& java.text.SimpleDateFormat
。
现在在maintenance mode中,Joda-Time项目还建议迁移到java.time。
要了解详情,请参阅Oracle Tutorial。并搜索Stack Overflow以获取许多示例和解释。
大部分java.time功能都被反向移植到Java 6& ThreeTen-Backport中的7,并在ThreeTenABP中进一步适应Android。
ThreeTen-Extra项目使用其他类扩展java.time。该项目是未来可能添加到java.time的试验场。
在java.time中,月份数确实是1月到12月的预期1-12。
LocalDate
类表示没有时间且没有时区的仅限日期的值。
时区对于确定日期至关重要。对于任何给定的时刻,日期在全球范围内因地区而异。例如,在Paris France午夜后的几分钟是新的一天,而Montréal Québec中仍然是“昨天”。
以continent/region
的格式指定proper time zone name,例如America/Montreal
,Africa/Casablanca
或Pacific/Auckland
。切勿使用诸如EST
或IST
之类的3-4字母缩写,因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!)。
LocalDate today = LocalDate.now( ZoneId.of( "America/Montreal" ) );
int month = today.getMonthValue(); // Returns 1-12 as values.
如果您想要时区的日期时间,请以相同的方式使用ZonedDateTime
对象。
ZonedDateTime now = ZonedDateTime.now( ZoneId.of( "America/Montreal" ) );
int month = now.getMonthValue(); // Returns 1-12 as values.
如果您手头有GregorianCalendar
个对象,请使用添加到旧类的新toZonedDateTime
方法转换为ZonedDateTime
。有关更多转化信息,请参阅Convert java.util.Date to what “java.time” type?
ZonedDateTime zdt = myGregorianCalendar.toZonedDateTime();
int month = zdt.getMonthValue(); // Returns 1-12 as values.
Month
枚举顺便说一句,java.time类包括方便的Month
enum。在代码中使用此类的实例而不仅仅是整数,以使代码更具自我文档,提供type-safety并确保有效值。
Month month = today.getMonth(); // Returns an instant of `Month` rather than integer.
Month
枚举提供了有用的方法,例如使用localized name of the month生成字符串。
java.time框架内置于Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.Date
,Calendar
和& SimpleDateFormat
现在位于Joda-Time的maintenance mode项目建议迁移到java.time类。
要了解详情,请参阅Oracle Tutorial。并搜索Stack Overflow以获取许多示例和解释。规范是JSR 310。
从哪里获取java.time类?
ThreeTen-Extra项目使用其他类扩展java.time。该项目是未来可能添加到java.time的试验场。您可以在此处找到一些有用的课程,例如Interval
,YearWeek
,YearQuarter
和more。
答案 7 :(得分:3)
cal.get(Calendar.MONTH) + 1;
以上陈述给出了月份的确切数字。当get(Calendar.Month)
从0开始返回月份时,向结果中添加1会得到正确的输出。并且请记住在设置月份时减去1。
cal.set(Calendar.MONTH, (8 - 1));
或者使用提供的常量变量。
cal.set(Calendar.MONTH, Calendar.AUGUST);
答案 8 :(得分:0)
最好使用
Calendar.JANUARY
这是零...