Package javax.time.calendar

Source Code of javax.time.calendar.TimeZone

/*
* Copyright (c) 2007-2009, Stephen Colebourne & Michael Nascimento Santos
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
*  * Redistributions of source code must retain the above copyright notice,
*    this list of conditions and the following disclaimer.
*
*  * Redistributions in binary form must reproduce the above copyright notice,
*    this list of conditions and the following disclaimer in the documentation
*    and/or other materials provided with the distribution.
*
*  * Neither the name of JSR-310 nor the names of its contributors
*    may be used to endorse or promote products derived from this software
*    without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package javax.time.calendar;

import java.io.Serializable;
import java.util.Map;

import javax.time.CalendricalException;
import javax.time.calendar.zone.ZoneRules;
import javax.time.calendar.zone.ZoneRulesGroup;

/**
* A time zone representing the set of rules by which the zone offset
* varies through the year and historically.
* <p>
* Time zones are geographical regions where the same rules for time apply.
* The rules are defined by governments and change frequently.
* <p>
* There are a number of sources of time zone information available,
* each represented by an instance of {@link ZoneRulesGroup}.
* One group is provided as standard - 'TZDB' - and more can be added.
* <p>
* Each group defines a naming scheme for the regions of the time zone.
* The format of the region is specific to the group.
* For example, the 'TZDB' group typically use the format {area}/{city},
* such as 'Europe/London'.
* <p>
* Each group typically produces multiple versions of their data.
* The format of the version is specific to the group.
* For example, the 'TZDB' group use the format {year}{letter}, such as '2009b'.
* <p>
* In combination, a unique ID is created expressing the time-zone, formed from
* {groupID}:{regionID}#{versionID}.
* <p>
* The version can be set to an empty string. This represents the "floating version".
* The floating version will always choose the latest applicable set of rules.
* Applications will probably choose to use the floating version, as it guarantees
* usage of the latest rules.
* <p>
* In addition to the group/region/version combinations, <code>TimeZone</code>
* can represent a fixed offset. This has an empty group and version ID.
* It is not possible to have an invalid instance of a fixed time zone.
* <p>
* The purpose of capturing all this information is to handle issues when
* manipulating and persisting time zones. For example, consider what happens if the
* government of a country changed the start or end of daylight savings time.
* If you created and stored a date using one version of the rules, and then load it
* up when a new version of the rules are in force, what should happen?
* The date might now be invalid, for example due to a gap in the local time-line.
* By storing the version of the time zone rules data together with the date, it is
* possible to tell that the rules have changed and to process accordingly.
* <p>
* <code>TimeZone</code> merely represents the identifier of the zone.
* The actual rules are provided by {@link ZoneRules}.
* One difference is that serializing this class only stores the reference to the zone,
* whereas serializing <code>ZoneRules</code> stores the entire set of rules.
* <p>
* After deserialization, or by using the special constructor, it is possible for the
* time zone to represent a group/region/version combination that is unavailable.
* Since this class can still be loaded even when the rules cannot, the application can
* continue. For example, a {@link ZonedDateTime} instance could still be queried.
* The application might also take appropriate corrective action.
* For example, an application might choose to download missing rules from a central server.
* <p>
* TimeZone is immutable and thread-safe.
*
* @author Stephen Colebourne
*/
public final class TimeZone implements Serializable {

    /**
     * A serialization identifier for this class.
     */
    private static final long serialVersionUID = 93618758758127L;
    /**
     * The time zone offset for UTC, with an id of 'UTC'.
     */
    public static final TimeZone UTC = new TimeZone("", "UTC", "", ZoneRules.fixed(ZoneOffset.UTC));

    /**
     * The time zone group ID.
     */
    private final String groupID;
    /**
     * The time zone region ID.
     */
    private final String regionID;
    /**
     * The time zone version ID.
     */
    private final String versionID;
    /**
     * The time zone rules.
     */
    private transient volatile ZoneRules rules;

