web-dev-qa-db-ja.com

Joda-Timeを使用して特定の日付とタイムゾーンのUTCオフセットを取得する

2013年1月20日、2012年8月8日などの形式の日付があり、それぞれに固有のタイムゾーンがあります。したがって、たとえば、20Jan2013のタイムゾーンIDはオーストラリア/メルボルン、08Aug2012のIDはヨーロッパ/ロンドンになります。これらのタイムゾーンと日付に基づいて、指定した日付のそのタイムゾーンのUTCオフセットを計算します。これまでにこれを思いつきました:

DateTimeFormatter dtf = DateTimeFormat.forPattern("ZZ");
DateTimeFormatter dtf1 = DateTimeFormat.forPattern("ddMMMYYYY");

DateTimeZone zone = DateTimeZone.forID("Australia/Melbourne");  

DateTime thisDate = dtf1.parseDateTime("30Jul2013");                                            
System.out.println("\nZone: " + thisDate.withZone(zone));

これは私に出力を与えます:

Zone: 2013-07-30T00:00:00.000+10:00

これは正しいですが、これからUTCオフセット(この場合は+10:00)だけを抽出したいと思います。これを行う方法を探しましたが、何も見つかりません。これを行う方法はありますか?私が見る唯一のオプションは、出力を文字列に変換し、substringメソッドを使用してUTCオフセットを取得することです。

上記のコードはDST(夏時間)を考慮に入れています。したがって、たとえば次の場合:DateTime thisDate = dtf1.parseDateTime( "30Jan2013");

出力は次のようになります:2013-01-30T00:00:00.000 + 11:00

(+10:00ではなく最後に+11:00)

つまり、基本的に私がする必要があるのは、2013-07-30T00:00:00.000 + 11:00から+11:00を抽出する方法を見つけることだけです。助けてください!

14
PrincessBelle

時間帯の名前とオフセットを時間単位で取得する簡単な方法

public static String getCurrentTimeZoneOffset() {
    DateTimeZone tz = DateTimeZone.getDefault();
    Long instant = DateTime.now().getMillis();

    String name = tz.getName(instant);

    long offsetInMilliseconds = tz.getOffset(instant);
    long hours = TimeUnit.MILLISECONDS.toHours( offsetInMilliseconds );
    String offset = Long.toString( hours );

    return name + " (" + offset + " Hours)";
    // Example: "Mountain Standard Time (-7 Hours)"
}

カップルの警告:

  • JodaTimeからデフォルトのDateTimeZoneを取得します。これを変更して、メソッドに渡される特定のDateTimeZoneを受け入れることができます。
  • これは、 "Mountain Standard Time(-7 Hours)"のような形式でそれを返しますが、非常に簡単に合うようにフォーマットすることができます。

お役に立てば幸いです。

JP

11
Joshua Pinter

Jodaが正しいオフセットを与えるためには、日付時刻のインスタントを提供する必要があります。日付時刻のインスタントがないと、オフセットが異なるため、オフセットを計算することはできません(夏時間)。これは、Jodaを使用して+ HH:mm形式でオフセットを取得する方法です。

    int offsetInMillis = DateTimeZone.forID(zoneId).getOffset(new DateTime().getMillis());
    String offset = String.format("%02d:%02d", Math.abs(offsetInMillis / 3600000),
            Math.abs((offsetInMillis / 60000) % 60));
    offset = (offsetInMillis >= 0 ? "+" : "-") + offset; 
3
Shweta

タイムゾーンのオフセットだけが必要な場合は、DateTimeZone.forID()を使用してタイムゾーンを取得し、次にtz.getOffset(instant)を使用してUTCへのオフセットをミリ秒単位で取得します。

UTCへのオフセットを計算するためにインスタントが必要なのは奇妙に見えるかもしれませんが、これは夏時間とタイムゾーンの変化を考慮するために必要です。はい、国は時々タイムゾーンを変更します:

タイムゾーンデータが変更される理由

タイムゾーン設定はローカルで採用されており、世界のタイムゾーン権限はありません。

[〜#〜] edit [〜#〜]これにより、正しい結果が得られます。

    DateTimeFormatter dtf1 = DateTimeFormat.forPattern("ddMMMYYYY");

    DateTimeZone zone = DateTimeZone.forID("Australia/Melbourne");  

    DateTime thisDate = dtf1.parseDateTime("30Jul2013").withZone(zone);                                            
    assertEquals( 10 * CommonConstants.MILLISECONDS_PER_HOUR,
        zone.getOffset( thisDate ) );

thisDate.get

3
Aaron Digulla

Java 8 より優れた日付と時刻の処理が導入されました その領域における言語の以前の制限の一部に対処します。私のプロジェクトのいくつかは、Jodaではなくそれを使用し始めています。

Java.timeパッケージの使用:

    ZonedDateTime dateTime = LocalDate.of(2013 , 1 , 20).atStartOfDay( ZoneId.of("Australia/Melbourne"));
    ZoneOffset zo = dateTime.getOffset();
    int offset = zo.getTotalSeconds();

    long hours = TimeUnit.SECONDS.toHours(offset);
    long minutes = TimeUnit.SECONDS.toMinutes(offset % 3600);

時間変数は11に設定され、分は0に設定されます。

また、カナダ東部のニューファンドランドやラブラドールなど、時間の一部であるタイムゾーンの分オフセットも計算します。

ZonedDateTime dateTime = LocalDate.of(2013, 1, 20).atStartOfDay( ZoneId.of("Canada/Newfoundland"));

この場合、オフセットは-03:30(UTCから3時間半遅れ)、hoursは-3、minutesは-30です。

時間と分の整数ではなく、文字列表現の場合は、ZoneOffsetのtoString()メソッドを使用します。上記の例では、次のように使用します。

String offsetString = zo.toString();
2
sjgp

オフセットとタイムスタンプがわかっているので、現在の時刻を取得するには、

 public static String formatMonthDayMinuteByGivenUtcOffset(long timestamp, int offset) {
        return JODA_FORMATTER.print(createDateTime(timestamp, offset));
    }
0
Waran-