betacode

Руководство Java ZoneId

  1. ZoneId
  2. Type1: Region-based ZoneId
  3. Type2: Offset-based ZoneId
  4. Type3: UTC, GMT, UT ZoneId
  5. ZoneId methods
  6. systemDefault()
  7. of(String)
  8. of(String, Map<String, String>)
  9. ofOffset(String, ZoneOffset)
  10. from(TemporalAccessor)
  11. getAvailableZoneIds()
  12. getRules()
  13. normalized()

1. ZoneId

Класс ZoneId используется для определения часового пояса и предоставления правил преобразования между LocalDateTime и Instant. С точки зрения правил смещения (offset rules), ZoneId делится на 2 типа:
  • ZoneId с фиксированным смещением часового пояса (time zone offset), таким как "UTC+07", "GMT-05:40", "UT-03", "+05:50".
  • ZoneId с нефиксированным смещением часового пояса, например "Europe/Paris". Его смещение часового пояса зависит от времени на временной шкале или зависит от дня года.
Например, ZoneId.of("Asia/Ho_Chi_Minh") является идентификатором часового пояса южного Вьетнама. В период с 1960 года по 13 июня 1975 года смещение часового пояса этой ZoneId cоставляло +8, но позже было изменено на +7 для объединения с северным Вьетнамом.
ZoneId
public abstract class ZoneId implements Serializable {
     public abstract String getId();  
     public abstract ZoneRules getRules();
     ...
}
Хотя ZoneId является абстрактным классом, он предоставляет несколько статических заводских методов для создания объектов ZoneId. Два важных свойства of ZoneId - это id и rules.
  • String id: ID уникален.
  • ZoneRules rules: Правила определения смещения часового пояса (time zone offset) в определенное время на временной шкале.
Класс ZoneOffset является подклассом of ZoneId.
Основываясь на синтаксисе of ID, ZoneId делится на 3 типа:
Type
Example
getId()
Type1
Region-based ZoneId
ZoneId.of("Europe/Paris")
Europe/Paris
Type2
Offset-based ZoneId
ZoneOffset.of("-06")
-06
Type2
Offset-based ZoneId
ZoneOffset.of("+06:05:20")
+06:05:20
Type3
UTC/GMT/UT ZoneId
ZoneId.ofOffset("UTC", ZoneOffset.of("+06"))
UTC+06
Type3
UTC/GMT/UT ZoneId
ZoneId.of("GMT-06:05:20")
GMT-06:05:20

2. Type1: Region-based ZoneId

Region-based ZoneId (ZoneId на основе смещения), значение параметра ZoneId должно быть 2 или более символов и не должно начинаться с "UTC", "GMT", "UT", "+", "-". Существует множество значений, таких как "Europe/Paris", "Asia/Ho_Chi_Minh",... Статический метод ZoneId.getAvailableZoneIds() возвращает набор этих zoneId.
public static ZoneId of(String zoneId)
Вы также можете определить географическую область и предоставить правила для нее через ZoneRulesProvider.
  • Руководство Java ZoneRulesProvider
Например:
ZoneId_region_based_ex1.java
ZoneId zoneId1 = ZoneId.of("Europe/Paris");  
ZoneId zoneId2 = ZoneId.of("Asia/Ho_Chi_Minh");  

System.out.println(zoneId1.getId()); // Europe/Paris
System.out.println(zoneId2.getId()); // Asia/Ho_Chi_Minh

// Show format of Zoned Date Time
ZonedDateTime zonedDateTime = ZonedDateTime.of(2021, 6, 22, 0, 0, 0, 0, zoneId2);
System.out.println("zonedDateTime: " + zonedDateTime); // 2021-06-22T00:00+07:00[Asia/Ho_Chi_Minh]
Region-based ZoneId содержит исторические данные о смещениях часовых поясов. Давайте рассмотрим ситуацию:
1 января 1986 года правительство Непала объявило свой часовой пояс +5h45 GMT. Это означает, что они на 15 минут быстрее, чем в соседней Индии. Этот шаг призван изменить ситуацию с соседом-гигантом и продемонстрировать национальную гордость непальского народа.
ID часового пояса Непала - "Asia/Kathmandu". Приведенный ниже пример показывает, что ZoneId.of("Asia/Kathmandu") уже содержит исторические данные:
ZoneId_nepal_ex1.java
package org.o7planning.zoneid.type.ex;

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

