Java 日历设置中的日期与获取月份中的日期存在差异

Discrepancy in Java Calendar set Day Of Month vs Get Day Of Month

我正在使用一个 int 值设置一个日历月中的第几天,但是当我再次检查创建的日历中的月中某天的值时,它比我设置的多了 1。我不确定为什么?

这是一个例子:

System.out.println("DEBUG: Reminder day of month = " + reminder.getReminderDayofMonth());

calendar.set(Calendar.YEAR, reminder.getReminderYear());                   
calendar.set(Calendar.MONTH, reminder.getReminderMonth());
calendar.set(Calendar.DAY_OF_MONTH, reminder.getReminderDayofMonth());
calendar.set(Calendar.HOUR, reminder.getReminderHour());
calendar.set(Calendar.MINUTE, reminder.getReminderMinute());

System.out.println("DEBUG: Calendar day of month = " + calendar.get(Calendar.DAY_OF_MONTH));

我做了 println,所以你可以看到输入值和输出值。我希望调用 calander.get(Calander.DAY_OF_MONTH) 会 return 与我输入的值相同。但它没有,我得到:

DEBUG: Reminder day of month = 18
DEBUG: Calendar day of month = 19

我确定这可能很简单,但我不知道为什么它们会有所不同,而且我在文档中找不到任何内容来解释差异

问题是什么?

感谢您的帮助

TL:DR

LocalDateTime ldt = LocalDateTime.of(
    reminder.getReminderYear(),
    reminder.getReminderMonth() + 1,  // Add one to adjust from zero-based counting.
    reminder.getReminderDayofMonth(),
    reminder.getReminderHour(),
    reminder.getReminderMinute()
);

java.time

我建议您停止使用非常陈旧且长期过时的 Calendar class。今天我们在 java.time 中有了更好的东西,现代 Java 日期和时间 API 也称为 JSR-310。上面的代码为您提供了我认为您正在尝试的等效内容。我假设 getReminderMonth() 返回基于 0 的月份,因此添加了 1,因为现代 API 数字月份从 1 开始,就像人类所做的那样。如果可以,我建议您使用 OffsetDateTimeZonedDateTime 来明确时间线上的要点。

问题:我的 Java 版本可以使用现代 API 吗?

如果至少使用 Java 6,则可以。

  • 在 Java 8 及更高版本中内置了新的 API。
  • 在 Java 6 和 7 中获取 ThreeTen Backport,新 classes 的 backport(ThreeTen 用于 JSR-310;下面的 link)。
  • 在 Android 上,使用 ThreeTen Backport 的 Android 版本。它叫做 ThreeTenABP。请参阅下面的 linked 问题。

你的代码出了什么问题

我认为观察到的日期增量发生在满足以下两个条件时:

  • 您的代码是 运行 下午,即 Calendar 时区的中午 12 点或更晚时间(通常是 JVM 的时区,通常是您当地的时区) .
  • getReminderHour()returns下午一个小时,也就是12点以后。

我不能 100% 确定,因为您没有向我们展示产生您的错误的代码。但很可能您的 Calendar 实例是使用当前时间创建的(例如,Calendar.getInstance()new GregorianCalendar(),执行此操作)。在下午,它显然是在 PM 中创建的。然后,当您调用 calendar.set(Calendar.HOUR, reminder.getReminderHour()) 时,它会尝试在 PM 内设置小时,但由于小时为 12 或更大,因此会溢出到第二天的 AM。例如,下午 14 点变成第二天凌晨 2 点。

如果我是对的,问题似乎已经解决,不是因为您将日历对象的创建移到 if 语句中,而是因为您 运行 早上的程序或提醒时间是早上(中午12点之前)。下次当上述两个条件都适用时,您的错误可能会再次出现,

链接