2017-06-10 4 views
-2

は、私は次のようにJavaのタイムスタンプの異なる表現を取得するように見える:次の呼び出しとインスタントメッセージはJavaのタイムスタンプと異なりますか?

en_US 
2017-06-10 14:34:35.088 
2017-06-10T18:34:35.102Z 

:示された時間の表現の間のオフセット4時間を等しくするのに役立ちますどのような追加構成

System.out.println(Locale.getDefault()); 
System.out.println(new Timestamp(System.currentTimeMillis())); 
System.out.println(Instant.now()); 

上記?ありがとう。

+0

1つはUTCです.1つはローカルタイムゾーンです。あなたはどちらを好みますか? – Marvin

+0

私は地元が好きですが、可能であれば、両方の方法でオフセットを正規化する方法のコードを見たいと思います。 –

+0

より多くのコンテキストを提供するために、私は、 '' 'Instant.now())' 'を使用するサードパーティライブラリのtoString()実装でUTCベースのタイムスタンプを取得しています。グローバルなJavaの設定で、そのライブラリから返されたものがすでにローカルタイムに変換されているか、この変換を処理するために独自のコードで余分なロジックを記述する必要がありますか?ありがとうございました。 –

答えて

2

1つは現地時間で、1つはUTCです。これは実際の(内部)値よりも印刷方法によります。両者が等しい示しているように

、あなたは

  • は、あなたのVMへ-Duser.timezone=UTCを渡すことにより、UTCにローカルタイムゾーンを設定することができます。
  • フォーマットローカルタイムゾーンにInstant

    new Timestamp(System.currentTimeMillis()).toInstant(); 
    

全コード:

public static void main(String[] args) { 
    DateTimeFormatter formatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME.withZone(ZoneId.systemDefault()); 
    Timestamp timestamp = new Timestamp(System.currentTimeMillis()); 
    Instant instant = Instant.now(); 
    System.out.println("Timestamp: " + timestamp); 
    System.out.println("Instant: " + instant); 
    System.out.println("Instant to local: " + formatter.format(instant)); 
    System.out.println("Timestamp to UTC: " + timestamp.toInstant()); 
} 
DateTimeFormatter formatter = 
DateTimeFormatter.ISO_LOCAL_DATE_TIME.withZone(ZoneId.systemDefault()); 
System.out.println(formatter.format(Instant.now())); 
  • TimestampInstantに変換は(私のローカルタイムゾーンで)出力します:

    Timestamp: 2017-06-10 21:17:13.935 
    Instant: 2017-06-10T19:17:13.935Z 
    Instant to local: 2017-06-10T21:17:13.935 
    Timestamp to UTC: 2017-06-10T19:17:13.935Z 
    

    だから、「いくつかのグローバル設定」があり、それはあなたがやりたいことではないかもしれないが。デフォルトではInstantwill always be printed in UTCです。

    あなただけのローカルな日付と仕事をしたいとあなたがInstantに制限されていない場合は、2つの*より多くのオプションがあります:

    • ZonedDateTimeInstantを変換します

      ZonedDateTime.ofInstant(Instant.now(), ZoneId.systemDefault()); 
      
    • Instantをすべて無効にしてください。ZonedDateTime.now()

    *ご要望に応じてOffsetDateTimeまたはLocalDateTimeと交換することができます。


    編集:魔法のように。

    public static void main(String[] args) throws Exception { 
        Field field = DateTimeFormatter.class.getField("ISO_INSTANT"); 
        field.setAccessible(true); 
        Field modifiersField = Field.class.getDeclaredField("modifiers"); 
        modifiersField.setAccessible(true); 
        modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL); 
        field.set(null, DateTimeFormatter.ISO_LOCAL_DATE_TIME.withZone(ZoneId.systemDefault())); 
    
        System.out.println(new Timestamp(System.currentTimeMillis())); 
        System.out.println(Instant.now()); 
    } 
    

    DateTimeFormatter.ISO_INSTANTを使用して、現地時間を使用するフォーマッタに変更します。 SecurityManagerで動作しない可能性があり、望ましくない副作用がある可能性があります。例えば、詳細はChange private static final field using Java reflectionをご覧ください。

  • +0

    デフォルトでUTCを使用するのではなく、即時呼び出しを処理するためにローカルタイムゾーンを適用するように、VMのデフォルトをリセットする方法はありますか? –

    +0

    私の更新を参照してください。 'Instant'を使用していますか? – Marvin

    +3

    代わりに 'LocalDateTime'、' OffsetDateTime'、 'ZonedDateTime'のいずれかを使うことをお勧めしますか? –

    関連する問題