几分钟之间的差异 - 不同月份 - Java

时间:2017-02-17 04:29:28

标签: java date date-arithmetic

我想找出两个日期之间的分钟差异。如果2个日期在同一个月(和年份),我的代码运作良好,但似乎差异考虑每个月为31天,所以对于日期:

 2016-02-29 12:21
 2016-03-1 12:21

我得到4320分钟或72小时

有:

 2016-04-30 12:21
 2016-05-01 12:21

我得到2880分钟或48小时

我的代码,其中d1和d2是Date对象:

long getDateDiff(Date d1, Date d2, TimeUnit timeUnit) {
    long diff = d2.getTime() - d1.getTime(); //in millisec
    long diffMinutes = TimeUnit.MILLISECONDS.toMinutes(diff);
    return diffMinutes;
}

3 个答案:

答案 0 :(得分:2)

TL;博士

解析你的输入字符串。

LocalDateTime startLdt = LocalDateTime.parse( "2016-04-30T12:21" ) ;
LocalDateTime stopLdt = LocalDateTime.parse( "2016-05-01T12:21") ;

分配时间区域或偏离UTC的预期但从输入中省略。我假设您打算使用UTC本身(零偏移)。

OffsetDateTime start = startLdt.atOffset( ZoneOffset.UTC );
OffsetDateTime stop = stopLdt.atOffset( ZoneOffset.UTC ) ;

计算天数(24小时时间),小时,分钟,秒和纳秒的经过时间。

Duration d = Duration.between( start , stop ) ;
  

d.toString():PT24H

您的第一个示例会在24小时内生成,如code runs live at IdeOne.com时所示。

你的第二个例子也是24小时,seen in IdeOne.com

详细

问题和其他答案都使用麻烦的旧日期时间类或Joda-Time库。两者都被java.time类取代。

使用java.time

Date个对象转换为Instant个对象,相当于java.time。 Instant类代表UTC中时间轴上的一个时刻,分辨率为nanoseconds(小数部分最多九(9)位)。

Instant start = d1.toInstant();
Instant stop = d2.toInstant();

使用Duration(或Period)表示其间的时间范围。

Duration d = Duration.between( start , stop );

提取整个时间段内的总分钟数。

long minutes = d.toMinutes() ;

时区

您没有提及用于示例日期时间值的时区。他们的背景是UTC吗?或者你打算某个特定的时区。在不同的时区,夏令时(DST)等异常意味着天数并不总是24小时。所以时区至关重要。

让我们看看UTC。

// of(int year, int month, int dayOfMonth, int hour, int minute, int second, int nanoOfSecond, ZoneOffset offset)
OffsetDateTime odtStart1 = OffsetDateTime.of ( 2016 , 2 , 29 , 12 , 21 , 0 , 0 , ZoneOffset.UTC );
OffsetDateTime odtStop1 = OffsetDateTime.of ( 2016 , 3 , 1 , 12 , 21 , 0 , 0 , ZoneOffset.UTC );
Duration d1 = Duration.between ( odtStart1 , odtStop1 );

OffsetDateTime odtStart2 = OffsetDateTime.of ( 2016 , 4 , 30 , 12 , 21 , 0 , 0 , ZoneOffset.UTC );
OffsetDateTime odtStop2 = OffsetDateTime.of ( 2016 , 5 , 1 , 12 , 21 , 0 , 0 , ZoneOffset.UTC );
Duration d2 = Duration.between ( odtStart2 , odtStop2 );

System.out.println ( odtStart1 + "/" + odtStop1 + " = " + d1 );
System.out.println ( odtStart2 + "/" + odtStop2 + " = " + d2 );
  

2016-02-29T12:21Z / 2016-03-01T12:21Z = PT24H

     

2016-04-30T12:21Z / 2016-05-01T12:21Z = PT24H

toString生成的字符串位于标准ISO 8601 format for durations中。 P标志着开头,T将任何年 - 月 - 日的部分与任何小时 - 分钟 - 秒部分分开。

在这两种情况下,结果是二十四小时。这是正确的,因为在每种情况下,您都选择从一个月的最后一天到下一个月的第一天。 UTC没有异常,所以我们预计会经过24小时。

您可以通过调用compareTo来比较Duration个对象。你可以做数学来区分它们。在这种情况下,我们期望零的不同。

Duration difference = d1.minus( d2 );
  

difference.toString():PT0S

请参阅此code run live at IdeOne.com

关于 java.time

java.time框架内置于Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.DateCalendar和& SimpleDateFormat

现在位于Joda-Timemaintenance mode项目建议迁移到java.time类。

要了解详情,请参阅Oracle Tutorial。并搜索Stack Overflow以获取许多示例和解释。规范是JSR 310

您可以直接与数据库交换 java.time 对象。使用符合JDBC driver或更高版本的JDBC 4.2。不需要字符串,不需要java.sql.*类。

从哪里获取java.time类?

ThreeTen-Extra项目使用其他类扩展java.time。该项目是未来可能添加到java.time的试验场。您可以在此处找到一些有用的课程,例如IntervalYearWeekYearQuartermore

答案 1 :(得分:1)

你的结果很奇怪。所以我试了一下:

$('#your-div').click(function() {
  $('#form-id').submit();
});
它完全恢复了24小时。

答案 2 :(得分:0)

我认为日期对象的顺序并不重要,所以我使用了<div ng-repeat="data in data.data" layout="column"> <span> ID: {{data.id}}</span> <md-checkbox ng-repeat="eachTag in data.tags"> {{eachTag}} </md-checkbox> </div>

Math.abs()

此方法为您的测试用例返回1440分钟:

public long getMinuteDifference(Date date1, Date date2) {
  long millis = Math.abs(date2.getTime() - date1.getTime());

  return TimeUnit.MILLISECONDS.toMinutes(millis);
}