Calender.getTimeInMillis()方法在不同的位置返回不同的值

时间:2015-05-26 05:48:11

标签: java datetime

在我的应用程序中,有一个计算可以获得两个日期之间的天数。计算如下:

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,从存储库中检索并传递给方法的值), Windows 7,64位。但是,此方法在位于加拿大的PC(Windows 7,64位)返回不正确的值(即2015-03-10 00:00:00.0,2015-03-02 00:00:00.0为7)

在本地PC上使用的JDK信息是;

java版“1.7.0”
Java(TM)SE运行时环境(版本1.7.0-b147)
Java HotSpot(TM)64位服务器VM(版本21.0-b17,混合模式)

加拿大个人电脑使用的JDK信息是;

java版“1.7.0_17”
Java(TM)SE运行时环境(版本1.7.0_17-b02)
Java HotSpot(TM)客户端VM(构建23.7-b01,混合模式,共享)

我知道;

1)类Date / Timestamp表示一个特定的时刻,自1970年1月1日00:00:00 GMT以来具有毫秒精度,所以这个时间差(从纪元到当前时间)将是相同的计算机遍布全球,与时区无关。
2)它不知道给定的时间是在哪个时区。
3)如果我们想要基于时区的时间,我们应该在java中使用Calendar或SimpleDateFormat 4)如果您尝试打印日期/时间戳对象(至字符串),它将使用您机器的默认时区转换并打印时间。
5)所以我们可以说(日期/时间戳).getTime()对象将始终具有UTC(以毫秒为单位的时间)
6)总结Date.getTime()将给出UTC时间。但是toString()是在特定于语言环境的时区而不是UTC。

有人看到这个计算的问题吗?我坚持这个。

2 个答案:

答案 0 :(得分:3)

正如您所发现的那样,手动计算与日期相关的事情很容易出错。 DST于今年3月8日在加拿大开始,所以当你的日期时区在那个国家时,你错过了一个小时。我怀疑你的其他位置没有DST更改,或者发生在另一天(例如3月29日发生在英国)。

您应该使用内置方法来计算两个日期之间经过的天数。它可以使用Calendar类完成,但使用新的Java时间API(Java 8+)或joda时间可能会让您省去一些麻烦。例如,使用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 :(得分:1)

  

有人看到这个计算的问题吗?

是的,由于多种原因,包括夏令时(+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