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 开始,就像人类所做的那样。如果可以,我建议您使用 OffsetDateTime
或 ZonedDateTime
来明确时间线上的要点。
问题:我的 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点之前)。下次当上述两个条件都适用时,您的错误可能会再次出现,
链接
我正在使用一个 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 开始,就像人类所做的那样。如果可以,我建议您使用 OffsetDateTime
或 ZonedDateTime
来明确时间线上的要点。
问题:我的 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点之前)。下次当上述两个条件都适用时,您的错误可能会再次出现,