喬達時間
至於添加依賴,恐怕與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