public class ZoneId_nepal_ex1 {

    public static void main(String[] args) {
        ZoneId nepalZoneId = ZoneId.of("Asia/Kathmandu");

        ZonedDateTime zdt1 = ZonedDateTime.of(1985, 12, 30, 0, 0, 0, 0, nepalZoneId);
        System.out.println(zdt1); // 1985-12-30T00:00+05:30[Asia/Kathmandu]

        System.out.println();

        ZonedDateTime zdt2 = ZonedDateTime.of(1986, 1, 1, 0, 0, 0, 0, nepalZoneId);
        System.out.println(zdt2); // 1986-01-01T00:15+05:45[Asia/Kathmandu]
    }
}
Output:
1985-12-30T00:00+05:30[Asia/Kathmandu]

1986-01-01T00:15+05:45[Asia/Kathmandu]
Продолжая приведенный выше пример, мы рассмотрим информацию о смещении часового пояса из RoleRules:
ZoneId_nepal_ex2.java
ZoneId nepalZoneId = ZoneId.of("Asia/Kathmandu");

ZoneRules rules = nepalZoneId.getRules();

LocalDateTime ldt1 = LocalDateTime.of(1985, 12, 30, 0, 0, 0, 0);
ZoneOffset offset1 = rules.getOffset(ldt1);
System.out.println(offset1); // +05:30

LocalDateTime ldt2 = LocalDateTime.of(1986, 1, 1, 0, 15, 0, 0);
ZoneOffset offset2 = rules.getOffset(ldt2);  
System.out.println(offset2); // +05:45

3. Type2: Offset-based ZoneId

// Static method of ZoneOffset class.
public static ZoneOffset of(String offsetId)

public static ZoneOffset ofHours(int hours)  
public static ZoneOffset ofHoursMinutes(int hours, int minutes)  
public static ZoneOffset ofHoursMinutesSeconds(int hours, int minutes, int seconds)
public static ZoneOffset ofTotalSeconds(int totalSeconds)
Offset-based ZoneId (ZoneId на основе смещения): Эти ID часовых поясов начинаются с "+" или "-". Параметр offsetId должен иметь следующий формат:
  • Z - for UTC
  • +h
  • +hh
  • +hh:mm
  • -hh:mm
  • +hhmm
  • -hhmm
  • +hh:mm:ss
  • -hh:mm:ss
  • +hhmmss
  • -hhmmss
Например:
ZoneId_offset_based_ex1.java
ZoneId zoneId1 = ZoneOffset.of("-06");
ZoneId zoneId2 = ZoneOffset.of("+06:05:20");
ZoneId zoneId3 = ZoneOffset.ofHoursMinutes(9, 45);

System.out.println(zoneId1.getId()); // -06:00
System.out.println(zoneId2.getId()); // +06:05:20
System.out.println(zoneId3.getId()); // +09:45

// Show format of Zoned Date Time:
ZonedDateTime zonedDateTime = ZonedDateTime.of(2021, 6, 22, 0, 0, 0, 0, zoneId2);
System.out.println("zonedDateTime: " + zonedDateTime); // 2021-06-22T00:00+06:05:20
Их смещения часовых поясов фиксированы:
ZoneId_offset_based_ex2.java
ZoneId zoneId = ZoneOffset.of("+07:05:30");

System.out.println(zoneId.getId()); // +07:05:30

ZoneRules zoneRules = zoneId.getRules();
ZoneOffset zoneOffset = zoneRules.getOffset(Instant.now());
System.out.println("zoneOffset: " + zoneOffset.getId()); // +07:05:30
  • ZoneOffset
  • ZoneRules

