package java.util;

import java.io.Serializable;

import ej.annotation.Nullable;

/**
 * <code>TimeZone</code> represents a time zone offset, and also figures out daylight savings.
 *
 * <p>
 * Typically, you get a <code>TimeZone</code> using <code>getDefault</code> which creates a
 * <code>TimeZone</code> based on the time zone where the program is running. For example, for a
 * program running in Japan, <code>getDefault</code> creates a <code>TimeZone</code> object based on
 * Japanese Standard Time.
 *
 * <p>
 * You can also get a <code>TimeZone</code> using <code>getTimeZone</code> along with a time zone
 * ID. For instance, the time zone ID for the U.S. Pacific Time zone is "America/Los_Angeles". So,
 * you can get a U.S. Pacific Time <code>TimeZone</code> object with: <blockquote>
 *
 * <pre>
 * TimeZone tz = TimeZone.getTimeZone(&quot;America/Los_Angeles&quot;);
 * </pre>
 *
 * </blockquote> You can use the <code>getAvailableIDs</code> method to iterate through all the
 * supported time zone IDs. You can then choose a supported ID to get a <code>TimeZone</code>. If
 * the time zone you want is not represented by one of the supported IDs, then a custom time zone ID
 * can be specified to produce a TimeZone. The syntax of a custom time zone ID is:
 *
 * <blockquote>
 *
 * <pre>
 * <a id="CustomID"><i>CustomID:</i></a>
 *         <code>GMT</code> <i>Sign</i> <i>Hours</i> <code>:</code> <i>Minutes</i>
 *         <code>GMT</code> <i>Sign</i> <i>Hours</i> <i>Minutes</i>
 *         <code>GMT</code> <i>Sign</i> <i>Hours</i>
 * <i>Sign:</i> one of
 *         <code>+ -</code>
 * <i>Hours:</i>
 *         <i>Digit</i>
 *         <i>Digit</i> <i>Digit</i>
 * <i>Minutes:</i>
 *         <i>Digit</i> <i>Digit</i>
 * <i>Digit:</i> one of
 *         <code>0 1 2 3 4 5 6 7 8 9</code>
 * </pre>
 *
 * </blockquote>
 *
 * <i>Hours</i> must be between 0 to 23 and <i>Minutes</i> must be between 00 to 59. For example,
 * "GMT+10" and "GMT+0010" mean ten hours and ten minutes ahead of GMT, respectively.
 * <p>
 * The format is locale independent and digits must be taken from the Basic Latin block of the
 * Unicode standard. No daylight saving time transition schedule can be specified with a custom time
 * zone ID. If the specified string doesn't match the syntax, <code>"GMT"</code> is used.
 * <p>
 * When creating a <code>TimeZone</code>, the specified custom time zone ID is normalized in the
 * following syntax: <blockquote>
 *
 * <pre>
 * <a id="NormalizedCustomID"><i>NormalizedCustomID:</i></a>
 *         <code>GMT</code> <i>Sign</i> <i>TwoDigitHours</i> <code>:</code> <i>Minutes</i>
 * <i>Sign:</i> one of
 *         <code>+ -</code>
 * <i>TwoDigitHours:</i>
 *         <i>Digit</i> <i>Digit</i>
 * <i>Minutes:</i>
 *         <i>Digit</i> <i>Digit</i>
 * <i>Digit:</i> one of
 *         <code>0 1 2 3 4 5 6 7 8 9</code>
 * </pre>
 *
 * </blockquote> For example, TimeZone.getTimeZone("GMT-8").getID() returns "GMT-08:00".
 *
 * <h3>Three-letter time zone IDs</h3>
 *
 * @see Calendar
 */
public abstract class TimeZone implements Cloneable, Serializable {
	/**
	 * A style specifier for <code>getDisplayName()</code> indicating a long name, such as "Pacific
	 * Standard Time."
	 *
	 * @see #SHORT
	 */
	public static final int LONG = 1;

	/**
	 * A style specifier for <code>getDisplayName()</code> indicating a short name, such as "PST."
	 *
	 * @see #LONG
	 */
	public static final int SHORT = 0;

	/**
	 * Sole constructor. (For invocation by subclass constructors, typically implicit.)
	 */
	public TimeZone() {
	}

	/**
	 * Gets all the available IDs supported.
	 *
	 * @return an array of IDs.
	 */
	public static String[] getAvailableIDs() {
		throw new RuntimeException();
	}

	/**
	 * Gets the default <code>TimeZone</code> for this host. The source of the default
	 * <code>TimeZone</code> may vary with implementation.
	 *
	 * @return a default <code>TimeZone</code>.
	 */
	public static TimeZone getDefault() {
		throw new RuntimeException();
	}

	/**
	 * Gets the <code>TimeZone</code> for the given ID.
	 *
	 * @param ID
	 *        the ID for a <code>TimeZone</code>, either an abbreviation such as "PST", a full name such
	 *        as "America/Los_Angeles", or a custom ID such as "GMT-8:00".
	 *
	 * @return the specified <code>TimeZone</code>, or the GMT zone if the given ID cannot be
	 *         understood.
	 */
	public static TimeZone getTimeZone(String ID) {
		throw new RuntimeException();
	}

