477

java.util.Date在 Scala 中使用 Java 的类,想比较一个Date对象和当前时间。我知道我可以使用 getTime() 计算增量:

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

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

4

45 回答 45

597

简单的差异(没有库)

/**
 * 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,从 nanos 到 days 的标准 Java 枚举。


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

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},单位是有序的。

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


警告

上面的代码片段计算了两个瞬间之间的简单差异。它可能会在夏令时切换期间引起问题,如本文所述。这意味着如果您计算没有时间的日期之间的差异,您可能会丢失一天/小时。

在我看来,日期差异有点主观,尤其是在日子里。你可以:

  • 计算 24 小时经过的时间:day+1 - day = 1 day = 24h

  • 计算经过的时间,注意夏令时:day+1 - day = 1 = 24h(但使用午夜时间和夏令时可能是 0 天和 23h)

  • 计算 的数量day switches,这意味着天 + 1 下午 1 点 - 天 11 上午 = 1 天,即使经过的时间只有 2 小时(如果有夏令时,则为 1 小时:p)

如果您对日期差异的定义与第一种情况相匹配,我的回答是有效的

与乔达时间

如果您使用的是 JodaTime,您可以通过以下方式获得 2 个瞬间(由 Millies 支持的 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()
于 2012-05-18T10:25:32.027 回答
215

不幸的是,JDK DateAPI 被严重破坏了。我推荐使用Joda Time library

Joda Time 有一个时间间隔的概念:

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

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

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

于 2009-10-12T15:43:21.807 回答
161
int diffInDays = (int)( (newerDate.getTime() - olderDate.getTime()) 
                 / (1000 * 60 * 60 * 24) )

请注意,这适用于 UTC 日期,因此如果您查看当地日期,差异可能是一天。由于夏令时,让它与当地日期正常工作需要完全不同的方法。

于 2010-08-16T08:49:36.430 回答
75

使用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 教程ISO 8601标准。

于 2014-04-20T16:00:11.427 回答
58
于 2014-03-23T07:50:20.210 回答
54

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

  • 这不会考虑时区 -Date始终采用 UTC
  • 这不会考虑夏令时(例如,可能有几天只有 23 小时)
  • 即使在 UTC 中,8 月 16 日晚上 11 点到 8 月 18 日凌晨 2 点有多少天?只有27小时,所以是一天吗?还是应该是三天,因为它涵盖了三个日期?
于 2010-08-16T08:47:58.233 回答
39
Days d = Days.daysBetween(startDate, endDate);
int days = d.getDays();

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

于 2010-12-28T20:38:15.870 回答
24

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

System.currentTimeMillis() - oldDate.getTime()

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

于 2009-10-12T15:51:23.693 回答
23

使用毫秒方法可能会在某些语言环境中导致问题。

例如,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;  
}  
于 2011-11-21T09:26:20.053 回答
23

有很多方法可以找到日期和时间之间的差异。我知道的最简单的方法之一是:

      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 语句只是一个例子——你可以按照你喜欢的方式来格式化它。

于 2012-04-03T05:30:18.450 回答
22

由于这里的所有答案都是正确的,但使用的是旧版 java 或 joda 或类似的 3rd 方库,因此我将放弃另一种方式,使用 Java 8 及更高版本中的新java.time类。请参阅Oracle 教程

使用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 );
于 2017-05-18T08:19:29.360 回答
9

如果您不想使用 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 和闰秒之外的奇怪时间跳跃)。

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

于 2010-08-30T14:13:56.970 回答
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
}
于 2013-08-12T08:05:43.767 回答
8

看看Joda Time,这是一个改进的 Java 日期/时间 API,应该可以在 Scala 中正常工作。

于 2009-10-12T15:43:30.183 回答
5
int daysDiff = (date1.getTime() - date2.getTime()) / MILLIS_PER_DAY;
于 2010-08-16T08:48:18.093 回答
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 
于 2012-02-06T03:47:51.693 回答
5

如果您需要像“2 Days 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;
}
于 2013-10-04T03:16:23.463 回答
5

注意: startDate 和 endDates 是 -> java.util.Date

import org.joda.time.Duration;
import org.joda.time.Interval;
// Use .getTime() unless it is a joda DateTime object
Interval interval = new Interval(startDate.getTime(), endDate.getTime());
Duration period = interval.toDuration();
//gives the number of days elapsed between start 
period.getStandardDays();

和结束日期

类似于天,你也可以得到小时、分钟和秒

period.getStandardHours();
period.getStandardMinutes();
period.getStandardSeconds();
于 2015-01-06T19:35:57.540 回答
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.");
    }
}
于 2010-08-16T08:48:48.963 回答
4

使用 GMT 时区获取 Calendar 的实例,使用 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));
于 2011-12-27T17:21:58.457 回答
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());
于 2015-02-19T07:44:58.107 回答
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";
    }
}   
于 2015-08-24T07:31:10.307 回答
3

最好的办法是

(Date1-Date2)/86 400 000 

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

一个日期-另一个日期给你以毫秒为单位的差异。

在双变量中收集答案。

于 2014-10-27T13:53:14.883 回答
3

这是 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;
}
于 2017-04-28T13:54:09.603 回答
3

在浏览了所有其他答案之后,为了保持 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;
}
于 2018-11-05T17:05:29.350 回答
2

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

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

或者你可以使用Joda

DateTime a = ..., b = ...;
Duration d = new Duration(a, b);
于 2009-10-12T15:41:47.490 回答
2

这可能是最直接的方法——也许是因为我已经用 Java 编码(带有公认的笨拙的日期和时间库)有一段时间了,但这段代码对我来说看起来“简单而漂亮”!

您是否对以毫秒为单位返回的结果感到满意,或者您希望以其他格式返回结果的一部分?

于 2009-10-12T15:44:20.400 回答
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 在其日期计算中应用的偏移量。

:)

于 2015-08-21T12:11:02.370 回答
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
于 2015-11-24T12:12:48.517 回答
2

如果您想解决跨越夏令时边界的日期范围的问题(例如,一个日期在夏季时间,另一个日期在冬季时间),您可以使用它来获取天数差异

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);
}
于 2019-02-14T15:51:13.750 回答
1

试试这个:

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

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

于 2013-03-11T09:10:08.310 回答
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
于 2014-06-10T21:06:54.567 回答
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;

PS Code 完全取自 SO 答案。

于 2015-10-05T10:43:31.497 回答
1

在阅读了这个问题的许多答案和评论后,我的印象是要么必须使用 Joda 时间,要么要考虑夏令时的一些特殊性等。因为我不想做任何一个这些,我最终编写了几行代码来计算两个日期之间的差异,而不使用任何与日期或时间相关的 Java 类。

在下面的代码中,年、月和日的数字与现实生活中的相同。例如,在 2015 年 12 月 24 日,年 = 2015,月 = 12,日 = 24。

我想共享此代码以防其他人想使用它。有 3 种方法: 1) 找出给定年份是否是闰年的方法 2) 计算与给定年份的 1 月 1 日相关的给定日期的方法 3) 计算日期数量的方法使用方法 2(结束日期数减去开始日期数)的任意两个日期之间的天数。

以下是方法:

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);

}
于 2015-10-31T00:15:09.763 回答
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+"";
    }
于 2016-10-26T15:12:52.393 回答
0

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

于 2010-08-16T08:48:00.807 回答
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));
于 2012-03-19T09:31:32.933 回答
0

@Michael Borgwardt 的答案实际上在 Android 中无法正常工作。存在舍入错误。示例 5 月 19 日至 21 日表示 1 天,因为它将 1.99 转换为 1。在转换为 int 之前使用 round。

使固定

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

请注意,这适用于 UTC 日期,因此如果您查看当地日期,差异可能是一天。由于夏令时,让它与当地日期正常工作需要完全不同的方法。

于 2013-05-01T14:54:25.523 回答
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();
    }

}

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

于 2014-11-22T15:59:57.830 回答
0

我喜欢基于 TimeUnit 的方法,直到我发现它只涵盖了一个 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;
}
于 2014-12-19T16:42:14.703 回答
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;        
   }
于 2015-01-29T03:43:53.980 回答
0

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

//创建一个实用方法

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

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

于 2015-10-27T12:30:55.187 回答
0

另一个纯 Java 变体:

public boolean isWithin30Days(Calendar queryCalendar) {

    // 1. Take the date you are checking, and roll it back N days
    Calendar queryCalMinus30Days = Calendar.getInstance();
    queryCalMinus30Days.setTime(queryCalendar.getTime());
    queryCalMinus30Days.add(Calendar.DATE, -30); // subtract 30 days from the calendar

    // 2. Get respective milliseconds for the two Calendars: now & queryCal minus N days 
    long nowL = Calendar.getInstance().getTimeInMillis();
    long queryCalMinus30DaysL = queryCalMinus30Days.getTimeInMillis();

    // 3. if nowL is still less than the queryCalMinus30DaysL, it means queryCalendar is more than 30 days into future
    boolean isWithin30Days = nowL >= queryCalMinus30DaysL;

    return isWithin30Days;
}

感谢这里的入门代码:https ://stackoverflow.com/a/30207726/2162226

于 2017-01-05T06:34:15.807 回答
-1

由于日期可以包含小时和分钟,因此最终结果将四舍五入,这将导致值不正确。例如,你计算今天 22:00 pm后天 00:00 am之间的差值,所以最终结果将是 1,因为实际上它是 1.08或 smth差值,然后在调用时将它向下舍入TimeUnit.MILLISECONDS.toDays(..)。这就是为什么你需要考虑到这一点,所以在我的解决方案中,我从一天中的毫秒数中减去剩余的毫秒数。此外,如果要计算结束日期,则需要 +1。

import java.util.Date;
import java.util.concurrent.TimeUnit;

public static long getDaysBetween(Date date1, Date date2, boolean includeEndDate) {
        long millisInDay = 60 * 60 * 24 * 1000;
        long difference = Math.abs(date1.getTime() - date2.getTime());
        long add = millisInDay - (difference % millisInDay);//is used to calculate true number of days, because by default hours, minutes are also counted

        return TimeUnit.MILLISECONDS.toDays(difference + add) + (includeEndDate ? 1 : 0);
    }

测试:

Date date1 = new Date(121, Calendar.NOVEMBER, 27); //2021 Nov 27
Date date2 = new Date(121, Calendar.DECEMBER, 29); //2021 Dec 29
System.out.println( getDaysBetween(date1, date2, false) ); //32 days difference
System.out.println( getDaysBetween(date1, date2, true) ); //33 days difference
于 2021-11-27T20:27:14.057 回答
-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

管他呢

于 2010-08-16T08:48:20.913 回答