4. Type3: UTC, GMT, UT ZoneId

UTC, GMT, UT ZoneId: ID часовых поясов этого типа начинаются с "UTC", "GMT" или "UT", за которыми следуют "+" или "-".
public static ZoneId ofOffset(String prefix, ZoneOffset offset)

public static ZoneId of(String zoneId)
  • GMT vs UTC
Например:
ZoneId_gmt_utc_ut_ex1.java
ZoneId z31 = ZoneId.ofOffset("UTC", ZoneOffset.of("+06"));
ZoneId z32 = ZoneId.ofOffset("GMT", ZoneOffset.of("-06:05:20"));
ZoneId z33 = ZoneId.ofOffset("UT", ZoneOffset.of("+05:20"));

System.out.println(z31.getId()); // UTC+06:00
System.out.println(z32.getId()); // GMT-06:05:20
System.out.println(z33.getId()); // UT+05:20   

// Parser:
ZoneId z31b = ZoneId.of("UTC+06:00");
ZoneId z32b = ZoneId.of("GMT-06:05:20");
ZoneId z33b = ZoneId.of("UT+05:20");

System.out.println(z31b.getId()); // UTC+06:00
System.out.println(z32b.getId()); // GMT-06:05:20
System.out.println(z33b.getId()); // UT+05:20
Output:
UTC+06:00
GMT-06:05:20
UT+05:20
UTC+06:00
GMT-06:05:20
UT+05:20
ID часовых поясов UTC, GMT, UT c имеют фиксированное смещение часового пояса.
ZoneId_gmt_utc_ut_ex2.java
ZoneId zoneId = ZoneId.ofOffset("GMT", ZoneOffset.of("+09"));
System.out.println(zoneId); // GMT+09:00

ZoneRules zoneRules = zoneId.getRules();
System.out.println("isFixedOffset? " + zoneRules.isFixedOffset()); // true

ZoneOffset zoneOffset = zoneRules.getOffset(Instant.now());
System.out.println("zoneOffset: " + zoneOffset); // +09:00

// Show format of Zoned Date Time.
ZonedDateTime zonedDateTime = ZonedDateTime.of(2021, 6, 22, 0, 0, 0, 0, zoneId);
System.out.println("zonedDateTime: " + zonedDateTime); // 2021-06-22T00:00+09:00[GMT+09:00]
Output:
GMT+09:00
isFixedOffset? true
zoneOffset: +09:00
zonedDateTime: 2021-06-22T00:00+09:00[GMT+09:00]

5. ZoneId methods

Статические заводские методы: (static factory method):
public static ZoneId systemDefault()    
public static ZoneId from(TemporalAccessor temporal)  
public static ZoneId of(String zoneId, Map<String, String> aliasMap)  
public static ZoneId of(String zoneId)  
public static ZoneId ofOffset(String prefix, ZoneOffset offset)
Другие методы:
public static Set<String> getAvailableZoneIds()  
public abstract String getId()  
public String getDisplayName(TextStyle style, Locale locale)  
public abstract ZoneRules getRules();
public ZoneId normalized()

6. systemDefault()

Возвращать часовой пояс системы по умолчанию. В операционных системах, таких как Windows, Linux, Mac OS, все позволяют изменять часовой пояс системы по умолчанию.
public static ZoneId systemDefault()
Этот метод вызывает метод TimeZone.getDefault() и преобразует результат в ZoneId. При изменении системного часового пояса также изменяется результат, возвращаемый этим методом.
Например:
ZoneId zoneId = ZoneId.systemDefault();

System.out.println(zoneId);
Output:
Asia/Bishkek

7. of(String)

Возвращать объект ZoneId, выполнив поиск доступного ZoneId в системе, соответствующего данной строке zoneId. Если он не найден, он проанализирует строку of ZoneId для создания объекта ZoneOffset (Примечание: ZoneOffset является подклассом of ZoneId).
public static ZoneId of(String zoneId)
Case 1:
ZoneId предопределены в системе, связанной с определенной географической областью. Вы можете получить этот набор ZoneId из метода ZoneId.getAvailableZoneIds().
  • Asia/Bishkek
  • Europe/Paris
  • ...
