2016-09-13 99 views
1

我想比較當前日期(2016-08-31)與給定日期(2016-08-31)。 我的當前移動設備時區是GMT-08:00太平洋時間。比較日期使用GregorianCalendar

如果我在設備上禁用自動日期&時區並將時區設置爲GMT + 08:00 Perth,則method1將返回true,但method2返回false;

由於我比較了沒有時區的日期,因此預計方法2的結果,因此「2016-08-31」之前的「2​​016-08-31」爲false;爲什麼method1返回true?

public boolean method1() { 
     try { 
      GregorianCalendar currentCalendar = new GregorianCalendar(); 
      SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); 
      Date endDate = sdf.parse("2016-08-31"); 
      Calendar endCalendar = new GregorianCalendar(); 
      endCalendar.setTime(endDate); 

      if (endCalendar.before(currentCalendar)) { 
       return true; 
      } else { 
       return false; 
      } 
     } catch (ParseException e) { 
      ... 
     } 
    } 


    public boolean method2() {  
     try { 
      SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); 
      Date currentDate = sdf.parse(formatter.format(new Date())); 
      Date endDate = sdf.parse("2016-08-31"); 

      if (endDate.before(currentDate)) { 
       return true; 
      } else { 
       return false; 
      } 

     } catch (ParseException e) { 
      ... 
     } 
    } 

回答

1

帶和不帶時區

可能的解釋:你的代碼混合使用劃和UTC日期時間對象。在某些行中,您有一個對象指定了一個時區(java.util.Calendar),即JVM當前的默認時區。在其他行中,您有一個在UTC中修復的對象(java.util.Date)。 Australia/Perth時區比UTC早8小時,所以當然你可以看到日期的差異。打印出他們的毫秒數,因爲時代號會使比較結果更加明顯。

自己做一個青睞:避免這些臭名昭着的麻煩老班。改用java.time代替。

Boolean isFuture = 
    LocalDate.parse("2016-08-31") 
      .isAfter(LocalDate.now(ZoneId.of("Australia/Perth"))) ; 

使用java.time

您使用麻煩的舊傳統的日期時間類,現在由java.time類取代。

獲取當前日期需要一個時區。對於任何特定的時刻,日期因地區而異。如果省略,則隱式應用JVM的當前默認時區。更好地指定,因爲該默認值可以隨時更改。

指定proper time zone name。切勿使用3-4字母縮寫,如ESTIST,因爲它們不是真正的時區,不是標準化的,甚至不是唯一的(!)。

ZoneId z = ZoneId.of("Australia/Perth") ; 

LocalDate類表示沒有時間一天和不同時區的日期,唯一的價值。

LocalDate today = LocalDate.now(z); 

您的輸入字符串恰好符合標準ISO 8601格式。所以直接用LocalDate解析。無需指定格式化模式。

LocalDate ld = LocalDate.parse("2016-08-31"); 

比較isBeforeisAfterisEqualcompareTo

Boolean isFuture = ld.isAfter(today); 

關於java.time

java.time框架是建立在Java 8和更高版本。這些課程取代了麻煩的舊日期時間課程,如java.util.Date,.Calendar,& java.text.SimpleDateFormat

Joda-Time項目現在位於maintenance mode,建議遷移到java.time。請參閱Oracle Tutorial。並搜索堆棧溢出了很多例子和解釋。

大部分的java.time功能後移植到Java 6 和ThreeTenABP還適於Android(見How to use…)。

ThreeTen-Extra項目擴展java.time與其他類。這個項目是未來可能增加java.time的一個試驗場。你可以在這裏找到一些有用的類,如Interval,YearWeek,YearQuarter,等等。

+0

謝謝@Basil Bourque,它非常詳細。 – Huigege