/*
 * Copyright (C) 2006 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.text.format;

import android.util.TimeFormatException;

import libcore.util.ZoneInfo;
import libcore.util.ZoneInfoDB;

import java.io.IOException;
import java.util.Locale;
import java.util.TimeZone;

/**
 * An alternative to the {@link java.util.Calendar} and
 * {@link java.util.GregorianCalendar} classes. An instance of the Time class represents
 * a moment in time, specified with second precision. It is modelled after
 * struct tm. This class is not thread-safe and does not consider leap seconds.
 *
 * <p>This class has a number of issues and it is recommended that
 * {@link java.util.GregorianCalendar} is used instead.
 *
 * <p>Known issues:
 * <ul>
 *     <li>For historical reasons when performing time calculations all arithmetic currently takes
 *     place using 32-bit integers. This limits the reliable time range representable from 1902
 *     until 2037.See the wikipedia article on the
 *     <a href="http://en.wikipedia.org/wiki/Year_2038_problem">Year 2038 problem</a> for details.
 *     Do not rely on this behavior; it may change in the future.
 *     </li>
 *     <li>Calling {@link #switchTimezone(String)} on a date that cannot exist, such as a wall time
 *     that was skipped due to a DST transition, will result in a date in 1969 (i.e. -1, or 1 second
 *     before 1st Jan 1970 UTC).</li>
 *     <li>Much of the formatting / parsing assumes ASCII text and is therefore not suitable for
 *     use with non-ASCII scripts.</li>
 *     <li>No support for pseudo-zones like "GMT-07:00".</li>
 * </ul>
 *
 * @deprecated Use {@link java.util.GregorianCalendar} instead.
 */
@Deprecated
public class Time {
    private static final String Y_M_D_T_H_M_S_000 = "%Y-%m-%dT%H:%M:%S.000";
    private static final String Y_M_D_T_H_M_S_000_Z = "%Y-%m-%dT%H:%M:%S.000Z";
    private static final String Y_M_D = "%Y-%m-%d";

    public static final String TIMEZONE_UTC = "UTC";

    /**
     * The Julian day of the epoch, that is, January 1, 1970 on the Gregorian
     * calendar.
     */
    public static final int EPOCH_JULIAN_DAY = 2440588;

    /**
     * The Julian day of the Monday in the week of the epoch, December 29, 1969
     * on the Gregorian calendar.
     */
    public static final int MONDAY_BEFORE_JULIAN_EPOCH = EPOCH_JULIAN_DAY - 3;

    /**
     * True if this is an allDay event. The hour, minute, second fields are
     * all zero, and the date is displayed the same in all time zones.
     */
    public boolean allDay;

    /**
     * Seconds [0-61] (2 leap seconds allowed)
     */
    public int second;

    /**
     * Minute [0-59]
     */
    public int minute;

    /**
     * Hour of day [0-23]
     */
    public int hour;

    /**
     * Day of month [1-31]
     */
    public int monthDay;

    /**
     * Month [0-11]
     */
    public int month;

    /**
     * Year. For example, 1970.
     */
    public int year;

    /**
     * Day of week [0-6]
     */
    public int weekDay;

    /**
     * Day of year [0-365]
     */
    public int yearDay;

    /**
     * This time is in daylight savings time. One of:
     * <ul>
     * <li><b>positive</b> - in dst</li>
     * <li><b>0</b> - not in dst</li>
     * <li><b>negative</b> - unknown</li>
     * </ul>
     */
    public int isDst;

    /**
     * Offset in seconds from UTC including any DST offset.
     */
    public long gmtoff;

    /**
     * The timezone for this Time.  Should not be null.
     */
    public String timezone;

    /*
     * Define symbolic constants for accessing the fields in this class. Used in
     * getActualMaximum().
     */
    public static final int SECOND = 1;
    public static final int MINUTE = 2;
    public static final int HOUR = 3;
    public static final int MONTH_DAY = 4;
    public static final int MONTH = 5;
    public static final int YEAR = 6;
    public static final int WEEK_DAY = 7;
    public static final int YEAR_DAY = 8;
    public static final int WEEK_NUM = 9;

    public static final int SUNDAY = 0;
    public static final int MONDAY = 1;
    public static final int TUESDAY = 2;
    public static final int WEDNESDAY = 3;
    public static final int THURSDAY = 4;
    public static final int FRIDAY = 5;
    public static final int SATURDAY = 6;

    // An object that is reused for date calculations.
    private TimeCalculator calculator;

    /**
     * Construct a Time object in the timezone named by the string
     * argument "timezone". The time is initialized to Jan 1, 1970.
     * @param timezoneId string containing the timezone to use.
     * @see TimeZone
     */
    public Time(String timezoneId) {
        if (timezoneId == null) {
            throw new NullPointerException("timezoneId is null!");
        }
        initialize(timezoneId);
    }

    /**
     * Construct a Time object in the default timezone. The time is initialized to
     * Jan 1, 1970.
     */
    public Time() {
        initialize(TimeZone.getDefault().getID());
    }