ZoneId_of_ex1.java
// ZoneId from region ID
ZoneId zoneId1 = ZoneId.of("Europe/Paris");
System.out.println("zoneId1: " + zoneId1); // Europe/Paris

ZoneId zoneId2 = ZoneId.of("America/Chicago");
System.out.println("zoneId2: " + zoneId2); // America/Chicago
Case 2:
Если параметр ZoneId равен "Z", результатом будет ZoneOffset.UTC. В противном случае, если параметр ZoneId содержит только один символ, отличающийся от "Z", он считается недопустимым и будет выдано исключение DateTimeException.
ZoneId_of_ex2.java
ZoneId zoneId = ZoneId.of("Z"); // return ZoneOffset.UTC
System.out.println("ZoneId.of('Z'): " + zoneId); // Z
System.out.println("ZoneOffset.UTC: " + ZoneOffset.UTC); // Z

boolean same = zoneId == ZoneOffset.UTC;  
System.out.println("ZoneId.of('Z') == ZoneOffset.UTC? " + same); // true
Case 3:
Если параметр ZoneId начинается с "+" или " -", то он будет проанализирован как ZoneOffset методом ZoneOffset.of(zoneId).
ZoneId_of_ex3.java
ZoneId zoneId = ZoneId.of("+09:30");
ZoneOffset zoneOffset1 = (ZoneOffset) zoneId;

// Same as:
ZoneOffset zoneOffset2 = ZoneOffset.of("+09:30");

System.out.println("zoneId: " + zoneId); // +09:30
System.out.println("zoneOffset: " + zoneOffset2); // +09:30
System.out.println("zoneOffset1.equals(zoneOffset2)? " + zoneOffset1.equals(zoneOffset2)); // true
Case 4:
Если параметр ZoneId является "UTC", "GMT" или "UT", метод возвращает объект ZoneId с тем же ZoneRules, что и ZoneOffset.UTC.
ZoneId_of_ex4.java
ZoneId zoneId = ZoneOffset.UTC;

ZoneId zoneId1 = ZoneId.of("UTC");
ZoneId zoneId2 = ZoneId.of("GMT");
ZoneId zoneId3 = ZoneId.of("UT");

// Print out Zone-ID
System.out.println(zoneId.getId());  // Z
System.out.println(zoneId1.getId()); // UTC
System.out.println(zoneId2.getId()); // GMT
System.out.println(zoneId3.getId()); // UT

ZoneRules rules = zoneId.getRules();
ZoneRules rules1 = zoneId1.getRules();
ZoneRules rules2 = zoneId2.getRules();
ZoneRules rules3 = zoneId3.getRules();

System.out.println(rules);  // ZoneRules[currentStandardOffset=Z]
System.out.println(rules1); // ZoneRules[currentStandardOffset=Z]
System.out.println(rules2); // ZoneRules[currentStandardOffset=Z]
System.out.println(rules3); // ZoneRules[currentStandardOffset=Z]

System.out.println("rules1.equals(rules): " + rules1.equals(rules)); // true
System.out.println("rules2.equals(rules): " + rules2.equals(rules)); // true
System.out.println("rules3.equals(rules): " + rules3.equals(rules)); // true
Case 5:
Если параметр ZoneId начинается с "UTC+", "UTC-", "GMT+", "GMT-", "UT+", "UT-", возвращается объект ZoneId. Например, параметр ZoneId, равный "GMT+09:30", будет эквивалентен ZoneId.ofOffset("GMT",ZoneOffset.of("+09:30")).
ZoneId_of_ex5.java
// UTC
ZoneId zoneId1a = ZoneId.of("UTC+09:30");
ZoneId zoneId1b = ZoneId.ofOffset("UTC", ZoneOffset.of("+09:30"));
ZoneId zoneId1c = ZoneId.ofOffset("UTC", ZoneOffset.ofHoursMinutes(9, 30));
System.out.println(zoneId1a); // UTC+09:30
System.out.println(zoneId1b); // UTC+09:30
System.out.println(zoneId1c); // UTC+09:30