    //-----------------------------------------------------------------------
    /**
     * Obtains an instance of <code>TimeZone</code> using its ID using a map
     * of aliases to supplement the standard zone IDs.
     * <p>
     * Many users of time zones use short abbreviations, such as PST for
     * 'Pacific Standard Time' and PDT for 'Pacific Daylight Time'.
     * These abbreviations are not unique, and so cannot be used as identifiers.
     * This method allows a map of string to time zone to be setup and reused
     * within an application.
     *
     * @param timeZoneIdentifier  the time zone id, not null
     * @param aliasMap  a map of time zone IDs (typically abbreviations) to time zones, not null
     * @return the TimeZone, never null
     * @throws IllegalArgumentException if the time zone cannot be found
     */
    public static TimeZone timeZone(String timeZoneIdentifier, Map<String, TimeZone> aliasMap) {
        // TODO: review
        ISOChronology.checkNotNull(timeZoneIdentifier, "Time Zone ID must not be null");
        ISOChronology.checkNotNull(aliasMap, "Alias map must not be null");
        TimeZone zone = aliasMap.get(timeZoneIdentifier);
        return zone == null ? timeZone(timeZoneIdentifier) : zone;
    }

    /**
     * Obtains an instance of <code>TimeZone</code> from an identifier.
     * <p>
     * Six forms of identifier are recognized:
     * <ul>
     * <li><code>{groupID}:{regionID}#{versionID}</code> - full
     * <li><code>{groupID}:{regionID}</code> - implies the floating version
     * <li><code>{regionID}#{versionID} - implies 'TZDB' group and specific version
     * <li><code>{regionID} - implies 'TZDB' group and the floating version
     * <li><code>UTC{offset} - fixed time zone
     * <li><code>GMT{offset} - fixed time zone
     * </ul>
     * <p>
     * Most of the formats are based around the group, version and region IDs.
     * The version and region ID formats are specific to the group.
     * If a group does not support versioning, then the version must be an empty string.
     * <p>
     * The default group is 'TZDB' which has versions of the form {year}{letter}, such as '2009b'.
     * The region ID for the 'TZDB' group is generally of the form '{area}/{city}', such as 'Europe/Paris'.
     * This is compatible with most IDs from {@link java.util.TimeZone}.
     * <p>
     * For example, if a provider is loaded with the ID 'MyProvider' containing a zone ID of
     * 'France', then the unique key for version 2.1 would be 'MyProvider:France#2.1'.
     * A specific version of the TZDB provider can be specified using this format,
     * for example 'TZDB:Asia/Tokyo#2008g'.
     * <p>
     * The alternate format is for fixed time zones, where the offset never changes over time.
     * It is intended that {@link ZoneOffset} and {@link OffsetDateTime} are used in preference,
     * however sometimes it is necessary to have a fixed time zone.
     * A fixed time zone is returned if the first three characters are 'UTC' or 'GMT'.
     * The remainder of the ID must be a valid format for {@link ZoneOffset#zoneOffset(String)}.
     * Using 'UTCZ' or 'GMTZ' is invalid.
     * The normalized time zone ID is 'UTC&plusmn;hh:mm:ss', or just 'UTC' if the offset is zero.
     *
     * @param zoneID  the time zone identifier, not null
     * @return the TimeZone, never null
     * @throws CalendricalException if the time zone cannot be found
     */
    public static TimeZone timeZone(String zoneID) {
        ISOChronology.checkNotNull(zoneID, "Time zone ID must not be null");
        if (zoneID.equals("UTC") || zoneID.equals("GMT")) {
            return UTC;
           
        } else if (zoneID.equals("UTCZ") || zoneID.equals("GMTZ")) {
            throw new CalendricalException("Invalid time zone ID: " + zoneID);
           
        } else if (zoneID.startsWith("UTC") || zoneID.startsWith("GMT")) {  // not sure about GMT
            try {
                return timeZone(ZoneOffset.zoneOffset(zoneID.substring(3)));
            } catch (IllegalArgumentException ex) {
                throw new CalendricalException("Invalid time zone ID: " + ex.toString(), ex);
            }
           
        } else {
            int pos = zoneID.indexOf(':');
            ZoneRulesGroup group;
            if (pos >= 0) {
                group = ZoneRulesGroup.getGroup(zoneID.substring(0, pos))// validates ID
                zoneID = zoneID.substring(pos + 1);
            } else {
                group = ZoneRulesGroup.getGroup("TZDB")// validates ID
            }
            pos = zoneID.indexOf('#');
            String versionID = "";
            if (pos >= 0) {
                versionID = zoneID.substring(pos + 1);
                zoneID = zoneID.substring(0, pos);
            }
            ZoneRules rules = group.getRules(zoneID, versionID)// validates IDs
            return new TimeZone(group.getID(), zoneID, versionID, rules);
        }
    }

