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

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

然而,这只给我留下一个长表示毫秒。有没有更简单,更好的方法来得到时间?


当前回答

让我来看看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 

其他回答

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";
    }
}   

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

Since dates can contain hours and minutes, final result will be rounded down, which will result in incorrect value. For example, you calculate difference between today at 22:00 p.m and day after tomorrow 00:00 a.m, so the final result will be 1, because in reality it was 1.08 or smth difference, then it gets rounded down when calling TimeUnit.MILLISECONDS.toDays(..). That's why you need to take that in account, so in my solution I subtract the remainder of milliseconds from milliseconds in a day. Additionally, if you want to count the end date, you need to +1 it.

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

看看Joda Time,它是一个改进的Java日期/时间API,应该可以很好地与Scala一起工作。

@Michael Borgwardt的回答实际上在Android上不能正常运行。存在舍入错误。例如5月19日到21日是1天,因为它是1.99:1。在转换为int型之前使用round。

Fix

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

请注意,这适用于UTC日期,因此如果查看本地日期,差异可能会减小一天。由于夏时制的原因,要让它在本地日期上正确工作,需要一种完全不同的方法。