GegorianCalendar 给我 2018 年的 int month = calendar.get(Calendar.FEBUARY)

GegorianCalendar is giving me 2018 for int month = calendar.get(Calendar.FEBUARY)

所以我正在开发日历程序并更改月份,我要求输入月份的整数。

如果我输入 calendar.get(Calendar.JANUARY),我会得到 1 作为 return,这是正确的,因为第一个月。但是,如果我输入 calendar.get(Calendar.FEBUARY),我会得到 2018 的响应,这当然是错误的。有谁知道可能是什么问题?

Calendar cal1 = new GregorianCalendar();
int month = cal1.get(Calendar.JANUARY);
int month2 = cal1.get(Calendar.FEBRUARY);
int year = cal1.get(Calendar.YEAR);

Calendar#get gets a field value. Calendar.JANUARY不是字段号,是潜在字段Calendar 中与 get(和 set)一起使用的唯一静态字段是描述以 "Field number for get and set...".

开头的字段

要获取月份,请使用 cal1.get(Calendar.MONTH)

Calendar API 是......不幸的是,尤其是因为它早于枚举,所以 int 被用于 get/set' s 真正需要枚举的字段标识符参数。虽然 get 采用 int,而 Calendar.JANUARYint,但它们在不同的域中是 int。请参阅 以了解经过显着改进的现代替代方案:java.time

java.time

是正确的。请允许我为您的问题提供真实、优秀和现代的解决方案。

    ZonedDateTime zdt = ZonedDateTime.now(ZoneId.of("Atlantic/Stanley"));
    // 2018-05-21T05:02:23.942763-03:00[Atlantic/Stanley]
    Month monthEnum = zdt.getMonth(); // MAY
    int monthNumber = zdt.getMonthValue(); // 5
    int year = zdt.getYear(); // 2018

我运行刚才的代码,并在每行代码后的注释中给出了结果。请把你想要的时区放在我放 Atlantic/Stanley 的地方,因为月份在不同时区的同一时间点不会改变。您是否同意我的观点,即此代码更清晰、更自然并且不会留下混淆的余地?顺便说一句,如果您只对日期感兴趣,而不是一天中的时间,请使用 LocalDate 而不是 ZonedDateTime,其余代码将相同。

获取特定月份的数字:

    int januaryNumber = Month.JANUARY.getValue(); // 1
    int februaryNumber = Month.FEBRUARY.getValue(); // 2

您的代码中发生了什么?

如T.J。 Crowder 已经说过,Calendar.get 需要 字段编号 ,例如 Calendar.MONTHCalendar.YEARCalendar.JANUARY 是 0. 零?!关于 Calendar 的另一个令人困惑的事情是,月份数字是从 0 开始的,也就是说,它们从 1 月的 0 到 12 月的 11。反正0也是Calendar.ERA的字段号。 GregorianCalendar 使用 0 表示 BC(或更多宗教中立:BCE 表示之前的共同时代)和 1 表示 AD(CE,共同时代)。由于你的日期是在共同时代,你得到 1。顺便说一句,由于月份是基于 0 的,所以一月份是不正确的。

同样,Calendar.FEBRUARY 等于 1 并且与字段编号 Calendar.YEAR 重合,这就是为什么你得到年份。

链接