    /**
     * Obtains an instance of <code>TimeZone</code> representing a fixed time zone.
     * <p>
     * The time zone returned from this factory has a fixed offset for all time.
     * The region ID will return an identifier formed from 'UTC' and the offset.
     * The group and version IDs will both return an empty string.
     * <p>
     * Fixed time zones are {@link #isValid() always valid}.
     *
     * @param offset  the zone offset to create a fixed zone for, not null
     * @return the TimeZone for the offset, never null
     */
    public static TimeZone timeZone(ZoneOffset offset) {
        ISOChronology.checkNotNull(offset, "ZoneOffset must not be null");
        if (offset == ZoneOffset.UTC) {
            return UTC;
        }
        String id = "UTC" + offset.getID();
        ZoneRules zoneRules = ZoneRules.fixed(offset);
        return new TimeZone("", id, "", zoneRules);
    }

    //-----------------------------------------------------------------------
    /**
     * Constructor.
     *
     * @param groupID  the time zone rules group ID, not null
     * @param regionID  the time zone region ID, not null
     * @param versionID  the time zone rules version ID, not null
     */
    private TimeZone(String groupID, String regionID, String versionID, ZoneRules rules) {
        super();
        this.groupID = groupID;
        this.regionID = regionID;
        this.versionID = versionID;
        this.rules = rules;
    }

    /**
     * Handle UTC on deserialization.
     *
     * @return the resolved instance, never null
     */
    private Object readResolve() {
        // fixed time zone must always be valid
        if (isFixed()) {
            if ("UTC".equals(regionID)) {
                return UTC;
            } else {
                return TimeZone.timeZone(getID());
            }
        }
        return this;
    }

    //-----------------------------------------------------------------------
    /**
     * Gets the unique time zone ID.
     * <p>
     * The unique key is created from the group ID, version ID and region ID.
     * The format is {groupID}:{regionID}#{versionID}.
     * If the group is 'TZDB' then the {groupID}: is omitted.
     * If the version is floating, then the #{versionID} is omitted.
     * Fixed time zones will only output the region ID.
     *
     * @return the time zone unique ID, never null
     */
    public String getID() {
        if (isFixed()) {
            return regionID;
        }
        if (groupID.equals("TZDB")) {
            return regionID + (versionID.length() == 0 ? "" : "#" + versionID);
        }
        return groupID + ":" + regionID + (versionID.length() == 0 ? "" : "#" + versionID);
    }

    /**
     * Gets the time zone rules group ID, such as 'TZDB'.
     * <p>
     * Time zone rules are provided by groups referenced by an ID.
     * <p>
     * For fixed time zones, the group ID will be an empty string.
     *
     * @return the time zone rules group ID, never null
     */
    public String getGroupID() {
        return groupID;
    }

    /**
     * Gets the time zone region identifier, such as 'Europe/London'.
     * <p>
     * The time zone region identifier is of a format specific to the group.
     * The default 'TZDB' group generally uses the format {area}/{city}, such as 'Europe/Paris'.
     *
     * @return the time zone rules region ID, never null
     */
    public String getRegionID() {
        return regionID;
    }

    /**
     * Gets the time zone rules group version, such as '2009b'.
     * <p>
     * Time zone rules change over time as governments change the associated laws.
     * The time zone groups capture these changes by issuing multiple versions
     * of the data. An application can reference the exact set of rules used
     * by using the group ID and version.
     * <p>
     * The version can be an empty string which represents the floating version.
     * This always uses the latest version of the rules available.
     * <p>
     * For fixed time zones, the version ID will be an empty string.
     *
     * @return the time zone rules version ID, empty if the version is floating, never null
     */
    public String getVersionID() {
        return versionID;
    }

    //-----------------------------------------------------------------------
    /**
     * Checks of the time zone is fixed, such that the offset never varies.
     * <p>
     * It is intended that {@link OffsetDateTime}, {@link OffsetDate} and
     * {@link OffsetTime} are used in preference to fixed offset time zones
     * in {@link ZonedDateTime}.
     *
     * @return true if the time zone is fixed and the offset never changes
     */
    public boolean isFixed() {
        return groupID.length() == 0;
    }

