JAVA8之 日期时间时区之 ZoneId[ZoneOffset, ZoneRegion] 笔记


前言

java.time.ZoneId 是java8的新时区类

  • 它对应以前的 TimeZone
  • 它的子类有 ZoneOffset , ZoneRegion

常用例子

获取系统时区

ZoneId.systemDefault()
TimeZone.getDefault().toZoneId()

获取我国时区

Etc/GMT-8

据说是新标准, 等同GMT+8 , 可能取代GMT+8 ? 一个+8 一个-8 😶

ZoneId.of("Etc/GMT-8")

GMT+8

ZoneId.of("GMT+8")
ZoneId.of("GMT+08")
ZoneId.of("GMT+08:00")

用"8:00"会报错

UTC+8

ZoneId.of("UTC+8")
ZoneId.of("UTC+08")
ZoneId.of("UTC+08:00")

UT+8

ZoneId.of("UT+8")
ZoneId.of("UT+08")
ZoneId.of("UT+08:00")

+8

ZoneId.of("+8")
ZoneId.of("+08")
ZoneId.of("+08:00")

上海

ZoneId.of("Asia/Shanghai")

重庆

重庆1

ZoneId.of("Asia/Chongqing")

重庆2

ZoneId.of("Asia/Chungking")

香港

香港1

ZoneId.of("Asia/Hong_Kong")

香港2

ZoneId.of("Hongkong")

查看所支持的时区代码

System.out.println(ZoneId.getAvailableZoneIds());

UTC 与 GMT 的区别

  • UTC : 世界协调时

  • GMT : 格林威治平时
    不是格林威治本地时 , 格林尼治本地的时间是GMT+1

  • UTC与GMT目前相差小于0.9秒(理论上) 受天体运动影响

  • UTC更精准(使用了原子钟)

我的理解是,GMT是时区,UTC不是时区,是一个基准,只是他们表示的时间近乎相同

ZoneId 源代码学习 来自OpenJDK15

类说明

ZoneId用于标识用于在Instant和LocalDateTime之间进行转换的规则。ID有两种不同的类型:
•固定的偏移量-相对于UTC /格林威治标准时间的完全解析的偏移量,它对所有本地日期时间都使用相同的偏移量
•地理区域-适用于查找与UTC /格林威治的偏移量的一组特定规则的区域
大多数固定偏移量由ZoneOffset表示。在任何ZoneId上调用normalized()将确保将固定的偏移量ID表示为ZoneOffset。
ZoneRules定义了描述偏移量何时更改以及如何更改的实际规则。此类仅是用于获取基础规则的ID。之所以采用这种方法,是因为规则是由政府定义且频繁更改的,而该ID是稳定的。

区别还有其他影响。序列化ZoneId仅将发送ID,而序列化规则将发送整个数据集。类似地,两个ID的比较仅检查ID,而两个规则的比较则检查整个数据集。

时区ID
该ID在系统内是唯一的.ID有三种类型。
最简单的ID类型是ZoneOffset中的ID,它由’Z’和以’+‘或’-'开头的ID组成。

下一类ID是带有某种形式的前缀的偏移样式ID,例如’GMT + 2’或’UTC + 01:00’。可识别的前缀为’UTC’,‘GMT’和’UT’。是后缀,将在创建过程中进行规范化。可以使用normalized()将这些ID规范化为ZoneOffset。

ID的第三种类型是基于区域的ID。基于区域的ID必须包含两个或多个字符,并且不能以’UTC’,‘GMT’,‘UT’,’+‘或’-'开头。基于区域的ID由配置定义,请参见ZoneRulesProvider。提供从ID到底层ZoneRules的查找。

时区规则由政府定义并经常更改。有许多组织(在此称为组)来监视时区更改并进行整理。默认组是IANA时区数据库(TZDB)。其他组织包括IATA (航空业团体)和Microsoft。

每个组为其提供的区域ID定义其自己的格式.TZDB组定义诸如欧洲/伦敦’‘或美国/纽约’'的ID.TZDB ID优先于其他组。

强烈建议将组名包括在TZDB以外的其他组提供的所有ID中,以免发生冲突。例如,国际航空运输协会(IATA)航空公司的时区区域ID通常与三个字母的机场代码相同,但是乌得勒支机场的代码为’UTC’,这显然是冲突的.TZDB以外的其他组的区域ID的推荐格式是’group〜region’。因此,如果定义了IATA数据,乌得勒支机场将是’IATA〜UTC’。

