计算两个Java日期实例之间的差异

时间:2009-10-12 15:35:50

标签: java date time timedelta java.util.date

我在Scala中使用Java的java.util.Date类,并希望比较Date对象和当前时间。我知道我可以使用getTime()来计算delta:

(new java.util.Date()).getTime() - oldDate.getTime()

但是,这只留下一个代表毫秒的long。有没有更简单,更好的方法来获得时间增量?

45 个答案:

答案 0 :(得分:497)

简单差异(不含lib)

/**
 * Get a diff between two dates
 * @param date1 the oldest date
 * @param date2 the newest date
 * @param timeUnit the unit in which you want the diff
 * @return the diff value, in the provided unit
 */
public static long getDateDiff(Date date1, Date date2, TimeUnit timeUnit) {
    long diffInMillies = date2.getTime() - date1.getTime();
    return timeUnit.convert(diffInMillies,TimeUnit.MILLISECONDS);
}

然后你可以打电话:

getDateDiff(date1,date2,TimeUnit.MINUTES);

以分钟为单位获得2个日期的差异。

TimeUnitjava.util.concurrent.TimeUnit,标准的Java枚举从纳米到天。


人类可读的差异(没有lib)

public static Map<TimeUnit,Long> computeDiff(Date date1, Date date2) {

    long diffInMillies = date2.getTime() - date1.getTime();

    //create the list
    List<TimeUnit> units = new ArrayList<TimeUnit>(EnumSet.allOf(TimeUnit.class));
    Collections.reverse(units);

    //create the result map of TimeUnit and difference
    Map<TimeUnit,Long> result = new LinkedHashMap<TimeUnit,Long>();
    long milliesRest = diffInMillies;

    for ( TimeUnit unit : units ) {

        //calculate difference in millisecond 
        long diff = unit.convert(milliesRest,TimeUnit.MILLISECONDS);
        long diffInMilliesForUnit = unit.toMillis(diff);
        milliesRest = milliesRest - diffInMilliesForUnit;

        //put the result in the map
        result.put(unit,diff);
    }

    return result;
}

http://ideone.com/5dXeu6

输出类似Map:{DAYS=1, HOURS=3, MINUTES=46, SECONDS=40, MILLISECONDS=0, MICROSECONDS=0, NANOSECONDS=0},单位已订购。

您只需将该地图转换为用户友好的字符串。


警告

以上代码片段计算2个瞬间之间的简单差异。在夏令时开关中可能会出现问题,如this post中所述。这意味着如果你计算日期之间没有时间的差异,你可能会缺少一天/小时。

在我看来,日期差异是一种主观的,特别是在日子里。你可以:

  • 计算24小时经过的时间:天+ 1天= 1天= 24小时

  • 计算经过的时间,照顾夏令时:白天+ 1天= 1 = 24小时(但使用午夜时间和夏令时可能是0天和23小时)

  • 计算day switches的数量,即日期+ 1下午1点 - 上午11点= 1天,即使经过的时间仅为2小时(如果有夏令时则​​为1小时:p)< / p>

如果您对日期差异的定义与第一种情况相符

,我的回答是有效的

使用JodaTime

如果您正在使用JodaTime,您可以获得2个瞬间的差异(毫秒支持的ReadableInstant)日期:

Interval interval = new Interval(oldInstant, new Instant());

但你也可以获得本地日期/时间的差异:

// returns 4 because of the leap year of 366 days
new Period(LocalDate.now(), LocalDate.now().plusDays(365*5), PeriodType.years()).getYears() 

// this time it returns 5
new Period(LocalDate.now(), LocalDate.now().plusDays(365*5+1), PeriodType.years()).getYears() 

// And you can also use these static methods
Years.yearsBetween(LocalDate.now(), LocalDate.now().plusDays(365*5)).getYears()

答案 1 :(得分:181)

遗憾的是,JDK Date API非常糟糕。我建议使用Joda Time library

Joda Time有一个时间概念Interval

Interval interval = new Interval(oldTime, new Instant());

编辑:顺便说一下,Joda有两个概念:Interval用于表示两个时间点之间的时间间隔(表示上午8点到上午10点之间的时间),以及Duration表示长度为没有实际时间边界的时间(例如代表两个小时!)

如果您只关心时间比较,大多数Date实现(包括JDK)实现Comparable接口,允许您使用Comparable.compareTo()

答案 2 :(得分:148)

int diffInDays = (int)( (newerDate.getTime() - olderDate.getTime()) 
                 / (1000 * 60 * 60 * 24) )

请注意,这适用于UTC日期,因此如果您查看本地日期,差异可能是休息日。并且由于夏令时,需要采用完全不同的方法使其与本地日期一起正常工作。

答案 3 :(得分:53)

您需要更清楚地定义问题。你可以只取两个Date个对象之间的毫秒数除以24小时内的毫秒数,例如......但是:

  • 这不会考虑时区 - Date始终为UTC
  • 这不会考虑夏令时(例如,可能有长达23小时的天数)
  • 即使在UTC内,8月16日晚上11点到8月18日凌晨2点有多少天?它只有27个小时,所以这意味着有一天?或者它应该是三天,因为它涵盖三个日期?

答案 4 :(得分:48)

使用Java 8 +中内置的java.time框架:

