Date d = new Date(today.getTimeInMillis());
Date d1 = new Date(dueDate.getTimeInMillis());
int daysUntil = (int) ((d1.getTime() - d.getTime())/ (1000 * 60 * 60 * 24));
使用上面的代码,其中today
是当天设置为00:00的日历,dueDate
在我今天比较的日期设置为00:00,我的结果从这个不同。
这里有一些变化,使我的输出为x或x + 1,其中x是正确的答案。
这里有什么问题,我该怎么做才能让它更稳定?
答案 0 :(得分:1)
您没有提供实际值,因此我们无法准确确定问题。我们不知道today
和dueDate
变量是什么。
现在问题已经过时了,因为新的java.time框架取代了包括java.util.Date/.Calendar在内的麻烦的旧日期时间类。见Tutorial。由JSR 310定义,受Joda-Time启发,并由ThreeTen-Extra项目扩展。
在java.time中:
Instant
是UTC时间轴上的一个时刻。ZoneId
表示时区。使用正确的时区名称,不要使用3-4字母代码,例如" EST"或者" IST"因为它们既不标准也不独特。ZonedDateTime
= Instant + ZoneId。不幸的是,java.time不包含用于计算日期时间值之间经过的天数的工具。我们可以使用ThreeTen-Extra项目及其Days
类和between
方法来提供该计算。 ThreeTen-Extra项目是JSR过程中被认为对java.time不重要的功能集合。
ZoneId zoneId = ZoneId.of ( "America/Montreal" );
ZonedDateTime now = ZonedDateTime.now ( zoneId );
ZonedDateTime then = now.minusDays ( 4 );
ZonedDateTime due = now.plusDays ( 3 );
Integer days = org.threeten.extra.Days.between ( then , due ).getAmount ();
转储到控制台。
System.out.println ( "From then: " + then + " to due: " + due + " = days: " + days );
从那时起:2015-10-31T16:01:13.082-04:00 [美国/蒙特利尔]到期日期:2015-11-07T16:01:13.082-05:00 [美国/蒙特利尔] =天数:7 < / p>
对于Android或旧版本的Java,请使用优秀的Joda-Time库。
Days
类很聪明,可以处理Daylight Saving Time(DST)等异常情况。
请注意,与java.util.Date不同,Joda-Time DateTime
对象知道自己的时区。
// Specify a time zone rather than rely on default.
DateTimeZone timeZone = DateTimeZone.forID( "America/Regina" ); // Or "Europe/London".
DateTime now = new DateTime( timeZone );
DateTime startOfToday = now.withTimeAtStartOfDay();
DateTime fewDaysFromNow = now.plusDays( 3 );
DateTime startOfAnotherDay = fewDaysFromNow.withTimeAtStartOfDay();
Days days = Days.daysBetween( startOfToday, startOfAnotherDay );
转储到控制台...
System.out.println( days.getDays() + " days between " + startOfToday + " and " + startOfAnotherDay + "." );
跑步时......
3 days between 2014-01-21T00:00:00.000-06:00 and 2014-01-24T00:00:00.000-06:00.
答案 1 :(得分:1)
您的代码损坏主要有两个原因:
我演示并解释了第二个原因。
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date d1 = sdf.parse("2016-03-20");
Date d2 = sdf.parse("2016-03-28");
int daysUntil = (int) ((d2.getTime() - d1.getTime()) / (1000 * 60 * 60 * 24));
System.out.println(daysUntil); // 7 (should be 8)
代码在时区&#34; Europe / Berlin&#34;中运行。由于冬季到夏季时间的变化导致2016-03-27凌晨2点时钟前进一小时,所以有一个小时失踪。一天只有23个小时,所以除以24会产生零,导致计算的时间少一天。
你还能做什么?
您的解决方法是向dueDate
添加1000毫秒的声音,就像您忽略了输入中可能的毫秒级增量一样。这可能会解决一个特殊情况,但通常也不足以解决夏令时问题。无论你在java.util.Date
的基础上选择什么,它或多或少都是邪恶的黑客。
我想到的最好(在Android内置的东西范围内)是构造一个java.util.GregorianCalendar
的实例,并在一天之后连续添加,直到你通过了 - 日期,然后计算您添加的天数。不优雅和错误,因为这里也很容易忽视不同的毫秒部分。
否则,您可以尝试各种外部库来执行此任务。 Android上有四种可以轻松计算经过的天数。