序列化
此类可以序列化并以外部格式存储字符串区域ID。ZoneOffset子类使用专用格式,该格式仅存储UTC /格林威治的偏移量。
可以在ID不明的Java运行时中反序列化ZoneId。例如,如果服务器端Java运行时已使用新的区域ID更新,但客户端Java运行时尚未更新。在这种情况下,ZoneId对象将存在,并且可以使用getId,equals,hashCode,toString,getDisplayName和normalized进行查询。但是,对getRules的任何调用都将失败并显示ZoneRulesException。此方法旨在允许加载和查询ZonedDateTime,但在具有不完整时区信息的Java Runtime上未进行修改。

这是一个基于值的类;在ZoneId实例上使用标识敏感的操作(包括引用等于(==),标识哈希码或同步)可能会产生不可预测的结果,应避免使用equals方法进行比较。

/**
 * A time-zone ID, such as {@code Europe/Paris}.
 * <p>
 * A {@code ZoneId} is used to identify the rules used to convert between
 * an {@link Instant} and a {@link LocalDateTime}.
 * There are two distinct types of ID:
 * <ul>
 * <li>Fixed offsets - a fully resolved offset from UTC/Greenwich, that uses
 *  the same offset for all local date-times
 * <li>Geographical regions - an area where a specific set of rules for finding
 *  the offset from UTC/Greenwich apply
 * </ul>
 * Most fixed offsets are represented by {@link ZoneOffset}.
 * Calling {@link #normalized()} on any {@code ZoneId} will ensure that a
 * fixed offset ID will be represented as a {@code ZoneOffset}.
 * <p>
 * The actual rules, describing when and how the offset changes, are defined by {@link ZoneRules}.
 * This class is simply an ID used to obtain the underlying rules.
 * This approach is taken because rules are defined by governments and change
 * frequently, whereas the ID is stable.
 * <p>
 * The distinction has other effects. Serializing the {@code ZoneId} will only send
 * the ID, whereas serializing the rules sends the entire data set.
 * Similarly, a comparison of two IDs only examines the ID, whereas
 * a comparison of two rules examines the entire data set.
 *
 * <h2>Time-zone IDs</h2>
 * The ID is unique within the system.
 * There are three types of ID.
 * <p>
 * The simplest type of ID is that from {@code ZoneOffset}.
 * This consists of 'Z' and IDs starting with '+' or '-'.
 * <p>
 * The next type of ID are offset-style IDs with some form of prefix,
 * such as 'GMT+2' or 'UTC+01:00'.
 * The recognised prefixes are 'UTC', 'GMT' and 'UT'.
 * The offset is the suffix and will be normalized during creation.
 * These IDs can be normalized to a {@code ZoneOffset} using {@code normalized()}.
 * <p>
 * The third type of ID are region-based IDs. A region-based ID must be of
 * two or more characters, and not start with 'UTC', 'GMT', 'UT' '+' or '-'.
 * Region-based IDs are defined by configuration, see {@link ZoneRulesProvider}.
 * The configuration focuses on providing the lookup from the ID to the
 * underlying {@code ZoneRules}.
 * <p>
 * Time-zone rules are defined by governments and change frequently.
 * There are a number of organizations, known here as groups, that monitor
 * time-zone changes and collate them.
 * The default group is the IANA Time Zone Database (TZDB).
 * Other organizations include IATA (the airline industry body) and Microsoft.
 * <p>
 * Each group defines its own format for the region ID it provides.
 * The TZDB group defines IDs such as 'Europe/London' or 'America/New_York'.
 * TZDB IDs take precedence over other groups.
 * <p>
 * It is strongly recommended that the group name is included in all IDs supplied by
 * groups other than TZDB to avoid conflicts. For example, IATA airline time-zone
 * region IDs are typically the same as the three letter airport code.
 * However, the airport of Utrecht has the code 'UTC', which is obviously a conflict.
 * The recommended format for region IDs from groups other than TZDB is 'group~region'.
 * Thus if IATA data were defined, Utrecht airport would be 'IATA~UTC'.
 *
 * <h2>Serialization</h2>
 * This class can be serialized and stores the string zone ID in the external form.
 * The {@code ZoneOffset} subclass uses a dedicated format that only stores the
 * offset from UTC/Greenwich.
 * <p>
 * A {@code ZoneId} can be deserialized in a Java Runtime where the ID is unknown.
 * For example, if a server-side Java Runtime has been updated with a new zone ID, but
 * the client-side Java Runtime has not been updated. In this case, the {@code ZoneId}
 * object will exist, and can be queried using {@code getId}, {@code equals},
 * {@code hashCode}, {@code toString}, {@code getDisplayName} and {@code normalized}.
 * However, any call to {@code getRules} will fail with {@code ZoneRulesException}.
 * This approach is designed to allow a {@link ZonedDateTime} to be loaded and
 * queried, but not modified, on a Java Runtime with incomplete time-zone information.
 *
 * <p>
 * This is a <a href="{@docRoot}/java.base/java/lang/doc-files/ValueBased.html">value-based</a>
 * class; use of identity-sensitive operations (including reference equality
 * ({@code ==}), identity hash code, or synchronization) on instances of
 * {@code ZoneId} may have unpredictable results and should be avoided.
 * The {@code equals} method should be used for comparisons.
 *
 * @implSpec
 * This abstract class has two implementations, both of which are immutable and thread-safe.
 * One implementation models region-based IDs, the other is {@code ZoneOffset} modelling
 * offset-based IDs. This difference is visible in serialization.
 *
 * @since 1.8
 */
