60

電話のタイムゾーンを[+/-]hh:mmの形式で保存する必要があります

これに対処するためにTimeZoneクラスを使用していますが、取得できる形式は次のとおりです。

PST -05:00
GMT +02:00

結果を部分文字列にしたくないのですが、そのタイムゾーンの名前(GMT / CET / PST ...)ではなく値のみを取得するように設定できるキーまたはオプションフラグはありますか?

4

8 に答える 8

105

電話のタイムゾーンを[+/-]hh:mmの形式で保存する必要があります

いいえ、しません。オフセットだけでは不十分です。タイムゾーン名/ID全体を保存する必要があります。たとえば、現在のオフセットが+02:00であるオスロに住んでいますが、冬(のため)は+01:00です。標準時間と夏時間の正確な切り替えは、調査したくない要因によって異なります。

したがって、保存する代わりに+ 02:00(または保存する必要があります+ 01:00か?)"Europe/Oslo"、データベースに保存します。これで、次を使用して完全な構成を復元できます。

TimeZone tz = TimeZone.getTimeZone("Europe/Oslo")

今日の私のタイムゾーンオフセットは何ですか?

tz.getOffset(new Date().getTime()) / 1000 / 60   //yields +120 minutes

ただし、12月も同じです。

Calendar christmas = new GregorianCalendar(2012, DECEMBER, 25);
tz.getOffset(christmas.getTimeInMillis()) / 1000 / 60   //yields +60 minutes

つまり、タイムゾーンの名前またはIDを保存し、日付を表示するたびに、固定値を保存するのではなく、現在のオフセット(今日)を確認します。TimeZone.getAvailableIDs()サポートされているすべてのタイムゾーンIDを列挙するために使用できます。

于 2012-07-09T16:46:00.707 に答える
73

@MrBean-サードパーティのWebサービスを呼び出して、Androidデバイスの現在のタイムゾーンオフセットを+/- hh:mmの形式で渡す必要がある同様の状況にありました。これが私の解決策です:

public static String getCurrentTimezoneOffset() {

    TimeZone tz = TimeZone.getDefault();  
    Calendar cal = GregorianCalendar.getInstance(tz);
    int offsetInMillis = tz.getOffset(cal.getTimeInMillis());

    String offset = String.format("%02d:%02d", Math.abs(offsetInMillis / 3600000), Math.abs((offsetInMillis / 60000) % 60));
    offset = (offsetInMillis >= 0 ? "+" : "-") + offset;

    return offset;
} 
于 2013-05-21T22:53:10.200 に答える
20

java8で、次を使用できるようになりました

Integer offset  = ZonedDateTime.now().getOffset().getTotalSeconds();

UTCから現在のシステム時間オフセットを取得します。次に、それを任意の形式に変換できます。私の場合は便利だと思いました。例:https ://docs.oracle.com/javase/tutorial/datetime/iso/timezones.html

于 2017-12-07T18:50:52.843 に答える
7

Java 8では、次のコードでこれを実現できます。

    TimeZone tz = TimeZone.getDefault();
    String offsetId = tz.toZoneId().getRules().getStandardOffset(Instant.now()).getId();

offsetId+01:00のようになります

getStandardOffset関数にはパラメータとしてが必要であることに注意しInstantてください。タイムゾーンのオフセットは時間中に変化する可能性があるため、特定のタイムゾーンのオフセットを確認する特定の時点です。一部の地域の理由により、夏時間があります。

@Tomasz Nurkiewiczが、オフセットを符号付き時間形式で直接保存するのではなく、必要になるたびにオフセットをチェックするように勧めるのは、このためだと思います。

于 2019-09-16T09:14:52.077 に答える
5
ZoneId here = ZoneId.of("Europe/Kiev");
ZonedDateTime hereAndNow = Instant.now().atZone(here);
String.format("%tz", hereAndNow);

「+0300」のような標準化された文字列表現を提供します

于 2018-06-29T15:54:28.797 に答える
4