    //-----------------------------------------------------------------------
    /**
     * Checks if the version is floating.
     * <p>
     * A floating version will track the latest available version of the rules.
     * <p>
     * For group based time zones, this returns true if the version ID is empty,
     * which is the definition of a floating zone.
     * <p>
     * For fixed time zones, true is returned.
     *
     * @return true if the version is floating
     */
    public boolean isFloatingVersion() {
        return isFixed() || versionID.length() == 0;
    }

    /**
     * Returns a copy of this time zone with the specified version ID.
     * <p>
     * For group based time zones, this returns a <code>TimeZone</code> with the
     * same group and region, but a floating version.
     * The group and region IDs are not validated.
     * <p>
     * For fixed time zones, <code>this</code> is returned.
     *
     * @return the new updated time zone, never null
     * @throws CalendricalException if the time zone is fixed
     */
    public TimeZone withFloatingVersion() {
        if (isFloatingVersion()) {
            return this;
        }
        return new TimeZone(groupID, regionID, "", null);
    }

    //-----------------------------------------------------------------------
    /**
     * Checks if the version is the latest version.
     * <p>
     * For floating group based time zones, true is returned.
     * <p>
     * For non-floating group based time zones, this returns true if the version
     * stored is the same as the latest version available for the group and region.
     * The group and region IDs are validated in order to calculate the latest version.
     * <p>
     * For fixed time zones, true is returned.
     *
     * @return true if the version is the latest available
     * @throws CalendricalException if the version is non-floating and the group or region ID is not found
     */
    public boolean isLatestVersion() {
        return isFloatingVersion() ||
                versionID.equals(getGroup().getLatestVersionID(regionID))// validates IDs
    }

    /**
     * Returns a copy of this time zone with the latest available version ID.
     * <p>
     * For floating group based time zones, <code>this</code> is returned.
     * <p>
     * For non-floating group based time zones, this returns a <code>TimeZone</code>
     * with the same group and region, but the latest version.
     * The group and region IDs are validated in order to calculate the latest version.
     * <p>
     * For fixed time zones, <code>this</code> is returned.
     *
     * @return the new updated time zone, never null
     * @throws CalendricalException if the version is non-floating and the group or region ID is not found
     */
    public TimeZone withLatestVersion() {
        if (isFloatingVersion()) {
            return this;
        }
        String versionID = getGroup().getLatestVersionID(regionID)// validates IDs
        if (versionID.equals(this.versionID)) {
            return this;
        }
        return new TimeZone(groupID, regionID, versionID, rules);
    }

    //-----------------------------------------------------------------------
    /**
     * Returns a copy of this time zone with the specified version ID.
     * <p>
     * For group based time zones, this returns a <code>TimeZone</code>
     * with the same group and region, but the specified version.
     * The group and region IDs are validated to ensure that the version is valid.
     * <p>
     * For fixed time zones, the version must be an empty string, otherwise an
     * exception is thrown.
     *
     * @param versionID  the version ID to use, empty means floating version, not null
     * @return the new updated time zone, never null
     * @throws CalendricalException if the time zone is fixed and the version is not empty
     * @throws CalendricalException if the group, region or version ID is not found
     */
    public TimeZone withVersion(String versionID) {
        ISOChronology.checkNotNull(versionID, "Version ID must not be null");
        if (isFixed()) {
            if (versionID.length() > 0) {
                throw new CalendricalException("Fixed time zone does not provide versions");
            }
            return this;
        }
        ZoneRules rules = getGroup().getRules(regionID, versionID)// validates IDs
        if (versionID.equals(this.versionID)) {
            return this;
        }
        return new TimeZone(groupID, regionID, versionID, rules);
    }

    /**
     * Returns a copy of this time zone with the latest version that is valid
     * for the specified date-time and offset.
     * <p>
     * This method validates the group and region IDs.
     *
     * @param dateTime  the date-time to get the latest version for
     * @return the new updated time zone, never null
     * @throws CalendricalException if the group or region ID is not found
     * @throws CalendricalException if there are no valid rules for the date-time
     */
    public TimeZone withLatestVersionValidFor(OffsetDateTime dateTime) {
        ISOChronology.checkNotNull(dateTime, "OffsetDateTime must not be null");
        if (isFixed()) {
            if (getRules().getOffset(dateTime).equals(dateTime.getOffset()) == false) {
                throw new CalendricalException("Fixed time zone " + getID() + " is invalid for date-time " + dateTime);
            }
            return this;
        }
        return withVersion(getGroup().getLatestVersionIDValidFor(regionID, dateTime));
    }

