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

天。daysBetween(start, end). getdays()如果开始在晚上,结束在早上,则返回0。

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

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


当前回答

博士tl;

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

…or…

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

java.time

仅供参考,Joda-Time项目现在处于维护模式,团队建议迁移到java。时间类。

相当于Joda-Time DateTime的是ZonedDateTime。

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

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

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

java。时间框架内置于Java 8及更高版本中。这些类取代了麻烦的旧遗留日期-时间类,如java.util。日期,日历和简单日期格式。

Joda-Time项目现在处于维护模式,建议迁移到java。时间类。

要了解更多,请参阅Oracle教程。搜索Stack Overflow可以找到很多例子和解释。规范是JSR 310。

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

从哪里获取java。时间类?

Java SE 8、Java SE 9、Java SE 10以及更高版本 内置的。 带有捆绑实现的标准Java API的一部分。 Java 9增加了一些小特性并进行了修复。 Java SE 6和Java SE 7 大部分的java。时间功能在ThreeTen-Backport中向后移植到Java 6和7。 安卓 后续版本的Android捆绑实现的java。时间类。 对于早期的Android (<26), ThreeTenABP项目适应ThreeTen-Backport(如上所述)。参见如何使用ThreeTenABP....

ThreeTen-Extra项目扩展了java。额外的课程时间。这个项目是未来可能添加到java.time的一个试验场。你可以在这里找到一些有用的类,比如Interval、YearWeek、YearQuarter等等。

ThreeTen-Extra项目扩展了java。额外的课程时间。这个项目是未来可能添加到java.time的一个试验场。你可以在这里找到一些有用的类,比如Interval、YearWeek、YearQuarter等等。

其他回答

令人恼火的是,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可以避免整个问题。

DateTime  dt  = new DateTime(laterDate);        

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

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

天类

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

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

博士tl;

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

…or…

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

java.time

仅供参考,Joda-Time项目现在处于维护模式,团队建议迁移到java。时间类。

相当于Joda-Time DateTime的是ZonedDateTime。

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

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

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

java。时间框架内置于Java 8及更高版本中。这些类取代了麻烦的旧遗留日期-时间类,如java.util。日期,日历和简单日期格式。

Joda-Time项目现在处于维护模式,建议迁移到java。时间类。

要了解更多,请参阅Oracle教程。搜索Stack Overflow可以找到很多例子和解释。规范是JSR 310。

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

从哪里获取java。时间类?

Java SE 8、Java SE 9、Java SE 10以及更高版本 内置的。 带有捆绑实现的标准Java API的一部分。 Java 9增加了一些小特性并进行了修复。 Java SE 6和Java SE 7 大部分的java。时间功能在ThreeTen-Backport中向后移植到Java 6和7。 安卓 后续版本的Android捆绑实现的java。时间类。 对于早期的Android (<26), ThreeTenABP项目适应ThreeTen-Backport(如上所述)。参见如何使用ThreeTenABP....

ThreeTen-Extra项目扩展了java。额外的课程时间。这个项目是未来可能添加到java.time的一个试验场。你可以在这里找到一些有用的类,比如Interval、YearWeek、YearQuarter等等。

ThreeTen-Extra项目扩展了java。额外的课程时间。这个项目是未来可能添加到java.time的一个试验场。你可以在这里找到一些有用的类,比如Interval、YearWeek、YearQuarter等等。

java.time.Period

使用java.time.Period类计算天数。

由于Java 8计算差异时使用LocalDate、LocalDateTime来表示两个日期更为直观

    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);