2017-11-15 10 views
0

にAndroidデバイス上でUTCに現在の日付を取得しようとする私のJavaコードの日付を返さない:あなたがdateUTCAsStringを見ることができるようににDateFormatパース - ここではUTC

dateUTCAsString = 2017-11-15T12:54:25 +0000 
dateResult = Wed Nov 15 14:54:25 EET 2017 

public static Date getCurrentDateUTC() { 
    try { 
     TimeZone timeZoneUTC = TimeZone.getTimeZone("UTC"); 
     Date localTime = new Date(); 
     DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss Z"); 
     dateFormat.setTimeZone(timeZoneUTC); 
     String dateUTCAsString = dateFormat.format(localTime); 
     Debug.d(TAG, "getCurrentDateUTC: dateUTCAsString = " + dateUTCAsString); 
     Date dateResult = dateFormat.parse(dateUTCAsString); 
     Debug.d(TAG, "getCurrentDateUTC: dateResult = " + dateResult); 
     return dateResult; 
    } catch (ParseException e) { 
     Debug.e(TAG, "getCurrentDateUTC: ", e); 
     return null; 
    } 
} 

の検索結果を IS CORRECTは現在の日付をUTCで表示しますが、parseの後にdateResultが正しくありません。どうして?

+0

EETがUTC + 2であるとすれば、正しいと思われます。あなたは何を見たいですか? – laalto

+0

日付はUTCでなければなりません。だから私は見たいと思う:Wed Nov 15 12:54:25 UTC 2017 – Alex

+1

'Date'は特定のタイムゾーンを持たない。 'Date#toString()'はローカルタイムゾーンのEETを出力します。 – laalto

答えて

0

あなたのコードには問題はないと思われますが、混乱するだけです。古いDateクラスが混乱していると思われる場合は、私が多くの人の中で最初にあなたに同意できるようにしてください。この問題に対する良い解決策は、Dateの使用を中止し、現代のJava日時APIを使用することです。

Androidをコーディングしているので、まず、現代のAPIを提供するAndroidのライブラリであるThreeTenABPを入手してください(Java 8または9を使用している場合は、現代のAPIが組み込み)。詳細はthis question: How to use ThreeTenABP in Android Projectに記載されています。今、あなたは行うことができます:私のコンピュータ上で

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss Z"); 
    String dateUTCAsString = "2017-11-15T12:54:25 +0000"; 
    Instant dateResult = OffsetDateTime.parse(dateUTCAsString, formatter).toInstant(); 
    System.out.println(dateResult); 

をこのちょうど印刷:

2017-11-15T12:54:25Z 

Zは終わりズールータイムゾーンまたはUTCを意味します。

ご存知のように、System.out.println(dateResult)はメソッドを暗黙のうちにdateResultオブジェクトから呼び出します。クラスInstantのオブジェクトは、あなたが望むと思ったように、上記のフォーマットを常にUTCで生成します。 Instantクラスは、ほとんどの目的のために古典的なDateクラスの自然な置き換えです。内部的にはInstantには、1970年1月1日午前0時0時(UTC)と定義されているエポック以降の秒数とナノ秒が保持されます。これは無関係な実装の詳細と考えることをお勧めします。 Instantは、タイムライン上のポイントです。

何が問題になりましたか?

あなたはUTCで日付を要求しました。あなたの見方に応じて、あなたはこれを持つことができます。一方Date

  • はエポックからの秒とミリ秒数として実装されているので、あなたは、エポックの上記の定義を使用している場合、あなたはそれが常にUTCでであることを言うかもしれません。
  • 一方、実装の詳細については心配する必要はありません。概念的にDateInstantのような)はタイムライン上のポイントであり、タイムゾーンもオフセットも持たないし、できない。それはUTCにすることはできません。問題をより混乱させるために、"getCurrentDateUTC: dateResult = " + dateResultを実行すると、dateResult.toString()が暗黙的に呼び出されます。このメソッドは、JVMのタイムゾーン設定を取得し、このゾーンに日付時刻を変換し、生成された文字列に使用します(Dateオブジェクトを変更することなく)。このため、印刷しようとしているに関係なく、コンピュータまたはデバイスでEETの時刻が表示されます。

java.timeまたは

近代的な日付と時刻のAPI JSR-310は、java.timeまたはJSR-310として知られています。それを使用することを学ぶための良い情報源の1つはthe Oracle tutorialです。

関連する問題