Java 获取当前年份和月份,从而产生奇怪的结果

Java 获取当前年份和月份,从而产生奇怪的结果,java,android,date,gregorian-calendar,Java,Android,Date,Gregorian Calendar,我正在做一个与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 有人能帮我吗

我正在做一个与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
有人能帮我吗?我做错什么了吗?请原谅,我是java开发新手。谢谢

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

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

请参阅此

以提供更多背景信息:

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

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

Calendar c = Calendar.getInstance();
int year = c.get(Calendar.YEAR);
int month = c.get(Calendar.MONTH);
请注意,月份数字是以0为基础的,因此在撰写本文时(4月份),月份数字将是3

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

我的建议:

  • 如果您的IDE允许(正如Eclipse所做的那样),那么让诸如
    c.YEAR
    之类的表达式给出编译时错误-如果您总是使用
    Calendar.YEAR
    ,您将得到更清晰的代码
  • 在可能的情况下,使用-一个更好的Java日期/时间库。诚然,在安卓系统上,你可能会有点空间受限,但如果你的应用程序进行了大量的日期/时间操作,这将为你省去很多麻烦

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

      int month=c.get(Calendar.MONTH)+1;
      
      如何获取当前年度和月份。
      添加1以获得正确的月份非常重要,因为第一个月的值为0:

              int month = calendar.get(Calendar.MONTH) + 1;
      
      :表示月份的get和set字段编号。这是特定于日历的值。在公历和儒略历中,一年的第一个月是1月,即0;最后一个取决于一年中的月数

      tl;博士 细节 答案是正确的。您正在访问常量,而不是询问自己的对象

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

      避免遗留日期时间类 旧的日期时间类,如,和
      java.text.SimpleTextFormat
      现在被类取代

      YearMonth
      如果你关注的是没有日期、没有时间、没有时区的年份和月份,请使用本课程

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

      确定当前年份和月份意味着确定当前日期。为此,时区至关重要。在任何一个特定的时刻,世界各地的日期都因地区而异

      ZoneId z = ZoneId.of( "America/Montreal" );
      YearMonth ym = YearMonth.now( z );
      
      你可以询问它的部分

      int year = ym.getYear();
      int month = ym.getMonthValue();
      
      这门课提供了方便的方法,比如告诉你这是闰年。你可以做数学,比如加/减月/年。你可以在这个月的任何一天得到一个日期。还有更多

      月份
      我建议您使用enum,而不是在一个月内只处理一个整数。这个类有十几个预定义的实例,一年中每个月一个。如上所述,使用对象可以提供类型安全性、有效值和自文档化代码

      Month m = ym.getMonth();
      
      该类有一些有用的方法,例如生成带有月份名称的本地化字符串


      关于java.time 该框架内置于Java8及更高版本中。这些类取代了麻烦的旧日期时间类,例如,&

      该项目现已启动,建议迁移到类

      要了解更多信息,请参阅。并搜索堆栈溢出以获得许多示例和解释。规格是

      从哪里获得java.time类

      • 后来
        • 内置的
        • 标准JavaAPI的一部分,带有捆绑实现
        • Java9添加了一些次要功能和修复
        • 大部分java.time功能都在中向后移植到Java6和Java7
        • 该项目专门针对Android采用了Three Ten Backport(如上所述)

      @YaqubAhmad:我很高兴——其他两个答案都是正确的,但我觉得它们需要更多的解释:)int cmonth=c.get(Calendar.MONTH)//今年是4月,因此您将收到3而不是4。投票反对我的结果的人…请参见已接受答案中的这一行…要使其与real month兼容,您必须添加1…否则1月将为0…如果您不理解,请不要投票…不要-1对于健全的编号,请使用java.time类的现代方法:
      LocalDate.now().getMonthValue()
      ➙ 1-12表示一月到十二月。仅供参考,c.get(Calendar.MONTH)是一个以零为基础的月份索引。这个糟糕的日历类在几年前被采用JSR 310的java.time类取代。现代方法:
      LocalDate.now().getMonthValue()
      ZoneId z = ZoneId.of( "America/Montreal" );
      YearMonth ym = YearMonth.now( z );
      
      int year = ym.getYear();
      int month = ym.getMonthValue();
      
      Month m = ym.getMonth();