web-dev-qa-db-ja.com

androidでGMT TimeZoneからIST TimeZoneおよびその逆に日付を解析する方法

IST(インド標準時)のバックエンドから日付/時刻を取得するプロジェクトに取り組んでいます"2013-01-09T19:32:49.103+05:30"。ただし、次のDateFormatを使用して解析する場合

DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");

解析が続きます。

Date date = sdf.parse("2013-01-09T19:32:49.103+05:30");


System.out.println("XYZ ==============>"+date);

出力としてGMT形式で日付を表示します

Wed Jan 09 14:02:49 GMT+00:00 2013.

TimeZoneクラスを使用して試してみました。

TimeZone timeZone=TimeZone.getTimeZone("IST");
sdf.setTimeZone(timeZone);

しかし、効果はありません。

GMTではなくDate形式の日付を持つISTクラスオブジェクトを取得するにはどうすればよいですか...

適切な解決策を提供してください。

編集:

これはコードがどのように見えるかです:

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");

TimeZone timeZone=TimeZone.getTimeZone("IST");
sdf.setTimeZone(timeZone);

Date date = sdf.parse("2013-01-09T19:32:49.103+05:30");
String formattedDate=sdf.format(date);

System.out.println("XYZ ==============>"+formattedDate);
13
Amritpal Singh

日付にはタイムゾーンがありません。 1970年1月1日00:00:00 GMT以降のミリ秒数の単なる保持者です。次の例のように、解析に使用したものと同じDateFormatを使用して、ISTタイムゾーンを設定し、日付をフォーマットします

    DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
    Date date = sdf.parse("2013-01-09T19:32:49.103+05:30"); 
    sdf.setTimeZone(TimeZone.getTimeZone("IST"));
    System.out.println(sdf.format(date));

出力

2013-01-09T19:32:49.103+05:30

1.7以降、XXXパターンはISO 8601タイムゾーン(-08:00)に使用されることに注意してください。 1.6を使用している場合は、Zを試してください。フォーマットパターンの詳細については、SimpleDateFormat APIを参照してください。

27

GMTではなくIST形式の日付を持つDateクラスオブジェクトを取得するにはどうすればよいですか...

できません。 Dateには、フォーマットまたはタイムゾーンがありません。 UTCの1970年1月1日午前0時のUnixエポックからのミリ秒数を単に表します。代わりに、 Date.toString()alwaysはデフォルトのタイムゾーンを使用します。

特定の形式とタイムゾーンを使用するには、Date.toString()の代わりに DateFormat を使用します。 DateFormat.setTimeZone() でタイムゾーンを設定し、 DateFormat.format() を使用してDateStringに変換できます。 。 DateFormat自体には、作成のためのファクトリメソッドがいくつかあります。特定のパターンを指定する場合は、 SimpleDateFormat を使用できます。

アブが言うように、 Joda Timeは組み込みのAPIよりもはるかに優れた日付/時刻APIです。ただし、日付/時刻をフォーマットするだけの場合、標準ライブラリは悪い仕事をしません。 DateFormatとそのサブクラスは一般にnotスレッドセーフであることに注意してください。

3
Jon Skeet

tl; dr

OffsetDateTime.parse( "2013-01-09T19:32:49.103+05:30" )  // Parsed.
              .toInstant()                               // Adjusted to UTC.

IdeOne.comのライブコード を参照してください。

ISO 8601

2013-01-09T19:32:49.103+05:30の入力文字列は、たまたま標準のISO 8601形式です。末尾の+05:30は、インドで使用される5時間半先の offset-from-UTC を示します。

Java.time

Java.timeクラスに取って代わられた、今ではレガシーである面倒な古い日時クラスを使用しています。

Java.timeクラスは、日時値を表す文字列を解析/生成するときに、デフォルトでISO 8601形式を使用します。したがって、書式設定パターンを指定する必要はまったくありません。

入力は、UTCからのオフセットを使用してタイムライン上の瞬間を表すため、 OffsetDateTime オブジェクトとして解析します。

OffsetDateTime odt = OffsetDateTime.parse( "2013-01-09T19:32:49.103+05:30" );

odt.toString():2013-01-09T19:32:49.103 + 05:30

