2016-09-13 10 views
1

現在の日付(2016-08-31)と指定された日付(2016-08-31)を比較しようとしています。 私の現在のモバイルデバイスのタイムゾーンは、GMT-08:00太平洋標準時です。GregorianCalendarを使用して日付を比較

自動日付&のデバイスでタイムゾーンを無効にし、タイムゾーンをGMT + 08:00パースに設定すると、method1はtrueを返しますが、method2はfalseを返します。

方法2の結果は、タイムゾーンなしの日付を比較するので、 "2016-08-31"より前の "2016-08-31"は偽です。 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の日付時刻オブジェクトの使用をミックス。いくつかの行には、JVMの現在のデフォルトのタイムゾーンであるタイムゾーン(java.util.Calendar)が割り当てられたオブジェクトがあります。他の行には、オブジェクト(java.util.Date)がUTCに固定されています。 Australia/Perthの時間帯はUTCより8時間早いので、もちろん日付の違いを見ることができます。エポック秒数からミリ秒を印刷すると、比較結果が明白になります。

あなた自身をしてください大きな好意:これらの悪名高い厄介な古いクラスを避けてください。代わりにjava.timeを使用してください。あなたが面倒な古いレガシー日時クラスを使用している

java.timeを使用して

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

は、今java.timeクラスに取って代わら。

現在の日付を取得するには、タイムゾーンが必要です。任意の瞬間について、日付は地球の周りでゾーンごとに異なります。これを省略すると、JVMの現在のデフォルトのタイムゾーンが暗黙的に適用されます。そのデフォルトはいつでも変更できるので、指定する方が良い。

proper time zone nameを指定します。 ESTまたはISTのような3〜4文字の略語は、標準化されておらず、一意ではなく(!)、実際のタイムゾーンではないので使用しないでください。

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

LocalDateクラスは、時間日の時間帯なしなし日付専用の値を表しています。

LocalDate today = LocalDate.now(z); 

あなたの入力文字列は、標準のISO 8601フォーマットに準拠しています。したがって、直接LocalDateと解析してください。書式設定のパターンを指定する必要はありません。

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

isBeforeisAfterisEqual、およびcompareToと比較してください。 java.timeについて

Boolean isFuture = ld.isAfter(today); 

java.timeフレームワークは、Java 8に組み込まれており、後にされています。これらのクラスは、java.util.Date.Calendar、& java.text.SimpleDateFormatなどの面倒な古い日時クラスに取って代わります。

にあるJoda-Timeプロジェクトは、java.timeへの移行を推奨しています。

詳しくはOracle Tutorialをご覧ください。そして、多くの例と説明のためにStack Overflowを検索してください。

java.time機能ThreeTen-BackportでJava 6 & 7に戻って、移植、さらにThreeTenABPAndroidに適合されているの多く(How to use…を参照)。

ThreeTen-Extraプロジェクトは、追加のクラスでjava.timeを拡張します。このプロジェクトは、将来のjava.timeへの追加の可能性を証明する土台です。ここでは、IntervalYearWeekYearQuarterなどの便利なクラスがあります。

+0

ありがとうございました@Basil Bourque、それは非常に詳細です。 – Huigege