在我的应用程序中,有一个计算来获得两个日期之间的天数。计算如下:
private int getDateDiff(Date currentDate, Date previousDate){
Calendar currDateCal = Calendar.getInstance();
currDateCal.clear();
currDateCal.setTime(currentDate);
Calendar previousDateCal = Calendar.getInstance();
previousDateCal.clear();
previousDateCal.setTime(previousDate);
long milisecond1 = currDateCal.getTimeInMillis();
long milisecond2 = previousDateCal.getTimeInMillis();
// Find date difference in milliseconds
long diffInMSec = milisecond1 - milisecond2;
// Find date difference in days
// (24 hours 60 minutes 60 seconds 1000 millisecond)
long diffOfDays = diffInMSec / (24 * 60 * 60 * 1000);
return (int)diffOfDays;
}
这个方法返回正确的值(例如,对于2015-03-10 00:00:00.0,2015-03-02 00:00:00.0,从存储库检索并传递给方法的值为8)在我的本地pc上,windows 7, 64位。但是,此方法在位于加拿大的pc (Windows 7, 64位)上返回不正确的值(即7 for 2015-03-10 00:00:00.0, 2015-03-02 00:00:00.0)
本地PC使用的JDK信息为;
java version "1.7.0"
Java(TM) SE运行环境(build 1.7.0-b147)
Java HotSpot(TM) 64位Server VM (build 21.0-b17, mixed mode)
加拿大PC使用的JDK信息为;
java version "1.7.0_17"
Java(TM) SE Runtime Environment (build 1.7.0_17-b02)
Java HotSpot(TM) Client VM (build 23.7-b01,混合模式,共享)
我知道;
1) Date/Timestamp类表示时间上的特定时刻,从1970年1月1日00:00:00 GMT开始,以毫秒精度,因此这个时间差(从epoch到当前时间)在世界各地的所有计算机中都是相同的,无论时区如何。
2)它不知道给定的时间在哪个时区。
3)如果我们想要基于时区的时间,我们应该在java中使用Calendar或SimpleDateFormat。4)如果你试图打印日期/时间戳对象(to String),它将转换并打印时间与您的机器的默认时区。
5)所以我们可以说(Date/Timestamp).getTime()对象将始终具有UTC(毫秒时间)
6)总之,Date.getTime()将给出UTC时间。但是toString()使用的是特定于地区的时区,而不是UTC。
有人看到这个计算的问题吗?
手动计算与日期相关的东西很容易出错,正如您已经发现的那样。今年的夏时制于3月8日在加拿大开始,所以当你的日期所在的时区在加拿大时,你会少一个小时。我怀疑你的其他位置没有夏令时变化,或者它发生在不同的一天(例如在英国发生在3月29日)。
您应该使用内置方法来计算两个日期之间经过的天数。这可以通过Calendar类完成,但是使用新的Java time API (Java 8+)或joda time可能会省去一些麻烦。例如在Java 8中:
ZonedDateTime start = LocalDate.of(2015, 3, 2).atStartOfDay(UTC);
ZonedDateTime end = LocalDate.of(2015, 3, 10).atStartOfDay(UTC);
long days = DAYS.between(start, end); //8
有人看到这个计算的问题吗?
是的,很多,毫秒的差异是不可靠的,原因有很多,包括夏令时(+1亚历),闰年/秒,世纪和千年的边界和其他问题
在可能的情况下使用专用库。如果要使用Java 8,请使用新的Time API,否则请使用Joda-Time
DateTime startDate = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss.S").
parseDateTime("2015-03-10 00:00:00.0");
DateTime endDate = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss.S").
parseDateTime("2015-03-02 00:00:00.0");
Period p = new Period(endDate, startDate);
System.out.println(p.getWeeks() + ", " + p.getDays());
Duration duration = new Duration(endDate, startDate);
System.out.println(duration.getStandardDays());
System.out.println(duration.getStandardHours());
System.out.println(duration.getStandardMinutes());
输出……
1, 1 // Week, days
8 // days
192 // hours
11520 // minutes