我想以两个日期之间的天数形式计算时间差。所以我写了以下代码:
public static int calculateTimeGap(long start, long end) {
GregorianCalendar calendar1 = new GregorianCalendar();
calendar1.setTimeInMillis(start);
System.out.println("calendar1:");
showCalendar(calendar1);
GregorianCalendar calendar2 = new GregorianCalendar();
calendar2.setTimeInMillis(end);
System.out.println("calendar2:");
showCalendar(calendar2);
int gap = (int) (end / 86400000 - start / 86400000);
System.out.println("gap in days:" + gap);
return gap;
}
以下是输出:
03-02 15:28:08.021 20814-20814/com.ywwynm.everythingdone I/System.out: calendar1:
03-02 15:28:08.021 20814-20814/com.ywwynm.everythingdone I/System.out: year: 2016
03-02 15:28:08.021 20814-20814/com.ywwynm.everythingdone I/System.out: month: 3
03-02 15:28:08.021 20814-20814/com.ywwynm.everythingdone I/System.out: day: 2
03-02 15:28:08.021 20814-20814/com.ywwynm.everythingdone I/System.out: week: 3
03-02 15:28:08.021 20814-20814/com.ywwynm.everythingdone I/System.out: hour: 15
03-02 15:28:08.021 20814-20814/com.ywwynm.everythingdone I/System.out: minute: 28
03-02 15:28:08.021 20814-20814/com.ywwynm.everythingdone I/System.out: second: 8
03-02 15:28:08.021 20814-20814/com.ywwynm.everythingdone I/System.out:
03-02 15:28:08.021 20814-20814/com.ywwynm.everythingdone I/System.out: calendar2:
03-02 15:28:08.021 20814-20814/com.ywwynm.everythingdone I/System.out: year: 2016
03-02 15:28:08.021 20814-20814/com.ywwynm.everythingdone I/System.out: month: 3
03-02 15:28:08.022 20814-20814/com.ywwynm.everythingdone I/System.out: day: 3
03-02 15:28:08.022 20814-20814/com.ywwynm.everythingdone I/System.out: week: 4
03-02 15:28:08.022 20814-20814/com.ywwynm.everythingdone I/System.out: hour: 1
03-02 15:28:08.022 20814-20814/com.ywwynm.everythingdone I/System.out: minute: 0
03-02 15:28:08.022 20814-20814/com.ywwynm.everythingdone I/System.out: second: 0
03-02 15:28:08.022 20814-20814/com.ywwynm.everythingdone I/System.out:
03-02 15:28:08.022 20814-20814/com.ywwynm.everythingdone I/System.out: gap in days:0
你可以看到两个GregorianCalendar
呈现不同的日子,但最后我们得到一个等于0的差距。
此方法的参数start
和end
来自以下代码:
GregorianCalendar curCalendar = new GregorianCalendar();
long start = curCalendar.getTimeInMillis(); // parameter start
GregorianCalendar calendar = new GregorianCalendar(2016, Calendar.MARCH, 3, 1, 0);
long end = calendar.getTimeInMillis(); // parameter end
所以行为很奇怪。我认为gregorianCalendar.getTimeInMillis()
将始终返回正确且与时区无关的值,以便它可以用作计算和比较时间的稳定且值得信赖的标准。但是,如图所示的代码和输出,这是错误的。如果我考虑了我的时区(北京GMT + 8:00),请将Timezone.getDefault().getRawOffset()
的偏移量添加到参数start
或将其减去end
,结果将是正确的。但这实际上很奇怪。
是什么让我得到错误的结果?
更新
public static void showCalendar(GregorianCalendar calendar) {
System.out.println("year: " + calendar.get(Calendar.YEAR));
System.out.println("month: " + (calendar.get(Calendar.MONTH) + 1));
System.out.println("day: " + calendar.get(Calendar.DATE));
System.out.println("week: " + (calendar.get(Calendar.DAY_OF_WEEK) - 1));
System.out.println("hour: " + calendar.get(Calendar.HOUR_OF_DAY));
System.out.println("minute: " + calendar.get(Calendar.MINUTE));
System.out.println("second: " + calendar.get(Calendar.SECOND));
System.out.println(" ");
}
答案 0 :(得分:1)
你可以看到两个GregorianCalendars呈现不同的日子,但最后我们得到一个等于0的差距。
是的,那是完全合理的。您将3月2日15:28:08与3月3日01:00:00进行比较。他们在不同的日期,但相隔不到一天。这里没问题。
哎呀,你可以看到相同的两个值只是一毫秒 - 他们仍然可以在不同的日期。
请注意,就时区而言,默认情况下GregorianCalendar
将使用您的系统默认时区。 getTimeInMillis
返回的值将始终返回自Unix纪元以来的毫秒数,因此该时区是中性的 - 但是您在此处调用的构造函数:
new GregorianCalendar(2016, Calendar.MARCH, 3, 1, 0)
...正在说"我希望代表3月3日,凌晨1点当地时间"其中当地时间表示"在您的默认时区"。
计算日期之间的差异很困难 - 我非常强烈建议您完全抛弃Calendar
和Date
,而不是java.time
如果你&#39 ;重新使用Java 8,否则使用Joda Time。然后,您可以使用LocalDate
来表示没有时间的日期,并轻松找到两个日期之间的差异。
答案 1 :(得分:0)
您所测量的不是天数的差距,正如您所定义的那样。您测量的是开始和结束之间的完整24小时的数量。
在您的示例中,您的结束时间实际上距离开始时间不到24小时。所以你24小时的距离是0。
如果要测量当前时区午夜定义的天数差异,即天数之间的界限,则应该比较两个日历对象的DAY_OF_YEAR和YEAR值。