public abstract class ZoneId implements Serializable {

从这里可以看出 CTT 代表上海时区的简写

区域覆盖图可启用短时区名称。
短区域ID的使用已在java.util.TimeZone中弃用。加粗样式此映射允许通过of(String,Map)工厂方法继续使用这些ID。
此映射包含与TZDB 2005r和更高版本一致的ID的映射,其中“ EST”,“ MST”和“ HST”映射到不包括夏时制的ID。

    /**
     * A map of zone overrides to enable the short time-zone names to be used.
     * <p>
     * Use of short zone IDs has been deprecated in {@code java.util.TimeZone}.
     * This map allows the IDs to continue to be used via the
     * {@link #of(String, Map)} factory method.
     * <p>
     * This map contains a mapping of the IDs that is in line with TZDB 2005r and
     * later, where 'EST', 'MST' and 'HST' map to IDs which do not include daylight  savings.
     *

     */
    public static final Map<String, String> SHORT_IDS = Map.ofEntries(
        entry("ACT", "Australia/Darwin"),
        entry("AET", "Australia/Sydney"),
        entry("AGT", "America/Argentina/Buenos_Aires"),
        entry("ART", "Africa/Cairo"),
        entry("AST", "America/Anchorage"),
        entry("BET", "America/Sao_Paulo"),
        entry("BST", "Asia/Dhaka"),
        entry("CAT", "Africa/Harare"),
        entry("CNT", "America/St_Johns"),
        entry("CST", "America/Chicago"),
        entry("CTT", "Asia/Shanghai"),
        entry("EAT", "Africa/Addis_Ababa"),
        entry("ECT", "Europe/Paris"),
        entry("IET", "America/Indiana/Indianapolis"),
        entry("IST", "Asia/Kolkata"),
        entry("JST", "Asia/Tokyo"),
        entry("MIT", "Pacific/Apia"),
        entry("NET", "Asia/Yerevan"),
        entry("NST", "Pacific/Auckland"),
        entry("PLT", "Asia/Karachi"),
        entry("PNT", "America/Phoenix"),
        entry("PRT", "America/Puerto_Rico"),
        entry("PST", "America/Los_Angeles"),
        entry("SST", "Pacific/Guadalcanal"),
        entry("VST", "Asia/Ho_Chi_Minh"),
        entry("EST", "-05:00"),
        entry("MST", "-07:00"),
        entry("HST", "-10:00")
    );

ZoneId的公有静态方法

ZoneId.systemDefault()

    public static ZoneId systemDefault() {
        return TimeZone.getDefault().toZoneId();
    }

ZoneId.of

ZoneId of(String zoneId, Map<String, String> aliasMap)

    public static ZoneId of(String zoneId, Map<String, String> aliasMap) {
        Objects.requireNonNull(zoneId, "zoneId");
        Objects.requireNonNull(aliasMap, "aliasMap");
        String id = Objects.requireNonNullElse(aliasMap.get(zoneId), zoneId);
        return of(id);
    }

ZoneId of(String zoneId)

    public static ZoneId of(String zoneId) {
        return of(zoneId, true);
    }

ZoneId ofOffset(String prefix, ZoneOffset offset)

