乔达时间
至于添加依赖,恐怕与java.util.Date & .Calendar真的是如此糟糕,我第一件事做任何新项目都要添加Joda-Time库。在Java 8中,您可以使用受Joda-Time启发的新的java.time包。
Joda-Time的核心是DateTime
类。与java.util.Date不同,它理解其分配的时区(DateTimeZone
)。从j.u.Date转换时,分配一个区域。
DateTimeZone zone = DateTimeZone.forID("America/Montreal");
DateTime dateTimeQuébec = new DateTime(date , zone);
LocalDate
一种验证如果两个日期时间降落在同一日期转换为LocalDate
对象。
该转换取决于指定的时区。要比较LocalDate
对象,它们必须已被转换为同一区域。
这是一个小实用方法。
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中。请注意,“午夜”相关课程已弃用。而应使用withTimeAtStartOfDay
方法。 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框架。受JSR 310定义的Joda-Time的启发,并由ThreeTen-Extra项目扩展。见Tutorial。
Joda-Time的制造商已经指示我们所有人尽快转移到java.time。与此同时,乔达时代继续作为一个积极维护的项目。但预计未来的工作只能在java.time和ThreeTen-Extra而不是Joda-Time中进行。
简而言之总结java.time ... Instant
是UTC时间轴上的一个时刻。应用时区(ZoneId
)获取ZonedDateTime
对象。要离开时间轴,为了获得日期时间的模糊不清的想法,请使用“本地”类:LocalDateTime
,LocalDate
,LocalTime
。
本答案的Joda-Time部分讨论的逻辑适用于java.time。
旧的java.util.Date类有一个新的toInstant
转换为java.time的方法。
Instant instant = yourJavaUtilDate.toInstant(); // Convert into java.time type.
确定日期需要时区。
ZoneId zoneId = ZoneId.of("America/Montreal");
我们应用该时区对象的Instant
获得ZonedDateTime
。由此我们提取仅限日期的值(一个LocalDate
),因为我们的目标是比较日期(而不是小时,分钟等)。
ZonedDateTime zdt1 = ZonedDateTime.ofInstant(instant , zoneId);
LocalDate localDate1 = LocalDate.from(zdt1);
对第二个java.util.Date
做同样的事情我们需要比较。我只是使用当前的时刻。
ZonedDateTime zdt2 = ZonedDateTime.now(zoneId);
LocalDate localDate2 = LocalDate.from(zdt2);
使用特殊的isEqual
方法来测试相同的日期值。
Boolean sameDate = localDate1.isEqual(localDate2);
只是为了澄清 - 你要知道,如果两个Date对象落在星期的同一天? – 2010-03-25 17:11:59
你想比较完整日期(日,月,年)还是只有一个月? – XpiritO 2010-03-25 17:13:47
@Rob:不,同一天/每月/每年......我会澄清。 – 2010-03-25 17:13:59