[〜#〜] utc [〜#〜] valueで単純なオブジェクトを取得するには、Instantを抽出します。このInstantクラスは、Java.timeの基本的なビルディングブロッククラスです。 Instant クラスは、 [〜#〜] utc [〜#〜] のタイムライン上の瞬間を表します。解像度は nanoseconds (小数部の最大9桁)。

OffsetDateTimeInstantに加えて ZoneOffset と考えることができます。

Instant instant = odt.toInstant();  // UTC.

toStringを呼び出すと、Stringオブジェクトが標準のISO 8601形式で生成されます。最後のZZuluの略で、UTCを意味します。

instant.toString():2013-01-09T14:02:49.103Z

Instantは、さまざまな形式の文字列を生成するときなど、さまざまな方法で制限されます。そのため、オフセットとして [〜#〜] utc [〜#〜] に調整されたOffsetDateTimeを使用することができます。言い換えると、ゼロのオフセット。 ZoneOffsetクラスは、UTCの定数 ZoneOffset.UTC を保持します。

OffsetDateTime odtUtc = odt.withOffsetSameInstant( ZoneOffset.UTC );

Instantにオフセット(またはタイムゾーン)を適用することもできます。 atOffset またはatZoneを呼び出します。

Instantクラスは、Java.timeの基本的なビルディングブロッククラスです。ベストプラクティスとしてコードで頻繁に使用される可能性が高いのは、ほとんどの作業をUTCで行うことです。

OffsetDateTime odt = instant.atOffset( ZoneOffset.ofHoursMinutes( 5 , 30 ) );

タイムゾーン

UTCからのオフセットはではなくタイムゾーンであることに注意してください。タイムゾーンは、 サマータイム(DST) などの異常を処理するためのオフセットplus過去および現在の一連のルールです。したがって、正しいゾーンが確実にわかっている場合は、単なるオフセットよりもタイムゾーンの方が常に適しています。

適切なタイムゾーン名 を、 continent/regionAmerica/Montreal などのAfrica/Casablancaの形式で指定します、またはPacific/AucklandESTISTなどの3〜4文字の略語は、not真のタイムゾーンであり、標準化されておらず、一意でもない(!)。

目的のタイムゾーンがわかっている場合は、ZoneIdを適用してZonedDateTimeオブジェクトを取得します。ただし、入力データのソースを確認せずに想定しないでください。多くの異なるゾーンが特定のオフセットを共有する場合があります。たとえば、ここでの入力の場合、オフセット+05:30は、インド(Asia/Kolkata)とスリランカ(Asia/Colombo)の両方で今日使用されています。これらの2つのタイムゾーンには、過去、現在、または将来のさまざまな異常に対するさまざまなルールがあります。

ZoneId z = ZoneId.of( "Asia/Kolkata" );
ZonedDateTime zdt = odt.atZoneSameInstant( z );

toStringZonedDateTimeメソッドは、タイムゾーンの名前を角かっこで追加することにより、標準ISO 8601形式を賢明な方法で拡張します。この場合、[Asia/Kolkata]

zdt.toString():2013-01-09T19:32:49.103 + 05:30 [アジア/コルカタ]


Java.timeについて

Java.time フレームワークはJava 8以降に組み込まれています。これらのクラスは、面倒な古い legacy のような日時クラスに取って代わります- Java.util.DateCalendar 、& SimpleDateFormat

Joda-Time プロジェクトは、現在は メンテナンスモード であり、Java.timeへの移行を推奨しています。

詳細については、 Oracle Tutorial を参照してください。また、Stack Overflowで多くの例と説明を検索してください。指定は JSR 31 です。

Java.timeクラスはどこで入手できますか?

  • Java SE 8 および SE 9 以降
    • ビルトイン。
    • 標準の一部Java実装がバンドルされたAPI。
    • Java 9は、いくつかのマイナーな機能と修正を追加します。
  • Java SE 6 および SE 7
  • Android
    • ThreeTenABP プロジェクトは適応しますThreeTen-Backport(上記)Android具体的に。
    • 使用方法… を参照してください。

ThreeTen-Extra プロジェクトは、追加のクラスでJava.timeを拡張します。このプロジェクトは、Java.timeに将来追加される可能性のある証明の場です。 IntervalYearWeekYearQuarter などの便利なクラスがあります。 、および more

2
Basil Bourque

これを行うには、Calendarクラスを使用します。以下のスニペットを確認してください。

Calendar calendar = Calendar.getInstance();
calendar.setTimeZone(TimeZone.getTimeZone("GMT"));
calendar.setTimeInMillis(<--time stamp-->);
//calendar.setTime(<--date object of gmt date-->); 
SimpleDateFormat sdf = new SimpleDateFormat("MMM dd, yyyy 'at' hh:mm a");
sdf.setTimeZone(TimeZone.getDefault());
String result=sdf.format(calendar.getTime()); 
1
Kalpesh