ZonedDateTime now = ZonedDateTime.now();
ZonedDateTime oldDate = now.minusDays(1).minusMinutes(10);
Duration duration = Duration.between(oldDate, now);
System.out.println("ISO-8601: " + duration);
System.out.println("Minutes: " + duration.toMinutes());

输出:

  

ISO-8601:PT24H10M

     

会议纪要:1450

有关详细信息,请参阅Oracle TutorialISO 8601标准。

答案 5 :(得分:39)

TL;博士

将过时的java.util.Date对象转换为替换java.time.Instant。然后将经过时间计算为Duration

Duration d = 
    Duration.between(                   // Calculate the span of time between two moments as a number of hours, minutes, and seconds.
        myJavaUtilDate.toInstant() ,    // Convert legacy class to modern class by calling new method added to the old class.
        Instant.now()                   // Capture the current moment in UTC. About two and a half hours later in this example.
    )
;
  

d.toString():PT2H34M56S

     

d.toMinutes():154

     

d.toMinutesPart():34

ISO 8601格式:PnYnMnDTnHnMnS

明智的标准ISO 8601将时间跨度的简明文本表示定义为若干年,月,日,小时等。标准称为跨度duration。格式为PnYnMnDTnHnMnS,其中P表示“期间”,T将日期部分与时间部分分开,中间是数字后跟字母。

示例:

  • P3Y6M4DT12H30M5S
    三年,六个月,四天,十二小时,三十五分五秒
  • PT4H30M
    四个半小时

java.time

Java 8及更高版本中内置的java.time框架取代了麻烦的旧java.util.Date / java.util.Calendar类。新课程的灵感来自非常成功的Joda-Time框架,旨在作为其继承者,在概念上类似但重新设计。由JSR 310定义。由ThreeTen-Extra项目扩展。请参阅Tutorial

Instant类代表UTC中时间轴上的一个时刻,分辨率为nanoseconds(小数部分最多九(9)位)。

Instant instant = Instant.now() ;  // Capture current moment in UTC.

最好避免遗留类,例如Date / Calendar。但是,如果您必须与尚未更新为 java.time 的旧代码进行互操作,请来回转换。调用添加到旧类的新转换方法。要从java.util.Date移至Instant,请致电Date::toInstant

Instant instant = myJavaUtilDate.toInstant() ;  // Convert from legacy `java.util.Date` class to modern `java.time.Instant` class.

时间跨度

java.time类已将这种将时间跨度表示为数年,月,日,小时,分钟,秒分为两半的想法分开了:

  • Period多年,几个月,几天
  • Duration天,小时,分钟,秒

这是一个例子。

ZoneId zoneId = ZoneId.of ( "America/Montreal" );
ZonedDateTime now = ZonedDateTime.now ( zoneId );
ZonedDateTime future = now.plusMinutes ( 63 );
Duration duration = Duration.between ( now , future );

转储到控制台。

PeriodDuration都使用ISO 8601标准生成其值的字符串表示。

System.out.println ( "now: " + now + " to future: " + now + " = " + duration );
  

现在:2015-11-26T00:46:48.016-05:00 [美国/蒙特利尔]到未来:2015-11-26T00:46:48.016-05:00 [美国/蒙特利尔] = PT1H3M

Java 9为Duration添加方法以获取日期部分,小时部分,分钟部分和秒部分。

您可以在整个持续时间内获得总天数或小时数,分钟数或秒数或毫秒数或纳秒数。

long totalHours = duration.toHours();

在Java 9中,Duration class gets new methods用于返回天,小时,分钟,秒,毫秒/纳秒的各个部分。调用to…Part方法:toDaysPart()toHoursPart(),依此类推。

ChronoUnit

如果您只关心更简单的更大粒度的时间,例如“已过去的天数”,请使用ChronoUnit枚举。

long daysElapsed = ChronoUnit.DAYS.between( earlier , later );

另一个例子。

Instant now = Instant.now();
Instant later = now.plus( Duration.ofHours( 2 ) );
…
long minutesElapsed = ChronoUnit.MINUTES.between( now , later );
  

120


关于java.time

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

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

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

从哪里获取java.time类?

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


约达时间

更新:Joda-Time项目现在位于maintenance mode,团队建议迁移到java.time课程。我保留此部分的历史记录。

Joda-Time库使用ISO 8601作为默认值。它的Period类解析并生成这些PnYnMnDTnHnMnS字符串。

DateTime now = DateTime.now(); // Caveat: Ignoring the important issue of time zones.
Period period = new Period( now, now.plusHours( 4 ).plusMinutes( 30));
System.out.println( "period: " + period );

渲染:

period: PT4H30M

答案 6 :(得分:34)

Days d = Days.daysBetween(startDate, endDate);
int days = d.getDays();

https://www.joda.org/joda-time/faq.html#datediff

答案 7 :(得分:24)

一个稍微简单的替代方案:

System.currentTimeMillis() - oldDate.getTime()

至于“更好”:嗯,你究竟需要什么?将持续时间表示为小时数和天数等的问题在于,由于日期的复杂性,可能会导致不准确和错误的预期(例如,由于夏令时,天数可能会达到23或25小时)。

答案 8 :(得分:22)

使用毫秒方法可能会导致某些区域设置出现问题。

