2017-04-20 6 views
1

日付文字列がCST(24時間)で、GMT(12時間)に変換したい。 私はシステム時間がコルカタ時間であるときにうまく動作する以下のようなjavaメソッドを持っています。 (私がJavaメソッドを実行するシステム) しかし、私のシステムが上海時間にあるとき、GMT時間は間違っています。CSTからGMTへの日付形式変換が機能しない

String inputDate = "01-19-2017 06:01 CST"; 
SimpleDateFormat inputFormatter = new SimpleDateFormat("MM-dd-yyyy hh:mm Z"); 
parsedInput = inputFormatter.parse(inputDate); 

// parsedInput -> Tue Jan 19 06:01:00 CST 2017 -> When system time is Shanghai time 
// parsedInput -> Thu Jan 19 17:31:00 IST 2017 -> When system time is Kolkata time 


SimpleDateFormat formatter = new SimpleDateFormat("MM-dd-yyyy hh:mm a Z"); 
TimeZone gmt = TimeZone.getTimeZone("GMT"); 
formatter.setTimeZone(gmt); 
String formattedDate = formatter.format(parsedInput); 

// formattedDate -> 01-18-2017 10:01 PM +0000 -> When system time is Shanghai time (Incorrect) 
// formattedDate -> 01-19-2017 12:01 PM +0000 -> When system time is Kolkata time 
+0

*「火1月19日午前六時01分00秒CST 2016 - システム時刻が上海の時間である>」<* - それだけのタイプミスですかそれは本当に年を変更ん2016年に? –

+1

「24時間」とはどういう意味ですか?入力と出力の両方で 'hh'(12時間制)を使用していることに注意してください。 –

+4

多くのタイムゾーンの略語は、あまりにもあいまいです。この場合、CSTが何を意味すると思いますか? –

答えて

4

避け擬似時間帯に上記snippettにAsia/Shanghai

3-4文字のタイムゾーンの省略形をGMTを交換することにより、あなたの現在のシステムでそれを再現することができますゾーン。それらは標準化されていません。彼らはユニークではありません!

CSTは、アメリカ標準では「中国標準時」、または「中部標準時」である可能性があります。 があるかどうかわかりません。

別の例:ISTは、「インド標準時」または「アイルランド標準時」などを意味する場合があります。

これらの疑似ゾーンを確実に解読することは不可能です。 Joda-Timeライブラリには、試しても拒否するという賢明な方針があります。残念ながら、java.timeクラスは解析時に推測を行いますが、結果は期待したゾーンではない可能性があります。

これらの無駄な疑似ゾーンを使用しないでください。 continent/regionAmerica/Chicago,Asia/Kolkata,Pacific/Aucklandなど)の形式のproper time zone nameを使用します。

あなたは今java.timeクラスに取って代わらレガシー、ある厄介な古い日時のクラスを使用しているレガシー日付時刻クラスに

を避けてください。

回避策

すべてのあなたの入力が同じ時間帯のために意図されているわかっている場合は、ZonedDateDateを生成するためにZoneIdとして意図されたゾーンを適用し、LocalDateTimeとして擬似ゾーンおよびプロセスを切り落とします。これから、InstantをUTC時間に抽出することができます。

String input = "01-19-2017 06:01".replace(" " , "T") ; // Insert a “T” to comply with standard ISO 8601 format used by default in java.time. 
LocalDateTime ldt = LocalDateTime.parse(input); // Lacks any concept of time zone or offset-from-UTC. So *not* an actual moment on the timeline. 
ZoneId z = ZoneId.of("America/Chicago"); // Assuming “CST” meant this zone in North America. 
ZonedDateTime zdt = ldt.atZone(z); // Assign a time zone to determine an actual moment on the timeline. 
Instant instant = zdt.toInstant(); // Extract a value in UTC. 

インドでは、同じ時刻を壁時計のレンズで見ることができます。

ZonedDateTime zdtKolkata = zdt.withZoneSameInstant(ZoneId.of("Asia/Kolkata")) ; 

は、デフォルトのゾーンに頼ることはありません

あなたのJVMの現在のデフォルトのタイムゾーンは、そのJVM内で実行任意のアプリのいずれかのスレッドで任意のコードによっていつでも変更することができます。これはいつでも変わる可能性があるので、一定の価値に頼ることはできません。

タイムゾーンのオプションの引数を省略すると、日時クラスは現在の既定のタイムゾーンを暗黙に適用します。したがって、解決策は簡単です:期待/希望のタイムゾーンを常に指定してください

上記のコード例では、機会ごとにゾーンを指定する方法に注目してください。

(ちなみにLocaleため同上は、。明示的に指定するのではなく、現在のデフォルトに依存している。)

0

例えば、同様inputFormatterTimeZoneを設定してみてください:

SimpleDateFormat inputFormatter = new SimpleDateFormat("MM-dd-yyyy hh:mm Z"); 
inputFormatter.setTimeZone(TimeZone.getTimeZone("GMT")); 

あなたはタイムゾーンを指定しない場合、それはので、あなたのケースでAsia/Shanghaiで、どのアカウントにデフォルトの値をとります、不正確な結果。

あなたはCSTが実際の時間でないなどの

+0

解析する前に 'inputFormatter'の時間帯を設定しても影響はありません..まだ同じです。 –

2

あなたの問題は、CSTの曖昧さです。ほとんどの場合、SimpleDateFormatは期待どおり中央標準時としてCSTを認識します。しかし、あなたのコンピュータがShanghai Timeを実行しているとき、これはフォーマッタのカレンダーのタイムゾーンになり、CSTを上海時と同じ中国標準時として突然理解します。

したがって、Darshan Mehta’s solutionは、inputFormatterのタイムゾーンを中国標準時以外に設定すると、自分のコンピュータで動作します。なぜそれがあなたの上で動作しなかったのか分かりません(私はTimeZone.getTimeZone("America/Chicago")にCSTの意図された解釈に合うように設定しました)。

ただし、3文字と4文字のタイムゾーンの略語を完全に避けることが適切かつ適切な解決策です。あなたのものは、トラブルの原因となる多くのもののほんの一例に過ぎません。あなたは、UTCからのオフセットの明示的なゾーンを使用して入力文字列を与えることができれば、そのようには決してあいまいです:お使いのコンピュータのタイムゾーンの設定に関係なく、期待しないよう

String inputDate = "01-19-2017 06:01 -0600"; 

今、あなたのコードが動作します。あなたがすでに持っているパターン文字列のZは、-0600とよく一致します。

Java 8の日付と時刻のクラスを使用することができれば、自分で自分に切り替えることができます。 Java 6と7にバックポートされているので、「Java 8の日付と時刻のクラス」と呼ぶのをためらっています。したがって、Java 8に到達するまでライブラリの依存関係で暮らすことができれば、あらゆる機会を取る必要があります。より新しいクラスは、プログラマーにやさしく、作業に便利です。簡単な例あなたが始めるために:

String inputDate = "01-19-2017 06:01 -0600"; 
    DateTimeFormatter inputFormatter = DateTimeFormatter.ofPattern("MM-dd-yyyy HH:mm Z"); 
    ZonedDateTime parsedInput = ZonedDateTime.parse(inputDate, inputFormatter); 

    OffsetDateTime gmtTime = parsedInput.toOffsetDateTime().withOffsetSameInstant(ZoneOffset.UTC); 
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM-dd-yyyy hh:mm a Z"); 
    String formattedDate = gmtTime.format(formatter); 
    System.out.println(formattedDate); // prints 01-19-2017 12:01 PM +0000 
関連する問題