获得当前年份和月份会产生奇怪的结果

时间:2022-09-28 04:05:22

I am working on a learning project related to Android. I am trying to get current year & month by using below code but it not works for me.

我正在开发一个与Android相关的学习项目。我试图通过使用下面的代码来获取当前年份和月份,但它不适用于我。

GregorianCalendar gc = new GregorianCalendar();
gc.YEAR // returning 1       
gc.MONTH // returning 2

Calendar c = Calendar.getInstance();
c.YEAR // returning 1       
c.MONTH // returning 2

Can someone help me? Am i doing something wrong? please forgive me i am new to java development. thanks.

有人能帮我吗?难道我做错了什么?请原谅我,我是java开发的新手。谢谢。

6 个解决方案

#1


52  

Just to give a bit more background:

只是为了提供更多背景知识:

Both new GregorianCalendar() and Calendar.getInstance() will correctly give a calendar initialized at the current date and time.

新的GregorianCalendar()和Calendar.getInstance()都将正确地给出在当前日期和时间初始化的日历。

MONTH and YEAR are constants within the Calendar class. You should not use them "via" a reference which makes it look like they're part of the state of an object. It's an unfortunate part of the design of the Calendar class that to access the values of different fields, you need to call get with a field number, specified as one of those constants, as shown in other answers:

MONTH和YEAR是Calendar类中的常量。你不应该使用它们“通过”一个引用,使它看起来像是一个对象状态的一部分。设计Calendar类是一个不幸的部分,要访问不同字段的值,您需要使用字段编号调用get,指定为其中一个常量,如其他答案所示:

Calendar c = Calendar.getInstance();
int year = c.get(Calendar.YEAR);
int month = c.get(Calendar.MONTH);

Note that the month numbers are 0-based, so at the time of this writing (in April) the month number will be 3.

请注意,月份数字是从0开始的,因此在撰写本文时(4月份),月份数字将为3。

It's an unfortunate part of the design of the Java language that you can reference static members (such as constants) via expressions of that type, rather than only through the type name.

这是Java语言设计的一个不幸的部分,您可以通过该类型的表达式引用静态成员(例如常量),而不是仅通过类型名称。

My recommendations:

  • If your IDE allows it (as Eclipse does), make expressions such as c.YEAR give a compile-time error - you'll end up with much clearer code if you always use Calendar.YEAR.
  • 如果你的IDE允许它(就像Eclipse那样),make表达式如c.YEAR会产生编译时错误 - 如果你总是使用Calendar.YEAR,你最终会得到更清晰的代码。

  • Where possible, use Joda Time - a much better date/time library for Java. Admittedly on Android you may be a bit space-constrained, but if your app does a lot of date/time manipulation, it would save you a lot of headaches.
  • 尽可能使用Joda Time - 一个更好的Java日期/时间库。不可否认,在Android上你可能有点空间限制,但如果你的应用程序做了很多日期/时间操作,它会为你省去很多麻烦。

#2


19  

Note MONTHS starts from 0..So if you need to map it to practical problems just add +1

注意MONTHS从0开始。因此,如果您需要将其映射到实际问题,只需添加+1

int month=c.get(Calendar.MONTH)+1;

#3


5  

int year=c.get(Calendar.YEAR);
int month=c.get(Calendar.MONTH);

   System.out.println(year);
   System.out.println(month);

#4


3  

tl;dr

YearMonth.now( 
    ZoneId.of( "America/Montreal" ) 
)

Details

The Answer by Jon Skeet is correct. You were accessing constants rather than interrogating your own object.

Jon Skeet的回答是正确的。您正在访问常量而不是询问您自己的对象。

Here is an entirely different alternative, using modern date-time classes.

这是一个完全不同的选择,使用现代日期时间类。

Avoid legacy date-time classes

The old date-time classes such as java.util.Date, java.util.Calendar, and java.text.SimpleTextFormat are now legacy, supplanted by the java.time classes.

旧的日期时间类(如java.util.Date,java.util.Calendar和java.text.SimpleTextFormat)现在是遗留的,由java.time类取代。

