良いあなたがSimpleDateFormat
と解決策を見つけました。古いクラス(Date
、Calendar
、SimpleDateFormat
)がlots of problemsとdesign issuesを持っていて、それらが新しいAPIに置き換えられているからです。
入力String
(2017-09-16T05:06:18.157
)には日付(年/月/日)と時間(時/分/秒/ミリ秒)のみが含まれますが、タイムゾーン情報は含まれません。したがって、parseDateTime
を呼び出すと、Joda-TimeはJVMのデフォルトタイムゾーンにあると仮定します。
入力がUTCであることがわかっているが、入力自体に情報がない場合は、それを伝える必要があります。一つの方法は、フォーマッタに設定することである。
// set the formatter to UTC
DateTimeFormatter inputFormatter = DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ss.SSS")
.withZone(DateTimeZone.UTC);
// DateTime will be in UTC
DateTime parsed = inputFormatter.parseDateTime("2017-09-16T05:06:18.157");
別の方法は、最初org.joda.time.LocalDateTime
(タイムゾーンなしの日付と時刻を表すクラス)への入力を解析し、その後UTCにDateTime
に変換することです:
// parse to LocalDateTime
DateTime = parsed = LocalDateTime.parse("2017-09-16T05:06:18.157")
// convert to a DateTime in UTC
.toDateTime(DateTimeZone.UTC);
はUTC 2017-09-16T05:06:18.157Z
に対応し、同じDateTime
を生成両方。
(実際のタイムゾーンではありません - 以下のようにより)「ISTのタイムゾーン」にそれをフォーマットするには、あなたはまた、フォーマッタでタイムゾーンを設定することができます
// convert to Asia/Kolkata
DateTimeFormatter outputFormatter = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss")
.withZone(DateTimeZone.forID("Asia/Kolkata"));
System.out.println(outputFormatter.print(parsed));
それともにDateTime
を変換することができますが使用して、別のタイムゾーン、withZone()
method:
DateTimeFormatter outputFormatter = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss");
// convert to Asia/Kolkata
System.out.println(outputFormatter.print(parsed.withZone(DateTimeZone.forID("Asia/Kolkata"))));
の両方が印刷されます:
(一部tricky detailsで)JVMのデフォルトのタイムゾーンを取得し、あなたがDateTimeZone.getDefault()
を使用しているあなたのコードでは2017年9月16日10時36分18秒
、。しかし、デフォルトのタイムゾーンcan be changed without notice, even at runtimeがありますので、どちらを使用するかを指定する方が良いです。
また、短い名前はISTのように、実際のタイムゾーンではありません。常にIANA timezones names(常にの形式、たとえばAsia/Kolkata
またはEurope/Berlin
)を使用することをお勧めします。
ambiguous and not standardであるため、3文字の略語(IST
またはなど)は使用しないでください。 this listで、ISTは「インド標準時」、「イスラエル標準時」、「アイルランド標準時」のいずれかにすることができます。
DateTimeZone.getAvailableIDs()
に電話すると、使用可能なタイムゾーンのリストが表示されます(システムに最適なタイムゾーンを選択できます)。
Javaの新しい日付/時刻API
ジョダ時はメンテナンスモードにあり、新しいAPIに置き換えられているので、私はそれを使用して新しいプロジェクトを開始することはお勧めしません。 joda's websiteでも、"Joda-Timeは主に完成したプロジェクトとみなされていることに注意してください.Java SE 8を使用している場合は、java.time(JSR-310)に移行してください。。
Joda-Timeから新しいAPIへの移行ができない(またはしたくない)場合は、このセクションを無視してください。
ThreeTen Backportは、Java 8の新しい日付/時刻クラスのための素晴らしいバックポートです。それを動作させるには、ThreeTenABP(詳細はhereの使い方)が必要です。
この新しいAPIには、状況ごとにlots of different date/time typesがあります。
最初に入力をorg.threeten.bp.LocalDateTime
に解析すると、org.threeten.bp.ZoneOffset
を使用してUTCに変換され、org.threeten.bp.OffsetDateTime
となります。
その後、私は(別のタイムゾーンにこれを変換し、それをフォーマットするorg.threeten.bp.format.DateTimeFormatter
を使用するorg.threeten.bp.ZoneId
を使用し、これは@Ole V.V's commentによって示唆されているものは基本的である - ちょうどそれがどのように単純明快を示すために、に多くの異なるものが存在しないとして、 )ん:
// parse to LocalDateTime
OffsetDateTime parsed = LocalDateTime.parse("2017-09-16T05:06:18.157")
// convert to UTC
.atOffset(ZoneOffset.UTC);
// convert to Asia/Kolkata
ZoneId zone = ZoneId.of("Asia/Kolkata");
DateTimeFormatter outputFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
System.out.println(outputFormatter.format(parsed.atZoneSameInstant(zone)));
出力は次のようになります。
2017年9月16日10時36分18秒
はSへようこそタックオーバーフロー。 Stack Overflowは、検索エンジンに代わるものではありません。この質問は何度も答えられましたが、あなたの検索エンジンはあなたの答えをはるかに早く見つけました。 –
Joda-Timeはこれまでに投稿された回答に使われている旧式のSimpleDateFormatより(私が知っている限り)優れています。ベストは[ThreeTenABP](https://github.com/JakeWharton/ThreeTenABP)です。 –
あなたのタイムスタンプ文字列はISO 8601に準拠しています。これは、Joda-Timeと確信している形式であり、確かにThreeTenABPがデフォルトとして認識しているため、解析に明示的なフォーマッタは必要ありません。 –