1概要

私たちが時間と日付を扱うときはいつでも、私たちは参照の枠組みが必要です。その標準はhttps://en.wikipedia.org/wiki/Coordinated

Universal

Time[UTC]ですが、一部のアプリケーションではhttps://en.wikipedia.org/wiki/Greenwich

Mean

Time[GMT]も参照してください。

つまり、UTCが標準であり、GMTがタイムゾーンです。

これは何を使うべきかに関してウィキペディアが私達に言うものです:

ほとんどの目的のために、UTCはグリニッジ標準時(GMT)と交換可能であると考えられるが、GMTはもはや科学界によって正確に定義されていない。

言い換えれば、UTCでタイムゾーンオフセット付きのリストをコンパイルすれば、GMT用にもそれができます。

まず、これを達成するためのJava 8の方法を見て、次にJava 7で同じ結果を得ることができる方法を見ていきます。

===

2ゾーンのリストを取得する

まず最初に、定義されているすべてのタイムゾーンのリストを取得する必要があります。

この目的のために、

ZoneId

クラスには便利な静的メソッドがあります。

Set<String> availableZoneIds = ZoneId.getAvailableZoneIds();

次に、

Set

を使用して、対応するオフセットを含むタイムゾーンのソートされたリストを生成します。

public List<String> getTimeZoneList(OffsetBase base) {

    LocalDateTime now = LocalDateTime.now();
    return ZoneId.getAvailableZoneIds().stream()
      .map(ZoneId::of)
      .sorted(new ZoneComparator())
      .map(id -> String.format(
        "(%s%s) %s",
        base, getOffset(now, id), id.getId()))
      .collect(Collectors.toList());
}

上記の方法は、見たいオフセットを表す

enum

パラメータを使用します。

public enum OffsetBase {
    GMT, UTC
}

それでは、コードの詳細を見てみましょう。

利用可能なゾーンIDをすべて取得したら、__LocalDateTime.now()で表される実際の時間参照が必要になります。

その後、Java Stream APIを使用して、タイムゾーン

String

idのセット内の各エントリを反復処理し、対応するオフセットを持つフォーマットされたタイムゾーンのリストに変換します。

これらの各エントリに対して、__map(ZoneId

of)を使用して

ZoneId

インスタンスを生成します。

===

3オフセットを取得する

実際のUTCオフセットも見つける必要があります。たとえば、中央ヨーロッパ標準時の場合、オフセットは__ 01:00です。

  • 特定のゾーンのUTCオフセットを取得するには、

    LocalDateTimeのgetOffset()

    メソッドを使用します。

また、Javaは

00:00

オフセットを

Z

として表しています。

そのため、オフセットがゼロのタイムゾーンで一貫した外観の

String

を使用するには、

Z



+ 00:00:

に置き換えます。

private String getOffset(LocalDateTime dateTime, ZoneId id) {
    return dateTime
      .atZone(id)
      .getOffset()
      .getId()
      .replace("Z", "+00:00");
}

===

4ゾーンを作る

比較できる

オプションで、オフセットに従ってタイムゾーンをソートすることもできます。

これには、

ZoneComparator

クラスを使用します。

private class ZoneComparator implements Comparator<ZoneId> {

    @Override
    public int compare(ZoneId zoneId1, ZoneId zoneId2) {
        LocalDateTime now = LocalDateTime.now();
        ZoneOffset offset1 = now.atZone(zoneId1).getOffset();
        ZoneOffset offset2 = now.atZone(zoneId2).getOffset();

        return offset1.compareTo(offset2);
    }
}

===

5タイムゾーンの表示

あとは、それぞれの

OffsetBase enum

値に対して

getTimeZoneList()

メソッドを呼び出してリストを表示するだけで、上記の要素をまとめることができます。

public class TimezoneDisplayApp {

    public static void main(String... args) {
        TimezoneDisplay display = new TimezoneDisplay();

        System.out.println("Time zones in UTC:");
        List<String> utc = display.getTimeZoneList(
          TimezoneDisplay.OffsetBase.UTC);
        utc.forEach(System.out::println);

        System.out.println("Time zones in GMT:");
        List<String> gmt = display.getTimeZoneList(
          TimezoneDisplay.OffsetBase.GMT);
        gmt.forEach(System.out::println);
    }
}

上記のコードを実行すると、UTCとGMTのタイムゾーンが表示されます。

これが、出力がどのようになるかのスニペットです。

Time zones in UTC:
(UTC+14:00) Pacific/Apia
(UTC+14:00) Pacific/Kiritimati
(UTC+14:00) Pacific/Tongatapu
(UTC+14:00) Etc/GMT-14

=== ** 6. Java 7以前

Java 8では、

Stream

および

DateとTime

のAPIを使用して、この作業が簡単になります。

ただし、Java 7がプロジェクト以前にある場合は、

getAvailableIDs()メソッドを使用して

java.util.TimeZone__クラスを使用しても同じ結果を得ることができます。

public List<String> getTimeZoneList(OffsetBase base) {
    String[]availableZoneIds = TimeZone.getAvailableIDs();
    List<String> result = new ArrayList<>(availableZoneIds.length);

    for (String zoneId : availableZoneIds) {
        TimeZone curTimeZone = TimeZone.getTimeZone(zoneId);
        String offset = calculateOffset(curTimeZone.getRawOffset());
        result.add(String.format("(%s%s) %s", base, offset, zoneId));
    }
    Collections.sort(result);
    return result;
}

Java 8コードとの主な違いは、オフセット計算です。


  • TimeZone()



    getRawOffset()

    メソッドから取得した

    rawOffset

    は、タイムゾーンのオフセットをミリ秒単位で表します** 。

したがって、

TimeUnit

クラスを使用してこれを時間と分に変換する必要があります。

private String calculateOffset(int rawOffset) {
    if (rawOffset == 0) {
        return "+00:00";
    }
    long hours = TimeUnit.MILLISECONDS.toHours(rawOffset);
    long minutes = TimeUnit.MILLISECONDS.toMinutes(rawOffset);
    minutes = Math.abs(minutes - TimeUnit.HOURS.toMinutes(hours));

    return String.format("%+03d:%02d", hours, Math.abs(minutes));
}

===

7. 結論

このクイックチュートリアルでは、利用可能なすべてのタイムゾーンのリストを、UTCとGMTのオフセットを使用してコンパイルする方法を説明しました。

そして、いつものように、この例の完全なソースコードはhttps://github.com/eugenp/tutorials/tree/master/java-dates[GitHubで利用可能]です。