    public static ZoneId ofOffset(String prefix, ZoneOffset offset) {
        Objects.requireNonNull(prefix, "prefix");
        Objects.requireNonNull(offset, "offset");
        if (prefix.isEmpty()) {
            return offset;
        }

        if (!prefix.equals("GMT") && !prefix.equals("UTC") && !prefix.equals("UT")) {
             throw new IllegalArgumentException("prefix should be GMT, UTC or UT, is: " + prefix);
        }

        if (offset.getTotalSeconds() != 0) {
            prefix = prefix.concat(offset.getId());
        }
        return new ZoneRegion(prefix, offset.getRules());
    }

ZoneId的实例可能是ZoneOffset或ZoneRegion

ZoneId of(String zoneId, boolean checkAvailable)

    static ZoneId of(String zoneId, boolean checkAvailable) {
        Objects.requireNonNull(zoneId, "zoneId");
        if (zoneId.length() <= 1 || zoneId.startsWith("+") || zoneId.startsWith("-")) {
            return ZoneOffset.of(zoneId);
        } else if (zoneId.startsWith("UTC") || zoneId.startsWith("GMT")) {
            return ofWithPrefix(zoneId, 3, checkAvailable);
        } else if (zoneId.startsWith("UT")) {
            return ofWithPrefix(zoneId, 2, checkAvailable);
        }
        return ZoneRegion.ofId(zoneId, checkAvailable);
    }

👆可以看出:

  • 如果以加或减{+|-}开头, 则创建ZoneOffset实例
  • 如果以{GMT|UTC|UT}开头, 则创建ZoneRegion实例
  • ZoneId.of(“UT+8”) 得到 ZoneRegion
  • ZoneId.of("+8") 得到ZoneOffset
  • ZoneId.of("+08:00") 得到ZoneOffset
  • ZoneId.of(“Asia/Shanghai”) 得到ZoneRegion

ZoneId与TimeZone

ZoneId与TimeZone 可以相互转换

ZoneId zoneId = TimeZone.getTimeZone(ZoneId.of("GMT+8")).toZoneId();

有意思的是ZoneId.systemDefault()就是通过TimeZone.getDefault().toZoneId()来获得
源码:

    /**
     * Gets the system default time-zone.
     * <p>
     * This queries {@link TimeZone#getDefault()} to find the default time-zone
     * and converts it to a {@code ZoneId}. If the system default time-zone is changed,
     * then the result of this method will also change.
     *
     * @return the zone ID, not null
     * @throws DateTimeException if the converted zone ID has an invalid format
     * @throws ZoneRulesException if the converted zone region ID cannot be found
     */
    public static ZoneId systemDefault() {
        return TimeZone.getDefault().toZoneId();
    }

systemDefault()通过调用TimeZone的toZoneId获得, 但后来还是调用ZoneId.of()方法
TimeZone的部门源码👇