YearMonth

If you are focused on the year and month without a date, without a time-of-day, and without a time zone, use the YearMonth class.

如果您专注于没有日期,没有时间和没有时区的年份和月份,请使用YearMonth类。

Rather than pass mere integer numbers around for year and for month, pass around objects of this class. Doing so provides type-safety, ensures valid values, and makes your code more self-documenting.

而不是仅传递年份和月份的整数,而是传递此类的对象。这样做可以提供类型安全性,确保有效值,并使您的代码更加自我记录。

Determining the current year and month means determining the current date. And for that a time zone is crucial. For any given moment, the date varies around the globe by zone.

确定当前年份和月份意味着确定当前日期。为此,时区至关重要。对于任何给定的时刻,日期在全球范围内因地区而异。

ZoneId z = ZoneId.of( "America/Montreal" );
YearMonth ym = YearMonth.now( z );

You can interrogate for its parts.

您可以查询其零件。

int year = ym.getYear();
int month = ym.getMonthValue();

This class offers handy methods such as telling you if this is a leap year. You can do math, such as adding/subtracting months/years. You can get a date for any day of this year-month. And more.

这个类提供了方便的方法,比如告诉你这是否是闰年。您可以进行数学运算,例如添加/减去月/年。您可以获得今年任何一天的日期。和更多。

Month

Rather than mess around with a mere integer for month, I suggest you use the Month enum. This class has a dozen instances pre-defined, one for each month of the year. As mentioned above, using objects gives you type-safety, valid values, and self-documenting code.

我建议您使用月枚举,而不是仅仅使用一个月的整数。这个类预定义了十几个实例,一年中每个月都有一个实例。如上所述,使用对象可以为您提供类型安全,有效值和自我记录代码。

Month m = ym.getMonth();

The class has helpful methods such as generating an localized string with the month’s name.

该类具有有用的方法,例如生成具有月份名称的本地化字符串。


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.

java.time框架内置于Java 8及更高版本中。这些类取代了麻烦的旧遗留日期时间类,如java.util.Date,Calendar和SimpleDateFormat。

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

现在处于维护模式的Joda-Time项目建议迁移到java.time类。

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

要了解更多信息,请参阅Oracle教程。并搜索Stack Overflow以获取许多示例和解释。规范是JSR 310。

Where to obtain the java.time classes?

从哪里获取java.time类?

  • Java SE 8 and SE 9 and later
    • Built-in.
    • Part of the standard Java API with a bundled implementation.
    • 带有捆绑实现的标准Java API的一部分。

    • Java 9 adds some minor features and fixes.
    • Java 9增加了一些小功能和修复。

  • Java SE 8和SE 9及更高版本内置。带有捆绑实现的标准Java API的一部分。 Java 9增加了一些小功能和修复。

  • Java SE 6 and SE 7
    • Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
    • 许多java.time功能都被反向移植到ThreeTen-Backport中的Java 6和7。

  • Java SE 6和SE 7大部分java.time功能都被反向移植到ThreeTen-Backport中的Java 6和7。

  • Android
    • The ThreeTenABP project adapts ThreeTen-Backport (mentioned above) for Android specifically.
    • ThreeTenABP项目特别适用于Android的ThreeTen-Backport(如上所述)。

    • See How to use….
    • 请参阅如何使用....

  • Android ThreeTenABP项目专门针对Android调整ThreeTen-Backport(如上所述)。请参阅如何使用....

#5


2  

Calendar c= Calendar.getInstance()
int cyear = c.get(Calendar.YEAR);//calender year starts from 1900 so you must add 1900 to the value recevie.i.e., 1990+112 = 2012
int cmonth = c.get(Calendar.MONTH);//this is april so you will receive  3 instead of 4.
int cday = c.get(Calendar.DAY_OF_MONTH);

refer this LINK

请参阅此链接

#6


1  

How to get current Year and Month.

        Calendar calendar = Calendar.getInstance();             
        int month = calendar.get(Calendar.MONTH) + 1;
        int year = calendar.get(Calendar.YEAR);

