更新:Joda-Time 项目现在处于维护模式。它的团队建议迁移到 Java 中内置的java.time类。
乔达时间
Joda-Time 提供 3 个类来表示时间跨度:Interval、Duration 和 Period。
ISO 8601 标准指定了如何格式化表示Duration和Interval的字符串。Joda-Time 解析和生成这样的字符串。
时区是一个重要的考虑因素。您的数据库应该以 UTC 格式存储其日期时间值。但是您的业务逻辑可能需要考虑时区。“一天”的开始取决于时区。顺便说一句,使用正确的时区名称而不是 3 或 4 个字母代码。
S.Lott的正确答案明智地建议使用半开逻辑,因为这通常最适合日期时间工作。时间跨度的开始是包容性的,而结束是排斥性的。Joda-Time 在其方法中使用半开逻辑。
DateTimeZone timeZone_NewYork = DateTimeZone.forID( "America/New_York" );
DateTime start = new DateTime( 2014, 9, 29, 15, 16, 17, timeZone_NewYork );
DateTime stop = new DateTime( 2014, 9, 30, 1, 2, 3, timeZone_NewYork );
int daysBetween = Days.daysBetween( start, stop ).getDays();
Period period = new Period( start, stop );
Interval interval = new Interval( start, stop );
Interval intervalWholeDays = new Interval( start.withTimeAtStartOfDay(), stop.plusDays( 1 ).withTimeAtStartOfDay() );
DateTime lateNight29th = new DateTime( 2014, 9, 29, 23, 0, 0, timeZone_NewYork );
boolean containsLateNight29th = interval.contains( lateNight29th );
转储到控制台...</p>
System.out.println( "start: " + start );
System.out.println( "stop: " + stop );
System.out.println( "daysBetween: " + daysBetween );
System.out.println( "period: " + period ); // Uses format: PnYnMnDTnHnMnS
System.out.println( "interval: " + interval );
System.out.println( "intervalWholeDays: " + intervalWholeDays );
System.out.println( "lateNight29th: " + lateNight29th );
System.out.println( "containsLateNight29th: " + containsLateNight29th );
运行时……</p>
start: 2014-09-29T15:16:17.000-04:00
stop: 2014-09-30T01:02:03.000-04:00
daysBetween: 0
period: PT9H45M46S
interval: 2014-09-29T15:16:17.000-04:00/2014-09-30T01:02:03.000-04:00
intervalWholeDays: 2014-09-29T00:00:00.000-04:00/2014-10-01T00:00:00.000-04:00
lateNight29th: 2014-09-29T23:00:00.000-04:00
containsLateNight29th: true