/*
 * 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.timezone.ZoneInfoDB;
import libcore.util.ZoneInfo;

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();
        }
    }
}