让我们看看,例如,03/24/2007和03/25/2007两个日期之间的差异应该是1天;

然而,使用毫秒路线,如果你在英国运行,你将获得0天!

/** Manual Method - YIELDS INCORRECT RESULTS - DO NOT USE**/  
/* This method is used to find the no of days between the given dates */  
public long calculateDays(Date dateEarly, Date dateLater) {  
   return (dateLater.getTime() - dateEarly.getTime()) / (24 * 60 * 60 * 1000);  
} 

实现这一点的更好方法是使用java.util.Calendar

/** Using Calendar - THE CORRECT WAY**/  
public static long daysBetween(Calendar startDate, Calendar endDate) {  
  Calendar date = (Calendar) startDate.clone();  
  long daysBetween = 0;  
  while (date.before(endDate)) {  
    date.add(Calendar.DAY_OF_MONTH, 1);  
    daysBetween++;  
  }  
  return daysBetween;  
}  

答案 9 :(得分:21)

您可以通过多种方式找到日期和时间之间的差异。倍。我所知道的最简单的方法之一是:

      Calendar calendar1 = Calendar.getInstance();
      Calendar calendar2 = Calendar.getInstance();
      calendar1.set(2012, 04, 02);
      calendar2.set(2012, 04, 04);
      long milsecs1= calendar1.getTimeInMillis();
      long milsecs2 = calendar2.getTimeInMillis();
      long diff = milsecs2 - milsecs1;
      long dsecs = diff / 1000;
      long dminutes = diff / (60 * 1000);
      long dhours = diff / (60 * 60 * 1000);
      long ddays = diff / (24 * 60 * 60 * 1000);

      System.out.println("Your Day Difference="+ddays);

print语句只是一个例子 - 您可以按照自己喜欢的方式对其进行格式化。

答案 10 :(得分:17)

由于这里的所有答案都是正确的,但使用遗留的java或第三方库,如joda或类似的,我将在Java 8及更高版本中使用新的java.time类。请参阅Oracle Tutorial

使用LocalDateChronoUnit

LocalDate d1 = LocalDate.of(2017, 5, 1);
LocalDate d2 = LocalDate.of(2017, 5, 18);

long days = ChronoUnit.DAYS.between(d1, d2);
System.out.println( days );

答案 11 :(得分:9)

以毫秒为单位减去日期(如另一篇文章所述),但 在清除日期的时间部分时使用HOUR_OF_DAY而不是HOUR:

public static final long MSPERDAY = 60 * 60 * 24 * 1000;
...
final Calendar dateStartCal = Calendar.getInstance();
dateStartCal.setTime(dateStart);
dateStartCal.set(Calendar.HOUR_OF_DAY, 0); // Crucial.
dateStartCal.set(Calendar.MINUTE, 0);
dateStartCal.set(Calendar.SECOND, 0);
dateStartCal.set(Calendar.MILLISECOND, 0);
final Calendar dateEndCal = Calendar.getInstance();
dateEndCal.setTime(dateEnd);
dateEndCal.set(Calendar.HOUR_OF_DAY, 0); // Crucial.
dateEndCal.set(Calendar.MINUTE, 0);
dateEndCal.set(Calendar.SECOND, 0);
dateEndCal.set(Calendar.MILLISECOND, 0);
final long dateDifferenceInDays = ( dateStartCal.getTimeInMillis()
                                  - dateEndCal.getTimeInMillis()
                                  ) / MSPERDAY;
if (dateDifferenceInDays > 15) {
    // Do something if difference > 15 days
}

答案 12 :(得分:8)

查看Joda Time,这是一个改进的Java日期/时间API,可以与Scala一起使用。

答案 13 :(得分:8)

如果您不想使用JodaTime或类似产品,最好的解决方案可能就是:

final static long MILLIS_PER_DAY = 24 * 3600 * 1000;
long msDiff= date1.getTime() - date2.getTime();
long daysDiff = Math.round(msDiff / ((double)MILLIS_PER_DAY));

每天的毫秒数并不总是相同(因为夏令时和闰秒),但它非常接近,并且至少由于夏令时的偏差会在较长时间内抵消。因此,分割然后舍入将给出正确的结果(至少只要使用的本地日历不包含除DST和闰秒之外的奇怪时间跳转)。

请注意,这仍然假定date1date2设置为一天的同一时间。正如Jon Skeet所指出的那样,对于一天中的不同时间,您首先必须定义“日期差异”的含义。

答案 14 :(得分:5)

如果你需要一个格式化的返回字符串 “2天03h 42m 07s”,试试这个:

public String fill2(int value)
{
    String ret = String.valueOf(value);

    if (ret.length() < 2)
        ret = "0" + ret;            
    return ret;
}

public String get_duration(Date date1, Date date2)
{                   
    TimeUnit timeUnit = TimeUnit.SECONDS;

    long diffInMilli = date2.getTime() - date1.getTime();
    long s = timeUnit.convert(diffInMilli, TimeUnit.MILLISECONDS);

    long days = s / (24 * 60 * 60);
    long rest = s - (days * 24 * 60 * 60);
    long hrs = rest / (60 * 60);
    long rest1 = rest - (hrs * 60 * 60);
    long min = rest1 / 60;      
    long sec = s % 60;

    String dates = "";
    if (days > 0) dates = days + " Days ";

    dates += fill2((int) hrs) + "h ";
    dates += fill2((int) min) + "m ";
    dates += fill2((int) sec) + "s ";

    return dates;
}