    private transient ZoneId zoneId;
    public ZoneId toZoneId() {
        ZoneId zId = zoneId;
        if (zId == null) {
            zoneId = zId = toZoneId0();
        }
        return zId;
    }
    private ZoneId toZoneId0() {
        String id = getID();
        TimeZone defaultZone = defaultTimeZone;
        // are we not defaultTimeZone but our id is equal to default's?
        if (defaultZone != this &&
            defaultZone != null && id.equals(defaultZone.getID())) {
            // delegate to default TZ which is effectively immutable
            return defaultZone.toZoneId();
        }
        // derive it ourselves
        if (ZoneInfoFile.useOldMapping() && id.length() == 3) {
            if ("EST".equals(id))
                return ZoneId.of("America/New_York");
            if ("MST".equals(id))
                return ZoneId.of("America/Denver");
            if ("HST".equals(id))
                return ZoneId.of("America/Honolulu");
        }
        return ZoneId.of(id, ZoneId.SHORT_IDS);
    }

TimeZone转ZoneId

TimeZone.getTimeZone("GMT+8").toZoneId()
TimeZone.getTimeZone("GMT+8:00").toZoneId()
TimeZone.getTimeZone("GMT+08:00").toZoneId()
TimeZone.getTimeZone("Asia/Shanghai").toZoneId()
TimeZone.getTimeZone("Asia/Chongqing").toZoneId()
TimeZone.getTimeZone("Asia/Chungking").toZoneId()
TimeZone.getTimeZone("Asia/Hong_Kong").toZoneId()
TimeZone.getTimeZone("CTT").toZoneId()

TimeZone可以用"CTT" , ZoneId不可以


ZoneId转TimeZone

TimeZone.getTimeZone(ZoneId.of("GMT+8"))




ZoneId 的子类: ZoneOffset , ZoneRegion

ZoneOffset

ZoneOffset的声明

public final class ZoneOffset
        extends ZoneId
        implements TemporalAccessor, TemporalAdjuster, Comparable<ZoneOffset>, Serializable {

ZoneOffset的静态变量

现成实例 UTC MIN(负18小时) MAX(正18小时)

    /**
     * The time-zone offset for UTC, with an ID of 'Z'.
     */
    public static final ZoneOffset UTC = ZoneOffset.ofTotalSeconds(0);
    /**
     * Constant for the minimum supported offset.
     */
    public static final ZoneOffset MIN = ZoneOffset.ofTotalSeconds(-MAX_SECONDS);
    /**
     * Constant for the maximum supported offset.
     */
    public static final ZoneOffset MAX = ZoneOffset.ofTotalSeconds(MAX_SECONDS);

MAX_SECONDS 取值范围 (正负18小时)

    /**
     * The abs maximum seconds.
     */
    private static final int MAX_SECONDS = 18 * SECONDS_PER_HOUR;

👆ZoneOffset的取值范围为正负18小时

两个ConcurrentMap作为秒缓存和id缓存

    /** Cache of time-zone offset by offset in seconds. */
    private static final ConcurrentMap<Integer, ZoneOffset> SECONDS_CACHE = new ConcurrentHashMap<>(16, 0.75f, 4);
    /** Cache of time-zone offset by ID. */
    private static final ConcurrentMap<String, ZoneOffset> ID_CACHE = new ConcurrentHashMap<>(16, 0.75f, 4);

ZoneOffset与ZoneId字符串格式的区别

ZoneId.of("UTC+8");
ZoneOffset.of("+08:00");

ZoneOffset的静态of(String)方法, String以 +或- 开头

    /**
     * Obtains an instance of {@code ZoneOffset} using the ID.
     * <p>
     * This method parses the string ID of a {@code ZoneOffset} to
     * return an instance. The parsing accepts all the formats generated by
     * {@link #getId()}, plus some additional formats:
     * <ul>
     * <li>{@code Z} - for UTC
     * <li>{@code +h}
     * <li>{@code +hh}
     * <li>{@code +hh:mm}
     * <li>{@code -hh:mm}
     * <li>{@code +hhmm}
     * <li>{@code -hhmm}
     * <li>{@code +hh:mm:ss}
     * <li>{@code -hh:mm:ss}
     * <li>{@code +hhmmss}
     * <li>{@code -hhmmss}
     * </ul>
     * Note that &plusmn; means either the plus or minus symbol.
     * <p>
     * The ID of the returned offset will be normalized to one of the formats
     * described by {@link #getId()}.
     * <p>
     * The maximum supported range is from +18:00 to -18:00 inclusive.
     *
     * @param offsetId  the offset ID, not null
     * @return the zone-offset, not null
     * @throws DateTimeException if the offset ID is invalid
     */
    @SuppressWarnings("fallthrough")
    public static ZoneOffset of(String offsetId) {
        Objects.requireNonNull(offsetId, "offsetId");
        // "Z" is always in the cache
        ZoneOffset offset = ID_CACHE.get(offsetId);
        if (offset != null) {
            return offset;
        }

        // parse - +h, +hh, +hhmm, +hh:mm, +hhmmss, +hh:mm:ss
        final int hours, minutes, seconds;
        switch (offsetId.length()) {
            case 2: //"+8"变为"+08"
                offsetId = offsetId.charAt(0) + "0" + offsetId.charAt(1);  // fallthru
            case 3:
                hours = parseNumber(offsetId, 1, false);
                minutes = 0;
                seconds = 0;
                break;
            case 5:
                hours = parseNumber(offsetId, 1, false);
                minutes = parseNumber(offsetId, 3, false);
                seconds = 0;
                break;
            case 6:
                hours = parseNumber(offsetId, 1, false);
                minutes = parseNumber(offsetId, 4, true);
                seconds = 0;
                break;
            case 7:
                hours = parseNumber(offsetId, 1, false);
                minutes = parseNumber(offsetId, 3, false);
                seconds = parseNumber(offsetId, 5, false);
                break;
            case 9:
                hours = parseNumber(offsetId, 1, false);
                minutes = parseNumber(offsetId, 4, true);
                seconds = parseNumber(offsetId, 7, true);
                break;
            default:
                throw new DateTimeException("Invalid ID for ZoneOffset, invalid format: " + offsetId);
        }
        char first = offsetId.charAt(0);
        if (first != '+' && first != '-') {
            throw new DateTimeException("Invalid ID for ZoneOffset, plus/minus not found when expected: " + offsetId);
        }
        if (first == '-') {
            return ofHoursMinutesSeconds(-hours, -minutes, -seconds);
        } else {
            return ofHoursMinutesSeconds(hours, minutes, seconds);
        }
    }

👆可看出开头必须为正或负号(+或-)

ZoneRegion

ZoneRegion不是公开类 没有public

/**
 * A geographical region where the same time-zone rules apply.
 * <p>
 * Time-zone information is categorized as a set of rules defining when and
 * how the offset from UTC/Greenwich changes. These rules are accessed using
 * identifiers based on geographical regions, such as countries or states.
 * The most common region classification is the Time Zone Database (TZDB),
 * which defines regions such as 'Europe/Paris' and 'Asia/Tokyo'.
 * <p>
 * The region identifier, modeled by this class, is distinct from the
 * underlying rules, modeled by {@link ZoneRules}.
 * The rules are defined by governments and change frequently.
 * By contrast, the region identifier is well-defined and long-lived.
 * This separation also allows rules to be shared between regions if appropriate.
 * 
 *适用于相同时区规则的地理区域。

时区信息归类为一组规则,这些规则定义了何时以及如何更改与UTC /格林威治的偏移量。 
可使用基于地理区域(例如国家或州)的标识符来访问这些规则。
最常见的区域分类是时区数据库(TZDB),时区数据库定义了“欧洲/巴黎”和“亚洲/东京”等区域。

由此类建模的区域标识符与由ZoneRules建模的基础规则不同,这些规则由政府定义且经常更改,相比之下,区域标识符定义明确且寿命长,这种分隔也使规则能够 适当时在区域之间共享。 
 * @implSpec
 * This class is immutable and thread-safe.
 * 此类不可变,且线程安全
 * @since 1.8
 */
final class ZoneRegion extends ZoneId implements Serializable {

👆没有public

构造方法 没有public

只能由同包下的类调用

    ZoneRegion(String id, ZoneRules rules) {
        this.id = id;
        this.rules = rules;
    }

ZoneRegion的成员变量

    /**
     * The time-zone ID, not null.
     */
    private final String id;
    /**
     * The time-zone rules, null if zone ID was loaded leniently.
     */
    private final transient ZoneRules rules;

👆可以看到ZoneRegion保存一个String id 和 ZoneRules ,
这里又牵扯到了ZoneRules(Zone规则)

ZoneRule的类定义
/**
 * 定义区域偏移量在单个时区中如何变化的规则。

该规则为时区建模了所有历史和未来的过渡。 ZoneOffsetTransition用于已知的过渡,通常是历史性的。 
ZoneOffsetTransitionRule用于基于算法结果的将来过渡。

这些规则通过ZoneRulesProvider使用ZoneId加载。
相同的规则可以在多个区域ID之间内部共享。

序列化ZoneRules实例将存储整个规则集。
它不存储区域ID,因为它不是该对象状态的一部分。

规则实现可能存储或不存储有关历史和未来过渡的完整信息,并且存储的信息仅与规则提供者提供给实现的信息一样准确。
应用程序应将提供的数据视为代表可用于实现此规则的最佳信息。 。 
 *
 * @implSpec
 * This class is immutable and thread-safe.
 *
 * @since 1.8
 */
public final class ZoneRules implements Serializable {

ZoneRegion的ofId(String zoneId, boolean checkAvailable)方法

    /**
     * Obtains an instance of {@code ZoneId} from an identifier.
     *
     * @param zoneId  the time-zone ID, not null
     * @param checkAvailable  whether to check if the zone ID is available
     * @return the zone ID, not null
     * @throws DateTimeException if the ID format is invalid
     * @throws ZoneRulesException if checking availability and the ID cannot be found
     */
    static ZoneRegion ofId(String zoneId, boolean checkAvailable) {
        Objects.requireNonNull(zoneId, "zoneId");
        checkName(zoneId);
        ZoneRules rules = null;
        try {
            // always attempt load for better behavior after deserialization
            rules = ZoneRulesProvider.getRules(zoneId, true);
        } catch (ZoneRulesException ex) {
            if (checkAvailable) {
                throw ex;
            }
        }
        return new ZoneRegion(zoneId, rules);
    }

  • 14
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kfepiza

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值