我已经看到了很多关于这个主题的问题和答案,但没有一个解决我的特定问题。我扩展了 java Calendar 类(标准——没有第三方库),并且需要找出两个任意日期之间的天数差异。
方法:
- 将两个日期的时间更改为午夜。
- 将日期转换为毫秒。
- 找出两个日期之间的差异。
- 将结果除以一天中的毫秒数 (24 * 60 * 60 * 1000)。
- 结果应该是天的差异。
有时是,有时不是。即使是同一天的测试也可以减少一个。这是怎么回事?
Joda Time Library对此类问题有很好的支持:
LocalDate d1 = new LocalDate(calendar1.getTimeInMillis());
LocalDate d2 = new LocalDate(calendar2.getTimeInMillis());
int days = Days.daysBetween(d1, d2).getDays();
更新(来自@basil-bourque 的反馈):
从 Java 8java.time
开始,引入了新的时间库,现在可以使用没有外部依赖项的类似选项:
int days = Duration.between(calendar1.toInstant(), calendar2.toInstant()).toDays();
正如其他用户所建议的,您还需要将日历的毫秒值设置为零以仅比较日期。这可以通过以下代码片段来实现:
someCalendar.set(Calendar.MILLISECOND, 0)
另外,请注意时区变化(例如从冬季时间到夏季时间)可能意味着一天的时间多于或少于 86,400,000 毫秒。
我已经写了一种更简单的方法来解决这个问题,即使我也面临同样的问题,即某些日期要多出一天。
这是我目前的做法,
public long getDays(long currentTime, long endDateTime) {
Calendar endDateCalendar;
Calendar currentDayCalendar;
//expiration day
endDateCalendar = Calendar.getInstance(TimeZone.getTimeZone("EST"));
endDateCalendar.setTimeInMillis(endDateTime);
endDateCalendar.set(Calendar.MILLISECOND, 0);
endDateCalendar.set(Calendar.MINUTE, 0);
endDateCalendar.set(Calendar.HOUR, 0);
//current day
currentDayCalendar = Calendar.getInstance(TimeZone.getTimeZone("EST"));
currentDayCalendar.setTimeInMillis(currentTime);
currentDayCalendar.set(Calendar.MILLISECOND, 0);
currentDayCalendar.set(Calendar.MINUTE, 0);
currentDayCalendar.set(Calendar.HOUR, 0);
long remainingDays = Math.round((float) (endDateCalendar.getTimeInMillis() - currentDayCalendar.getTimeInMillis()) / (24 * 60 * 60 * 1000));
return remainingDays;
}
以前我用的是这条线,其余的都是一样的:-
long remainingDays = TimeUnit.MILLISECONDS.toDays(
Math.abs(expiryCalendar.getTimeInMillis() - currentDayCalendar.getTimeInMillis()));
但似乎不适合我。
您在第一步中通过将时间设置为午夜来识别问题:确保所有小时、分钟和秒都为零。但你走得还不够远!您还必须确保毫秒也被归零。
这里有一些代码可以做到这一点。
protected long truncate_to_seconds (long date_in_millis) {
long l = date_in_millis / 1000L;
l *= 1000L;
return l;
}
我相信您需要在计算差异之前从日期截断时间部分,如下所示:
DateFormat formatter= new SimpleDateFormat("MM/dd/yyyy");
String truncatedDateString1 = formatter.format(date1);
Date truncatedDate1 = formatter.parse(truncatedDateString1);
String truncatedDateString2 = formatter.format(date2);
Date truncatedDate2 = formatter.parse(truncatedDateString2);
long timeDifference = truncatedDate2.getTime()- truncatedDate1.getTime();
int daysInBetween = timeDifference / (24*60*60*1000);
希望这有效。
根据您的要求,我有我的职责。我正在使用日历,在比较之前我将所有时间部分设置为 0。
int countDays(Date dateBegin, Date dateEnd) {
if (dateBegin == null || dateEnd == null)
return 0;
Calendar from = asCalendar(dateBegin); // asCalendar() Initialise a Calendar from a Date
Calendar to = asCalendar(dateEnd);
// Set the time part to 0
from.set(Calendar.MILLISECOND, 0);
from.set(Calendar.SECOND, 0);
from.set(Calendar.MINUTE, 0);
from.set(Calendar.HOUR_OF_DAY, 0);
to.set(Calendar.MILLISECOND, 0);
to.set(Calendar.SECOND, 0);
to.set(Calendar.MINUTE, 0);
to.set(Calendar.HOUR_OF_DAY, 0);
int nbJours = 0;
for (Calendar c = from ; c.before(to) ; c.add(Calendar.DATE, +1))
{
nbJours++;
}
for (Calendar c = from ; c.after(to) ; c.add(Calendar.DATE, -1))
{
nbJours--;
}
return nbJours;
}