    //-----------------------------------------------------------------------
    /**
     * Finds the zone rules group for the stored group ID, such as 'TZDB'.
     * <p>
     * Time zone rules are provided by groups referenced by an ID.
     * <p>
     * Fixed time zones are not provided by a group, thus this method throws
     * an exception if the time zone is fixed.
     * <p>
     * Callers of this method need to be aware of an unusual scenario.
     * It is possible to obtain a <code>TimeZone</code> instance even when the
     * rules are not available. This typically occurs when a <code>TimeZone</code>
     * is loaded from a previously stored version but the rules are not available.
     * In this case, the <code>TimeZone</code> instance is still valid, as is
     * any associated object, such as {@link ZonedDateTime}. It is impossible to
     * perform any calculations that require the rules however, and this method
     * will throw an exception.
     *
     * @return the time zone rules group ID, never null
     * @throws CalendricalException if the time zone is fixed
     * @throws CalendricalException if the group ID cannot be found
     */
    public ZoneRulesGroup getGroup() {
        if (isFixed()) {
            throw new CalendricalException("Fixed time zone is not provided by a group");
        }
        return ZoneRulesGroup.getGroup(groupID);
    }

    //-----------------------------------------------------------------------
    /**
     * Checks if this time zone is valid such that rules can be obtained for it.
     * <p>
     * This will return true if the rules are available for the group, region
     * and version ID combination. If this method returns true, then
     * {@link #getRules()} will return a valid rules instance.
     * <p>
     * A time zone can be invalid if it is deserialized in a JVM which does not
     * have the same rules loaded as the JVM that stored it.
     * <p>
     * If this object declares a floating version of the rules and a background
     * thread is used to update the available rules, then the result of calling
     * this method may vary over time.
     * Each individual call will be still remain thread-safe.
     * <p>
     * If this is a fixed time zone, then it is always valid.
     *
     * @return true if this time zone is valid and rules are available
     */
    public boolean isValid() {
        if (isFixed()) {
            return true;
        }
        if (ZoneRulesGroup.isValidGroup(groupID) == false) {
            return false;
        }
        ZoneRulesGroup group = ZoneRulesGroup.getGroup(groupID);
        return group.isValidRules(regionID, versionID);
    }

    /**
     * Gets the time zone rules allowing calculations to be performed.
     * <p>
     * The rules provide the functionality associated with a time zone,
     * such as finding the offset for a given instant or local date-time.
     * Different rules may be returned depending on the group, version and zone.
     * <p>
     * If this object declares a specific version of the rules, then the result will
     * be of that version. If this object declares a floating version of the rules,
     * then the latest version available will be returned.
     * <p>
     * A time zone can be invalid if it is deserialized in a JVM which does not
     * have the same rules loaded as the JVM that stored it. In this case, calling
     * this method will throw an exception.
     * <p>
     * If this object declares a floating version of the rules and a background
     * thread is used to update the available rules, then the result of calling
     * this method may vary over time.
     * Each individual call will be still remain thread-safe.
     *
     * @return the rules, never null
     * @throws CalendricalException if the group, region or version ID cannot be found
     */
    public ZoneRules getRules() {
        // fixed rules always in transient field
        if (rules != null) {
            return rules;
        }
        ZoneRulesGroup group = ZoneRulesGroup.getGroup(groupID);
        ZoneRules r = group.getRules(regionID, versionID);
        if (versionID.length() > 0) {
            rules = r;
        }
        return r;
    }