答案 15 :(得分:5)

让我展示Joda Interval和Days之间的区别:

DateTime start = new DateTime(2012, 2, 6, 10, 44, 51, 0);
DateTime end = new DateTime(2012, 2, 6, 11, 39, 47, 1);
Interval interval = new Interval(start, end);
Period period = interval.toPeriod();
System.out.println(period.getYears() + " years, " + period.getMonths() + " months, " + period.getWeeks() + " weeks, " + period.getDays() + " days");
System.out.println(period.getHours() + " hours, " + period.getMinutes() + " minutes, " + period.getSeconds() + " seconds ");
//Result is:
//0 years, 0 months, *1 weeks, 1 days*
//0 hours, 54 minutes, 56 seconds 

//Period can set PeriodType,such as PeriodType.yearMonthDay(),PeriodType.yearDayTime()...
Period p = new Period(start, end, PeriodType.yearMonthDayTime());
System.out.println(p.getYears() + " years, " + p.getMonths() + " months, " + p.getWeeks() + " weeks, " + p.getDays() + "days");
System.out.println(p.getHours() + " hours, " + p.getMinutes() + " minutes, " + p.getSeconds() + " seconds ");
//Result is:
//0 years, 0 months, *0 weeks, 8 days*
//0 hours, 54 minutes, 56 seconds 

答案 16 :(得分:4)

使用GMT时区获取日历的实例,使用Calendar类的set方法设置时间。 GMT时区有0偏移(不是很重要)和夏令时标志设置为false。

    final Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));

    cal.set(Calendar.YEAR, 2011);
    cal.set(Calendar.MONTH, 9);
    cal.set(Calendar.DAY_OF_MONTH, 29);
    cal.set(Calendar.HOUR, 0);
    cal.set(Calendar.MINUTE, 0);
    cal.set(Calendar.SECOND, 0);
    final Date startDate = cal.getTime();

    cal.set(Calendar.YEAR, 2011);
    cal.set(Calendar.MONTH, 12);
    cal.set(Calendar.DAY_OF_MONTH, 21);
    cal.set(Calendar.HOUR, 0);
    cal.set(Calendar.MINUTE, 0);
    cal.set(Calendar.SECOND, 0);
    final Date endDate = cal.getTime();

    System.out.println((endDate.getTime() - startDate.getTime()) % (1000l * 60l * 60l * 24l));

答案 17 :(得分:4)

在此处查看示例http://www.roseindia.net/java/beginners/DateDifferent.shtml 这个例子给出了天,小时,分钟,秒和毫秒的区别:)。

import java.util.Calendar;
import java.util.Date;

public class DateDifferent {
    public static void main(String[] args) {
        Date date1 = new Date(2009, 01, 10);
        Date date2 = new Date(2009, 07, 01);
        Calendar calendar1 = Calendar.getInstance();
        Calendar calendar2 = Calendar.getInstance();
        calendar1.setTime(date1);
        calendar2.setTime(date2);
        long milliseconds1 = calendar1.getTimeInMillis();
        long milliseconds2 = calendar2.getTimeInMillis();
        long diff = milliseconds2 - milliseconds1;
        long diffSeconds = diff / 1000;
        long diffMinutes = diff / (60 * 1000);
        long diffHours = diff / (60 * 60 * 1000);
        long diffDays = diff / (24 * 60 * 60 * 1000);
        System.out.println("\nThe Date Different Example");
        System.out.println("Time in milliseconds: " + diff + " milliseconds.");
        System.out.println("Time in seconds: " + diffSeconds + " seconds.");
        System.out.println("Time in minutes: " + diffMinutes + " minutes.");
        System.out.println("Time in hours: " + diffHours + " hours.");
        System.out.println("Time in days: " + diffDays + " days.");
    }
}

答案 18 :(得分:4)

public static String getDifferenceBtwTime(Date dateTime) {

    long timeDifferenceMilliseconds = new Date().getTime() - dateTime.getTime();
    long diffSeconds = timeDifferenceMilliseconds / 1000;
    long diffMinutes = timeDifferenceMilliseconds / (60 * 1000);
    long diffHours = timeDifferenceMilliseconds / (60 * 60 * 1000);
    long diffDays = timeDifferenceMilliseconds / (60 * 60 * 1000 * 24);
    long diffWeeks = timeDifferenceMilliseconds / (60 * 60 * 1000 * 24 * 7);
    long diffMonths = (long) (timeDifferenceMilliseconds / (60 * 60 * 1000 * 24 * 30.41666666));
    long diffYears = (long)(timeDifferenceMilliseconds / (1000 * 60 * 60 * 24 * 365));

    if (diffSeconds < 1) {
        return "one sec ago";
    } else if (diffMinutes < 1) {
        return diffSeconds + " seconds ago";
    } else if (diffHours < 1) {
        return diffMinutes + " minutes ago";
    } else if (diffDays < 1) {
        return diffHours + " hours ago";
    } else if (diffWeeks < 1) {
        return diffDays + " days ago";
    } else if (diffMonths < 1) {
        return diffWeeks + " weeks ago";
    } else if (diffYears < 12) {
        return diffMonths + " months ago";
    } else {
        return diffYears + " years ago";
    }
}   