// GMT
ZoneId zoneId2a = ZoneId.of("GMT+05:30:20");
ZoneId zoneId2b = ZoneId.ofOffset("GMT", ZoneOffset.of("+05:30:20"));
ZoneId zoneId2c = ZoneId.ofOffset("GMT", ZoneOffset.ofHoursMinutesSeconds(5, 30, 20));
System.out.println(zoneId2a); // GMT+05:30:20
System.out.println(zoneId2b); // GMT+05:30:20
System.out.println(zoneId2c); // GMT+05:30:20

// UT
ZoneId zoneId3a = ZoneId.of("UT-07");
ZoneId zoneId3b = ZoneId.ofOffset("UT", ZoneOffset.of("-07"));
ZoneId zoneId3c = ZoneId.ofOffset("UT", ZoneOffset.ofHours(-7));
System.out.println(zoneId3a); // UT-07:00
System.out.println(zoneId3b); // UT-07:00
System.out.println(zoneId3c); // UT-07:00

8. of(String, Map<String, String>)

public static ZoneId of(String zoneId, Map<String, String> aliasMap)
Например:
ZoneId_of_aliasMap_ex1.java
package org.o7planning.zoneid.fm;

import java.time.ZoneId;
import java.util.HashMap;
import java.util.Map;

public class ZoneId_of_aliasMap_ex1 {

    public static void main(String[] args) {
        // Alias IDs:
        Map<String, String> aliasMap = new HashMap<>();
        aliasMap.put("hcm", "Asia/Ho_Chi_Minh");
        aliasMap.put("usc", "US/Central");
        aliasMap.put("prs", "Europe/Paris");

        ZoneId frZoneId = ZoneId.of("prs", aliasMap);
        ZoneId vnZoneId = ZoneId.of("hcm", aliasMap);
        ZoneId usZoneId = ZoneId.of("US/Central", aliasMap);
        ZoneId jpZoneId = ZoneId.of("Asia/Tokyo", aliasMap);
        ZoneId os9ZoneId = ZoneId.of("+09", aliasMap);

        System.out.println(frZoneId); // Europe/Paris
        System.out.println(vnZoneId); // Asia/Ho_Chi_Minh
        System.out.println(usZoneId); // US/Central
        System.out.println(jpZoneId); // Asia/Tokyo
        System.out.println(os9ZoneId); // +09:00

        System.out.println(" ------ ");

        // throws ZoneRulesException - Unknown time-zone ID: xx
        ZoneId xxZoneId = ZoneId.of("xx", aliasMap); // throws ZoneRulesException

        System.out.println(xxZoneId);
    }
}
Output:
Europe/Paris
Asia/Ho_Chi_Minh
US/Central
Asia/Tokyo
+09:00
 ------
Exception in thread "main" java.time.zone.ZoneRulesException: Unknown time-zone ID: xx
    at java.base/java.time.zone.ZoneRulesProvider.getProvider(ZoneRulesProvider.java:279)
    at java.base/java.time.zone.ZoneRulesProvider.getRules(ZoneRulesProvider.java:234)
    at java.base/java.time.ZoneRegion.ofId(ZoneRegion.java:120)
    at java.base/java.time.ZoneId.of(ZoneId.java:408)
    at java.base/java.time.ZoneId.of(ZoneId.java:356)
    at java.base/java.time.ZoneId.of(ZoneId.java:312)
    at org.o7planning.zoneid.fm.ZoneId_of_aliasMap_ex1.main(ZoneId_of_aliasMap_ex1.java:31)
ZoneId_of_aliasMap_ex2.java
package org.o7planning.zoneid.fm;

import java.time.ZoneId;
import java.util.Map;