    /**
     * A copy constructor.  Construct a Time object by copying the given
     * Time object.  No normalization occurs.
     *
     * @param other
     */
    public Time(Time other) {
        initialize(other.timezone);
        set(other);
    }

    /** Initialize the Time to 00:00:00 1/1/1970 in the specified timezone. */
    private void initialize(String timezoneId) {
        this.timezone = timezoneId;
        this.year = 1970;
        this.monthDay = 1;
        // Set the daylight-saving indicator to the unknown value -1 so that
        // it will be recomputed.
        this.isDst = -1;

        // A reusable object that performs the date/time calculations.
        calculator = new TimeCalculator(timezoneId);
    }

    /**
     * Ensures the values in each field are in range. For example if the
     * current value of this calendar is March 32, normalize() will convert it
     * to April 1. It also fills in weekDay, yearDay, isDst and gmtoff.
     *
     * <p>
     * If "ignoreDst" is true, then this method sets the "isDst" field to -1
     * (the "unknown" value) before normalizing.  It then computes the
     * time in milliseconds and sets the correct value for "isDst" if the
     * fields resolve to a valid date / time.
     *
     * <p>
     * See {@link #toMillis(boolean)} for more information about when to
     * use <tt>true</tt> or <tt>false</tt> for "ignoreDst" and when {@code -1}
     * might be returned.
     *
     * @return the UTC milliseconds since the epoch, or {@code -1}
     */
    public long normalize(boolean ignoreDst) {
        calculator.copyFieldsFromTime(this);
        long timeInMillis = calculator.toMillis(ignoreDst);
        calculator.copyFieldsToTime(this);
        return timeInMillis;
    }

    /**
     * Convert this time object so the time represented remains the same, but is
     * instead located in a different timezone. This method automatically calls
     * normalize() in some cases.
     *
     * <p>This method can return incorrect results if the date / time cannot be normalized.
     */
    public void switchTimezone(String timezone) {
        calculator.copyFieldsFromTime(this);
        calculator.switchTimeZone(timezone);
        calculator.copyFieldsToTime(this);
        this.timezone = timezone;
    }

    private static final int[] DAYS_PER_MONTH = { 31, 28, 31, 30, 31, 30, 31,
            31, 30, 31, 30, 31 };

    /**
     * Return the maximum possible value for the given field given the value of
     * the other fields. Requires that it be normalized for MONTH_DAY and
     * YEAR_DAY.
     * @param field one of the constants for HOUR, MINUTE, SECOND, etc.
     * @return the maximum value for the field.
     */
    public int getActualMaximum(int field) {
        switch (field) {
        case SECOND:
            return 59; // leap seconds, bah humbug
        case MINUTE:
            return 59;
        case HOUR:
            return 23;
        case MONTH_DAY: {
            int n = DAYS_PER_MONTH[this.month];
            if (n != 28) {
                return n;
            } else {
                int y = this.year;
                return ((y % 4) == 0 && ((y % 100) != 0 || (y % 400) == 0)) ? 29 : 28;
            }
        }
        case MONTH:
            return 11;
        case YEAR:
            return 2037;
        case WEEK_DAY:
            return 6;
        case YEAR_DAY: {
            int y = this.year;
            // Year days are numbered from 0, so the last one is usually 364.
            return ((y % 4) == 0 && ((y % 100) != 0 || (y % 400) == 0)) ? 365 : 364;
        }
        case WEEK_NUM:
            throw new RuntimeException("WEEK_NUM not implemented");
        default:
            throw new RuntimeException("bad field=" + field);
        }
    }

    /**
     * Clears all values, setting the timezone to the given timezone. Sets isDst
     * to a negative value to mean "unknown".
     * @param timezoneId the timezone to use.
     */
    public void clear(String timezoneId) {
        if (timezoneId == null) {
            throw new NullPointerException("timezone is null!");
        }
        this.timezone = timezoneId;
        this.allDay = false;
        this.second = 0;
        this.minute = 0;
        this.hour = 0;
        this.monthDay = 0;
        this.month = 0;
        this.year = 0;
        this.weekDay = 0;
        this.yearDay = 0;
        this.gmtoff = 0;
        this.isDst = -1;
    }

    /**
     * Compare two {@code Time} objects and return a negative number if {@code
     * a} is less than {@code b}, a positive number if {@code a} is greater than
     * {@code b}, or 0 if they are equal.
     *
     * <p>
     * This method can return an incorrect answer when the date / time fields of
     * either {@code Time} have been set to a local time that contradicts the
     * available timezone information.
     *
     * @param a first {@code Time} instance to compare
     * @param b second {@code Time} instance to compare
     * @throws NullPointerException if either argument is {@code null}
     * @throws IllegalArgumentException if {@link #allDay} is true but {@code
     *             hour}, {@code minute}, and {@code second} are not 0.
     * @return a negative result if {@code a} is earlier, a positive result if
     *         {@code b} is earlier, or 0 if they are equal.
     */
    public static int compare(Time a, Time b) {
        if (a == null) {
            throw new NullPointerException("a == null");
        } else if (b == null) {
            throw new NullPointerException("b == null");
        }
        a.calculator.copyFieldsFromTime(a);
        b.calculator.copyFieldsFromTime(b);

        return TimeCalculator.compare(a.calculator, b.calculator);
    }