インスタンスと。TimeZoneだけで、aのミリ秒オフセットを簡単に取得できます。次に、クラスを使用して、ミリ秒から任意の時間単位に変換できます。TimeZoneSystem.currentTimeMillis()TimeUnit

そのようです:

public static int getOffsetHours(TimeZone timeZone) {
    return (int) TimeUnit.MILLISECONDS.toHours(timeZone.getOffset(System.currentTimeMillis()));
}

または、新しいJava8時間APIをご希望の場合

public static ZoneOffset getOffset(TimeZone timeZone) { //for using ZoneOffsett class
    ZoneId zi = timeZone.toZoneId();
    ZoneRules zr = zi.getRules();
    return zr.getOffset(LocalDateTime.now());
}

public static int getOffsetHours(TimeZone timeZone) { //just hour offset
    ZoneOffset zo = getOffset(timeZone);
    TimeUnit.SECONDS.toHours(zo.getTotalSeconds());
}
于 2018-11-20T10:07:33.143 に答える
3

java.time:最新の日時API

を使用してタイムゾーンのオフセットを取得できますZonedDateTime#getOffset

DSTを監視するタイムゾーンのオフセットは、DSTの変更に従って変更されることに注意してください。他の場所(インドなど)については、修正されたままです。したがって、タイムゾーンのオフセットが表示される瞬間について言及することをお勧めします。モーメントはとして言及されInstant.now()、UTCでの日時を表します(ZこれはZuluを表し、+00:00時間のタイムゾーンオフセットを指定します)。

によって返されるすべてのタイムゾーンのオフセットを表示しZoneId.getAvailableZoneIds()ます。

import java.time.Instant;
import java.time.ZoneId;
import java.time.ZonedDateTime;

public class Main {
    public static void main(String[] args) {
        // Test
        Instant instant = Instant.now();
        System.out.println("Timezone offset at " + instant);
        System.out.println("==============================================");
        ZoneId.getAvailableZoneIds()
            .stream()
            .sorted()
            .forEach(strZoneId -> System.out.printf("%-35s: %-6s%n",
                strZoneId, getTzOffsetString(ZoneId.of(strZoneId), instant)));
    }

    static String getTzOffsetString(ZoneId zoneId, Instant instant) {
        return ZonedDateTime.ofInstant(instant, zoneId).getOffset().toString();
    }
}

出力:

Timezone offset at 2021-05-05T21:45:34.150901Z
==============================================
Africa/Abidjan                     : Z     
Africa/Accra                       : Z     
Africa/Addis_Ababa                 : +03:00
...
...
...    
W-SU                               : +03:00
WET                                : +01:00
Zulu                               : Z  

最新の日時API *の詳細については、Trail DateTimeをご覧ください。


*何らかの理由で、Java6またはJava7に固執する必要がある場合は、 Java.time機能のほとんどをJava6および7にバックポートするThreeTen-Backportを使用できます。AndroidプロジェクトおよびAndroidAPIで作業している場合レベルはまだJava-8に準拠していません。脱糖によって利用可能なJava8+APIAndroidプロジェクトでのThreeTenABPの使用方法を確認してください。

于 2021-05-05T22:18:40.793 に答える
2

私はこれが古いことを知っていますが、私は自分の意見を述べると思いました。私は仕事中のプロジェクトのためにこれをしなければなりませんでした、そしてこれは私の解決策でした。

TimeZoneクラスを使用してTimezoneを含むBuildingオブジェクトがあり、新しいクラスにzoneIdフィールドとoffsetフィールドを作成したいと考えています。

だから私がしたことは作成することでした:

private String timeZoneId;
private String timeZoneOffset;

次に、コンストラクターでBuildingオブジェクトを渡し、次のようにこれらのフィールドを設定します。

this.timeZoneId = building.getTimeZone().getID();
this.timeZoneOffset = building.getTimeZone().toZoneId().getId();

したがって、timeZoneIdは「EST」のようなものに等しく、timeZoneOffsetは「-05:00」のようなものに等しい可能性があります。

私はあなたがそうしないかもしれないことをしたくない

于 2017-04-10T15:21:42.123 に答える