2017-12-23 36 views
1

SimpleDateFormatとタイムゾーンを使用しているときに奇妙な問題が発生しました。私はロサンゼルスのタイムゾーン(GMT-8) SimpleDateFormat setTimeZoneが電話のタイムゾーンが変更された場合には機能しません。

  • Iと入力日付を持って

    • String input    = "2017-12-21 16:15:00"; 
          String inputTZ   = "America/Los_Angeles"; 
          String phoneTZ   = TimeZone.getDefault().getID(); 
          SimpleDateFormat fmtInput = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.US); 
          fmtInput.setTimeZone(TimeZone.getTimeZone(inputTZ)); 
      
          SimpleDateFormat fmtOutputEventTZ = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.US); 
          fmtOutputEventTZ.setTimeZone(TimeZone.getTimeZone(inputTZ)); 
      
          SimpleDateFormat fmtOutputPhoneTZ = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.US); 
          fmtOutputPhoneTZ.setTimeZone(TimeZone.getTimeZone(phoneTZ)); 
      
      
          try { 
           LocalDateTime dt = new LocalDateTime(fmtInput.parse(input)); 
      
           Log.d("DEBUG>>>>", "INPUT=" + input); 
           Log.d("DEBUG>>>>", "TZ_EVENT=" + inputTZ); 
           Log.d("DEBUG>>>>", "TZ_PHONE=" + phoneTZ); 
           Log.d("DEBUG>>>>", "DT=" + dt); 
           Log.d("DEBUG>>>>", "OUTPUT_EVENT=" + fmtOutputEventTZ.format(dt.toDate())); 
           Log.d("DEBUG>>>>", "OUTPUT_PHONE=" + fmtOutputPhoneTZ.format(dt.toDate())); 
          } 
          catch (Exception e) { 
           e.printStackTrace(); 
          } 
      

      コードロジックは以下の通りである:

      は基本的に、私はこのコードスニペットを持っていますこの日付を解析してタイムゾーン(LA)を指定します

    • 次に、元のタイムゾーン(LA)と現在の電話タイムゾーンを使用して日付をフォーマットします

    シカゴ(GMT-6)に設定した電話タイムゾーンでコードを実行し、次の出力を得ました。

    D/DEBUG>>>>: INPUT=2017-12-21 16:15:00 
    D/DEBUG>>>>: TZ_EVENT=America/Los_Angeles 
    D/DEBUG>>>>: TZ_PHONE=America/Chicago 
    D/DEBUG>>>>: DT=2017-12-21T18:15:00.000 
    D/DEBUG>>>>: OUTPUT_EVENT=2017-12-21 16:15:00 
    D/DEBUG>>>>: OUTPUT_PHONE=2017-12-21 18:15:00 
    

    基本的に、結果は予期されたとおりです。私はアプリを再起動せずにニューヨーク(GMT-5)のものであることを自分の携帯電話のタイムゾーンを変更した場合

    しかし、私はTimeZone.getDefault().getID()によって返されたタイムゾーンが正しいことを

    D/DEBUG>>>>: INPUT=2017-12-21 16:15:00 
    D/DEBUG>>>>: TZ_EVENT=America/Los_Angeles 
    D/DEBUG>>>>: TZ_PHONE=America/New_York 
    D/DEBUG>>>>: DT=2017-12-21T18:15:00.000 
    D/DEBUG>>>>: OUTPUT_EVENT=2017-12-21 15:15:00 
    D/DEBUG>>>>: OUTPUT_PHONE=2017-12-21 18:15:00 
    

    お知らせ次の出力を得ました一方、それが解析されると、SimpleDateFormatは電話タイムゾーンがシカゴであるかのように変換し、間違った時刻を返します。

    私はアプリを殺すし、それを再起動する場合は、同じコードが正常に動作します:

    D/DEBUG>>>>: INPUT=2017-12-21 16:15:00 
    D/DEBUG>>>>: TZ_EVENT=America/Los_Angeles 
    D/DEBUG>>>>: TZ_PHONE=America/New_York 
    D/DEBUG>>>>: DT=2017-12-21T19:15:00.000 
    D/DEBUG>>>>: OUTPUT_EVENT=2017-12-21 16:15:00 
    D/DEBUG>>>>: OUTPUT_PHONE=2017-12-21 19:15:00 
    

    私の理解から、SimpleDateFormat.parse日付を解析し、setTimeZoneを使用した1970年からの秒数としてそれを保存する必要がありますタイムゾーンを使用して時間を適切にシフトします。

    しかし、電話のタイムゾーンの変更がSimpleDateFormatに反映されていないようですが、TimeZone.getDefault().getID()には変更が反映されているようです。

    この問題を解決する方法はありますか?

  • 答えて

    2

    解決策を見つけました!

    私は最初にDateTimeZone.setDefault(DateTimeZone.forID(TimeZone.getDefault().getID()))と呼んでいました。

    DateTimeZone.setDefaultは、アプリケーションの起動時に呼び出されますが、ユーザーのタイムゾーンが変更されている可能性があるにもかかわらず、あとでjoda-time自体でリセットされることはありません。

    +1

    期待どおりの動作です。 JVMには独自のタイムゾーン設定がありますが、これはデバイスのタイムゾーン設定と異なる場合があります。設定するために何もしないと、JVMの起動時にデバイス設定に初期化されます。その後、それは自動的に変更されませんが、Joda-Time(すでにこのライブラリを使用している場合)を使用して変更する方法(と良い方法)があります。 –