    /**
     * Print the current value given the format string provided. See man
     * strftime for what means what. The final string must be less than 256
     * characters.
     * @param format a string containing the desired format.
     * @return a String containing the current time expressed in the current locale.
     */
    public String format(String format) {
        calculator.copyFieldsFromTime(this);
        return calculator.format(format);
    }

    /**
     * Return the current time in YYYYMMDDTHHMMSS&lt;tz&gt; format
     */
    @Override
    public String toString() {
        // toString() uses its own TimeCalculator rather than the shared one. Otherwise crazy stuff
        // happens during debugging when the debugger calls toString().
        TimeCalculator calculator = new TimeCalculator(this.timezone);
        calculator.copyFieldsFromTime(this);
        return calculator.toStringInternal();
    }

    /**
     * Parses a date-time string in either the RFC 2445 format or an abbreviated
     * format that does not include the "time" field.  For example, all of the
     * following strings are valid:
     *
     * <ul>
     *   <li>"20081013T160000Z"</li>
     *   <li>"20081013T160000"</li>
     *   <li>"20081013"</li>
     * </ul>
     *
     * Returns whether or not the time is in UTC (ends with Z).  If the string
     * ends with "Z" then the timezone is set to UTC.  If the date-time string
     * included only a date and no time field, then the <code>allDay</code>
     * field of this Time class is set to true and the <code>hour</code>,
     * <code>minute</code>, and <code>second</code> fields are set to zero;
     * otherwise (a time field was included in the date-time string)
     * <code>allDay</code> is set to false. The fields <code>weekDay</code>,
     * <code>yearDay</code>, and <code>gmtoff</code> are always set to zero,
     * and the field <code>isDst</code> is set to -1 (unknown).  To set those
     * fields, call {@link #normalize(boolean)} after parsing.
     *
     * To parse a date-time string and convert it to UTC milliseconds, do
     * something like this:
     *
     * <pre>
     *   Time time = new Time();
     *   String date = "20081013T160000Z";
     *   time.parse(date);
     *   long millis = time.normalize(false);
     * </pre>
     *
     * @param s the string to parse
     * @return true if the resulting time value is in UTC time
     * @throws android.util.TimeFormatException if s cannot be parsed.
     */
    public boolean parse(String s) {
        if (s == null) {
            throw new NullPointerException("time string is null");
        }
        if (parseInternal(s)) {
            timezone = TIMEZONE_UTC;
            return true;
        }
        return false;
    }

    /**
     * Parse a time in the current zone in YYYYMMDDTHHMMSS format.
     */
    private boolean parseInternal(String s) {
        int len = s.length();
        if (len < 8) {
            throw new TimeFormatException("String is too short: \"" + s +
                    "\" Expected at least 8 characters.");
        }

        boolean inUtc = false;

        // year
        int n = getChar(s, 0, 1000);
        n += getChar(s, 1, 100);
        n += getChar(s, 2, 10);
        n += getChar(s, 3, 1);
        year = n;

        // month
        n = getChar(s, 4, 10);
        n += getChar(s, 5, 1);
        n--;
        month = n;

        // day of month
        n = getChar(s, 6, 10);
        n += getChar(s, 7, 1);
        monthDay = n;

        if (len > 8) {
            if (len < 15) {
                throw new TimeFormatException(
                        "String is too short: \"" + s
                                + "\" If there are more than 8 characters there must be at least"
                                + " 15.");
            }
            checkChar(s, 8, 'T');
            allDay = false;

            // hour
            n = getChar(s, 9, 10);
            n += getChar(s, 10, 1);
            hour = n;

            // min
            n = getChar(s, 11, 10);
            n += getChar(s, 12, 1);
            minute = n;

            // sec
            n = getChar(s, 13, 10);
            n += getChar(s, 14, 1);
            second = n;

            if (len > 15) {
                // Z
                checkChar(s, 15, 'Z');
                inUtc = true;
            }
        } else {
            allDay = true;
            hour = 0;
            minute = 0;
            second = 0;
        }

        weekDay = 0;
        yearDay = 0;
        isDst = -1;
        gmtoff = 0;
        return inUtc;
    }

    private void checkChar(String s, int spos, char expected) {
        char c = s.charAt(spos);
        if (c != expected) {
            throw new TimeFormatException(String.format(
                    "Unexpected character 0x%02d at pos=%d.  Expected 0x%02d (\'%c\').",
                    (int) c, spos, (int) expected, expected));
        }
    }

    private static int getChar(String s, int spos, int mul) {
        char c = s.charAt(spos);
        if (Character.isDigit(c)) {
            return Character.getNumericValue(c) * mul;
        } else {
            throw new TimeFormatException("Parse error at pos=" + spos);
        }
    }

