web-dev-qa-db-ja.com

Java:タイムゾーンの違いを計算する

Javaの特定の日付とタイムゾーンのGMTとの時差を取得するにはどうすればよいですか?

特定のタイムゾーンがDSTにあるかどうかを判断するのは、非常に簡単です。

boolean isIsraelInDST = TimeZone.getTimeZone("Israel").inDaylightTime(new Date());

実際の時差を取得するにはどうすればよいですか?

12
Adam Matan

TimeZone.getRawOffset()を使用します。このタイムゾーンの標準時間を取得するためにUTCに追加する時間をミリ秒単位で返します。この値は夏時間の影響を受けないため、生のオフセットと呼ばれます

DSTを含むオフセットが必要な場合は、TimeZone.getOffset(long date)を使用します。メソッドに具体的な日付を指定する必要があります。例:now --System.currentTimeMillis()

22

GetRawOffsetに夏/冬の時間オフセットを追加することをお勧めします。

    TimeZone tz1 = TimeZone.getTimeZone("GMT");
    TimeZone tz2 = TimeZone.getTimeZone("America/New_York");
    long timeDifference = tz1.getRawOffset() - tz2.getRawOffset() + tz1.getDSTSavings() - tz2.getDSTSavings();
11
Andy Malakov

tl; dr

ZoneId.of( "Pacific/Auckland" )   // Specify a time zone.
    .getRules()                   // Get the object representing the rules for all the past, present, and future changes in offset used by the people in the region of that zone.
    .getOffset( Instant.now() )   // Get a `ZoneOffset` object representing the number of hours, minutes, and seconds displaced from UTC. Here we ask for the offset in effect right now.
    .toString()                   // Generate a String in standard ISO 8601 format.

+13:00

ある日付の最初の瞬間。

ZoneId.of( "Pacific/Auckland" )
    .getRules()
    .getOffset( 
        LocalDate.of( 2018 , Month.AUGUST , 23 )          // Specify a certain date. Has no concept of time zone or offset.
        .atStartOfDay( ZoneId.of( "Pacific/Auckland" ) )  // Determine the first moment of the day on that date in that region. Not always `00:00:00` because of anomalies such as Daylight Saving Time.
        .toInstant()                                      // Adjust to UTC by extracting an `Instant`. 
    ) 
    .toString()

+12:00

従来の日時クラスを避ける

TimeZoneクラスがレガシーになっているため、他の回答は時代遅れになっています。これと他の厄介な古い日時クラスは、Java.time時間クラスに取って代わられます。

Java.time

ここでは、従来のZoneIdクラスの代わりに、 ZoneOffsetZoneRules、およびTimeZoneを使用します。

適切なタイムゾーン名continent/regionの形式で指定します。たとえば、 America/MontrealAfrica/CasablancaPacific/Aucklandなどです。 ESTISTなどの3〜4文字の省略形は、ではなく真のタイムゾーンであり、標準化されておらず、一意でもないため、絶対に使用しないでください(!)。

ZoneId z = ZoneId.of( "Africa/Tunis" ) ;  

そのゾーンのルールを取得します。

ZoneRules rules = z.getRules() ;

特定の時点で夏時間(DST)が有効になっているかどうかをルールに確認します。モーメントをInstantとして指定します。 Instant クラスは、タイムライン上の瞬間を [〜#〜] utc [〜#〜] で表し、解像度は ナノ秒 (最大9(9 )小数の桁)。

Instant instant = Instant.now() ;  // Capture current moment in UTC.
boolean isDst = rules.isDaylightSavings( instant ) ;

実際の時差を取得するにはどうすればよいですか?

意味はわかりませんが、その時点で有効な offset-from-UTC をゾーンよりも要求していると思います。オフセットは、 [〜#〜] utc [〜#〜] からの時間、分、秒の変位です。 ZoneOffset クラスを使用してオフセットを表します。タイムゾーンは、特定の地域の人々が使用するオフセットの過去、現在、および将来の変化の履歴です。 ZoneId クラスを使用してタイムゾーンを表します。

地域によってはオフセットが時間とともに変化する可能性があるため、オフセットを要求するときは少し時間をとる必要があります。

ZoneOffset offset = rules.getOffset( instant ) ;

そのオフセットを表す文字列を ISO 8601 標準形式で生成します。

String output output = offset.toString() ;

オフセットは合計秒数として要求できます。

int offsetInSeconds = offset.getTotalSeconds() ;

についてJava.time

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

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

詳細については、 Oracleチュートリアル を参照してください。そして、StackOverflowで多くの例と説明を検索してください。仕様は JSR 31 です。

JDBC 4.2 以降に準拠した JDBCドライバー を使用すると、Java.timeオブジェクトをデータベースと直接交換できます。文字列やJava.sql。*クラスは必要ありません。

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

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

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

8
Basil Bourque

これは古いスレッドだと思いますが、最近同様の要件があったため、これを追加します。これにより、現在の時間(エポックからのミリス)に基づいたミリス単位の実際の差が得られます。

    TimeZone.getTimeZone("America/New_York").getOffset(Calendar.getInstance().getTimeInMillis())
8
Vinay Rao
public String timeZone(Date date) {
    TimeZone timeZone = TimeZone.getTimeZone("America/New_York");
    long millis = timeZone.getRawOffset() + (timeZone.inDaylightTime(date) ? timeZone.getDSTSavings() : 0);

    return String.format("%s%s:%s",
            millis < 0 ? "-" : "+",
            String.format("%02d", Math.abs(TimeUnit.MILLISECONDS.toHours(millis))),
            String.format("%02d", Math.abs(TimeUnit.MILLISECONDS.toMinutes(millis) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(millis))))
    );
}
2
yogeshd