答案 19 :(得分:4)

以下代码可以为您提供所需的输出:

String startDate = "Jan 01 2015";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MMM dd yyyy");
LocalDate date = LocalDate.parse(startDate, formatter);

String currentDate = "Feb 11 2015";
LocalDate date1 = LocalDate.parse(currentDate, formatter);

System.out.println(date1.toEpochDay() - date.toEpochDay());

答案 20 :(得分:3)

int daysDiff = (date1.getTime() - date2.getTime()) / MILLIS_PER_DAY;

答案 21 :(得分:3)

最好的办法是

(Date1-Date2)/86 400 000 

该数字是一天中毫秒的数量。

一个日期 - 其他日期为您提供毫秒差异。

double 变量中收集答案。

答案 22 :(得分:3)

注意:startDate和endDates是 - &gt; java.util.Date

import org.joda.time.Duration;
import org.joda.time.Interval;
Interval interval = new Interval(startDate.getTime(), endDate.getTime);
Duration period = interval.toDuration();
period.getStandardDays() //gives the number of days elapsed between start and end date

与天相似,您还可以获得小时,分钟和秒

period.getStandardHours();
period.getStandardMinutes();
period.getStandardSeconds();

答案 23 :(得分:2)

由于问题是用Scala标记的,

import scala.concurrent.duration._
val diff = (System.currentTimeMillis() - oldDate.getTime).milliseconds
val diffSeconds = diff.toSeconds
val diffMinutes = diff.toMinutes
val diffHours = diff.toHours
val diffDays = diff.toDays

答案 24 :(得分:2)

仔细研究了所有其他答案之后,要保留Java 7 Date类型,但要使用Java 8 diff方法更精确/标准,

public static long daysBetweenDates(Date d1, Date d2) {
    Instant instant1 = d1.toInstant();
    Instant instant2 = d2.toInstant();
    long diff = ChronoUnit.DAYS.between(instant1, instant2);
    return diff;
}

答案 25 :(得分:2)

这可能是最简单的方法 - 或许这是因为我已经用Java编写了一段时间(其公认的笨重的日期和时间库)一段时间了,但这段代码看起来“简单而美观”!

您对以毫秒为单位返回的结果感到满意,还是您希望以某种替代格式返回结果的问题的一部分?

答案 26 :(得分:2)

不使用标准API,没有。你可以自己做这样的事情:

class Duration {
    private final TimeUnit unit;
    private final long length;
    // ...
}

或者您可以使用Joda

DateTime a = ..., b = ...;
Duration d = new Duration(a, b);

答案 27 :(得分:2)

这是O(1)中没有任何依赖关系的正确Java 7解决方案。

public static int countDaysBetween(Date date1, Date date2) {

    Calendar c1 = removeTime(from(date1));
    Calendar c2 = removeTime(from(date2));

    if (c1.get(YEAR) == c2.get(YEAR)) {

        return Math.abs(c1.get(DAY_OF_YEAR) - c2.get(DAY_OF_YEAR)) + 1;
    }
    // ensure c1 <= c2
    if (c1.get(YEAR) > c2.get(YEAR)) {
        Calendar c = c1;
        c1 = c2;
        c2 = c;
    }
    int y1 = c1.get(YEAR);
    int y2 = c2.get(YEAR);
    int d1 = c1.get(DAY_OF_YEAR);
    int d2 = c2.get(DAY_OF_YEAR);

    return d2 + ((y2 - y1) * 365) - d1 + countLeapYearsBetween(y1, y2) + 1;
}

private static int countLeapYearsBetween(int y1, int y2) {

    if (y1 < 1 || y2 < 1) {
        throw new IllegalArgumentException("Year must be > 0.");
    }
    // ensure y1 <= y2
    if (y1 > y2) {
        int i = y1;
        y1 = y2;
        y2 = i;
    }

    int diff = 0;

    int firstDivisibleBy4 = y1;
    if (firstDivisibleBy4 % 4 != 0) {
        firstDivisibleBy4 += 4 - (y1 % 4);
    }
    diff = y2 - firstDivisibleBy4 - 1;
    int divisibleBy4 = diff < 0 ? 0 : diff / 4 + 1;

    int firstDivisibleBy100 = y1;
    if (firstDivisibleBy100 % 100 != 0) {
        firstDivisibleBy100 += 100 - (firstDivisibleBy100 % 100);
    }
    diff = y2 - firstDivisibleBy100 - 1;
    int divisibleBy100 = diff < 0 ? 0 : diff / 100 + 1;

    int firstDivisibleBy400 = y1;
    if (firstDivisibleBy400 % 400 != 0) {
        firstDivisibleBy400 += 400 - (y1 % 400);
    }
    diff = y2 - firstDivisibleBy400 - 1;
    int divisibleBy400 = diff < 0 ? 0 : diff / 400 + 1;

    return divisibleBy4 - divisibleBy100 + divisibleBy400;
}


public static Calendar from(Date date) {

    Calendar c = Calendar.getInstance();
    c.setTime(date);

    return c;
}


public static Calendar removeTime(Calendar c) {

    c.set(HOUR_OF_DAY, 0);
    c.set(MINUTE, 0);
    c.set(SECOND, 0);
    c.set(MILLISECOND, 0);

    return c;
}