    /**
     * Parse a time in RFC 3339 format.  This method also parses simple dates
     * (that is, strings that contain no time or time offset).  For example,
     * all of the following strings are valid:
     *
     * <ul>
     *   <li>"2008-10-13T16:00:00.000Z"</li>
     *   <li>"2008-10-13T16:00:00.000+07:00"</li>
     *   <li>"2008-10-13T16:00:00.000-07:00"</li>
     *   <li>"2008-10-13"</li>
     * </ul>
     *
     * <p>
     * If the string contains a time and time offset, then the time offset will
     * be used to convert the time value to UTC.
     * </p>
     *
     * <p>
     * If the given string contains just a date (with no time field), then
     * the {@link #allDay} field is set to true and the {@link #hour},
     * {@link #minute}, and  {@link #second} fields are set to zero.
     * </p>
     *
     * <p>
     * Returns true if the resulting time value is in UTC time.
     * </p>
     *
     * @param s the string to parse
     * @return true if the resulting time value is in UTC time
     * @throws android.util.TimeFormatException if s cannot be parsed.
     */
     public boolean parse3339(String s) {
         if (s == null) {
             throw new NullPointerException("time string is null");
         }
         if (parse3339Internal(s)) {
             timezone = TIMEZONE_UTC;
             return true;
         }
         return false;
     }

     private boolean parse3339Internal(String s) {
         int len = s.length();
         if (len < 10) {
             throw new TimeFormatException("String too short --- expected at least 10 characters.");
         }
         boolean inUtc = false;

         // year
         int n = getChar(s, 0, 1000);
         n += getChar(s, 1, 100);
         n += getChar(s, 2, 10);
         n += getChar(s, 3, 1);
         year = n;

         checkChar(s, 4, '-');

         // month
         n = getChar(s, 5, 10);
         n += getChar(s, 6, 1);
         --n;
         month = n;

         checkChar(s, 7, '-');

         // day
         n = getChar(s, 8, 10);
         n += getChar(s, 9, 1);
         monthDay = n;

         if (len >= 19) {
             // T
             checkChar(s, 10, 'T');
             allDay = false;

             // hour
             n = getChar(s, 11, 10);
             n += getChar(s, 12, 1);

             // Note that this.hour is not set here. It is set later.
             int hour = n;

             checkChar(s, 13, ':');

             // minute
             n = getChar(s, 14, 10);
             n += getChar(s, 15, 1);
             // Note that this.minute is not set here. It is set later.
             int minute = n;

             checkChar(s, 16, ':');

             // second
             n = getChar(s, 17, 10);
             n += getChar(s, 18, 1);
             second = n;

             // skip the '.XYZ' -- we don't care about subsecond precision.

             int tzIndex = 19;
             if (tzIndex < len && s.charAt(tzIndex) == '.') {
                 do {
                     tzIndex++;
                 } while (tzIndex < len && Character.isDigit(s.charAt(tzIndex)));
             }

             int offset = 0;
             if (len > tzIndex) {
                 char c = s.charAt(tzIndex);
                 // NOTE: the offset is meant to be subtracted to get from local time
                 // to UTC.  we therefore use 1 for '-' and -1 for '+'.
                 switch (c) {
                     case 'Z':
                         // Zulu time -- UTC
                         offset = 0;
                         break;
                     case '-':
                         offset = 1;
                         break;
                     case '+':
                         offset = -1;
                         break;
                     default:
                         throw new TimeFormatException(String.format(
                                 "Unexpected character 0x%02d at position %d.  Expected + or -",
                                 (int) c, tzIndex));
                 }
                 inUtc = true;

                 if (offset != 0) {
                     if (len < tzIndex + 6) {
                         throw new TimeFormatException(
                                 String.format("Unexpected length; should be %d characters",
                                         tzIndex + 6));
                     }

                     // hour
                     n = getChar(s, tzIndex + 1, 10);
                     n += getChar(s, tzIndex + 2, 1);
                     n *= offset;
                     hour += n;

                     // minute
                     n = getChar(s, tzIndex + 4, 10);
                     n += getChar(s, tzIndex + 5, 1);
                     n *= offset;
                     minute += n;
                 }
             }
             this.hour = hour;
             this.minute = minute;

             if (offset != 0) {
                 normalize(false);
             }
         } else {
             allDay = true;
             this.hour = 0;
             this.minute = 0;
             this.second = 0;
         }

         this.weekDay = 0;
         this.yearDay = 0;
         this.isDst = -1;
         this.gmtoff = 0;
         return inUtc;
     }

    /**
     * Returns the timezone string that is currently set for the device.
     */
    public static String getCurrentTimezone() {
        return TimeZone.getDefault().getID();
    }

    /**
     * Sets the time of the given Time object to the current time.
     */
    public void setToNow() {
        set(System.currentTimeMillis());
    }

