計算兩個Java日期實例之間的差異


Answers

簡單差異(無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();
    List<TimeUnit> units = new ArrayList<TimeUnit>(EnumSet.allOf(TimeUnit.class));
    Collections.reverse(units);
    Map<TimeUnit,Long> result = new LinkedHashMap<TimeUnit,Long>();
    long milliesRest = diffInMillies;
    for ( TimeUnit unit : units ) {
        long diff = unit.convert(milliesRest,TimeUnit.MILLISECONDS);
        long diffInMilliesForUnit = unit.toMillis(diff);
        milliesRest = milliesRest - diffInMilliesForUnit;
        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小時經過時間的數量:天+ 1天= 1天= 24小時

  • 計算經過時間的數量,照顧夏令時:天+ 1天= 1 = 24小時(但使用午夜時間和夏令時可以是0天和23小時)

  • 計算day switches的數量,這意味著即使經過的時間僅為2小時(或者如果存在夏令時:p,則為1天),即日期+ 1 1pm - 上午11am = 1天,

如果您的日期差異定義與第一種情況相符,我的回答是有效的

隨著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()
Question

我在Scala中使用Java的java.util.Date類,想要比較Date對象和當前時間。 我知道我可以使用getTime()來計算增量:

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

但是,這只會讓我有很long代表毫秒。 有沒有更簡單,更好的方法來獲得時間增量?




Best thing to do is

(Date1-Date2)/86 400 000 

That number is the number of milliseconds in a day.

One date-other date gives you difference in milliseconds.

Collect the answer in a double variable.







Just to answer the initial question:

Put the following code in a Function like 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;

The most important here is to work with long numbers when multiplying and dividing. And of course, the offset that Java applies in its calculus of Dates.

:)




您可以嘗試更早版本的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+"";
    }



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



如果你需要一個格式化的返回字符串,比如“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;
}



Not using the standard API, no. You can roll your own doing something like this:

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

Or you can use Joda :

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



看看Joda Time ,這是一個改進的Java日期/時間API,應該可以很好地與Scala一起工作。




稍簡單一些的選擇:

System.currentTimeMillis() - oldDate.getTime()

至於“更好”:那麼,你到底需要什麼? 將時間持續時間表示為小時數和天數等問題在於,由於日期的複雜性(例如由於夏令時可能有23或25小時),它可能導致不准確和錯誤的期望。




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



你需要更清楚地定義你的問題。 您可以將兩個Date對象之間的毫秒數除以24小時內的毫秒數,例如...但:

  • 這不會考慮時區 - Date始終以UTC
  • 這不會考慮夏令時(例如,可能有隻有23小時的日子)
  • 即使在UTC內,8月16日晚上11點到8月18日凌晨2點還有多少天? 這只有27個小時,這是否意味著某一天? 還是應該是三天,因為它涵蓋了三個日期?



有很多方法可以找到日期和時間之間的差異。 我知道的最簡單的方法之一是:

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

打印語句只是一個例子 - 你可以按照你喜歡的方式格式化它。




以毫秒為單位減去日期(如另一篇文章中所述),但在清除日期的時間部分時,您必須使用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
}



Since you are using Scala, there is a very good Scala library Lamma . With Lamma you can minus date directly with - operator

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



Links