答案 28 :(得分:2)

回答最初的问题:

将以下代码放在像Long getAge(){}

这样的函数中
Date dahora = new Date();
long MillisToYearsByDiv = 1000l *60l * 60l * 24l * 365l;
long javaOffsetInMillis = 1990l * MillisToYearsByDiv;
long realNowInMillis = dahora.getTime() + javaOffsetInMillis;
long realBirthDayInMillis = this.getFechaNac().getTime() + javaOffsetInMillis;
long ageInMillis = realNowInMillis - realBirthDayInMillis;

return ageInMillis / MillisToYearsByDiv;

这里最重要的是在乘法和除法时使用长数。当然,Java在其日期计算中应用的偏移量。

:)

答案 29 :(得分:1)

After having read many answers and comments to this question, I was left with the impression that one either has to use the Joda time or else take into account some peculiarities with the daylight saving time etc. Since I didn't want to do either of these, I ended up writing a few lines of code to calculate the difference between two dates without using any date or time related Java classes. In the code below the numbers of year, month and day are the same as in real life. For example in December 24th 2015, the year = 2015, the month = 12 and the day = 24. I want to share this code in case someone else wants to use it. There are 3 methods: 1) A method to find out whether a given year is a leap year 2) A method to calculate the number of a given day in relation to January 1st of a given year 3) A method to calculate the number of days between any two dates using the method 2 (number of the end date minus number of the start date). Here are the methods: 1) public static boolean isLeapYear (int year) { //Every 4. year is a leap year, except if the year is divisible by 100 and not by 400 //For example 1900 is not a leap year but 2000 is boolean result = false; if (year % 4 == 0) { result = true; } if (year % 100 == 0) { result = false; } if (year % 400 == 0) { result = true; } return result; } 2) public static int daysGoneSince (int yearZero, int year, int month, int day) { //Calculates the day number of the given date; day 1 = January 1st in the yearZero //Validate the input if (year < yearZero || month < 1 || month > 12 || day < 1 || day > 31) { //Throw an exception throw new IllegalArgumentException("Too many or too few days in month or months in year or the year is smaller than year zero"); } else if (month == 4 || month == 6 || month == 9 || month == 11) {//Months with 30 days if (day == 31) { //Throw an exception throw new IllegalArgumentException("Too many days in month"); } } else if (month == 2) {//February 28 or 29 if (isLeapYear(year)) { if (day > 29) { //Throw an exception throw new IllegalArgumentException("Too many days in month"); } } else if (day > 28) { //Throw an exception throw new IllegalArgumentException("Too many days in month"); } } //Start counting days int days = 0; //Days in the target month until the target day days = days + day; //Days in the earlier months in the target year for (int i = 1; i < month; i++) { switch (i) { case 1: case 3: case 5: case 7: case 8: case 10: case 12: days = days + 31; break; case 2: days = days + 28; if (isLeapYear(year)) { days = days + 1; } break; case 4: case 6: case 9: case 11: days = days + 30; break; } } //Days in the earlier years for (int i = yearZero; i < year; i++) { days = days + 365; if (isLeapYear(i)) { days = days + 1; } } return days; } 3) public static int dateDiff (int startYear, int startMonth, int startDay, int endYear, int endMonth, int endDay) { int yearZero; //daysGoneSince presupposes that the first argument be smaller or equal to the second argument if (10000 * startYear + 100 * startMonth + startDay > 10000 * endYear + 100 * endMonth + endDay) {//If the end date is earlier than the start date yearZero = endYear; } else { yearZero = startYear; } return daysGoneSince(yearZero, endYear, endMonth, endDay) - daysGoneSince(yearZero, startYear, startMonth, startDay); }

答案 30 :(得分:1)

使用以下方法,只使用两个Date个对象。如果你想传递当前日期,只需将new Date()作为第二个参数传递,因为它是用当前时间初始化的。

public String getDateDiffString(Date dateOne, Date dateTwo)
{
    long timeOne = dateOne.getTime();
    long timeTwo = dateTwo.getTime();
    long oneDay = 1000 * 60 * 60 * 24;
    long delta = (timeTwo - timeOne) / oneDay;

    if (delta > 0) {
        return "dateTwo is " + delta + " days after dateOne";
    }
    else {
        delta *= -1;
        return "dateTwo is " + delta + " days before dateOne";
     }
}

另外,除了天数之外,如果您还想要其他参数差异,请使用以下代码段,

int year = delta / 365;
int rest = delta % 365;
int month = rest / 30;
rest = rest % 30;
int weeks = rest / 7;
int days = rest % 7;

P.S代码完全取自SO答案。

答案 31 :(得分:1)

您可以尝试早期版本的Java。

 public static String daysBetween(Date createdDate, Date expiryDate) {

        Calendar createdDateCal = Calendar.getInstance();
        createdDateCal.clear();
        createdDateCal.setTime(createdDate);

        Calendar expiryDateCal = Calendar.getInstance();
        expiryDateCal.clear();
        expiryDateCal.setTime(expiryDate);


        long daysBetween = 0;
        while (createdDateCal.before(expiryDateCal)) {
            createdDateCal.add(Calendar.DAY_OF_MONTH, 1);
            daysBetween++;
        }
        return daysBetween+"";
    }