    /**
     * Converts this time to milliseconds. Suitable for interacting with the
     * standard java libraries. The time is in UTC milliseconds since the epoch.
     * This does an implicit normalization to compute the milliseconds but does
     * <em>not</em> change any of the fields in this Time object.  If you want
     * to normalize the fields in this Time object and also get the milliseconds
     * then use {@link #normalize(boolean)}.
     *
     * <p>
     * If "ignoreDst" is false, then this method uses the current setting of the
     * "isDst" field and will adjust the returned time if the "isDst" field is
     * wrong for the given time.  See the sample code below for an example of
     * this.
     *
     * <p>
     * If "ignoreDst" is true, then this method ignores the current setting of
     * the "isDst" field in this Time object and will instead figure out the
     * correct value of "isDst" (as best it can) from the fields in this
     * Time object.  The only case where this method cannot figure out the
     * correct value of the "isDst" field is when the time is inherently
     * ambiguous because it falls in the hour that is repeated when switching
     * from Daylight-Saving Time to Standard Time.
     *
     * <p>
     * Here is an example where <tt>toMillis(true)</tt> adjusts the time,
     * assuming that DST changes at 2am on Sunday, Nov 4, 2007.
     *
     * <pre>
     * Time time = new Time();
     * time.set(4, 10, 2007);  // set the date to Nov 4, 2007, 12am
     * time.normalize(false);       // this sets isDst = 1
     * time.monthDay += 1;     // changes the date to Nov 5, 2007, 12am
     * millis = time.toMillis(false);   // millis is Nov 4, 2007, 11pm
     * millis = time.toMillis(true);    // millis is Nov 5, 2007, 12am
     * </pre>
     *
     * <p>
     * To avoid this problem, use <tt>toMillis(true)</tt>
     * after adding or subtracting days or explicitly setting the "monthDay"
     * field.  On the other hand, if you are adding
     * or subtracting hours or minutes, then you should use
     * <tt>toMillis(false)</tt>.
     *
     * <p>
     * You should also use <tt>toMillis(false)</tt> if you want
     * to read back the same milliseconds that you set with {@link #set(long)}
     * or {@link #set(Time)} or after parsing a date string.
     *
     * <p>
     * This method can return {@code -1} when the date / time fields have been
     * set to a local time that conflicts with available timezone information.
     * For example, when daylight savings transitions cause an hour to be
     * skipped: times within that hour will return {@code -1} if isDst =
     * {@code -1}.
     */
    public long toMillis(boolean ignoreDst) {
        calculator.copyFieldsFromTime(this);
        return calculator.toMillis(ignoreDst);
    }

    /**
     * Sets the fields in this Time object given the UTC milliseconds.  After
     * this method returns, all the fields are normalized.
     * This also sets the "isDst" field to the correct value.
     *
     * @param millis the time in UTC milliseconds since the epoch.
     */
    public void set(long millis) {
        allDay = false;
        calculator.timezone = timezone;
        calculator.setTimeInMillis(millis);
        calculator.copyFieldsToTime(this);
    }

    /**
     * Format according to RFC 2445 DATE-TIME type.
     *
     * <p>The same as format("%Y%m%dT%H%M%S"), or format("%Y%m%dT%H%M%SZ") for a Time with a
     * timezone set to "UTC".
     */
    public String format2445() {
        calculator.copyFieldsFromTime(this);
        return calculator.format2445(!allDay);
    }

    /**
     * Copy the value of that to this Time object. No normalization happens.
     */
    public void set(Time that) {
        this.timezone = that.timezone;
        this.allDay = that.allDay;
        this.second = that.second;
        this.minute = that.minute;
        this.hour = that.hour;
        this.monthDay = that.monthDay;
        this.month = that.month;
        this.year = that.year;
        this.weekDay = that.weekDay;
        this.yearDay = that.yearDay;
        this.isDst = that.isDst;
        this.gmtoff = that.gmtoff;
    }

    /**
     * Sets the fields. Sets weekDay, yearDay and gmtoff to 0, and isDst to -1.
     * Call {@link #normalize(boolean)} if you need those.
     */
    public void set(int second, int minute, int hour, int monthDay, int month, int year) {
        this.allDay = false;
        this.second = second;
        this.minute = minute;
        this.hour = hour;
        this.monthDay = monthDay;
        this.month = month;
        this.year = year;
        this.weekDay = 0;
        this.yearDay = 0;
        this.isDst = -1;
        this.gmtoff = 0;
    }

    /**
     * Sets the date from the given fields.  Also sets allDay to true.
     * Sets weekDay, yearDay and gmtoff to 0, and isDst to -1.
     * Call {@link #normalize(boolean)} if you need those.
     *
     * @param monthDay the day of the month (in the range [1,31])
     * @param month the zero-based month number (in the range [0,11])
     * @param year the year
     */
    public void set(int monthDay, int month, int year) {
        this.allDay = true;
        this.second = 0;
        this.minute = 0;
        this.hour = 0;
        this.monthDay = monthDay;
        this.month = month;
        this.year = year;
        this.weekDay = 0;
        this.yearDay = 0;
        this.isDst = -1;
        this.gmtoff = 0;
    }

    /**
     * Returns true if the time represented by this Time object occurs before
     * the given time.
     *
     * <p>
     * Equivalent to {@code Time.compare(this, that) < 0}. See
     * {@link #compare(Time, Time)} for details.
     *
     * @param that a given Time object to compare against
     * @return true if this time is less than the given time
     */
    public boolean before(Time that) {
        return Time.compare(this, that) < 0;
    }