public class ZoneId_of_aliasMap_ex2 {

    public static void main(String[] args) {
        // Alias IDs:
        Map<String, String> aliasMap = ZoneId.SHORT_IDS;

        aliasMap.forEach((k, v) -> System.out.println(k + " --> " + v));

        System.out.println(" ------ ");

        ZoneId zoneId1 = ZoneId.of("JST", aliasMap);
        ZoneId zoneId2 = ZoneId.of("VST", aliasMap);  

        System.out.println(zoneId1); // Asia/Tokyo
        System.out.println(zoneId2); // Asia/Ho_Chi_Minh
    }
}
Output:
NET --> Asia/Yerevan
CST --> America/Chicago
IST --> Asia/Kolkata
AET --> Australia/Sydney
BST --> Asia/Dhaka
ACT --> Australia/Darwin
HST --> -10:00
NST --> Pacific/Auckland
AST --> America/Anchorage
MST --> -07:00
SST --> Pacific/Guadalcanal
CTT --> Asia/Shanghai
PRT --> America/Puerto_Rico
ECT --> Europe/Paris
EAT --> Africa/Addis_Ababa
EST --> -05:00
PNT --> America/Phoenix
PLT --> Asia/Karachi
CNT --> America/St_Johns
IET --> America/Indiana/Indianapolis
VST --> Asia/Ho_Chi_Minh
JST --> Asia/Tokyo
ART --> Africa/Cairo
PST --> America/Los_Angeles
BET --> America/Sao_Paulo
MIT --> Pacific/Apia
CAT --> Africa/Harare
AGT --> America/Argentina/Buenos_Aires
 ------
Asia/Tokyo
Asia/Ho_Chi_Minh

9. ofOffset(String, ZoneOffset)

Параметр prefix может принимать только одно из четырех значений: "UTC", "GMT", "UT", "".
public static ZoneId ofOffset(String prefix, ZoneOffset offset)
Например:
ZoneId_ofOffset_ex1.java
ZoneId zoneId1 = ZoneId.ofOffset("UTC", ZoneOffset.ofHours(9));
ZoneId zoneId2 = ZoneId.ofOffset("GMT", ZoneOffset.ofHoursMinutes(9, 30));
ZoneId zoneId3 = ZoneId.ofOffset("UT", ZoneOffset.ofHours(-7));

ZoneId zoneId4 = ZoneId.ofOffset("", ZoneOffset.ofHours(-5)); // Can cast to ZoneOffset

System.out.println(zoneId1); // UTC+09:00
System.out.println(zoneId2); // GMT+09:30
System.out.println(zoneId3); // UT-07:00
System.out.println(zoneId4); // -05:00
  • Руководство Java ZoneOffset

10. from(TemporalAccessor)

Возвращать объект ZoneId, связанный с данным объектом TemporalAccessor.
public static ZoneId from(TemporalAccessor temporal)
Например:
ZoneId_from_ex1.java
package org.o7planning.zoneid.fm;

import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.temporal.TemporalAccessor;

public class ZoneId_from_ex1 {

    public static void main(String[] args) {
        // Obtains the current date-time from the system clock in the default time-zone.
        TemporalAccessor temporalAccessor = ZonedDateTime.now();
        System.out.println("ZonedDateTime: " + temporalAccessor);

        ZoneId zoneId = ZoneId.from(temporalAccessor);
        System.out.println("zoneId: " + zoneId);
    }
}
Output:
ZonedDateTime: 2021-06-24T21:34:23.518679+06:00[Asia/Bishkek]
zoneId: Asia/Bishkek

11. getAvailableZoneIds()

No ADS
Возвращать Set<String>, содержащий все доступные ID часовых поясов в системе. Его количество элементов может со временем увеличиваться, но в обычных приложениях он обычно имеет фиксированный размер. Этот метод потокобезопасен (thread-safe).
  • Включить все Region-based ZoneId.
  • Исключить Offset-based ZoneId.