Very important to add 1 to get the correct month, because the first month value is 0:

添加1以获得正确的月份非常重要,因为第一个月的值为0:

        int month = calendar.get(Calendar.MONTH) + 1;

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

MONTH:获取和设置的字段编号,表示月份。这是特定于日历的值。格里高利和朱利安日历中的第一个月是1月,即0;最后一个取决于一年中的月数。

#1


52  

Just to give a bit more background:

只是为了提供更多背景知识:

Both new GregorianCalendar() and Calendar.getInstance() will correctly give a calendar initialized at the current date and time.

新的GregorianCalendar()和Calendar.getInstance()都将正确地给出在当前日期和时间初始化的日历。

MONTH and YEAR are constants within the Calendar class. You should not use them "via" a reference which makes it look like they're part of the state of an object. It's an unfortunate part of the design of the Calendar class that to access the values of different fields, you need to call get with a field number, specified as one of those constants, as shown in other answers:

MONTH和YEAR是Calendar类中的常量。你不应该使用它们“通过”一个引用,使它看起来像是一个对象状态的一部分。设计Calendar类是一个不幸的部分,要访问不同字段的值,您需要使用字段编号调用get,指定为其中一个常量,如其他答案所示:

Calendar c = Calendar.getInstance();
int year = c.get(Calendar.YEAR);
int month = c.get(Calendar.MONTH);

Note that the month numbers are 0-based, so at the time of this writing (in April) the month number will be 3.

请注意,月份数字是从0开始的,因此在撰写本文时(4月份),月份数字将为3。

It's an unfortunate part of the design of the Java language that you can reference static members (such as constants) via expressions of that type, rather than only through the type name.

这是Java语言设计的一个不幸的部分,您可以通过该类型的表达式引用静态成员(例如常量),而不是仅通过类型名称。

My recommendations:

  • If your IDE allows it (as Eclipse does), make expressions such as c.YEAR give a compile-time error - you'll end up with much clearer code if you always use Calendar.YEAR.
  • 如果你的IDE允许它(就像Eclipse那样),make表达式如c.YEAR会产生编译时错误 - 如果你总是使用Calendar.YEAR,你最终会得到更清晰的代码。

  • Where possible, use Joda Time - a much better date/time library for Java. Admittedly on Android you may be a bit space-constrained, but if your app does a lot of date/time manipulation, it would save you a lot of headaches.
  • 尽可能使用Joda Time - 一个更好的Java日期/时间库。不可否认,在Android上你可能有点空间限制,但如果你的应用程序做了很多日期/时间操作,它会为你省去很多麻烦。

#2


19  

Note MONTHS starts from 0..So if you need to map it to practical problems just add +1

注意MONTHS从0开始。因此,如果您需要将其映射到实际问题,只需添加+1

int month=c.get(Calendar.MONTH)+1;

#3


5  

int year=c.get(Calendar.YEAR);
int month=c.get(Calendar.MONTH);

   System.out.println(year);
   System.out.println(month);

#4


3  

tl;dr

YearMonth.now( 
    ZoneId.of( "America/Montreal" ) 
)

Details

The Answer by Jon Skeet is correct. You were accessing constants rather than interrogating your own object.

Jon Skeet的回答是正确的。您正在访问常量而不是询问您自己的对象。

Here is an entirely different alternative, using modern date-time classes.

这是一个完全不同的选择,使用现代日期时间类。

Avoid legacy date-time classes

The old date-time classes such as java.util.Date, java.util.Calendar, and java.text.SimpleTextFormat are now legacy, supplanted by the java.time classes.

旧的日期时间类(如java.util.Date,java.util.Calendar和java.text.SimpleTextFormat)现在是遗留的,由java.time类取代。

YearMonth

If you are focused on the year and month without a date, without a time-of-day, and without a time zone, use the YearMonth class.

如果您专注于没有日期,没有时间和没有时区的年份和月份,请使用YearMonth类。

Rather than pass mere integer numbers around for year and for month, pass around objects of this class. Doing so provides type-safety, ensures valid values, and makes your code more self-documenting.