    /**
     * Returns true if the time represented by this Time object occurs after
     * the given time.
     *
     * <p>
     * Equivalent to {@code Time.compare(this, that) > 0}. See
     * {@link #compare(Time, Time)} for details.
     *
     * @param that a given Time object to compare against
     * @return true if this time is greater than the given time
     */
    public boolean after(Time that) {
        return Time.compare(this, that) > 0;
    }

    /**
     * This array is indexed by the weekDay field (SUNDAY=0, MONDAY=1, etc.)
     * and gives a number that can be added to the yearDay to give the
     * closest Thursday yearDay.
     */
    private static final int[] sThursdayOffset = { -3, 3, 2, 1, 0, -1, -2 };

    /**
     * Computes the week number according to ISO 8601.  The current Time
     * object must already be normalized because this method uses the
     * yearDay and weekDay fields.
     *
     * <p>
     * In IS0 8601, weeks start on Monday.
     * The first week of the year (week 1) is defined by ISO 8601 as the
     * first week with four or more of its days in the starting year.
     * Or equivalently, the week containing January 4.  Or equivalently,
     * the week with the year's first Thursday in it.
     * </p>
     *
     * <p>
     * The week number can be calculated by counting Thursdays.  Week N
     * contains the Nth Thursday of the year.
     * </p>
     *
     * @return the ISO week number.
     */
    public int getWeekNumber() {
        // Get the year day for the closest Thursday
        int closestThursday = yearDay + sThursdayOffset[weekDay];

        // Year days start at 0
        if (closestThursday >= 0 && closestThursday <= 364) {
            return closestThursday / 7 + 1;
        }

        // The week crosses a year boundary.
        Time temp = new Time(this);
        temp.monthDay += sThursdayOffset[weekDay];
        temp.normalize(true /* ignore isDst */);
        return temp.yearDay / 7 + 1;
    }

    /**
     * Return a string in the RFC 3339 format.
     * <p>
     * If allDay is true, expresses the time as Y-M-D</p>
     * <p>
     * Otherwise, if the timezone is UTC, expresses the time as Y-M-D-T-H-M-S UTC</p>
     * <p>
     * Otherwise the time is expressed the time as Y-M-D-T-H-M-S +- GMT</p>
     * @return string in the RFC 3339 format.
     */
    public String format3339(boolean allDay) {
        if (allDay) {
            return format(Y_M_D);
        } else if (TIMEZONE_UTC.equals(timezone)) {
            return format(Y_M_D_T_H_M_S_000_Z);
        } else {
            String base = format(Y_M_D_T_H_M_S_000);
            String sign = (gmtoff < 0) ? "-" : "+";
            int offset = (int) Math.abs(gmtoff);
            int minutes = (offset % 3600) / 60;
            int hours = offset / 3600;

            return String.format(Locale.US, "%s%s%02d:%02d", base, sign, hours, minutes);
        }
    }

    /**
     * Returns true if the day of the given time is the epoch on the Julian Calendar
     * (January 1, 1970 on the Gregorian calendar).
     *
     * <p>
     * This method can return an incorrect answer when the date / time fields have
     * been set to a local time that contradicts the available timezone information.
     *
     * @param time the time to test
     * @return true if epoch.
     */
    public static boolean isEpoch(Time time) {
        long millis = time.toMillis(true);
        return getJulianDay(millis, 0) == EPOCH_JULIAN_DAY;
    }

    /**
     * Computes the Julian day number for a point in time in a particular
     * timezone. The Julian day for a given date is the same for every
     * timezone. For example, the Julian day for July 1, 2008 is 2454649.
     *
     * <p>Callers must pass the time in UTC millisecond (as can be returned
     * by {@link #toMillis(boolean)} or {@link #normalize(boolean)})
     * and the offset from UTC of the timezone in seconds (as might be in
     * {@link #gmtoff}).
     *
     * <p>The Julian day is useful for testing if two events occur on the
     * same calendar date and for determining the relative time of an event
     * from the present ("yesterday", "3 days ago", etc.).
     *
     * @param millis the time in UTC milliseconds
     * @param gmtoff the offset from UTC in seconds
     * @return the Julian day
     */
    public static int getJulianDay(long millis, long gmtoff) {
        long offsetMillis = gmtoff * 1000;
        long julianDay = (millis + offsetMillis) / DateUtils.DAY_IN_MILLIS;
        return (int) julianDay + EPOCH_JULIAN_DAY;
    }