public static Set<String> getAvailableZoneIds()
Например:
ZoneId_getAvailableZoneIds_ex1.java
package org.o7planning.zoneid.ex;

import java.time.ZoneId;
import java.util.Set;

public class ZoneId_getAvailableZoneIds_ex1 {

    public static void main(String[] args) {
        Set<String> zoneIds = ZoneId.getAvailableZoneIds();

        for (String zoneId : zoneIds) {
           System.out.println(zoneId);
        }
    }
}
Output:
Asia/Aden
America/Cuiaba
...
America/Sao_Paulo
Asia/Jayapura
America/Curacao
Asia/Dushanbe
America/Guyana
...
UTC
...
GMT0
...
Europe/Nicosia
Pacific/Guadalcanal
Europe/Athens
US/Pacific
Europe/Monaco

12. getRules()

No ADS
Возвращать объект ZoneRules, представляющий правила часового пояса (time-zone rules) этого ZoneId.
public abstract ZoneRules getRules()
Смещение часового пояса в ZoneRules, полученных из Region-based ZoneId, не фиксировано. Это зависит от конкретного времени или зависит от времени года.
Например: ZoneId.of("Asia/Ho_Chi_Minh") - часовой пояс южного Вьетнама. С 1960 года по 13 июня 1975 года этот ZoneId использовал часовой пояс +8, затем было изменено на часовой пояс +7 для объединения с северным Вьетнамом.
ZoneId_getRules_ex1.java
package org.o7planning.zoneid.ex;

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.zone.ZoneRules;

public class ZoneId_getRules_ex1 {

    public static void main(String[] args) {
        ZoneId zoneId = ZoneId.of("Asia/Ho_Chi_Minh");
        ZoneRules zoneRules = zoneId.getRules();
        
        ZoneOffset zoneOffset1 = zoneRules.getOffset(LocalDateTime.of(1975, 6, 12, 0, 0, 0));
        ZoneOffset zoneOffset2 = zoneRules.getOffset(LocalDateTime.of(1975, 6, 13, 0, 0, 0));
        
        System.out.println("zoneOffset1: " + zoneOffset1); // +08:00
        System.out.println("zoneOffset2: " + zoneOffset2); // +07:00
    }
}
Output:
zoneOffset1: +08:00
zoneOffset2: +07:00
Вы также можете создать ZoneId с пользовательскими правилами часового пояса с помощью ZoneRulesProvider:
  • ZoneRulesProvider
  • ZoneRules

13. normalized()

No ADS
Метод normalized() возвращает нормализованный (normalized) ZoneId. В принципе, он проверяет, фиксировано ли смещение часового пояса этого ZoneId или нет. Если фиксировано, ZoneOffset будет возвращен, в противном случае он возвращает этот ZoneI.
public ZoneId normalized()
Например:
ZoneId_normalized_ex1.java
package org.o7planning.zoneid.ex;

import java.time.ZoneId;

public class ZoneId_normalized_ex1 {

    public static void main(String[] args) {
        ZoneId zoneId1 = ZoneId.of("US/Central");
        System.out.println("zoneId1: " + zoneId1); // US/Central
        System.out.println("zoneId1.normalized(): " + zoneId1.normalized()); // US/Central

        ZoneId zoneId2 = ZoneId.of("Asia/Tokyo");
        System.out.println("\nzoneId2: " + zoneId2); // Asia/Tokyo
        System.out.println("zoneId2.normalized(): " + zoneId2.normalized()); // Asia/Tokyo

        ZoneId zoneId3 = ZoneId.of("UTC-09:30");
        System.out.println("\nzoneId3: " + zoneId3); // UTC-09:30
        System.out.println("zoneId3.normalized(): " + zoneId3.normalized()); // -09:30
    }
}
Output:
zoneId1: US/Central
zoneId1.normalized(): US/Central

zoneId2: Asia/Tokyo
zoneId2.normalized(): Asia/Tokyo

zoneId3: UTC-09:30
zoneId3.normalized(): -09:30
No ADS