	/**
	 * Creates a copy of this <code>TimeZone</code>.
	 *
	 * @return a clone of this <code>TimeZone</code>
	 */
	@Override
	public Object clone() {
		throw new RuntimeException();
	}

	/**
	 * Returns the amount of time to be added to local standard time to get local wall clock time.
	 *
	 * <p>
	 * The default implementation returns 3600000 milliseconds (i.e., one hour) if a call to
	 * {@link #useDaylightTime()} returns {@code true}. Otherwise, 0 (zero) is returned.
	 *
	 * <p>
	 * If an underlying {@code TimeZone} implementation subclass supports historical and future Daylight
	 * Saving Time schedule changes, this method returns the amount of saving time of the last known
	 * Daylight Saving Time rule that can be a future prediction.
	 *
	 * <p>
	 * If the amount of saving time at any given time stamp is required, construct a {@link Calendar}
	 * with this {@code TimeZone} and the time stamp, and call {@link Calendar#get(int)
	 * Calendar.get}{@code (}{@link Calendar#DST_OFFSET}{@code )}.
	 *
	 * @return the amount of saving time in milliseconds
	 * @see #getOffset(long)
	 * @see #getOffset(int,int,int,int,int,int)
	 * @see Calendar#ZONE_OFFSET
	 */
	public int getDSTSavings() {
		throw new RuntimeException();
	}

	/**
	 * Gets the ID of this time zone.
	 *
	 * @return the ID of this time zone.
	 */
	public String getID() {
		throw new RuntimeException();
	}

	/**
	 * Gets the time zone offset, for current date, modified in case of daylight savings. This is the
	 * offset to add to UTC to get local time.
	 * <p>
	 * This method returns a historically correct offset if an underlying <code>TimeZone</code>
	 * implementation subclass supports historical Daylight Saving Time schedule and GMT offset changes.
	 *
	 * @param era
	 *        the era of the given date.
	 * @param year
	 *        the year in the given date.
	 * @param month
	 *        the month in the given date. Month is 0-based. e.g., 0 for January.
	 * @param day
	 *        the day-in-month of the given date.
	 * @param dayOfWeek
	 *        the day-of-week of the given date.
	 * @param milliseconds
	 *        the milliseconds in day in <em>standard</em> local time.
	 *
	 * @return the offset in milliseconds to add to GMT to get local time.
	 *
	 * @see Calendar#ZONE_OFFSET
	 * @see Calendar#DST_OFFSET
	 */
	public abstract int getOffset(int era, int year, int month, int day, int dayOfWeek, int milliseconds);

	/**
	 * Returns the offset of this time zone from UTC at the specified date. If Daylight Saving Time is
	 * in effect at the specified date, the offset value is adjusted with the amount of daylight saving.
	 * <p>
	 * This method returns a historically correct offset value if an underlying TimeZone implementation
	 * subclass supports historical Daylight Saving Time schedule and GMT offset changes.
	 *
	 * @param date
	 *        the date represented in milliseconds since January 1, 1970 00:00:00 GMT
	 * @return the amount of time in milliseconds to add to UTC to get local time.
	 *
	 * @see Calendar#ZONE_OFFSET
	 * @see Calendar#DST_OFFSET
	 */
	public int getOffset(long date) {
		throw new RuntimeException();
	}

	/**
	 * Returns the amount of time in milliseconds to add to UTC to get standard time in this time zone.
	 * Because this value is not affected by daylight saving time, it is called <I>raw offset</I>.
	 * <p>
	 * If an underlying <code>TimeZone</code> implementation subclass supports historical GMT offset
	 * changes, the method returns the raw offset value of the current date. In Honolulu, for example,
	 * its raw offset changed from GMT-10:30 to GMT-10:00 in 1947, and this method always returns
	 * -36000000 milliseconds (i.e., -10 hours).
	 *
	 * @return the amount of raw offset time in milliseconds to add to UTC.
	 * @see Calendar#ZONE_OFFSET
	 */
	public abstract int getRawOffset();

	/**
	 * Returns true if this zone has the same rule and offset as another zone. That is, if this zone
	 * differs only in ID, if at all. Returns false if the other zone is null.
	 *
	 * @param other
	 *        the <code>TimeZone</code> object to be compared with
	 * @return true if the other zone is not null and is the same as this one, with the possible
	 *         exception of the ID
	 */
	public boolean hasSameRules(@Nullable TimeZone other) {
		throw new RuntimeException();
	}

	/**
	 * Sets the time zone ID. This does not change any other data in the time zone object.
	 *
	 * @param ID
	 *        the new time zone ID.
	 */
	public void setID(String ID) {
		throw new RuntimeException();
	}

	/**
	 * Queries if this {@code TimeZone} uses Daylight Saving Time.
	 *
	 * <p>
	 * If an underlying {@code TimeZone} implementation subclass supports historical and future Daylight
	 * Saving Time schedule changes, this method refers to the last known Daylight Saving Time rule that
	 * can be a future prediction and may not be the same as the current rule.
	 *
	 * @return {@code true} if this {@code TimeZone} uses Daylight Saving Time, {@code false},
	 *         otherwise.
	 * @see Calendar#DST_OFFSET
	 */
	public abstract boolean useDaylightTime();

}