    /**
     * <p>Sets the time from the given Julian day number, which must be based on
     * the same timezone that is set in this Time object.  The "gmtoff" field
     * need not be initialized because the given Julian day may have a different
     * GMT offset than whatever is currently stored in this Time object anyway.
     * After this method returns all the fields will be normalized and the time
     * will be set to 12am at the beginning of the given Julian day.
     * </p>
     *
     * <p>
     * The only exception to this is if 12am does not exist for that day because
     * of daylight saving time.  For example, Cairo, Eqypt moves time ahead one
     * hour at 12am on April 25, 2008 and there are a few other places that
     * also change daylight saving time at 12am.  In those cases, the time
     * will be set to 1am.
     * </p>
     *
     * @param julianDay the Julian day in the timezone for this Time object
     * @return the UTC milliseconds for the beginning of the Julian day
     */
    public long setJulianDay(int julianDay) {
        // Don't bother with the GMT offset since we don't know the correct
        // value for the given Julian day.  Just get close and then adjust
        // the day.
        long millis = (julianDay - EPOCH_JULIAN_DAY) * DateUtils.DAY_IN_MILLIS;
        set(millis);

        // Figure out how close we are to the requested Julian day.
        // We can't be off by more than a day.
        int approximateDay = getJulianDay(millis, gmtoff);
        int diff = julianDay - approximateDay;
        monthDay += diff;

        // Set the time to 12am and re-normalize.
        hour = 0;
        minute = 0;
        second = 0;
        millis = normalize(true);
        return millis;
    }

    /**
     * Returns the week since {@link #EPOCH_JULIAN_DAY} (Jan 1, 1970) adjusted
     * for first day of week. This takes a julian day and the week start day and
     * calculates which week since {@link #EPOCH_JULIAN_DAY} that day occurs in,
     * starting at 0. *Do not* use this to compute the ISO week number for the
     * year.
     *
     * @param julianDay The julian day to calculate the week number for
     * @param firstDayOfWeek Which week day is the first day of the week, see
     *            {@link #SUNDAY}
     * @return Weeks since the epoch
     */
    public static int getWeeksSinceEpochFromJulianDay(int julianDay, int firstDayOfWeek) {
        int diff = THURSDAY - firstDayOfWeek;
        if (diff < 0) {
            diff += 7;
        }
        int refDay = EPOCH_JULIAN_DAY - diff;
        return (julianDay - refDay) / 7;
    }

    /**
     * Takes a number of weeks since the epoch and calculates the Julian day of
     * the Monday for that week. This assumes that the week containing the
     * {@link #EPOCH_JULIAN_DAY} is considered week 0. It returns the Julian day
     * for the Monday week weeks after the Monday of the week containing the
     * epoch.
     *
     * @param week Number of weeks since the epoch
     * @return The julian day for the Monday of the given week since the epoch
     */
    public static int getJulianMondayFromWeeksSinceEpoch(int week) {
        return MONDAY_BEFORE_JULIAN_EPOCH + week * 7;
    }

    /**
     * A class that handles date/time calculations.
     *
     * This class originated as a port of a native C++ class ("android.Time") to pure Java. It is
     * separate from the enclosing class because some methods copy the result of calculations back
     * to the enclosing object, but others do not: thus separate state is retained.
     */
    private static class TimeCalculator {
        public final ZoneInfo.WallTime wallTime;
        public String timezone;

        // Information about the current timezone.
        private ZoneInfo zoneInfo;

        public TimeCalculator(String timezoneId) {
            this.zoneInfo = lookupZoneInfo(timezoneId);
            this.wallTime = new ZoneInfo.WallTime();
        }

        public long toMillis(boolean ignoreDst) {
            if (ignoreDst) {
                wallTime.setIsDst(-1);
            }

            int r = wallTime.mktime(zoneInfo);
            if (r == -1) {
                return -1;
            }
            return r * 1000L;
        }

        public void setTimeInMillis(long millis) {
            // Preserve old 32-bit Android behavior.
            int intSeconds = (int) (millis / 1000);

            updateZoneInfoFromTimeZone();
            wallTime.localtime(intSeconds, zoneInfo);
        }

        public String format(String format) {
            if (format == null) {
                format = "%c";
            }
            TimeFormatter formatter = new TimeFormatter();
            return formatter.format(format, wallTime, zoneInfo);
        }

        private void updateZoneInfoFromTimeZone() {
            if (!zoneInfo.getID().equals(timezone)) {
                this.zoneInfo = lookupZoneInfo(timezone);
            }
        }

        private static ZoneInfo lookupZoneInfo(String timezoneId) {
            try {
                ZoneInfo zoneInfo = ZoneInfoDB.getInstance().makeTimeZone(timezoneId);
                if (zoneInfo == null) {
                    zoneInfo = ZoneInfoDB.getInstance().makeTimeZone("GMT");
                }
                if (zoneInfo == null) {
                    throw new AssertionError("GMT not found: \"" + timezoneId + "\"");
                }
                return zoneInfo;
            } catch (IOException e) {
                // This should not ever be thrown.
                throw new AssertionError("Error loading timezone: \"" + timezoneId + "\"", e);
            }
        }

        public void switchTimeZone(String timezone) {
            int seconds = wallTime.mktime(zoneInfo);
            this.timezone = timezone;
            updateZoneInfoFromTimeZone();
            wallTime.localtime(seconds, zoneInfo);
        }

