Java日历中的差异设置“每月的天数"与“获取每月的天数" [英] Discrepancy in Java Calendar set Day Of Month vs Get Day Of Month
问题描述
我正在使用一个int值设置一个月的日历天,但是当我再次检查该值时,它比创建的日历要大1.我不确定为什么吗?
I am setting a Calendar day of month with an int value but when I check the value again the day of month from the created calendar it is 1 more than I set it to. And I am not sure why?
这里是一个例子:
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,所以您可以看到in值和out值.我希望调用calander.get(Calander.DAY_OF_MONTH)
将返回与我输入的值相同的值.但是没有,我得到了:
I did the println so you can see the value in and the value out. I would expect that calling calander.get(Calander.DAY_OF_MONTH)
would return the same value as I put into it. But it doesn't, I get:
DEBUG: Reminder day of month = 18
DEBUG: Calendar day of month = 19
我确信这可能很简单,但是我不知道为什么它们会有所不同,并且我在文档中找不到任何可以解释差异的地方
I am sure it is probably something simple but I have no idea why they would be different and I can't find anything in the docs to explain the discrepancy
出什么问题了?
感谢您的帮助
推荐答案
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
类.今天,我们在java.time
(现代Java日期和时间API,也称为JSR-310)中有了更好的表现.上面的代码为您提供了与我认为您尝试的功能等效的功能.我假设getReminderMonth()
返回的是基于0的月份,所以加1的原因是因为现代API像人类一样从1月份起数月.如果可以,我建议您使用OffsetDateTime
或ZonedDateTime
来使时间线上的点明确.
java.time
I suggest you put an end to using the very old and long outmoded Calendar
class. Today we have so much better in java.time
, the modern Java date and time API also known as JSR-310. The above code gives you the equivalent of what I think you were trying. I assumed getReminderMonth()
returned 0-based month, so added 1 since the modern API numbers months from 1 just as humans do. If you can, I recommend you use an OffsetDateTime
or ZonedDateTime
to make the point on the time line unambiguous.
如果至少使用Java 6 ,则可以.
If using at least Java 6, you can.
- 在Java 8和更高版本中,新的API是内置的.
- 在Java 6和7中,获得ThreeTen Backport,即新类的Backport(JSR-310的ThreeTen;下面的链接).
- 在Android上,使用Android版本的ThreeTen Backport.称为ThreeTenABP.请参阅下面的链接问题.
我认为,当同时满足以下两个条件时,就会发生观察到的日期增量:
I think the observed date increment happens when both of the following conditions are met:
- 您的代码在下午运行,即
Calendar
的时区(通常是JVM的时区,通常是您的本地时区)中午12点或更晚. -
getReminderHour()
返回下午的一个小时,即12点或更晚.
- Your code is running in the afternoon, that is at 12 noon or later in the
Calendar
’s time zone (typically the JVM’s time zone, in turn typically your local time zone). getReminderHour()
returns an hour in the afternoon, that is, 12 or later.
由于您没有向我们展示产生错误的代码,因此我不能100%地确定.但是很有可能您的Calendar
实例是使用当前时间创建的(例如,执行Calendar.getInstance()
和new GregorianCalendar()
).下午显然是在下午的某个时间创建的.然后,当您调用calendar.set(Calendar.HOUR, reminder.getReminderHour())
时,它将尝试在PM内设置小时,但是由于小时为12或更大,因此会溢出到第二天的AM中.例如,一个小时14(PM)变成第二天凌晨2点.
I cannot be 100 % sure since you haven’t shown us the code that produced your bug. But very likely your Calendar
instance was created with the current time (Calendar.getInstance()
and new GregorianCalendar()
, for example, do this). In the afternoon it is obviously created with a time in PM. Then when you call calendar.set(Calendar.HOUR, reminder.getReminderHour())
, this tries to set the hour within PM, but since the hour is 12 or greater, this overflows into AM of the following day. An hour of 14 (PM), for example, becomes 2 AM the next day.
如果我是正确的话,问题似乎似乎解决了,不是因为您将日历对象的创建移到了if
语句内,而是因为您是在早上运行程序或提醒时间是在早上(之前正午12点).下次同时满足上述两个条件时,您的错误可能再次浮出水面,
If I am correct, the problem may seem solved not because you moved the creation of the calendar object inside your if
statement, but because either you ran your program in the morning or the reminder hour was in the morning (before 12 noon). And your bug may surface again next time both the above-mentioned conditions apply,
- Oracle教程跟踪:日期时间
- 问题:如何在Android Project中使用ThreeTenABP
- ThreeTen Backport主页
- Java规范请求(JSR)310 ,现代API是首先定义
- Oracle tutorial trail: Date Time
- Question: How to use ThreeTenABP in Android Project
- ThreeTen Backport home page
- Java Specification Request (JSR) 310, where the modern API was first defined
这篇关于Java日历中的差异设置“每月的天数"与“获取每月的天数"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!