答案 32 :(得分:1)

由于您使用的是Scala,因此有一个非常好的Scala库Lamma。使用Lamma,您可以直接使用-运算符

减去日期
scala> Date(2015, 5, 5) - 2     // minus days by int
res1: io.lamma.Date = Date(2015,5,3)

scala> Date(2015, 5, 15) - Date(2015, 5, 8)   // minus two days => difference between two days
res2: Int = 7

答案 33 :(得分:1)

试试这个:

int epoch = (int) (new java.text.SimpleDateFormat("MM/dd/yyyy HH:mm:ss").parse("01/01/1970  00:00:00").getTime() / 1000);

你可以在parse()方法参数中编辑字符串。

答案 34 :(得分:0)

另一种纯Java变体:

here is exact solution for this

By default controllers, entities or repositories are not loaded
automatically.
You can autoload your modules using psr-4. For example :


 "autoload": {
    "psr-4": {
        "App\\": "app/",
        "Modules\\": "Modules/"
    }
},

 1) copy the above code and paste it in your Composer.json
 2) then do composer dumpautoload
 3) then do  php artisan module:use blog

感谢此处的初学者代码:https://stackoverflow.com/a/30207726/2162226

答案 35 :(得分:0)

如果您要解决日期范围超出了夏时制时间限制的问题(例如,夏季的一个日期和冬季的另一个日期),可以使用它来获取天差异

public static long calculateDifferenceInDays(Date start, Date end, Locale locale) {
    Calendar cal = Calendar.getInstance(locale);

    cal.setTime(start);
    cal.set(Calendar.HOUR_OF_DAY, 0);
    cal.set(Calendar.MINUTE, 0);
    cal.set(Calendar.SECOND, 0);
    cal.set(Calendar.MILLISECOND, 0);
    long startTime = cal.getTimeInMillis();

    cal.setTime(end);
    cal.set(Calendar.HOUR_OF_DAY, 0);
    cal.set(Calendar.MINUTE, 0);
    cal.set(Calendar.SECOND, 0);
    cal.set(Calendar.MILLISECOND, 0);
    long endTime = cal.getTimeInMillis();

    // calculate the offset if one of the dates is in summer time and the other one in winter time
    TimeZone timezone = cal.getTimeZone();
    int offsetStart = timezone.getOffset(startTime);
    int offsetEnd = timezone.getOffset(endTime);
    int offset = offsetEnd - offsetStart;

    return TimeUnit.MILLISECONDS.toDays(endTime - startTime + offset);
}

答案 36 :(得分:0)

这是另一个样本。这基本上适用于用户定义的模式。

   public static LinkedHashMap<String, Object> checkDateDiff(DateTimeFormatter dtfObj, String startDate, String endDate)
   {
          Map<String, Object> dateDiffMap = new HashMap<String, Object>();
          DateTime start = DateTime.parse(startDate,dtfObj);
          DateTime end = DateTime.parse(endDate,dtfObj);
          Interval interval = new Interval(start, end);
          Period period = interval.toPeriod();

          dateDiffMap.put("ISO-8601_PERIOD_FORMAT", period);
          dateDiffMap.put("YEAR", period.getYears());
          dateDiffMap.put("MONTH", period.getMonths());
          dateDiffMap.put("WEEK", period.getWeeks());
          dateDiffMap.put("DAY", period.getWeeks());             
          dateDiffMap.put("HOUR", period.getHours());
          dateDiffMap.put("MINUTE", period.getMinutes());
          dateDiffMap.put("SECOND", period.getSeconds());

          return dateDiffMap;        
   }

答案 37 :(得分:0)

在java中有一种简单的方法可以做到这一点

//创建一个实用工具方法

public long getDaysBetweenDates(Date d1, Date d2){
return TimeUnit.MILLISECONDS.toDays(d1.getTime() - d2.getTime());
}

此方法将返回两个日期之间的天数。您可以使用默认的Java日期格式,也可以从任何日期格式轻松转换。

答案 38 :(得分:0)

我喜欢基于TimeUnit的方法,直到我发现它只涵盖了下一个更高单元中一个时间单元的单元数量是固定的微不足道的情况。当你想知道中间有多少个月,一年等时,这就会分崩离析。

这是一种计数方法,不像其他方法那样有效,但它似乎对我有用并且也考虑了DST。

public static String getOffsetAsString( Calendar cNow, Calendar cThen) {
    Calendar cBefore;
    Calendar cAfter;
    if ( cNow.getTimeInMillis() < cThen.getTimeInMillis()) {
        cBefore = ( Calendar) cNow.clone();
        cAfter = cThen;
    } else {
        cBefore = ( Calendar) cThen.clone();
        cAfter = cNow;
    }
    // compute diff
    Map<Integer, Long> diffMap = new HashMap<Integer, Long>();
    int[] calFields = { Calendar.YEAR, Calendar.MONTH, Calendar.DAY_OF_MONTH, Calendar.HOUR_OF_DAY, Calendar.MINUTE, Calendar.SECOND, Calendar.MILLISECOND};
    for ( int i = 0; i < calFields.length; i++) {
        int field = calFields[ i];
        long    d = computeDist( cAfter, cBefore, field);
        diffMap.put( field, d);
    }
    final String result = String.format( "%dY %02dM %dT %02d:%02d:%02d.%03d",
            diffMap.get( Calendar.YEAR), diffMap.get( Calendar.MONTH), diffMap.get( Calendar.DAY_OF_MONTH), diffMap.get( Calendar.HOUR_OF_DAY), diffMap.get( Calendar.MINUTE), diffMap.get( Calendar.SECOND), diffMap.get( Calendar.MILLISECOND));
    return result;
}

