Java中的日历...我得到两个不同值的相同结果

时间:2013-11-21 00:52:31

标签: java calendar

    Calendar cal = Calendar.getInstance();
    long now = cal.getTimeInMillis();
    int year = 2014;
    int month = 3;
    int date = 8;
    cal.set(year, month - 1, date);
    long dday = cal.getTimeInMillis();
    long count = (dday - now) / (1000 * 24 * 60 * 60);
    System.out.println((dday - now));
    System.out.println(count);

此代码指出从现在到日期之间的天数。 但是,我在3月8日和3月9日得到了相同的结果。 请帮忙! 提前谢谢。


更详细的源代码示例,作者:Basil Bourque。

Calendar cal = Calendar.getInstance();
long nowInMillis = cal.getTimeInMillis();

cal.set( 2014, Calendar.MARCH, 8 );  // March 8, 2014   // year, month, day
long march_8_2014_inMillis = cal.getTimeInMillis();

cal.set( 2014,  Calendar.MARCH, 9 );  // March 9, 2014   // year, month, day
long march_9_2014_inMillis = cal.getTimeInMillis();

long daysTil8th = ( march_8_2014_inMillis - nowInMillis ) / ( 1000 * 24 * 60 * 60 );
long daysTil9th = ( march_9_2014_inMillis - nowInMillis ) / ( 1000 * 24 * 60 * 60 );

System.out.println( "( march_8_2014_inMillis - nowInMillis ) in artificial days: " + daysTil8th + ", in milliseconds: " + ( march_8_2014_inMillis - nowInMillis ) );
System.out.println( "( march_9_2014_inMillis - nowInMillis ) in artificial days: " + daysTil9th + ", in milliseconds: " + ( march_9_2014_inMillis - nowInMillis ) );

System.out.println( "( march_9_2014_inMillis - nowInMillis ) - ( march_8_2014_inMillis - nowInMillis ): " + ( ( march_9_2014_inMillis - nowInMillis ) - ( march_8_2014_inMillis - nowInMillis ) ) ) ;
System.out.println( "( march_9_2014_inMillis - nowInMillis ) - ( march_8_2014_inMillis - nowInMillis ) / ( 1000 * 60 * 60 ): " + ( ( march_9_2014_inMillis - nowInMillis ) - ( march_8_2014_inMillis - nowInMillis ) ) / ( 1000 * 60 * 60 ) ) ;

在西雅图,Java 7,Mac OS X 10.8.5上运行时2013-11-20T17:35:01.119-08:00(太平洋标准时间)......

( march_8_2014_inMillis - nowInMillis ) in artificial days: 108, in milliseconds: 9331200000
( march_9_2014_inMillis - nowInMillis ) in artificial days: 108, in milliseconds: 9414000000
( march_9_2014_inMillis - nowInMillis ) - ( march_8_2014_inMillis - nowInMillis ): 82800000
( march_9_2014_inMillis - nowInMillis ) - ( march_8_2014_inMillis - nowInMillis ) / ( 1000 * 60 * 60 ): 23

注意:对于我的时区,DST将于2014年3月9日星期日凌晨2:00开始。

问题:为什么上面两行输出中都有108?答案是夏令时,但究竟是怎么回事?

2 个答案:

答案 0 :(得分:3)

3月9日是夏令时将在2014年转换的日子。因此,计算结果是正确的,3月9日的差异是108天23小时,即108天。

答案 1 :(得分:0)

正如Jim Garrison在his correct answer中所说,基于整数的数学(1000 * 24 * 60 * 60)假设一天24小时。对于我们这些在Daylight Saving Time(DST)的非理性实践的时区而言,情况并非如此。在美国的时区8日至9日之间是23小时,而不是24小时。

经验教训:

  • 永远不要做自己的日期和时间数学。
  • 永远不要使用java.util.Date& .Calendar捆绑在Java中。
  • 始终在Java 8中使用合适的库,例如Joda-Time或新的JSR 310

这是使用Joda-Time 2.3在Java 7中解决的相同问题,以及正确的输出。

// © 2013 Basil Bourque. This source code may be used freely forever by anyone taking full responsibility for doing so.

// Using US west coast time zone because March 9, 2014 at 02:00 is the start of DST Daylight Saving Time.
org.joda.time.DateTimeZone californiaTimeZone = org.joda.time.DateTimeZone.forID("America/Los_Angeles");

org.joda.time.DateTime now = new org.joda.time.DateTime(californiaTimeZone);

// Note the arbitrary choice of times (14 & 21 hours) assigned to new DateTimes.
org.joda.time.DateTime march_8_2014 = new org.joda.time.DateTime( 2014, 3, 8, 14, 0);
org.joda.time.DateTime march_9_2014 = new org.joda.time.DateTime( 2014, 3, 9, 21, 0);

int daysUntil8th = org.joda.time.Days.daysBetween( now , march_8_2014 ).getDays();
int daysUntil9th = org.joda.time.Days.daysBetween( now , march_9_2014 ).getDays();

// If you want whole days, call 'withTimeAtStartOfDate()' method.
// Don't get clever with trying to set a midnight time. Not every day in every time zone has a midnight.
int daysUntil8thStarts = org.joda.time.Days.daysBetween( now , march_8_2014.withTimeAtStartOfDay() ).getDays();
int daysUntil9thStarts = org.joda.time.Days.daysBetween( now , march_9_2014.withTimeAtStartOfDay() ).getDays();

System.out.println("Now in 'America/Los_Angeles' (Pacific Standard Time): " + now );

System.out.println("Days until " +  march_8_2014 + ": " + daysUntil8th );
System.out.println("Days until " + march_9_2014 + ": " + daysUntil9th );

System.out.println("Days until March 8, 2014 starts: " + daysUntil8thStarts );
System.out.println("Days until March 9, 2014 starts: " + daysUntil9thStarts );

跑步时......

Now in 'America/Los_Angeles' (Pacific Standard Time): 2013-11-20T18:25:06.424-08:00
Days until 2014-03-08T14:00:00.000-08:00: 107
Days until 2014-03-09T21:00:00.000-07:00: 109
Days until March 8, 2014 starts: 107
Days until March 9, 2014 starts: 108

注意:时间会影响天数。通知107& 109对107& 108,两天天差异与一天天差异。