乔达时间
至于添加依赖项,我担心java.util.Date& .Calendar真是太糟糕了,我对任何新项目做的第一件事就是添加Joda-Time库。 在Java 8中,您可以使用受Joda-Time启发的新java.time包。
Joda-Time的核心是isEqual类。 与java.util.Date不同,它了解其指定的时区(isEqual)。 从j.u.Date转换时,指定一个区域。
DateTimeZone zone = DateTimeZone.forID( "America/Montreal" );
DateTime dateTimeQuébec = new DateTime( date , zone );
isEqual
验证同一日期的两个日期时间是否转换为isEqual对象的一种方法。
该转换取决于指定的时区。 要比较isEqual对象,它们必须已使用相同的区域进行转换。
这是一个小实用方法。
static public Boolean sameDate ( DateTime dt1 , DateTime dt2 )
{
LocalDate ld1 = new LocalDate( dt1 );
// LocalDate determination depends on the time zone.
// So be sure the date-time values are adjusted to the same time zone.
LocalDate ld2 = new LocalDate( dt2.withZone( dt1.getZone() ) );
Boolean match = ld1.equals( ld2 );
return match;
}
更好的是另一个参数,指定时区而不是假设应该使用第一个DateTime对象的时区。
static public Boolean sameDate ( DateTimeZone zone , DateTime dt1 , DateTime dt2 )
{
LocalDate ld1 = new LocalDate( dt1.withZone( zone ) );
// LocalDate determination depends on the time zone.
// So be sure the date-time values are adjusted to the same time zone.
LocalDate ld2 = new LocalDate( dt2.withZone( zone ) );
return ld1.equals( ld2 );
}
字符串表示
另一种方法是创建每个日期时间的日期部分的字符串表示,然后比较字符串。
同样,指定的时区至关重要。
DateTimeFormatter formatter = ISODateTimeFormat.date(); // Static method.
String s1 = formatter.print( dateTime1 );
String s2 = formatter.print( dateTime2.withZone( dt1.getZone() ) );
Boolean match = s1.equals( s2 );
return match;
时间跨度
通用解决方案是定义一段时间,然后询问跨度是否包含您的目标。 此示例代码位于Joda-Time 2.4中。 请注意,不推荐使用“午夜”相关类。 而是使用isEqual方法。 Joda-Time提供三个类来以各种方式表示时间跨度:间隔,周期和持续时间。
使用“半开”方法,其中跨度的开头是包含性的,而结尾是独占的。
目标的时区可以与间隔的时区不同。
DateTimeZone timeZone = DateTimeZone.forID( "Europe/Paris" );
DateTime target = new DateTime( 2012, 3, 4, 5, 6, 7, timeZone );
DateTime start = DateTime.now( timeZone ).withTimeAtStartOfDay();
DateTime stop = start.plusDays( 1 ).withTimeAtStartOfDay();
Interval interval = new Interval( start, stop );
boolean containsTarget = interval.contains( target );
java.time
Java 8及更高版本附带了java.time框架。 灵感来自Joda-Time,由JSR 310定义,并由ThreeTen-Extra项目扩展。 请参阅教程。
Joda-Time的制造商已经指示我们尽快转移到java.time。 与此同时,Joda-Time继续作为一个积极维护的项目。 但是期望未来的工作只发生在java.time和ThreeTen-Extra而不是Joda-Time。
简而言之,总结一下java.time ... isEqual是UTC时间轴上的一个时刻。 应用时区(ZonedDateTime)以获取LocalDate对象。 要离开时间线,要获得模糊日期时间的无限想法,请使用“本地”类:LocalDateTime,LocalDate,LocalTime。
本答案的Joda-Time部分中讨论的逻辑适用于java.time。
旧的java.util.Date类有一个新的isEqual方法,用于转换为java.time。
Instant instant = yourJavaUtilDate.toInstant(); // Convert into java.time type.
确定日期需要时区。
ZoneId zoneId = ZoneId.of( "America/Montreal" );
我们将该时区对象应用于isEqual以获得ZonedDateTime.由此我们提取仅日期值(LocalDate),因为我们的目标是比较日期(而不是小时,分钟等)。
ZonedDateTime zdt1 = ZonedDateTime.ofInstant( instant , zoneId );
LocalDate localDate1 = LocalDate.from( zdt1 );
对我们需要进行比较的第二个isEqual对象做同样的事情。 我只会用当前的时刻代替。
ZonedDateTime zdt2 = ZonedDateTime.now( zoneId );
LocalDate localDate2 = LocalDate.from( zdt2 );
使用特殊的isEqual方法测试相同的日期值。
Boolean sameDate = localDate1.isEqual( localDate2 );