private static int computeDist( Calendar cAfter, Calendar cBefore, int field) {
    cBefore.setLenient( true);
    System.out.print( "D " + new Date( cBefore.getTimeInMillis()) + " --- " + new Date( cAfter.getTimeInMillis()) + ": ");
    int count = 0;
    if ( cAfter.getTimeInMillis() > cBefore.getTimeInMillis()) {
        int fVal = cBefore.get( field);
        while ( cAfter.getTimeInMillis() >= cBefore.getTimeInMillis()) {
            count++;
            fVal = cBefore.get( field);
            cBefore.set( field, fVal + 1);
            System.out.print( count + "/"  + ( fVal + 1) + ": " + new Date( cBefore.getTimeInMillis()) + " ] ");
        }
        int result = count - 1;
        cBefore.set( field, fVal);
        System.out.println( "" + result + " at: " + field + " cb = " + new Date( cBefore.getTimeInMillis()));
        return result;
    }
    return 0;
}

答案 39 :(得分:0)

public static void main(String[] args) {

    String dateStart = "01/14/2012 09:29:58";
    String dateStop = "01/14/2012 10:31:48";

    SimpleDateFormat format = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");

    Date d1 = null;
    Date d2 = null;

    try {
        d1 = format.parse(dateStart);
        d2 = format.parse(dateStop);

        DateTime date11 = new DateTime(d1);
        DateTime date22 = new DateTime(d2);
        int days = Days.daysBetween(date11.withTimeAtStartOfDay(), date22.withTimeAtStartOfDay()).getDays();
        int hours = Hours.hoursBetween(date11, date22).getHours() % 24;
        int minutes = Minutes.minutesBetween(date11, date22).getMinutes() % 60;
        int seconds = Seconds.secondsBetween(date11, date22).getSeconds() % 60;
        if (hours > 0 || minutes > 0 || seconds > 0) {
            days = days + 1;
        }

        System.out.println(days);

    } catch (Exception e) {
        e.printStackTrace();
    }

}

这将给出同一天的日期差异

答案 40 :(得分:0)

@Michael Borgwardt的回答实际上在Android中无效。存在舍入错误。示例19到21月5日说是1天,因为它施放1.99到1.在转换为int之前使用round。

修复

int diffInDays = (int)Math.round(( (newerDate.getTime() - olderDate.getTime()) 
                 / (1000 * 60 * 60 * 24) ))

请注意,这适用于UTC日期,因此如果您查看本地日期,差异可能是休息日。并且由于夏令时,需要采用完全不同的方法使其与本地日期一起正常工作。

答案 41 :(得分:0)

以下是一种解决方案,因为我们可以通过多种方式实现这一目标:

  import java.util.*; 
   int syear = 2000;
   int eyear = 2000;
   int smonth = 2;//Feb
   int emonth = 3;//Mar
   int sday = 27;
   int eday = 1;
   Date startDate = new Date(syear-1900,smonth-1,sday);
   Date endDate = new Date(eyear-1900,emonth-1,eday);
   int difInDays = (int) ((endDate.getTime() - startDate.getTime())/(1000*60*60*24));

答案 42 :(得分:-1)

好消息。

有一种方法可以在不使用第三方工具的情况下在两个日期之间的日历日中获得差异。为此,您只需使用Java Calendar-class将日期轮换为一天。然后我们简单地计算两个日期之间的差异(以毫秒为单位)并将其除以一天(以毫秒为单位)。

public int getDiffernceInDays(long timeAfter, long timeBefore) {
    Calendar calendarAfter = Calendar.getInstance();
    calendarAfter.setTime(new Date(timeAfter));

    Calendar calendarNewAfter = Calendar.getInstance();
    calendarNewAfter.set(calendarAfter.get(Calendar.YEAR), calendarAfter.get(Calendar.MONTH), calendarAfter.get(Calendar.DAY_OF_MONTH));

    Calendar calendarBefore = Calendar.getInstance();
    calendarBefore.setTime(new Date(timeBefore));

    Calendar calendarNewBefore = Calendar.getInstance();
    calendarNewBefore.set(calendarBefore.get(Calendar.YEAR), calendarBefore.get(Calendar.MONTH), calendarBefore.get(Calendar.DAY_OF_MONTH));

    return (int) ((calendarNewAfter.getTime().getTime() - calendarNewBefore.getTime().getTime()) / (24 * 60 * 60 * 1000));
}

答案 43 :(得分:-2)

只需在每个上调用getTime,取差值,然后除以一天中的毫秒数。

答案 44 :(得分:-3)

如果您的日期为d1和d2,则最佳解决方案可能如下:

int days1 = d1.getTime()/(60*60*24*1000);//find the number of days since the epoch.
int days2 = d2.getTime()/(60*60*24*1000);

然后再说

days2-days1

或其他什么