我不确定我做错了什么,但我有一段代码可以计算两个日期之间的天数,看起来如下:
final Calendar first = new GregorianCalendar(2010, Calendar.OCTOBER, 1);
final Calendar last = new GregorianCalendar(2010, Calendar.NOVEMBER, 1);
final long difference = last.getTimeInMillis() - first.getTimeInMillis();
final long days = difference / (1000 * 60 * 60 * 24);
System.out.println("difference: " + difference);
System.out.println("days: " + days);
总结一下,上面的代码块计算了2010年10月1日到2010年11月1日之间的天数。我希望看到它返回31天(看到10月份的31天)
difference: xxxx
days: 31
但相反它在十月份显示了30天!
difference: 2674800000
days: 30
我已经设法将其缩小到2010年10月2日和2010年10月3日之间,这似乎只有82800000毫秒,而不是完整的86400000毫秒(恰好缺少一个小时)。
有没有人有任何想法我做错了什么?或者10月2日是一个比常规日少一分钟的特殊日期?
答案 0 :(得分:10)
(86400000 - 82800000)/1000 = 3600
,这是一个小时。您将看到夏令时,再加上整数数学的舍入
您可以通过使用浮点数进行计算并在最后进行舍入来绕过它,或者您可以查看像Joda time这样的库,它提供了比内置数据更好的日期数学。
答案 1 :(得分:0)
您可能最好比较一年,一天或一年,而不是一天中经过的毫秒数。
int lastYear= last.get(Calendar.YEAR);
int firstYear= first.get(Calendar.YEAR);
int lastDayofYear = last.get(Calendar.DAY_OF_YEAR);
int firstDayofYear = first.get(Calendar.DAY_OF_YEAR);
int nDaysElapse = lastDayofYear - firstDayofYear;
int nYearsElapse = lastYear- firstYear;
int days = (nYearsElapse*365)+nDaysElapse;
答案 2 :(得分:0)
您应该阅读this post以更好地了解日历与日期/时间戳的相互关系。
阅读该网站后,我最初的问题是:
你的日子是什么意思?你的意思是'24小时块'或者你的意思是日历日?同样,你是否因为夏令时等问题而关心?
如果您的意思是日历日,那么最好的选择可能是:
final Calendar first = new GregorianCalendar(2010, 9, 1);
final Calendar last = new GregorianCalendar(2010, 10, 1);
Calendar difference = Calendar.getInstance();
difference.setTimeInMillis(last.getTimeInMillis() - first.getTimeInMillis());
int numDays = difference.get(Calendar.DAY_OF_YEAR) - difference.getMinimum(Calendar.DAY_OF_YEAR);
当然,上述代码仅在天数< 365.您需要创建滚动计算,例如
int yearDiff = last.get(Calendar.YEAR) - first.get(Calendar.YEAR);
Calendar tmp = new GregorianCalendar();
tmp.setTimeInMillis(first.getTimeInMillis());
for(int i = 0; i < yearDiff; i++) {
numDays += tmp.getActualMaximum(Calendar.DAY_OF_YEAR);
i++;
tmp.add(Calendar.YEAR, 1);
}
这应该允许您以正确和一致的方式获得天数,而不必担心夏令时,闰年等。
也就是说,JodaTime可能内置了这个功能。
答案 3 :(得分:0)
answer by Brad Mace是正确的。
这个问题是一个很好的例子,说明为什么你应该使用一个好的日期时间库,而不是自己动手。对于Java,这意味着在Java 8中使用Joda-Time或新的java.time包。
Joda-Time中的示例代码。
DateTimeZone timeZone = DateTimeZone.forID( "Australia/Melbourne" );
DateTime theFirst = new DateTime( 2014, DateTimeConstants.OCTOBER, 1, 0, 0, 0, timeZone ).withTimeAtStartOfDay();
DateTime nextMonth = theFirst.plusMonths( 1 ).withTimeAtStartOfDay();
int days = Days.daysBetween( theFirst, nextMonth ).getDays();
如果您不关心时间,请使用LocalDate
课程。
Java 8及更高版本附带了一个新的java.time框架来取代旧的java.util.Date/.Calendar类。灵感来自Joda-Time,由JSR 310定义,并由ThreeTen-Extra项目扩展。
使用Java 8的示例代码。请注意,枚举ChronoUnit
返回64位long
而不是int
。
LocalDate firstOfOctober = LocalDate.of( 2010 , java.time.Month.OCTOBER , 1 );
LocalDate nextMonth = firstOfOctober.plusMonths( 1 );
long daysInMonth = ChronoUnit.DAYS.between( firstOfOctober , nextMonth );
答案 4 :(得分:-3)
您在帖子中输入的代码是计算9月1日到10月1日之间的时间,而不是10月1日和11月1日。您输出的代码输出正确。