Joda-Time中两个日期之间的天数

pvg*_*ijn 321 java date jodatime

如何找到两个Joda-Time DateTime实例之间的天数差异?"天数差异"是指如果开始时间是星期一而结束时间是星期二,我预计返回值为1,无论开始日期和结束日期的小时/分钟/秒.

Days.daysBetween(start, end).getDays() 如果开始是在晚上并在早上结束,则给我0.

我也和其他日期字段有同样的问题所以我希望有一种通用的方法来"忽略"不太重要的字段.

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

Ali*_*ell 384

令人讨厌的是,withTimeAtStartOfDay答案是错误的,但只是偶尔.你要:

Days.daysBetween(start.toLocalDate(), end.toLocalDate()).getDays()
Run Code Online (Sandbox Code Playgroud)

事实证明,"午夜/一天的开始"有时意味着凌晨1点(在某些地方以这种方式发生夏令时),Days.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
Run Code Online (Sandbox Code Playgroud)

通过LocalDate回避整个问题.

  • @BasilBourque - 这个例子已经在我的回答中了. (2认同)

Mic*_*rdt 184

Days

使用该方法的DayswithTimeAtStartOfDay应该工作:

Days.daysBetween(start.withTimeAtStartOfDay() , end.withTimeAtStartOfDay() ).getDays() 
Run Code Online (Sandbox Code Playgroud)

  • @akhyar:你为什么不试试呢? (7认同)
  • 您现在应该使用.withTimeAtStartOfDay()而不是.toDateMidnight() (2认同)
  • 如果“结束”早于“开始”,会返回负数天怎么办? (2认同)

Boz*_*zho 83

你可以使用LocalDate:

Days.daysBetween(new LocalDate(start), new LocalDate(end)).getDays() 
Run Code Online (Sandbox Code Playgroud)


Bas*_*que 7

TL;博士

java.time.temporal.ChronoUnit.DAYS.between( 
    earlier.toLocalDate(), 
    later.toLocalDate() 
)
Run Code Online (Sandbox Code Playgroud)

…要么…

java.time.temporal.ChronoUnit.HOURS.between( 
    earlier.truncatedTo( ChronoUnit.HOURS )  , 
    later.truncatedTo( ChronoUnit.HOURS ) 
)
Run Code Online (Sandbox Code Playgroud)

java.time

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

乔达-时间的等效DateTimeZonedDateTime.

ZoneId z = ZoneId.of( "Pacific/Auckland" ) ;
ZonedDateTime now = ZonedDateTime.now( z ) ;
Run Code Online (Sandbox Code Playgroud)

显然你想按日期计算日期,这意味着你想忽略一天中的时间.例如,在午夜前一分钟开始到午夜后一分钟结束应该会导致一天.对于此行为,请LocalDate从您的ZonedDateTime.该LocalDate级表示没有时间一天和不同时区的日期,唯一的价值.

LocalDate localDateStart = zdtStart.toLocalDate() ;
LocalDate localDateStop = zdtStop.toLocalDate() ;
Run Code Online (Sandbox Code Playgroud)

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

long days = ChronoUnit.DAYS.between( localDateStart , localDateStop ) ;
Run Code Online (Sandbox Code Playgroud)

截短

至于你问一个更通用的方法来计算你感兴趣的地方的小时数增量作为时钟的时间而不是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 ) );
Run Code Online (Sandbox Code Playgroud)

1

按日期计算天数,截断为java.util.Date.这是一个例子,从过去的五分钟到五分钟后的午夜,经过了几天Calendar.

java.time.temporal.ChronoUnit.DAYS.between( 
    earlier.toLocalDate(), 
    later.toLocalDate() 
)
Run Code Online (Sandbox Code Playgroud)

1


关于java.time

java.time框架是建立在Java 8和更高版本.这些类取代麻烦的老传统日期时间类,如SimpleDateFormat,java.sql.*,和Interval.

现在处于维护模式Joda-Time项目建议迁移到java.time类.

要了解更多信息,请参阅Oracle教程.并搜索Stack Overflow以获取许多示例和解释.规范是JSR 310.

您可以直接与数据库交换java.time对象.使用符合JDBC 4.2或更高版本的JDBC驱动程序.不需要字符串,不需要课程.YearWeek

从哪里获取java.time类?

ThreeTen-额外项目与其他类扩展java.time.该项目是未来可能添加到java.time的试验场.您可以在此比如找到一些有用的类YearQuarter,Interval,YearWeek,和更多.

ThreeTen-额外项目与其他类扩展java.time.该项目是未来可能添加到java.time的试验场.您可以在此比如找到一些有用的类YearQuarter,DateTime,ZonedDateTime,和更多.