Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/320.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/date/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java日期比较以天为单位_Java_Date_Calendar - Fatal编程技术网

Java日期比较以天为单位

Java日期比较以天为单位,java,date,calendar,Java,Date,Calendar,我有一个Java方法,它比较两个日期并返回它们之间的天数,但它以天为单位 即使在我计算出小时、分钟和秒后,计算仍处于关闭状态 public long compareDates(Date exp, Date today){ TimeZone tzone = TimeZone.getTimeZone("America/New_York"); Calendar expDate = Calendar.getInstance(); Calendar toda

我有一个
Java
方法,它比较两个
日期
并返回它们之间的天数,但它以天为单位

即使在我计算出小时、分钟和秒后,计算仍处于关闭状态

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。

你可以看到,你没有清除毫秒,并且
1454544000000-1453939200030=604799970
除以
86400000
得到
6.9999965277777…
,这意味着当截断为
int
6

现在,如果您也清除毫秒,今天将变成
14539200000
,这将导致您回答
7

注意:这并不意味着你已经完成了,因为夏令时。使用DST时,其中一个时间戳可能与另一个时间戳相差±1小时,因此您可能仍然会遇到截断问题


这是对你的特殊问题的回答。尝试在Java中搜索如何正确查找日期之间的天数。

正如您所看到的,您没有清除毫秒,并且
1454544000000-1453939200030=604799970
除以
86400000
得到
6.9999965277777…
,这意味着当截断为
int
6

现在,如果您也清除毫秒,今天将变成
14539200000
,这将导致您回答
7

注意:这并不意味着你已经完成了,因为夏令时。使用DST时,其中一个时间戳可能与另一个时间戳相差±1小时,因此您可能仍然会遇到截断问题

这是对你的特殊问题的回答。尝试搜索如何在Java中正确查找日期之间的天数

今天=14539200030

时间以毫秒为单位,看起来输入的
Date
多了30毫秒

当我减去30毫秒,然后在计算器上计算,我得到7天。根据您的数字,我得到
6.999999652777778
,在
long
数学中,十进制数字被截断为
6

也将毫秒归零

expDate.set(Calendar.MILLISECOND, 0);
todayDate.set(Calendar.MILLISECOND, 0);
今天=14539200030

时间以毫秒为单位,看起来输入的
Date
多了30毫秒

当我减去30毫秒,然后在计算器上计算,我得到7天。根据您的数字,我得到
6.999999652777778
,在
long
数学中,十进制数字被截断为
6

也将毫秒归零

expDate.set(Calendar.MILLISECOND, 0);
todayDate.set(Calendar.MILLISECOND, 0);
java.time 这个问题和其他答案使用了过时的课程。与最早版本的java捆绑在一起的旧日期时间类,如java.util.date/.Calendar,已经证明非常麻烦。这些旧类已经被Java8和更高版本中的框架所取代

正如其他答案正确指出的那样,问题在于开始
long
的右侧有
30
,排除了全天计算

天数定义 此外,您必须定义天数的含义。你的意思是按日期计数,所以1月3日的任何时间到4日的任何时间都是一天,即使时间是午夜前后一分钟?或者,你的意思是指一个通用的24小时时间段的计数,而忽略一个事实,即由于夏令时(DST)和其他异常情况,特定时区中的特定日期并不总是24小时长

按日期计算天数 如果要使用前者,请按日期计数,然后使用java.time中的
LocalDate
类(一个日期既没有日期也没有时区)和
Period
类(时间跨度定义为年、月、日的计数)

定义您的输入。使用
long
而不是
int
。这些数字显然代表自1970年第一个UTC时刻以来的毫秒计数

long startMilli = 1_453_939_200_030L;
long stopMilli = 1_454_544_000_000L;
将那些
long
数字转换为
Instant
对象,即UTC时间轴上的一个瞬间

Instant startInstant = Instant.ofEpochMilli ( startMilli );
Instant stopInstant = Instant.ofEpochMilli ( stopMilli );

定义要考虑日历日期的时区。请注意,时区对于定义日期至关重要。全球各地的日期并不同时相同。日期因时区而异

ZoneId zoneId = ZoneId.of ( "America/Montreal" );
将该时区应用于每个
瞬间
,以生成
zoneDateTime

ZonedDateTime startZdt = ZonedDateTime.ofInstant ( startInstant , zoneId );
ZonedDateTime stopZdt = ZonedDateTime.ofInstant ( stopInstant , zoneId );
要获得
期间
,我们需要“本地”日期。“本地”是指任何特定的地点,一个通用的日期值。
LocalDate
类不包含时区,但在确定
LocalDate
时,将应用
ZonedDateTime
中包含的时区

LocalDate startLocalDate = startZdt.toLocalDate ();;
LocalDate stopLocalDate = stopZdt.toLocalDate ();
将我们的时间跨度定义为通用天数的计数,单位为
期间

Period period = Period.between ( startLocalDate , stopLocalDate );
询问
期间
,询问该期间内包含的一般天数

int days = period.getDays ();
转储到控制台

System.out.println ( "milli: " + startMilli + "/" + stopMilli + " | Instant: " + startInstant + "/" + stopInstant + " | ZonedDateTime: " + startZdt + "/" + stopZdt + " | LocalDate: " + startLocalDate + "/" + stopLocalDate + " | period: " + period + " | days: " + days );
milli:14539200030/1454544000000 |即时:2016-01-28:00:00.030Z/2016-02-04T00:00:00Z |分区日期:2016-01-27T19:00:00.030-05:00[美国/蒙特利尔]/2016-02-03T19:00-05:00[美国/蒙特利尔]|当地日期:2016-01-27/2016-02-03 |期间:第7天:7天

全天数 如果您想计算整天的天数,请使用中的类。请注意,在下面的输出中,我们得到了六(6)天的计数,而不是如上所示的七(7)

额外加三十 该项目扩展了java.time。由构建java.time的人运行

该方法的行为没有明确记录。实验表明,它似乎是基于24小时的时间段,而不是日期。将
030
替换为
000
,并尝试将stopMilli中最后一个
000
替换为
030
,以查看您自己的行为

Days daysObject = Days.between ( startZdt , stopZdt );
int daysObjectCount = daysObject.getAmount ();
转储到控制台。您在输出中看到的
P6D
字符串是根据表单生成的
expDate.setTime(exp);
todayDate.setTime(today);
expDate.setTimeZone(tzone);
todayDate.setTimeZone(tzone);

expDate.set(Calendar.HOUR_OF_DAY, 0);
expDate.set(Calendar.MINUTE, 0);
expDate.set(Calendar.SECOND, 0);
expDate.set(Calendar.MILLISECOND, 0);

todayDate.set(Calendar.HOUR_OF_DAY, 0);
todayDate.set(Calendar.MINUTE, 0);
todayDate.set(Calendar.SECOND, 0);
todayDate.set(Calendar.MILLISECOND, 0);

double diff = ((double)expDate.getTimeInMillis()-(double)todayDate.getTimeInMillis())/86400000;

return Math.round(diff);