约达时间中两个日期之间的天数

我如何找到两个Joda-Time DateTime实例之间的天的差异? 对于“天数差异”,我的意思是如果开始是周一,结束是周二,我期望返回值为1,而不管开始日期和结束日期的小时/分钟/秒

Days.daysBetween(start, end).getDays()如果开始时间是晚上,结束时间是早上,则返回0。

我也有其他日期字段相同的问题,所以我希望有一种通用的方法来“忽略”较不重要的字段。

换句话说,2月到3月4日之间的月份也是1,14:45到15:12之间的时间也是1。但是14:01和14:55之间的小时差是0。

227359 次浏览

你可以使用LocalDate:

Days.daysBetween(new LocalDate(start), new LocalDate(end)).getDays()

Days

使用Days类和withTimeAtStartOfDay方法应该可以工作:

Days.daysBetween(start.withTimeAtStartOfDay() , end.withTimeAtStartOfDay() ).getDays()

令人恼火的是,withTimeAtStartOfDay答案是错误的,但只是偶尔错误。你想要的:

Days.daysBetween(start.toLocalDate(), end.toLocalDate()).getDays()

事实证明,“午夜/一天的开始”有时意味着凌晨1点(夏令时在某些地方是这样发生的)。daysBetween不能正确处理。

// 5am on the 20th to 1pm on the 21st, October 2013, Brazil
DateTimeZone BRAZIL = DateTimeZone.forID("America/Sao_Paulo");
DateTime start = new DateTime(2013, 10, 20, 5, 0, 0, BRAZIL);
DateTime end = new DateTime(2013, 10, 21, 13, 0, 0, BRAZIL);
System.out.println(daysBetween(start.withTimeAtStartOfDay(),
end.withTimeAtStartOfDay()).getDays());
// prints 0
System.out.println(daysBetween(start.toLocalDate(),
end.toLocalDate()).getDays());
// prints 1

通过LocalDate可以避免整个问题。

public static int getDifferenceIndays(long timestamp1, long timestamp2) {
final int SECONDS = 60;
final int MINUTES = 60;
final int HOURS = 24;
final int MILLIES = 1000;
long temp;
if (timestamp1 < timestamp2) {
temp = timestamp1;
timestamp1 = timestamp2;
timestamp2 = temp;
}
Calendar startDate = Calendar.getInstance(TimeZone.getDefault());
Calendar endDate = Calendar.getInstance(TimeZone.getDefault());
endDate.setTimeInMillis(timestamp1);
startDate.setTimeInMillis(timestamp2);
if ((timestamp1 - timestamp2) < 1 * HOURS * MINUTES * SECONDS * MILLIES) {
int day1 = endDate.get(Calendar.DAY_OF_MONTH);
int day2 = startDate.get(Calendar.DAY_OF_MONTH);
if (day1 == day2) {
return 0;
} else {
return 1;
}
}
int diffDays = 0;
startDate.add(Calendar.DAY_OF_MONTH, diffDays);
while (startDate.before(endDate)) {
startDate.add(Calendar.DAY_OF_MONTH, 1);
diffDays++;
}
return diffDays;
}
接受的答案构建两个LocalDate对象,如果你读取大量数据,这是相当昂贵的。 我使用这个:

  public static int getDaysBetween(DateTime earlier, DateTime later)
{
return (int) TimeUnit.MILLISECONDS.toDays(later.getMillis()- earlier.getMillis());
}

通过调用getMillis(),您将使用已经存在的变量 MILLISECONDS.toDays()然后,使用简单的算术计算,不创建任何对象

博士tl;

java.time.temporal.ChronoUnit.DAYS.between(
earlier.toLocalDate(),
later.toLocalDate()
)

…或…

java.time.temporal.ChronoUnit.HOURS.between(
earlier.truncatedTo( ChronoUnit.HOURS )  ,
later.truncatedTo( ChronoUnit.HOURS )
)

java.time

仅供参考,Joda-Time项目现在在维护模式中,团队建议迁移到java.time类。

Joda-Time DateTime的等效函数是ZonedDateTime

ZoneId z = ZoneId.of( "Pacific/Auckland" ) ;
ZonedDateTime now = ZonedDateTime.now( z ) ;

显然,你想通过日期来计算天数,这意味着你想忽略一天中的时间。例如,从午夜前一分钟开始,到午夜后一分钟结束,结果应该是一天。对于这种行为,从你的ZonedDateTime中提取LocalDateLocalDate类表示一个只有日期的值,没有日期和时区。

LocalDate localDateStart = zdtStart.toLocalDate() ;
LocalDate localDateStop = zdtStop.toLocalDate() ;

使用ChronoUnit枚举来计算经过的天数或其他单位。

long days = ChronoUnit.DAYS.between( localDateStart , localDateStop ) ;

截断

至于你问一个更一般的方法来做这个计数,当你感兴趣的时候,小时的增量作为一个小时,而不是完整的小时作为60分钟的时间范围,使用truncatedTo方法。

这是你在同一天的14:45到15:12的例子。

ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime start = ZonedDateTime.of( 2017 , 1 , 17 , 14 , 45 , 0 , 0 , z );
ZonedDateTime stop = ZonedDateTime.of( 2017 , 1 , 17 , 15 , 12 , 0 , 0 , z );


long hours = ChronoUnit.HOURS.between( start.truncatedTo( ChronoUnit.HOURS ) , stop.truncatedTo( ChronoUnit.HOURS ) );

1

这几天都不起作用。在这种情况下使用toLocalDate()。


关于java.time

< em > java.time < / em >框架内置于Java 8及更高版本中。这些类取代了麻烦的旧遗产日期-时间类,如java.util.DateCalendar, &SimpleDateFormat

现在在维护模式中的< em > Joda-Time < / em >项目建议迁移到java.time类。

要了解更多信息,请参见< < em >甲骨文教程/ em >。搜索Stack Overflow可以找到很多例子和解释。规格是JSR 310

你可以直接与你的数据库交换java.time对象。使用与JDBC 4.2或更高版本兼容的JDBC驱动程序。不需要字符串,不需要java.sql.*类。

从哪里获取java。时间类?

DateTime  dt  = new DateTime(laterDate);


DateTime newDate = dt.minus( new  DateTime ( previousDate ).getMillis());


System.out.println("No of days : " + newDate.getDayOfYear() - 1 );

java.time.Period

使用java.time.Period类来数天

由于Java 8计算差异更直观,使用LocalDateLocalDateTime来表示两个日期

    LocalDate now = LocalDate.now();
LocalDate inputDate = LocalDate.of(2018, 11, 28);


Period period = Period.between( inputDate, now);
int diff = period.getDays();
System.out.println("diff = " + diff);

常量日期和当前日期之间的差异(Joda)

你可以使用Days.daysBetween(jodaDate1,jodaDate2)

这里有一个例子:

        val dateTime: DateTime = DateTime.parse("14/09/2020",
DateTimeFormat.forPattern("dd/MM/yyyy"))
val currentDate = DateTime.now()
//To calculate the days in between
val dayCount = Days.daysBetween(dateTime,currentDate).days
//Set Value to TextView
binding.daysCount.text = dayCount.toString()