Java日历中的差异设置“每月的天数"与“获取每月的天数" [英] Discrepancy in Java Calendar set Day Of Month vs Get Day Of Month

查看:164
本文介绍了Java日历中的差异设置“每月的天数"与“获取每月的天数"的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用一个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月份起数月.如果可以,我建议您使用OffsetDateTimeZonedDateTime来使时间线上的点明确.

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 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