而不是仅传递年份和月份的整数,而是传递此类的对象。这样做可以提供类型安全性,确保有效值,并使您的代码更加自我记录。

Determining the current year and month means determining the current date. And for that a time zone is crucial. For any given moment, the date varies around the globe by zone.

确定当前年份和月份意味着确定当前日期。为此,时区至关重要。对于任何给定的时刻,日期在全球范围内因地区而异。

ZoneId z = ZoneId.of( "America/Montreal" );
YearMonth ym = YearMonth.now( z );

You can interrogate for its parts.

您可以查询其零件。

int year = ym.getYear();
int month = ym.getMonthValue();

This class offers handy methods such as telling you if this is a leap year. You can do math, such as adding/subtracting months/years. You can get a date for any day of this year-month. And more.

这个类提供了方便的方法,比如告诉你这是否是闰年。您可以进行数学运算,例如添加/减去月/年。您可以获得今年任何一天的日期。和更多。

Month

Rather than mess around with a mere integer for month, I suggest you use the Month enum. This class has a dozen instances pre-defined, one for each month of the year. As mentioned above, using objects gives you type-safety, valid values, and self-documenting code.

我建议您使用月枚举,而不是仅仅使用一个月的整数。这个类预定义了十几个实例,一年中每个月都有一个实例。如上所述,使用对象可以为您提供类型安全,有效值和自我记录代码。

Month m = ym.getMonth();

The class has helpful methods such as generating an localized string with the month’s name.

该类具有有用的方法,例如生成具有月份名称的本地化字符串。


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.

java.time框架内置于Java 8及更高版本中。这些类取代了麻烦的旧遗留日期时间类,如java.util.Date,Calendar和SimpleDateFormat。

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

现在处于维护模式的Joda-Time项目建议迁移到java.time类。

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

要了解更多信息,请参阅Oracle教程。并搜索Stack Overflow以获取许多示例和解释。规范是JSR 310。

Where to obtain the java.time classes?

从哪里获取java.time类?

  • Java SE 8 and SE 9 and later
    • Built-in.
    • Part of the standard Java API with a bundled implementation.
    • 带有捆绑实现的标准Java API的一部分。

    • Java 9 adds some minor features and fixes.
    • Java 9增加了一些小功能和修复。

  • Java SE 8和SE 9及更高版本内置。带有捆绑实现的标准Java API的一部分。 Java 9增加了一些小功能和修复。

  • Java SE 6 and SE 7
    • Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
    • 许多java.time功能都被反向移植到ThreeTen-Backport中的Java 6和7。

  • Java SE 6和SE 7大部分java.time功能都被反向移植到ThreeTen-Backport中的Java 6和7。

  • Android
    • The ThreeTenABP project adapts ThreeTen-Backport (mentioned above) for Android specifically.
    • ThreeTenABP项目特别适用于Android的ThreeTen-Backport(如上所述)。

    • See How to use….
    • 请参阅如何使用....

  • Android ThreeTenABP项目专门针对Android调整ThreeTen-Backport(如上所述)。请参阅如何使用....

#5


2  

Calendar c= Calendar.getInstance()
int cyear = c.get(Calendar.YEAR);//calender year starts from 1900 so you must add 1900 to the value recevie.i.e., 1990+112 = 2012
int cmonth = c.get(Calendar.MONTH);//this is april so you will receive  3 instead of 4.
int cday = c.get(Calendar.DAY_OF_MONTH);

refer this LINK

请参阅此链接

#6


1  

How to get current Year and Month.

        Calendar calendar = Calendar.getInstance();             
        int month = calendar.get(Calendar.MONTH) + 1;
        int year = calendar.get(Calendar.YEAR);

Very important to add 1 to get the correct month, because the first month value is 0:

添加1以获得正确的月份非常重要,因为第一个月的值为0:

        int month = calendar.get(Calendar.MONTH) + 1;

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

MONTH:获取和设置的字段编号,表示月份。这是特定于日历的值。格里高利和朱利安日历中的第一个月是1月,即0;最后一个取决于一年中的月数。