        public String format2445(boolean hasTime) {
            char[] buf = new char[hasTime ? 16 : 8];
            int n = wallTime.getYear();

            buf[0] = toChar(n / 1000);
            n %= 1000;
            buf[1] = toChar(n / 100);
            n %= 100;
            buf[2] = toChar(n / 10);
            n %= 10;
            buf[3] = toChar(n);

            n = wallTime.getMonth() + 1;
            buf[4] = toChar(n / 10);
            buf[5] = toChar(n % 10);

            n = wallTime.getMonthDay();
            buf[6] = toChar(n / 10);
            buf[7] = toChar(n % 10);

            if (!hasTime) {
                return new String(buf, 0, 8);
            }

            buf[8] = 'T';

            n = wallTime.getHour();
            buf[9] = toChar(n / 10);
            buf[10] = toChar(n % 10);

            n = wallTime.getMinute();
            buf[11] = toChar(n / 10);
            buf[12] = toChar(n % 10);

            n = wallTime.getSecond();
            buf[13] = toChar(n / 10);
            buf[14] = toChar(n % 10);

            if (TIMEZONE_UTC.equals(timezone)) {
                // The letter 'Z' is appended to the end.
                buf[15] = 'Z';
                return new String(buf, 0, 16);
            } else {
                return new String(buf, 0, 15);
            }
        }

        private char toChar(int n) {
            return (n >= 0 && n <= 9) ? (char) (n + '0') : ' ';
        }

        /**
         * A method that will return the state of this object in string form. Note: it has side
         * effects and so has deliberately not been made the default {@link #toString()}.
         */
        public String toStringInternal() {
            // This implementation possibly displays the un-normalized fields because that is
            // what it has always done.
            return String.format("%04d%02d%02dT%02d%02d%02d%s(%d,%d,%d,%d,%d)",
                    wallTime.getYear(),
                    wallTime.getMonth() + 1,
                    wallTime.getMonthDay(),
                    wallTime.getHour(),
                    wallTime.getMinute(),
                    wallTime.getSecond(),
                    timezone,
                    wallTime.getWeekDay(),
                    wallTime.getYearDay(),
                    wallTime.getGmtOffset(),
                    wallTime.getIsDst(),
                    toMillis(false /* use isDst */) / 1000
            );

        }

        public static int compare(TimeCalculator aObject, TimeCalculator bObject) {
            if (aObject.timezone.equals(bObject.timezone)) {
                // If the timezones are the same, we can easily compare the two times.
                int diff = aObject.wallTime.getYear() - bObject.wallTime.getYear();
                if (diff != 0) {
                    return diff;
                }

                diff = aObject.wallTime.getMonth() - bObject.wallTime.getMonth();
                if (diff != 0) {
                    return diff;
                }

                diff = aObject.wallTime.getMonthDay() - bObject.wallTime.getMonthDay();
                if (diff != 0) {
                    return diff;
                }

                diff = aObject.wallTime.getHour() - bObject.wallTime.getHour();
                if (diff != 0) {
                    return diff;
                }

                diff = aObject.wallTime.getMinute() - bObject.wallTime.getMinute();
                if (diff != 0) {
                    return diff;
                }

                diff = aObject.wallTime.getSecond() - bObject.wallTime.getSecond();
                if (diff != 0) {
                    return diff;
                }

                return 0;
            } else {
                // Otherwise, convert to milliseconds and compare that. This requires that object be
                // normalized. Note: For dates that do not exist: toMillis() can return -1, which
                // can be confused with a valid time.
                long am = aObject.toMillis(false /* use isDst */);
                long bm = bObject.toMillis(false /* use isDst */);
                long diff = am - bm;
                return (diff < 0) ? -1 : ((diff > 0) ? 1 : 0);
            }

        }

        public void copyFieldsToTime(Time time) {
            time.second = wallTime.getSecond();
            time.minute = wallTime.getMinute();
            time.hour = wallTime.getHour();
            time.monthDay = wallTime.getMonthDay();
            time.month = wallTime.getMonth();
            time.year = wallTime.getYear();

            // Read-only fields that are derived from other information above.
            time.weekDay = wallTime.getWeekDay();
            time.yearDay = wallTime.getYearDay();

            // < 0: DST status unknown, 0: is not in DST, 1: is in DST
            time.isDst = wallTime.getIsDst();
            // This is in seconds and includes any DST offset too.
            time.gmtoff = wallTime.getGmtOffset();
        }

        public void copyFieldsFromTime(Time time) {
            wallTime.setSecond(time.second);
            wallTime.setMinute(time.minute);
            wallTime.setHour(time.hour);
            wallTime.setMonthDay(time.monthDay);
            wallTime.setMonth(time.month);
            wallTime.setYear(time.year);
            wallTime.setWeekDay(time.weekDay);
            wallTime.setYearDay(time.yearDay);
            wallTime.setIsDst(time.isDst);
            wallTime.setGmtOffset((int) time.gmtoff);

            if (time.allDay && (time.second != 0 || time.minute != 0 || time.hour != 0)) {
                throw new IllegalArgumentException("allDay is true but sec, min, hour are not 0.");
            }

            timezone = time.timezone;
            updateZoneInfoFromTimeZone();
        }
    }
}