    //-----------------------------------------------------------------------
    /**
     * Checks if this time zone is valid such that rules can be obtained for it
     * which are valid for the specified date-time and offset.
     * <p>
     * This will return true if the rules are available for the group, region
     * and version ID combination that are valid for the specified date-time.
     * If this method returns true, then {@link #getRules(OffsetDateTime)} will
     * return a valid rules instance.
     * <p>
     * A time zone can be invalid if it is deserialized in a JVM which does not
     * have the same rules loaded as the JVM that stored it.
     * <p>
     * If this object declares a floating version of the rules and a background
     * thread is used to update the available rules, then the result of calling
     * this method may vary over time.
     * Each individual call will be still remain thread-safe.
     * <p>
     * If this is a fixed time zone, then it is valid if the offset matches the date-time.
     *
     * @param dateTime  a date-time for which the rules must be valid, null returns false
     * @return true if this time zone is valid and rules are available
     */
    public boolean isValidFor(OffsetDateTime dateTime) {
        if (dateTime == null) {
            return false;
        }
        if (isFixed()) {
            return getRules().getOffset(dateTime).equals(dateTime.getOffset());
        }
        if (ZoneRulesGroup.isValidGroup(groupID) == false) {
            return false;
        }
        ZoneRulesGroup group = ZoneRulesGroup.getGroup(groupID);
        return group.isValidRulesFor(regionID, versionID, dateTime);
    }

    /**
     * Gets the time zone rules allowing calculations to be performed, ensuring that
     * the date-time and offset specified is valid for the returned rules.
     * <p>
     * The rules provide the functionality associated with a time zone,
     * such as finding the offset for a given instant or local date-time.
     * Different rules may be returned depending on the group, version and zone.
     * <p>
     * If this object declares a specific version of the rules, then the result will
     * be of that version providing that the specified date-time is valid for those rules.
     * If this object declares a floating version of the rules, then the latest
     * version of the rules where the date-time is valid will be returned.
     * <p>
     * A time zone can be invalid if it is deserialized in a JVM which does not
     * have the same rules loaded as the JVM that stored it. In this case, calling
     * this method will throw an exception.
     * <p>
     * If this object declares a floating version of the rules and a background
     * thread is used to update the available rules, then the result of calling
     * this method may vary over time.
     * Each individual call will be still remain thread-safe.
     *
     * @param dateTime  a date-time for which the rules must be valid, not null
     * @return the latest rules for this zone where the date-time is valid, never null
     * @throws CalendricalException if the zone ID cannot be found
     * @throws CalendricalException if no rules match the zone ID and date-time
     */
    public ZoneRules getRulesValidFor(OffsetDateTime dateTime) {
        ISOChronology.checkNotNull(dateTime, "OffsetDateTime must not be null");
        if (isFixed()) {
            if (getRules().getOffset(dateTime).equals(dateTime.getOffset()) == false) {
                throw new CalendricalException("Fixed time zone " + getID() + " is invalid for date-time " + dateTime);
            }
            return ZoneRules.fixed(getRules().getOffset(dateTime));
        }
        ZoneRulesGroup group = ZoneRulesGroup.getGroup(groupID);
        return group.getRulesValidFor(regionID, versionID, dateTime);
    }

    //-----------------------------------------------------------------------
    /**
     * Gets the textual name of this zone.
     *
     * @return the time zone name, never null
     */
    public String getName() {
        return regionID;  // TODO
    }

    /**
     * Gets the short textual name of this zone.
     *
     * @return the time zone short name, never null
     */
    public String getShortName() {
        return regionID;  // TODO
    }

    //-----------------------------------------------------------------------
    /**
     * Is this instance equal to that specified by comparing the ID.
     *
     * @param otherZone  the other zone, null returns false
     * @return true if this zone is the same as that specified
     */
    @Override
    public boolean equals(Object otherZone) {
        if (this == otherZone) {
           return true;
        }
        if (otherZone instanceof TimeZone) {
            TimeZone zone = (TimeZone) otherZone;
            return regionID.equals(zone.regionID) &&
                    versionID.equals(zone.versionID) &&
                    groupID.equals(zone.groupID);
        }
        return false;
    }

    /**
     * A hash code for this time zone ID.
     *
     * @return a suitable hash code
     */
    @Override
    public int hashCode() {
        return groupID.hashCode() ^ regionID.hashCode() ^ versionID.hashCode();
    }

    //-----------------------------------------------------------------------
    /**
     * Returns a string representation of the time zone.
     * <p>
     * This returns {@link #getID()}.
     *
     * @return the time zone ID, never null
     */
    @Override
    public String toString() {
        return getID();
    }

}
TOP

Related Classes of javax.time.calendar.TimeZone

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.