Java日期比较以天为单位
我有一个Java
方法,它比较两个Dates
并返回它们之间的天数,但它以一天为间隔
即使在我计算出小时、分钟和秒之后,计算仍然是关闭的
public long compareDates(Date exp, Date today){
TimeZone tzone = TimeZone.getTimeZone("America/New_York");
Calendar expDate = Calendar.getInstance();
Calendar todayDate = Calendar.getInstance();
expDate.setTime(exp);
todayDate.setTime(today);
expDate.set(Calendar.HOUR_OF_DAY, 0);
expDate.set(Calendar.MINUTE, 0);
expDate.set(Calendar.SECOND, 0);
todayDate.set(Calendar.HOUR_OF_DAY, 0);
todayDate.set(Calendar.MINUTE, 0);
todayDate.set(Calendar.SECOND, 0);
logger.info("Today = " + Long.toString(todayDate.getTimeInMillis()) + " Expiration = " + Long.toString(expDate.getTimeInMillis()));
expDate.setTimeZone(tzone);
todayDate.setTimeZone(tzone);
return (expDate.getTimeInMillis()-todayDate.getTimeInMillis())/86400000;
}
输出
Today = 1453939200030 Expiration = 1454544000000
1/28和2/4之间有7天,但这会返回6天
# 1 楼答案
爪哇。时间
这个问题和其他答案使用了过时的课程。旧的日期时间类,比如java。util。日期/。事实证明,与最早版本的Java捆绑在一起的日历相当麻烦。这些旧类已被Java8及更高版本中的java.time框架取代
正如其他答案正确指出的那样,问题在于开始
long
在右边有30
,排除了一整天的计算天数定义
此外,你必须定义天数的含义。你的意思是按日期计数,所以1月3日的任何时间到4日的任何时间都是一天,即使时间是午夜前后一分钟?或者,你的意思是计算一个通用的24小时时间段,而忽略一个事实,即由于夏令时(DST)和其他异常情况,特定时区中的特定日期并不总是24小时长
按日期计算天数
如果想要前者,请按日期计数,然后使用java中的
LocalDate
类(一个只有日期,没有一天中的时间,也没有时区)和Period
类(定义为年、月、日计数的时间跨度)。时间到了定义你的输入。使用
long
而不是int
。这些数字显然代表了自UTC 1970年第一个时刻以来的毫秒计数将这些
long
数字转换为Instant
对象,这是UTC时间轴上的一个时刻定义要考虑日历日期的时区。请注意,时区对于定义日期至关重要。全球各地的日期并不同时相同。日期因时区而异
将该时区应用于每个
Instant
以生成ZonedDateTime
要获得
Period
,我们需要“本地”日期。“本地”是指任何特定的地点,一个通用的日期值。LocalDate
类不包含时区,但在确定ZonedDateTime
时,将应用LocalDate
中包含的时区将我们的时间跨度定义为通用天数的计数,单位为
Period
询问
Period
以询问包含的通用天数转储到控制台
计算整日
如果需要计算整天的天数,请使用ThreeTen-Extra中的^{} 类。请注意,在下面的输出中,我们得到了六(6)天的计数,而不是如上所示的七(7)
额外加收30美元
ThreeTen-Extra项目扩展了java。时间由那些开发java的人运营。时间到了
^{} 方法的行为没有明确的记录。实验表明,它似乎是基于24小时的时间段,而不是日期。将
030
替换为000
,并尝试将stopMilli中的最后一个000
替换为030
,以便自己查看行为转储到控制台。您在输出中看到的
P6D
字符串是根据ISO 8601标准中定义的格式生成的。java中默认使用此标准。所有解析和生成日期时间值的文本表示的时间。这些标准格式非常合理和有用,所以请浏览一下链接的维基百科页面# 2 楼答案
时间是以毫秒为单位的,看起来你输入的
Date
有30个额外的毫秒当我减去30毫秒,然后在计算器上计算,我得到7天。根据你的数字,我得到
6.9999996527777777777777777777778
,在long
数学中,十进制数字被截断为6
把毫秒也归零
# 3 楼答案
为了解决我的问题,我已经将上面提到的毫秒归零,并将长数转换为双倍,以便在必要时保持精度和圆度
# 4 楼答案
正如你所看到的,你没有清除毫秒,并且
1454544000000 - 1453939200030 = 604799970
除以86400000
得到6.99999965277777...
,这意味着当被截断为int
时6
现在,如果你也清除毫秒,今天变成
1453939200000
,这将导致你回答7
注意:这并不意味着你完成了,因为夏令时。使用DST时,其中一个时间戳可能与另一个时间戳相差±1小时,因此可能仍然存在截断问题
这是对你特定问题的回答。尝试在Java中搜索如何正确查找日期之间的天数