Snap for 8426163 from 6e29ad1dfe9b353af1c41a30101673bf01d7a144 to mainline-tzdata2-release

Change-Id: Ie2b1811eb5f583f2a44fbeeb34cd4d795a87e3d1
diff --git a/Android.bp b/Android.bp
index 2708e2a..4e3ea06 100644
--- a/Android.bp
+++ b/Android.bp
@@ -12,10 +12,6 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package {
-    default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
 java_library {
     name: "calendar-common",
     sdk_version: "15",
diff --git a/src/com/android/calendarcommon2/EventRecurrence.java b/src/com/android/calendarcommon2/EventRecurrence.java
index d54f2fe..45fd12f 100644
--- a/src/com/android/calendarcommon2/EventRecurrence.java
+++ b/src/com/android/calendarcommon2/EventRecurrence.java
@@ -17,7 +17,9 @@
 package com.android.calendarcommon2;
 
 import android.text.TextUtils;
+import android.text.format.Time;
 import android.util.Log;
+import android.util.TimeFormatException;
 
 import java.util.Calendar;
 import java.util.HashMap;
@@ -474,7 +476,7 @@
 
         EventRecurrence er = (EventRecurrence) obj;
         return  (startDate == null ?
-                        er.startDate == null : startDate.compareTo(er.startDate) == 0) &&
+                        er.startDate == null : Time.compare(startDate, er.startDate) == 0) &&
                 freq == er.freq &&
                 (until == null ? er.until == null : until.equals(er.until)) &&
                 count == er.count &&
@@ -738,7 +740,7 @@
                     // Parse the time to validate it.  The result isn't retained.
                     Time until = new Time();
                     until.parse(value);
-                } catch (IllegalArgumentException iae) {
+                } catch (TimeFormatException tfe) {
                     throw new InvalidFormatException("Invalid UNTIL value: " + value);
                 }
             }
diff --git a/src/com/android/calendarcommon2/RecurrenceProcessor.java b/src/com/android/calendarcommon2/RecurrenceProcessor.java
index 24decce..d0a647a 100644
--- a/src/com/android/calendarcommon2/RecurrenceProcessor.java
+++ b/src/com/android/calendarcommon2/RecurrenceProcessor.java
@@ -17,6 +17,7 @@
 
 package com.android.calendarcommon2;
 
+import android.text.format.Time;
 import android.util.Log;
 
 import java.util.TreeSet;
@@ -92,7 +93,7 @@
                 } else if (rrule.until != null) {
                     // according to RFC 2445, until must be in UTC.
                     mIterator.parse(rrule.until);
-                    long untilTime = mIterator.toMillis();
+                    long untilTime = mIterator.toMillis(false /* use isDst */);
                     if (untilTime > lastTime) {
                         lastTime = untilTime;
                     }
@@ -128,8 +129,9 @@
             // The expansion might not contain any dates if the exrule or
             // exdates cancel all the generated dates.
             long[] dates = expand(dtstart, recur,
-                    dtstart.toMillis() /* range start */,
-                    (maxtime != null) ? maxtime.toMillis() : -1 /* range end */);
+                    dtstart.toMillis(false /* use isDst */) /* range start */,
+                    (maxtime != null) ?
+                            maxtime.toMillis(false /* use isDst */) : -1 /* range end */);
 
             // The expansion might not contain any dates if exrule or exdates
             // cancel all the generated dates.
@@ -199,7 +201,7 @@
             // BYMONTH
             if (r.bymonthCount > 0) {
                 found = listContains(r.bymonth, r.bymonthCount,
-                        iterator.getMonth() + 1);
+                        iterator.month + 1);
                 if (!found) {
                     return 1;
                 }
@@ -221,7 +223,7 @@
             // BYYEARDAY
             if (r.byyeardayCount > 0) {
                 found = listContains(r.byyearday, r.byyeardayCount,
-                                iterator.getYearDay(), iterator.getActualMaximum(Time.YEAR_DAY));
+                                iterator.yearDay, iterator.getActualMaximum(Time.YEAR_DAY));
                 if (!found) {
                     return 3;
                 }
@@ -229,7 +231,7 @@
             // BYMONTHDAY
             if (r.bymonthdayCount > 0 ) {
                 found = listContains(r.bymonthday, r.bymonthdayCount,
-                                iterator.getDay(),
+                                iterator.monthDay,
                                 iterator.getActualMaximum(Time.MONTH_DAY));
                 if (!found) {
                     return 4;
@@ -241,7 +243,7 @@
             if (r.bydayCount > 0) {
                 int a[] = r.byday;
                 int N = r.bydayCount;
-                int v = EventRecurrence.timeDay2Day(iterator.getWeekDay());
+                int v = EventRecurrence.timeDay2Day(iterator.weekDay);
                 for (int i=0; i<N; i++) {
                     if (a[i] == v) {
                         break byday;
@@ -253,7 +255,7 @@
         if (EventRecurrence.HOURLY >= freq) {
             // BYHOUR
             found = listContains(r.byhour, r.byhourCount,
-                            iterator.getHour(),
+                            iterator.hour,
                             iterator.getActualMaximum(Time.HOUR));
             if (!found) {
                 return 6;
@@ -262,7 +264,7 @@
         if (EventRecurrence.MINUTELY >= freq) {
             // BYMINUTE
             found = listContains(r.byminute, r.byminuteCount,
-                            iterator.getMinute(),
+                            iterator.minute,
                             iterator.getActualMaximum(Time.MINUTE));
             if (!found) {
                 return 7;
@@ -271,7 +273,7 @@
         if (EventRecurrence.SECONDLY >= freq) {
             // BYSECOND
             found = listContains(r.bysecond, r.bysecondCount,
-                            iterator.getSecond(),
+                            iterator.second,
                             iterator.getActualMaximum(Time.SECOND));
             if (!found) {
                 return 8;
@@ -324,7 +326,7 @@
          * (day of the month - 1) mod 7, and then make sure it's positive.  We can simplify
          * that with some algebra.
          */
-        int dotw = (instance.getWeekDay() - instance.getDay() + 36) % 7;
+        int dotw = (instance.weekDay - instance.monthDay + 36) % 7;
 
         /*
          * The byday[] values are specified as bits, so we can just OR them all
@@ -366,14 +368,14 @@
                 if (index > daySetLength) {
                     continue;  // out of range
                 }
-                if (daySet[index-1] == instance.getDay()) {
+                if (daySet[index-1] == instance.monthDay) {
                     return true;
                 }
             } else if (index < 0) {
                 if (daySetLength + index < 0) {
                     continue;  // out of range
                 }
-                if (daySet[daySetLength + index] == instance.getDay()) {
+                if (daySet[daySetLength + index] == instance.monthDay) {
                     return true;
                 }
             } else {
@@ -427,29 +429,29 @@
 
         boolean get(Time iterator, int day)
         {
-            int realYear = iterator.getYear();
-            int realMonth = iterator.getMonth();
+            int realYear = iterator.year;
+            int realMonth = iterator.month;
 
             Time t = null;
 
             if (SPEW) {
                 Log.i(TAG, "get called with iterator=" + iterator
-                        + " " + iterator.getMonth()
-                        + "/" + iterator.getDay()
-                        + "/" + iterator.getYear() + " day=" + day);
+                        + " " + iterator.month
+                        + "/" + iterator.monthDay
+                        + "/" + iterator.year + " day=" + day);
             }
             if (day < 1 || day > 28) {
                 // if might be past the end of the month, we need to normalize it
                 t = mTime;
                 t.set(day, realMonth, realYear);
                 unsafeNormalize(t);
-                realYear = t.getYear();
-                realMonth = t.getMonth();
-                day = t.getDay();
+                realYear = t.year;
+                realMonth = t.month;
+                day = t.monthDay;
                 if (SPEW) {
-                    Log.i(TAG, "normalized t=" + t + " " + t.getMonth()
-                            + "/" + t.getDay()
-                            + "/" + t.getYear());
+                    Log.i(TAG, "normalized t=" + t + " " + t.month
+                            + "/" + t.monthDay
+                            + "/" + t.year);
                 }
             }
 
@@ -464,9 +466,9 @@
                     t.set(day, realMonth, realYear);
                     unsafeNormalize(t);
                     if (SPEW) {
-                        Log.i(TAG, "set t=" + t + " " + t.getMonth()
-                                + "/" + t.getDay()
-                                + "/" + t.getYear()
+                        Log.i(TAG, "set t=" + t + " " + t.month
+                                + "/" + t.monthDay
+                                + "/" + t.year
                                 + " realMonth=" + realMonth + " mMonth=" + mMonth);
                     }
                 }
@@ -505,11 +507,11 @@
             count = r.bydayCount;
             if (count > 0) {
                 // calculate the day of week for the first of this month (first)
-                j = generated.getDay();
+                j = generated.monthDay;
                 while (j >= 8) {
                     j -= 7;
                 }
-                first = generated.getWeekDay();
+                first = generated.weekDay;
                 if (first >= j) {
                     first = first - j + 1;
                 } else {
@@ -629,13 +631,13 @@
      * UTC milliseconds; use -1 for the entire range.
      * @return an array of dates, each date is in UTC milliseconds
      * @throws DateException
-     * @throws IllegalArgumentException if recur cannot be parsed
+     * @throws android.util.TimeFormatException if recur cannot be parsed
      */
     public long[] expand(Time dtstart,
             RecurrenceSet recur,
             long rangeStartMillis,
             long rangeEndMillis) throws DateException {
-        String timezone = dtstart.getTimezone();
+        String timezone = dtstart.timezone;
         mIterator.clear(timezone);
         mGenerated.clear(timezone);
 
@@ -701,7 +703,7 @@
         int i = 0;
         for (Long val: dtSet) {
             setTimeFromLongValue(mIterator, val);
-            dates[i++] = mIterator.toMillis();
+            dates[i++] = mIterator.toMillis(true /* ignore isDst */);
         }
         return dates;
     }
@@ -726,7 +728,7 @@
      * @param add Whether or not we should add to out, or remove from out.
      * @param out the TreeSet you'd like to fill with the events
      * @throws DateException
-     * @throws IllegalArgumentException if r cannot be parsed.
+     * @throws android.util.TimeFormatException if r cannot be parsed.
      */
     public void expand(Time dtstart,
             EventRecurrence r,
@@ -825,7 +827,7 @@
                     // we'll skip months if it's greater than 28.
                     // XXX Do we generate days for MONTHLY w/ BYHOUR?  If so,
                     // we need to do this then too.
-                    iterator.setDay(1);
+                    iterator.monthDay = 1;
                 }
             }
 
@@ -845,7 +847,7 @@
                 // We need the "until" year/month/day values to be in the same
                 // timezone as all the generated dates so that we can compare them
                 // using the values returned by normDateTimeComparisonValue().
-                until.switchTimezone(dtstart.getTimezone());
+                until.switchTimezone(dtstart.timezone);
                 untilDateValue = normDateTimeComparisonValue(until);
             } else {
                 untilDateValue = Long.MAX_VALUE;
@@ -874,17 +876,17 @@
 
                     unsafeNormalize(iterator);
 
-                    int iteratorYear = iterator.getYear();
-                    int iteratorMonth = iterator.getMonth() + 1;
-                    int iteratorDay = iterator.getDay();
-                    int iteratorHour = iterator.getHour();
-                    int iteratorMinute = iterator.getMinute();
-                    int iteratorSecond = iterator.getSecond();
+                    int iteratorYear = iterator.year;
+                    int iteratorMonth = iterator.month + 1;
+                    int iteratorDay = iterator.monthDay;
+                    int iteratorHour = iterator.hour;
+                    int iteratorMinute = iterator.minute;
+                    int iteratorSecond = iterator.second;
 
                     // year is never expanded -- there is no BYYEAR
                     generated.set(iterator);
 
-                    if (SPEW) Log.i(TAG, "year=" + generated.getYear());
+                    if (SPEW) Log.i(TAG, "year=" + generated.year);
 
                     do { // month
                         int month = usebymonth
@@ -921,9 +923,9 @@
                                  * Thursday.  If weeks started on Mondays, we would only
                                  * need to move back (2 - 1 + 7) % 7 = 1 day.
                                  */
-                                int weekStartAdj = (iterator.getWeekDay() -
+                                int weekStartAdj = (iterator.weekDay -
                                         EventRecurrence.day2TimeDay(r.wkst) + 7) % 7;
-                                dayIndex = iterator.getDay() - weekStartAdj;
+                                dayIndex = iterator.monthDay - weekStartAdj;
                                 lastDayToExamine = dayIndex + 6;
                             } else {
                                 lastDayToExamine = generated
@@ -1063,21 +1065,35 @@
                     // We don't want to "generate" dates with the iterator.
                     // XXX: We do this for days, because there is a varying number of days
                     // per month
-                    int oldDay = iterator.getDay();
+                    int oldDay = iterator.monthDay;
                     generated.set(iterator);  // just using generated as a temporary.
                     int n = 1;
                     while (true) {
                         int value = freqAmount * n;
                         switch (freqField) {
                             case Time.SECOND:
+                                iterator.second += value;
+                                break;
                             case Time.MINUTE:
+                                iterator.minute += value;
+                                break;
                             case Time.HOUR:
+                                iterator.hour += value;
+                                break;
                             case Time.MONTH_DAY:
+                                iterator.monthDay += value;
+                                break;
                             case Time.MONTH:
+                                iterator.month += value;
+                                break;
                             case Time.YEAR:
+                                iterator.year += value;
+                                break;
                             case Time.WEEK_DAY:
+                                iterator.monthDay += value;
+                                break;
                             case Time.YEAR_DAY:
-                                iterator.add(freqField, value);
+                                iterator.monthDay += value;
                                 break;
                             default:
                                 throw new RuntimeException("bad field=" + freqField);
@@ -1087,7 +1103,7 @@
                         if (freqField != Time.YEAR && freqField != Time.MONTH) {
                             break;
                         }
-                        if (iterator.getDay() == oldDay) {
+                        if (iterator.monthDay == oldDay) {
                             break;
                         }
                         n++;
@@ -1120,12 +1136,12 @@
      * This method does not modify the fields isDst, or gmtOff.
      */
     static void unsafeNormalize(Time date) {
-        int second = date.getSecond();
-        int minute = date.getMinute();
-        int hour = date.getHour();
-        int monthDay = date.getDay();
-        int month = date.getMonth();
-        int year = date.getYear();
+        int second = date.second;
+        int minute = date.minute;
+        int hour = date.hour;
+        int monthDay = date.monthDay;
+        int month = date.month;
+        int year = date.year;
 
         int addMinutes = ((second < 0) ? (second - 59) : second) / 60;
         second -= addMinutes * 60;
@@ -1186,14 +1202,14 @@
         // At this point, monthDay <= the length of the current month and is
         // in the range [1,31].
 
-        date.setSecond(second);
-        date.setMinute(minute);
-        date.setHour(hour);
-        date.setDay(monthDay);
-        date.setMonth(month);
-        date.setYear(year);
-        date.setWeekDay(weekDay(year, month, monthDay));
-        date.setYearDay(yearDay(year, month, monthDay));
+        date.second = second;
+        date.minute = minute;
+        date.hour = hour;
+        date.monthDay = monthDay;
+        date.month = month;
+        date.year = year;
+        date.weekDay = weekDay(year, month, monthDay);
+        date.yearDay = yearDay(year, month, monthDay);
     }
 
     /**
@@ -1284,17 +1300,17 @@
     private static final long normDateTimeComparisonValue(Time normalized) {
         // 37 bits for the year, 4 bits for the month, 5 bits for the monthDay,
         // 5 bits for the hour, 6 bits for the minute, 6 bits for the second.
-        return ((long)normalized.getYear() << 26) + (normalized.getMonth() << 22)
-                + (normalized.getDay() << 17) + (normalized.getHour() << 12)
-                + (normalized.getMinute() << 6) + normalized.getSecond();
+        return ((long)normalized.year << 26) + (normalized.month << 22)
+                + (normalized.monthDay << 17) + (normalized.hour << 12)
+                + (normalized.minute << 6) + normalized.second;
     }
 
     private static final void setTimeFromLongValue(Time date, long val) {
-        date.setYear((int) (val >> 26));
-        date.setMonth((int) (val >> 22) & 0xf);
-        date.setDay((int) (val >> 17) & 0x1f);
-        date.setHour((int) (val >> 12) & 0x1f);
-        date.setMinute((int) (val >> 6) & 0x3f);
-        date.setSecond((int) (val & 0x3f));
+        date.year = (int) (val >> 26);
+        date.month = (int) (val >> 22) & 0xf;
+        date.monthDay = (int) (val >> 17) & 0x1f;
+        date.hour = (int) (val >> 12) & 0x1f;
+        date.minute = (int) (val >> 6) & 0x3f;
+        date.second = (int) (val & 0x3f);
     }
 }
diff --git a/src/com/android/calendarcommon2/RecurrenceSet.java b/src/com/android/calendarcommon2/RecurrenceSet.java
index e42c0e9..86e6a2d 100644
--- a/src/com/android/calendarcommon2/RecurrenceSet.java
+++ b/src/com/android/calendarcommon2/RecurrenceSet.java
@@ -20,7 +20,9 @@
 import android.database.Cursor;
 import android.provider.CalendarContract;
 import android.text.TextUtils;
+import android.text.format.Time;
 import android.util.Log;
+import android.util.TimeFormatException;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -160,14 +162,14 @@
             // The timezone is updated to UTC if the time string specified 'Z'.
             try {
                 time.parse(rawDates[i]);
-            } catch (IllegalArgumentException e) {
+            } catch (TimeFormatException e) {
                 throw new EventRecurrence.InvalidFormatException(
-                        "IllegalArgumentException thrown when parsing time " + rawDates[i]
+                        "TimeFormatException thrown when parsing time " + rawDates[i]
                                 + " in recurrence " + recurrence);
 
             }
-            dates[i] = time.toMillis();
-            time.setTimezone(tz);
+            dates[i] = time.toMillis(false /* use isDst */);
+            time.timezone = tz;
         }
         return dates;
     }
@@ -194,9 +196,8 @@
             // NOTE: the timezone may be null, if this is a floating time.
             String tzid = tzidParam == null ? null : tzidParam.value;
             Time start = new Time(tzidParam == null ? Time.TIMEZONE_UTC : tzid);
-            start.parse(dtstart);
-            boolean inUtc = dtstart.length() == 16 && dtstart.charAt(15) == 'Z';
-            boolean allDay = start.isAllDay();
+            boolean inUtc = start.parse(dtstart);
+            boolean allDay = start.allDay;
 
             // We force TimeZone to UTC for "all day recurring events" as the server is sending no
             // TimeZone in DTSTART for them
@@ -223,9 +224,9 @@
             }
 
             if (allDay) {
-                start.setTimezone(Time.TIMEZONE_UTC);
+                start.timezone = Time.TIMEZONE_UTC;
             }
-            long millis = start.toMillis();
+            long millis = start.toMillis(false /* use isDst */);
             values.put(CalendarContract.Events.DTSTART, millis);
             if (millis == -1) {
                 if (false) {
@@ -242,7 +243,7 @@
             values.put(CalendarContract.Events.DURATION, duration);
             values.put(CalendarContract.Events.ALL_DAY, allDay ? 1 : 0);
             return true;
-        } catch (IllegalArgumentException e) {
+        } catch (TimeFormatException e) {
             // Something is wrong with the format of this event
             Log.i(TAG,"Failed to parse event: " + component.toString());
             return false;
@@ -300,10 +301,10 @@
         // TODO: android.pim.Time really should take care of this for us.
         if (allDay) {
             dtstartProp.addParameter(new ICalendar.Parameter("VALUE", "DATE"));
-            dtstartTime.setAllDay(true);
-            dtstartTime.setHour(0);
-            dtstartTime.setMinute(0);
-            dtstartTime.setSecond(0);
+            dtstartTime.allDay = true;
+            dtstartTime.hour = 0;
+            dtstartTime.minute = 0;
+            dtstartTime.second = 0;
         }
 
         dtstartProp.setValue(dtstartTime.format2445());
@@ -359,10 +360,10 @@
         // TODO: android.pim.Time really should take care of this for us.
         if (allDay) {
             dtstartProp.addParameter(new ICalendar.Parameter("VALUE", "DATE"));
-            dtstartTime.setAllDay(true);
-            dtstartTime.setHour(0);
-            dtstartTime.setMinute(0);
-            dtstartTime.setSecond(0);
+            dtstartTime.allDay = true;
+            dtstartTime.hour = 0;
+            dtstartTime.minute = 0;
+            dtstartTime.second = 0;
         }
 
         dtstartProp.setValue(dtstartTime.format2445());
@@ -479,13 +480,14 @@
         ICalendar.Parameter endTzidParameter =
                 dtendProperty.getFirstParameter("TZID");
         String endTzid = (endTzidParameter == null)
-                ? start.getTimezone() : endTzidParameter.value;
+                ? start.timezone : endTzidParameter.value;
 
         Time end = new Time(endTzid);
         end.parse(dtendProperty.getValue());
-        long durationMillis = end.toMillis() - start.toMillis();
+        long durationMillis = end.toMillis(false /* use isDst */)
+                - start.toMillis(false /* use isDst */);
         long durationSeconds = (durationMillis / 1000);
-        if (start.isAllDay() && (durationSeconds % 86400) == 0) {
+        if (start.allDay && (durationSeconds % 86400) == 0) {
             return "P" + (durationSeconds / 86400) + "D"; // Server wants this instead of P86400S
         } else {
             return "P" + durationSeconds + "S";
diff --git a/src/com/android/calendarcommon2/Time.java b/src/com/android/calendarcommon2/Time.java
deleted file mode 100644
index f0af248..0000000
--- a/src/com/android/calendarcommon2/Time.java
+++ /dev/null
@@ -1,532 +0,0 @@
-/*
- * Copyright (C) 2020 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 com.android.calendarcommon2;
-
-import java.text.SimpleDateFormat;
-import java.util.Calendar;
-import java.util.GregorianCalendar;
-import java.util.Locale;
-import java.util.TimeZone;
-
-/**
- * Helper class to make migration out of android.text.format.Time smoother.
- */
-public class Time {
-
-    public static final String TIMEZONE_UTC = "UTC";
-
-    private static final int EPOCH_JULIAN_DAY = 2440588;
-    private static final long HOUR_IN_MILLIS = 60 * 60 * 1000;
-    private static final long DAY_IN_MILLIS = 24 * HOUR_IN_MILLIS;
-
-    private static final String FORMAT_ALL_DAY_PATTERN = "yyyyMMdd";
-    private static final String FORMAT_TIME_PATTERN = "yyyyMMdd'T'HHmmss";
-    private static final String FORMAT_TIME_UTC_PATTERN = "yyyyMMdd'T'HHmmss'Z'";
-    private static final String FORMAT_LOG_TIME_PATTERN = "EEE, MMM dd, yyyy hh:mm a";
-
-    /*
-     * 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;
-
-    private final GregorianCalendar mCalendar;
-
-    private int year;
-    private int month;
-    private int monthDay;
-    private int hour;
-    private int minute;
-    private int second;
-
-    private int yearDay;
-    private int weekDay;
-
-    private String timezone;
-    private boolean allDay;
-
-    /**
-     * Enabling this flag will apply appropriate dst transition logic when calling either
-     * {@code toMillis()} or {@code normalize()} and their respective *ApplyDst() equivalents. <br>
-     * When this flag is enabled, the following calls would be considered equivalent:
-     * <ul>
-     *     <li>{@code a.t.f.Time#normalize(true)} and {@code #normalize()}</li>
-     *     <li>{@code a.t.f.Time#toMillis(true)} and {@code #toMillis()}</li>
-     *     <li>{@code a.t.f.Time#normalize(false)} and {@code #normalizeApplyDst()}</li>
-     *     <li>{@code a.t.f.Time#toMillis(false)} and {@code #toMillisApplyDst()}</li>
-     * </ul>
-     * When the flag is disabled, both {@code toMillis()} and {@code normalize()} will ignore any
-     * dst transitions unless minutes or hours were added to the time (the default behavior of the
-     * a.t.f.Time class). <br>
-     *
-     * NOTE: currently, this flag is disabled because there are no direct manipulations of the day,
-     * hour, or minute fields. All of the accesses are correctly done via setters and they rely on
-     * a private normalize call in their respective classes to achieve their expected behavior.
-     * Additionally, using any of the {@code #set()} methods or {@code #parse()} will result in
-     * normalizing by ignoring DST, which is what the default behavior is for the a.t.f.Time class.
-     */
-    static final boolean APPLY_DST_CHANGE_LOGIC = false;
-    private int mDstChangedByField = -1;
-
-    public Time() {
-        this(TimeZone.getDefault().getID());
-    }
-
-    public Time(String timezone) {
-        if (timezone == null) {
-            throw new NullPointerException("timezone cannot be null.");
-        }
-        this.timezone = timezone;
-        // Although the process's default locale is used here, #clear() will explicitly set the
-        // first day of the week to MONDAY to match with the expected a.t.f.Time implementation.
-        mCalendar = new GregorianCalendar(getTimeZone(), Locale.getDefault());
-        clear(this.timezone);
-    }
-
-    private void readFieldsFromCalendar() {
-        year = mCalendar.get(Calendar.YEAR);
-        month = mCalendar.get(Calendar.MONTH);
-        monthDay = mCalendar.get(Calendar.DAY_OF_MONTH);
-        hour = mCalendar.get(Calendar.HOUR_OF_DAY);
-        minute = mCalendar.get(Calendar.MINUTE);
-        second = mCalendar.get(Calendar.SECOND);
-    }
-
-    private void writeFieldsToCalendar() {
-        clearCalendar();
-        mCalendar.set(year, month, monthDay, hour, minute, second);
-        mCalendar.set(Calendar.MILLISECOND, 0);
-    }
-
-    private boolean isInDst() {
-        return mCalendar.getTimeZone().inDaylightTime(mCalendar.getTime());
-    }
-
-    public void add(int field, int amount) {
-        final boolean wasDstBefore = isInDst();
-        mCalendar.add(getCalendarField(field), amount);
-        if (APPLY_DST_CHANGE_LOGIC && wasDstBefore != isInDst()
-                && (field == MONTH_DAY || field == HOUR || field == MINUTE)) {
-            mDstChangedByField = field;
-        }
-    }
-
-    public void set(long millis) {
-        clearCalendar();
-        mCalendar.setTimeInMillis(millis);
-        readFieldsFromCalendar();
-    }
-
-    public void set(Time other) {
-        clearCalendar();
-        mCalendar.setTimeZone(other.getTimeZone());
-        mCalendar.setTimeInMillis(other.mCalendar.getTimeInMillis());
-        readFieldsFromCalendar();
-    }
-
-    public void set(int day, int month, int year) {
-        clearCalendar();
-        mCalendar.set(year, month, day);
-        readFieldsFromCalendar();
-    }
-
-    public void set(int second, int minute, int hour, int day, int month, int year) {
-        clearCalendar();
-        mCalendar.set(year, month, day, hour, minute, second);
-        readFieldsFromCalendar();
-    }
-
-    public long setJulianDay(int julianDay) {
-        long millis = (julianDay - EPOCH_JULIAN_DAY) * DAY_IN_MILLIS;
-        mCalendar.setTimeInMillis(millis);
-        readFieldsFromCalendar();
-
-        // adjust day approximation, set the time to 12am, and re-normalize
-        monthDay += julianDay - getJulianDay(millis, getGmtOffset());
-        hour = 0;
-        minute = 0;
-        second = 0;
-        writeFieldsToCalendar();
-        return normalize();
-    }
-
-    public static int getJulianDay(long begin, long gmtOff) {
-        return android.text.format.Time.getJulianDay(begin, gmtOff);
-    }
-
-    public int getWeekNumber() {
-        return mCalendar.get(Calendar.WEEK_OF_YEAR);
-    }
-
-    private int getCalendarField(int field) {
-        switch (field) {
-            case SECOND: return Calendar.SECOND;
-            case MINUTE: return Calendar.MINUTE;
-            case HOUR: return Calendar.HOUR_OF_DAY;
-            case MONTH_DAY: return Calendar.DAY_OF_MONTH;
-            case MONTH: return Calendar.MONTH;
-            case YEAR: return Calendar.YEAR;
-            case WEEK_DAY: return Calendar.DAY_OF_WEEK;
-            case YEAR_DAY: return Calendar.DAY_OF_YEAR;
-            case WEEK_NUM: return Calendar.WEEK_OF_YEAR;
-            default:
-                throw new RuntimeException("bad field=" + field);
-        }
-    }
-
-    public int getActualMaximum(int field) {
-        return mCalendar.getActualMaximum(getCalendarField(field));
-    }
-
-    public void switchTimezone(String timezone) {
-        long msBefore = mCalendar.getTimeInMillis();
-        mCalendar.setTimeZone(TimeZone.getTimeZone(timezone));
-        mCalendar.setTimeInMillis(msBefore);
-        mDstChangedByField = -1;
-        readFieldsFromCalendar();
-    }
-
-    /**
-     * @param apply whether to apply dst logic on the ms or not; if apply is true, it is equivalent
-     *              to calling the normalize or toMillis APIs in a.t.f.Time with ignoreDst=false
-     */
-    private long getDstAdjustedMillis(boolean apply, long ms) {
-        if (APPLY_DST_CHANGE_LOGIC) {
-            if (apply && mDstChangedByField == MONTH_DAY) {
-                return isInDst() ? (ms + HOUR_IN_MILLIS) : (ms - HOUR_IN_MILLIS);
-            } else if (!apply && (mDstChangedByField == HOUR || mDstChangedByField == MINUTE)) {
-                return isInDst() ? (ms - HOUR_IN_MILLIS) : (ms + HOUR_IN_MILLIS);
-            }
-        }
-        return ms;
-    }
-
-    private long normalizeInternal() {
-        final long ms = mCalendar.getTimeInMillis();
-        readFieldsFromCalendar();
-        return ms;
-    }
-
-    public long normalize() {
-        return getDstAdjustedMillis(false, normalizeInternal());
-    }
-
-    long normalizeApplyDst() {
-        return getDstAdjustedMillis(true, normalizeInternal());
-    }
-
-    public void parse(String time) {
-        if (time == null) {
-            throw new NullPointerException("time string is null");
-        }
-        parseInternal(time);
-        writeFieldsToCalendar();
-    }
-
-    public String format2445() {
-        writeFieldsToCalendar();
-        final SimpleDateFormat sdf = new SimpleDateFormat(
-                allDay ? FORMAT_ALL_DAY_PATTERN
-                       : (TIMEZONE_UTC.equals(getTimezone()) ? FORMAT_TIME_UTC_PATTERN
-                                                             : FORMAT_TIME_PATTERN));
-        sdf.setTimeZone(getTimeZone());
-        return sdf.format(mCalendar.getTime());
-    }
-
-    public long toMillis() {
-        return getDstAdjustedMillis(false, mCalendar.getTimeInMillis());
-    }
-
-    long toMillisApplyDst() {
-        return getDstAdjustedMillis(true, mCalendar.getTimeInMillis());
-    }
-
-    private TimeZone getTimeZone() {
-        return timezone != null ? TimeZone.getTimeZone(timezone) : TimeZone.getDefault();
-    }
-
-    public int compareTo(Time other) {
-        return mCalendar.compareTo(other.mCalendar);
-    }
-
-    private void clearCalendar() {
-        mDstChangedByField = -1;
-        mCalendar.clear();
-        mCalendar.set(Calendar.HOUR_OF_DAY, 0); // HOUR_OF_DAY doesn't get reset with #clear
-        mCalendar.setTimeZone(getTimeZone());
-        // set fields for week number computation according to ISO 8601.
-        mCalendar.setFirstDayOfWeek(Calendar.MONDAY);
-        mCalendar.setMinimalDaysInFirstWeek(4);
-    }
-
-    public void clear(String timezoneId) {
-        clearCalendar();
-        readFieldsFromCalendar();
-        setTimezone(timezoneId);
-    }
-
-    public int getYear() {
-        return mCalendar.get(Calendar.YEAR);
-    }
-
-    public void setYear(int year) {
-        this.year = year;
-        mCalendar.set(Calendar.YEAR, year);
-    }
-
-    public int getMonth() {
-        return mCalendar.get(Calendar.MONTH);
-    }
-
-    public void setMonth(int month) {
-        this.month = month;
-        mCalendar.set(Calendar.MONTH, month);
-    }
-
-    public int getDay() {
-        return mCalendar.get(Calendar.DAY_OF_MONTH);
-    }
-
-    public void setDay(int day) {
-        this.monthDay = day;
-        mCalendar.set(Calendar.DAY_OF_MONTH, day);
-    }
-
-    public int getHour() {
-        return mCalendar.get(Calendar.HOUR_OF_DAY);
-    }
-
-    public void setHour(int hour) {
-        this.hour = hour;
-        mCalendar.set(Calendar.HOUR_OF_DAY, hour);
-    }
-
-    public int getMinute() {
-        return mCalendar.get(Calendar.MINUTE);
-    }
-
-    public void setMinute(int minute) {
-        this.minute = minute;
-        mCalendar.set(Calendar.MINUTE, minute);
-    }
-
-    public int getSecond() {
-        return mCalendar.get(Calendar.SECOND);
-    }
-
-    public void setSecond(int second) {
-        this.second = second;
-        mCalendar.set(Calendar.SECOND, second);
-    }
-
-    public String getTimezone() {
-        return mCalendar.getTimeZone().getID();
-    }
-
-    public void setTimezone(String timezone) {
-        this.timezone = timezone;
-        mCalendar.setTimeZone(getTimeZone());
-    }
-
-    public int getYearDay() {
-        // yearDay in a.t.f.Time's implementation starts from 0, whereas Calendar's starts from 1.
-        return mCalendar.get(Calendar.DAY_OF_YEAR) - 1;
-    }
-
-    public void setYearDay(int yearDay) {
-        this.yearDay = yearDay;
-        // yearDay in a.t.f.Time's implementation starts from 0, whereas Calendar's starts from 1.
-        mCalendar.set(Calendar.DAY_OF_YEAR, yearDay + 1);
-    }
-
-    public int getWeekDay() {
-        // weekDay in a.t.f.Time's implementation starts from 0, whereas Calendar's starts from 1.
-        return mCalendar.get(Calendar.DAY_OF_WEEK) - 1;
-    }
-
-    public void setWeekDay(int weekDay) {
-        this.weekDay = weekDay;
-        // weekDay in a.t.f.Time's implementation starts from 0, whereas Calendar's starts from 1.
-        mCalendar.set(Calendar.DAY_OF_WEEK, weekDay + 1);
-    }
-
-    public boolean isAllDay() {
-        return allDay;
-    }
-
-    public void setAllDay(boolean allDay) {
-        this.allDay = allDay;
-    }
-
-    public long getGmtOffset() {
-        return mCalendar.getTimeZone().getOffset(mCalendar.getTimeInMillis()) / 1000;
-    }
-
-    private void parseInternal(String s) {
-        int len = s.length();
-        if (len < 8) {
-            throw new IllegalArgumentException("String is too short: \"" + s +
-                    "\" Expected at least 8 characters.");
-        } else if (len > 8 && len < 15) {
-            throw new IllegalArgumentException("String is too short: \"" + s
-                    + "\" If there are more than 8 characters there must be at least 15.");
-        }
-
-        // 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) {
-            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');
-                timezone = TIMEZONE_UTC;
-            }
-        } else {
-            allDay = true;
-            hour = 0;
-            minute = 0;
-            second = 0;
-        }
-
-        weekDay = 0;
-        yearDay = 0;
-    }
-
-    private void checkChar(String s, int spos, char expected) {
-        final char c = s.charAt(spos);
-        if (c != expected) {
-            throw new IllegalArgumentException(String.format(
-                    "Unexpected character 0x%02d at pos=%d.  Expected 0x%02d (\'%c\').",
-                    (int) c, spos, (int) expected, expected));
-        }
-    }
-
-    private int getChar(String s, int spos, int mul) {
-        final char c = s.charAt(spos);
-        if (Character.isDigit(c)) {
-            return Character.getNumericValue(c) * mul;
-        } else {
-            throw new IllegalArgumentException("Parse error at pos=" + spos);
-        }
-    }
-
-    // NOTE: only used for outputting time to error logs
-    public String format() {
-        final SimpleDateFormat sdf =
-                new SimpleDateFormat(FORMAT_LOG_TIME_PATTERN, Locale.getDefault());
-        return sdf.format(mCalendar.getTime());
-    }
-
-    // NOTE: only used in tests
-    public boolean parse3339(String time) {
-        android.text.format.Time tmp = generateInstance();
-        boolean success = tmp.parse3339(time);
-        copyAndWriteInstance(tmp);
-        return success;
-    }
-
-    // NOTE: only used in tests
-    public String format3339(boolean allDay) {
-        return generateInstance().format3339(allDay);
-    }
-
-    private android.text.format.Time generateInstance() {
-        android.text.format.Time tmp = new android.text.format.Time(timezone);
-        tmp.set(second, minute, hour, monthDay, month, year);
-
-        tmp.yearDay = yearDay;
-        tmp.weekDay = weekDay;
-
-        tmp.timezone = timezone;
-        tmp.gmtoff = getGmtOffset();
-        tmp.allDay = allDay;
-        tmp.set(mCalendar.getTimeInMillis());
-        if (tmp.allDay && (tmp.hour != 0 || tmp.minute != 0 || tmp.second != 0)) {
-            // Time SDK expects hour, minute, second to be 0 if allDay is true
-            tmp.hour = 0;
-            tmp.minute = 0;
-            tmp.second = 0;
-        }
-
-        return tmp;
-    }
-
-    private void copyAndWriteInstance(android.text.format.Time time) {
-        year = time.year;
-        month = time.month;
-        monthDay = time.monthDay;
-        hour = time.hour;
-        minute = time.minute;
-        second = time.second;
-
-        yearDay = time.yearDay;
-        weekDay = time.weekDay;
-
-        timezone = time.timezone;
-        allDay = time.allDay;
-
-        writeFieldsToCalendar();
-    }
-}
diff --git a/tests/Android.bp b/tests/Android.bp
index 938b51c..cdda049 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -12,10 +12,6 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package {
-    default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
 android_test {
     name: "CalendarCommonTests",
     sdk_version: "current",
diff --git a/tests/src/com/android/calendarcommon2/RRuleTest.java b/tests/src/com/android/calendarcommon2/RRuleTest.java
index 18217a3..1d72366 100644
--- a/tests/src/com/android/calendarcommon2/RRuleTest.java
+++ b/tests/src/com/android/calendarcommon2/RRuleTest.java
@@ -24,6 +24,7 @@
 import android.os.Debug;
 import android.test.suitebuilder.annotation.MediumTest;
 import android.test.suitebuilder.annotation.Suppress;
+import android.text.format.Time;
 import junit.framework.TestCase;
 
 /**
@@ -114,7 +115,8 @@
         RecurrenceProcessor rp = new RecurrenceProcessor();
         RecurrenceSet recur = new RecurrenceSet(rrule, rdate, exrule, exdate);
 
-        long[] out = rp.expand(dtstart, recur, rangeStart.toMillis(), rangeEnd.toMillis());
+        long[] out = rp.expand(dtstart, recur, rangeStart.toMillis(false /* use isDst */),
+                rangeEnd.toMillis(false /* use isDst */));
 
         if (METHOD_TRACE) {
             Debug.stopMethodTracing();
diff --git a/tests/src/com/android/calendarcommon2/RecurrenceProcessorTest.java b/tests/src/com/android/calendarcommon2/RecurrenceProcessorTest.java
index 3cd9177..3503aae 100644
--- a/tests/src/com/android/calendarcommon2/RecurrenceProcessorTest.java
+++ b/tests/src/com/android/calendarcommon2/RecurrenceProcessorTest.java
@@ -22,7 +22,9 @@
 import android.test.suitebuilder.annotation.MediumTest;
 import android.test.suitebuilder.annotation.SmallTest;
 import android.text.TextUtils;
+import android.text.format.Time;
 import android.util.Log;
+import android.util.TimeFormatException;
 import junit.framework.TestCase;
 
 import java.util.TreeSet;
@@ -104,7 +106,8 @@
         RecurrenceProcessor rp = new RecurrenceProcessor();
         RecurrenceSet recur = new RecurrenceSet(rrule, rdate, exrule, exdate);
 
-        long[] out = rp.expand(dtstart, recur, rangeStart.toMillis(), rangeEnd.toMillis());
+        long[] out = rp.expand(dtstart, recur, rangeStart.toMillis(false /* use isDst */),
+                rangeEnd.toMillis(false /* use isDst */));
 
         if (METHOD_TRACE) {
             Debug.stopMethodTracing();
@@ -147,12 +150,12 @@
         if (lastOccur != -1) {
             outCal.set(lastOccur);
             lastStr = outCal.format2445();
-            lastMillis = outCal.toMillis();
+            lastMillis = outCal.toMillis(true /* ignore isDst */);
         }
         if (last != null && last.length() > 0) {
             Time expectedLast = new Time(tz);
             expectedLast.parse(last);
-            expectedMillis = expectedLast.toMillis();
+            expectedMillis = expectedLast.toMillis(true /* ignore isDst */);
         }
         if (lastMillis != expectedMillis) {
             if (SPEW) {
@@ -595,7 +598,7 @@
                             "20060219T100000"
                     }, "20060220T020001");
             fail("Bad UNTIL string failed to throw exception");
-        } catch (IllegalArgumentException e) {
+        } catch (TimeFormatException e) {
             // expected
         }
     }
@@ -2457,8 +2460,8 @@
         dtstart.parse("20010101T000000");
         rangeStart.parse("20010101T000000");
         rangeEnd.parse("20090101T000000");
-        long rangeStartMillis = rangeStart.toMillis();
-        long rangeEndMillis = rangeEnd.toMillis();
+        long rangeStartMillis = rangeStart.toMillis(false /* use isDst */);
+        long rangeEndMillis = rangeEnd.toMillis(false /* use isDst */);
 
         long startTime = System.currentTimeMillis();
         for (int iterations = 0; iterations < 5; iterations++) {
@@ -2501,12 +2504,12 @@
         long startTime = System.currentTimeMillis();
 
         for (int i = 0; i < ITERATIONS; i++) {
-            date.add(Time.MONTH, 1);
-            date.add(Time.MONTH_DAY, 100);
-            date.normalize();
-            date.add(Time.MONTH, -1);
-            date.add(Time.MONTH_DAY, -100);
-            date.normalize();
+            date.month += 1;
+            date.monthDay += 100;
+            date.normalize(true);
+            date.month -= 1;
+            date.monthDay -= 100;
+            date.normalize(true);
         }
 
         long endTime = System.currentTimeMillis();
@@ -2518,11 +2521,11 @@
         date.parse("20090404T100000");
         startTime = System.currentTimeMillis();
         for (int i = 0; i < ITERATIONS; i++) {
-            date.add(Time.MONTH, 1);
-            date.add(Time.MONTH_DAY, 100);
+            date.month += 1;
+            date.monthDay += 100;
             RecurrenceProcessor.unsafeNormalize(date);
-            date.add(Time.MONTH, -1);
-            date.add(Time.MONTH_DAY, -100);
+            date.month -= 1;
+            date.monthDay -= 100;
             RecurrenceProcessor.unsafeNormalize(date);
         }
 
diff --git a/tests/src/com/android/calendarcommon2/TimeTest.java b/tests/src/com/android/calendarcommon2/TimeTest.java
deleted file mode 100644
index df27c4f..0000000
--- a/tests/src/com/android/calendarcommon2/TimeTest.java
+++ /dev/null
@@ -1,762 +0,0 @@
-/*
- * Copyright (C) 2020 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 com.android.calendarcommon2;
-
-import android.test.suitebuilder.annotation.MediumTest;
-import android.test.suitebuilder.annotation.SmallTest;
-import android.util.TimeFormatException;
-
-import junit.framework.TestCase;
-
-/**
- * Tests for com.android.calendarcommon2.Time.
- *
- * Some of these tests are borrowed from android.text.format.TimeTest.
- */
-public class TimeTest extends TestCase {
-
-    @SmallTest
-    public void testNullTimezone() {
-        try {
-            Time t = new Time(null);
-            fail("expected a null timezone to throw an exception.");
-        } catch (NullPointerException npe) {
-            // expected.
-        }
-    }
-
-    @SmallTest
-    public void testTimezone() {
-        Time t = new Time(Time.TIMEZONE_UTC);
-        assertEquals(Time.TIMEZONE_UTC, t.getTimezone());
-    }
-
-    @SmallTest
-    public void testSwitchTimezone() {
-        Time t = new Time(Time.TIMEZONE_UTC);
-        String newTimezone = "America/Los_Angeles";
-        t.switchTimezone(newTimezone);
-        assertEquals(newTimezone, t.getTimezone());
-    }
-
-    @SmallTest
-    public void testGetActualMaximum() {
-        Time t = new Time(Time.TIMEZONE_UTC);
-        t.set(1, 0, 2020);
-        assertEquals(59, t.getActualMaximum(Time.SECOND));
-        assertEquals(59, t.getActualMaximum(Time.MINUTE));
-        assertEquals(23, t.getActualMaximum(Time.HOUR));
-        assertEquals(31, t.getActualMaximum(Time.MONTH_DAY));
-        assertEquals(11, t.getActualMaximum(Time.MONTH));
-        assertEquals(7, t.getActualMaximum(Time.WEEK_DAY));
-        assertEquals(366, t.getActualMaximum(Time.YEAR_DAY)); // 2020 is a leap year
-        t.set(1, 0, 2019);
-        assertEquals(365, t.getActualMaximum(Time.YEAR_DAY));
-    }
-
-    @SmallTest
-    public void testAdd() {
-        Time t = new Time(Time.TIMEZONE_UTC);
-        t.set(0, 0, 0, 1, 0, 2020);
-        t.add(Time.SECOND, 1);
-        assertEquals(1, t.getSecond());
-        t.add(Time.MINUTE, 1);
-        assertEquals(1, t.getMinute());
-        t.add(Time.HOUR, 1);
-        assertEquals(1, t.getHour());
-        t.add(Time.MONTH_DAY, 1);
-        assertEquals(2, t.getDay());
-        t.add(Time.MONTH, 1);
-        assertEquals(1, t.getMonth());
-        t.add(Time.YEAR, 1);
-        assertEquals(2021, t.getYear());
-    }
-
-    @SmallTest
-    public void testClear() {
-        Time t = new Time(Time.TIMEZONE_UTC);
-        t.clear(Time.TIMEZONE_UTC);
-
-        assertEquals(Time.TIMEZONE_UTC, t.getTimezone());
-        assertFalse(t.isAllDay());
-        assertEquals(0, t.getSecond());
-        assertEquals(0, t.getMinute());
-        assertEquals(0, t.getHour());
-        assertEquals(1, t.getDay()); // default for Calendar is 1
-        assertEquals(0, t.getMonth());
-        assertEquals(1970, t.getYear());
-        assertEquals(4, t.getWeekDay()); // 1970 Jan 1 --> Thursday
-        assertEquals(0, t.getYearDay());
-        assertEquals(0, t.getGmtOffset());
-    }
-
-    @SmallTest
-    public void testCompare() {
-        Time a = new Time(Time.TIMEZONE_UTC);
-        Time b = new Time("America/Los_Angeles");
-        assertTrue(a.compareTo(b) < 0);
-
-        Time c = new Time("Asia/Calcutta");
-        assertTrue(a.compareTo(c) > 0);
-
-        Time d = new Time(Time.TIMEZONE_UTC);
-        assertEquals(0, a.compareTo(d));
-    }
-
-    @SmallTest
-    public void testFormat2445() {
-        Time t = new Time();
-        assertEquals("19700101T000000", t.format2445());
-        t.setTimezone(Time.TIMEZONE_UTC);
-        assertEquals("19700101T000000Z", t.format2445());
-        t.setAllDay(true);
-        assertEquals("19700101", t.format2445());
-    }
-
-    @SmallTest
-    public void testFormat3339() {
-        Time t = new Time(Time.TIMEZONE_UTC);
-        assertEquals("1970-01-01", t.format3339(true));
-        t.set(29, 1, 2020);
-        assertEquals("2020-02-29", t.format3339(true));
-    }
-
-    @SmallTest
-    public void testToMillis() {
-        Time t = new Time(Time.TIMEZONE_UTC);
-        t.set(1, 0, 0, 1, 0, 1970);
-        assertEquals(1000L, t.toMillis());
-
-        t.set(0, 0, 0, 1, 1, 2020);
-        assertEquals(1580515200000L, t.toMillis());
-        t.set(1, 0, 0, 1, 1, 2020);
-        assertEquals(1580515201000L, t.toMillis());
-
-        t.set(1, 0, 2020);
-        assertEquals(1577836800000L, t.toMillis());
-        t.set(1, 1, 2020);
-        assertEquals(1580515200000L, t.toMillis());
-    }
-
-    @SmallTest
-    public void testToMillis_overflow() {
-        Time t = new Time(Time.TIMEZONE_UTC);
-        t.set(32, 0, 2020);
-        assertEquals(1580515200000L, t.toMillis());
-        assertEquals(1, t.getDay());
-        assertEquals(1, t.getMonth());
-    }
-
-    @SmallTest
-    public void testParse() {
-        Time t = new Time(Time.TIMEZONE_UTC);
-        t.parse("20201010T160000Z");
-        assertEquals(2020, t.getYear());
-        assertEquals(9, t.getMonth());
-        assertEquals(10, t.getDay());
-        assertEquals(16, t.getHour());
-        assertEquals(0, t.getMinute());
-        assertEquals(0, t.getSecond());
-
-        t.parse("20200220");
-        assertEquals(2020, t.getYear());
-        assertEquals(1, t.getMonth());
-        assertEquals(20, t.getDay());
-        assertEquals(0, t.getHour());
-        assertEquals(0, t.getMinute());
-        assertEquals(0, t.getSecond());
-
-        try {
-            t.parse("invalid");
-            fail();
-        } catch (IllegalArgumentException e) {
-            // expected
-        }
-
-        try {
-            t.parse("20201010Z160000");
-            fail();
-        } catch (IllegalArgumentException e) {
-            // expected
-        }
-    }
-
-    @SmallTest
-    public void testParse3339() {
-        Time t = new Time(Time.TIMEZONE_UTC);
-
-        t.parse3339("1980-05-23");
-        if (!t.isAllDay() || t.getYear() != 1980 || t.getMonth() != 4 || t.getDay() != 23) {
-            fail("Did not parse all-day date correctly");
-        }
-
-        t.parse3339("1980-05-23T09:50:50");
-        if (t.isAllDay() || t.getYear() != 1980 || t.getMonth() != 4 || t.getDay() != 23
-                || t.getHour() != 9 || t.getMinute() != 50 || t.getSecond() != 50
-                || t.getGmtOffset() != 0) {
-            fail("Did not parse timezone-offset-less date correctly");
-        }
-
-        t.parse3339("1980-05-23T09:50:50Z");
-        if (t.isAllDay() || t.getYear() != 1980 || t.getMonth() != 4 || t.getDay() != 23
-                || t.getHour() != 9 || t.getMinute() != 50 || t.getSecond() != 50
-                || t.getGmtOffset() != 0) {
-            fail("Did not parse UTC date correctly");
-        }
-
-        t.parse3339("1980-05-23T09:50:50.0Z");
-        if (t.isAllDay() || t.getYear() != 1980 || t.getMonth() != 4 || t.getDay() != 23
-                || t.getHour() != 9 || t.getMinute() != 50 || t.getSecond() != 50
-                || t.getGmtOffset() != 0) {
-            fail("Did not parse UTC date correctly");
-        }
-
-        t.parse3339("1980-05-23T09:50:50.12Z");
-        if (t.isAllDay() || t.getYear() != 1980 || t.getMonth() != 4 || t.getDay() != 23
-                || t.getHour() != 9 || t.getMinute() != 50 || t.getSecond() != 50
-                || t.getGmtOffset() != 0) {
-            fail("Did not parse UTC date correctly");
-        }
-
-        t.parse3339("1980-05-23T09:50:50.123Z");
-        if (t.isAllDay() || t.getYear() != 1980 || t.getMonth() != 4 || t.getDay() != 23
-                || t.getHour() != 9 || t.getMinute() != 50 || t.getSecond() != 50
-                || t.getGmtOffset() != 0) {
-            fail("Did not parse UTC date correctly");
-        }
-
-        // the time should be normalized to UTC
-        t.parse3339("1980-05-23T09:50:50-01:05");
-        if (t.isAllDay() || t.getYear() != 1980 || t.getMonth() != 4 || t.getDay() != 23
-                || t.getHour() != 10 || t.getMinute() != 55 || t.getSecond() != 50
-                || t.getGmtOffset() != 0) {
-            fail("Did not parse timezone-offset date correctly");
-        }
-
-        // the time should be normalized to UTC
-        t.parse3339("1980-05-23T09:50:50.123-01:05");
-        if (t.isAllDay() || t.getYear() != 1980 || t.getMonth() != 4 || t.getDay() != 23
-                || t.getHour() != 10 || t.getMinute() != 55 || t.getSecond() != 50
-                || t.getGmtOffset() != 0) {
-            fail("Did not parse timezone-offset date correctly");
-        }
-
-        try {
-            t.parse3339("1980");
-            fail("Did not throw error on truncated input length");
-        } catch (TimeFormatException e) {
-            // successful
-        }
-
-        try {
-            t.parse3339("1980-05-23T09:50:50.123+");
-            fail("Did not throw error on truncated timezone offset");
-        } catch (TimeFormatException e1) {
-            // successful
-        }
-
-        try {
-            t.parse3339("1980-05-23T09:50:50.123+05:0");
-            fail("Did not throw error on truncated timezone offset");
-        } catch (TimeFormatException e1) {
-            // successful
-        }
-    }
-
-    @SmallTest
-    public void testSet_millis() {
-        Time t = new Time(Time.TIMEZONE_UTC);
-
-        t.set(1000L);
-        assertEquals(1970, t.getYear());
-        assertEquals(1, t.getSecond());
-
-        t.set(2000L);
-        assertEquals(2, t.getSecond());
-        assertEquals(0, t.getMinute());
-
-        t.set(1000L * 60);
-        assertEquals(1, t.getMinute());
-        assertEquals(0, t.getHour());
-
-        t.set(1000L * 60 * 60);
-        assertEquals(1, t.getHour());
-        assertEquals(1, t.getDay());
-
-        t.set((1000L * 60 * 60 * 24) + 1000L);
-        assertEquals(2, t.getDay());
-        assertEquals(1970, t.getYear());
-    }
-
-    @SmallTest
-    public void testSet_dayMonthYear() {
-        Time t = new Time(Time.TIMEZONE_UTC);
-        t.set(1, 2, 2021);
-        assertEquals(1, t.getDay());
-        assertEquals(2, t.getMonth());
-        assertEquals(2021, t.getYear());
-    }
-
-    @SmallTest
-    public void testSet_secondMinuteHour() {
-        Time t = new Time(Time.TIMEZONE_UTC);
-        t.set(1, 2, 3, 4, 5, 2021);
-        assertEquals(1, t.getSecond());
-        assertEquals(2, t.getMinute());
-        assertEquals(3, t.getHour());
-        assertEquals(4, t.getDay());
-        assertEquals(5, t.getMonth());
-        assertEquals(2021, t.getYear());
-    }
-
-    @SmallTest
-    public void testSet_overflow() {
-        // Jan 32nd --> Feb 1st
-        Time t = new Time(Time.TIMEZONE_UTC);
-        t.set(32, 0, 2020);
-        assertEquals(1, t.getDay());
-        assertEquals(1, t.getMonth());
-        assertEquals(2020, t.getYear());
-
-        t = new Time(Time.TIMEZONE_UTC);
-        t.set(5, 10, 15, 32, 0, 2020);
-        assertEquals(5, t.getSecond());
-        assertEquals(10, t.getMinute());
-        assertEquals(15, t.getHour());
-        assertEquals(1, t.getDay());
-        assertEquals(1, t.getMonth());
-        assertEquals(2020, t.getYear());
-    }
-
-    @SmallTest
-    public void testSet_other() {
-        Time t = new Time(Time.TIMEZONE_UTC);
-        t.set(1, 2, 3, 4, 5, 2021);
-        Time t2 = new Time();
-        t2.set(t);
-        assertEquals(Time.TIMEZONE_UTC, t2.getTimezone());
-        assertEquals(1, t2.getSecond());
-        assertEquals(2, t2.getMinute());
-        assertEquals(3, t2.getHour());
-        assertEquals(4, t2.getDay());
-        assertEquals(5, t2.getMonth());
-        assertEquals(2021, t2.getYear());
-    }
-
-    @SmallTest
-    public void testSetToNow() {
-        long now = System.currentTimeMillis();
-        Time t = new Time(Time.TIMEZONE_UTC);
-        t.set(now);
-        long ms = t.toMillis();
-        // ensure time is within 1 second because of rounding errors
-        assertTrue("now: " + now + "; actual: " + ms, Math.abs(ms - now) < 1000);
-    }
-
-    @SmallTest
-    public void testGetWeekNumber() {
-        Time t = new Time(Time.TIMEZONE_UTC);
-        t.set(1000L);
-        assertEquals(1, t.getWeekNumber());
-        t.set(1, 1, 2020);
-        assertEquals(5, t.getWeekNumber());
-
-        // ensure ISO 8601 standards are met: weeks start on Monday and the first week has at least
-        // 4 days in it (the year's first Thursday or Jan 4th)
-        for (int i = 1; i <= 8; i++) {
-            t.set(i, 0, 2020);
-            // Jan 6th is the first Monday in 2020 so that would be week 2
-            assertEquals(i < 6 ? 1 : 2, t.getWeekNumber());
-        }
-    }
-
-    private static class DateTest {
-        public int year1;
-        public int month1;
-        public int day1;
-        public int hour1;
-        public int minute1;
-
-        public int offset;
-
-        public int year2;
-        public int month2;
-        public int day2;
-        public int hour2;
-        public int minute2;
-
-        public DateTest(int year1, int month1, int day1, int hour1, int minute1,
-                int offset, int year2, int month2, int day2, int hour2, int minute2) {
-            this.year1 = year1;
-            this.month1 = month1;
-            this.day1 = day1;
-            this.hour1 = hour1;
-            this.minute1 = minute1;
-            this.offset = offset;
-            this.year2 = year2;
-            this.month2 = month2;
-            this.day2 = day2;
-            this.hour2 = hour2;
-            this.minute2 = minute2;
-        }
-
-        public boolean equals(Time time) {
-            return time.getYear() == year2 && time.getMonth() == month2 && time.getDay() == day2
-                    && time.getHour() == hour2 && time.getMinute() == minute2;
-        }
-    }
-
-    @SmallTest
-    public void testNormalize() {
-        Time t = new Time(Time.TIMEZONE_UTC);
-        t.parse("20060432T010203");
-        assertEquals(1146531723000L, t.normalize());
-    }
-
-    /* These tests assume that DST changes on Nov 4, 2007 at 2am (to 1am). */
-
-    // The "offset" field in "dayTests" represents days.
-    // Note: the month numbers are 0-relative, so Jan=0, Feb=1,...Dec=11
-    private DateTest[] dayTests = {
-            // Nov 4, 12am + 0 day = Nov 4, 12am
-            new DateTest(2007, 10, 4, 0, 0, 0, 2007, 10, 4, 0, 0),
-            // Nov 5, 12am + 0 day = Nov 5, 12am
-            new DateTest(2007, 10, 5, 0, 0, 0, 2007, 10, 5, 0, 0),
-            // Nov 3, 12am + 1 day = Nov 4, 12am
-            new DateTest(2007, 10, 3, 0, 0, 1, 2007, 10, 4, 0, 0),
-            // Nov 4, 12am + 1 day = Nov 5, 12am
-            new DateTest(2007, 10, 4, 0, 0, 1, 2007, 10, 5, 0, 0),
-            // Nov 5, 12am + 1 day = Nov 6, 12am
-            new DateTest(2007, 10, 5, 0, 0, 1, 2007, 10, 6, 0, 0),
-            // Nov 3, 1am + 1 day = Nov 4, 1am
-            new DateTest(2007, 10, 3, 1, 0, 1, 2007, 10, 4, 1, 0),
-            // Nov 4, 1am + 1 day = Nov 5, 1am
-            new DateTest(2007, 10, 4, 1, 0, 1, 2007, 10, 5, 1, 0),
-            // Nov 5, 1am + 1 day = Nov 6, 1am
-            new DateTest(2007, 10, 5, 1, 0, 1, 2007, 10, 6, 1, 0),
-            // Nov 3, 2am + 1 day = Nov 4, 2am
-            new DateTest(2007, 10, 3, 2, 0, 1, 2007, 10, 4, 2, 0),
-            // Nov 4, 2am + 1 day = Nov 5, 2am
-            new DateTest(2007, 10, 4, 2, 0, 1, 2007, 10, 5, 2, 0),
-            // Nov 5, 2am + 1 day = Nov 6, 2am
-            new DateTest(2007, 10, 5, 2, 0, 1, 2007, 10, 6, 2, 0),
-    };
-
-    // The "offset" field in "minuteTests" represents minutes.
-    // Note: the month numbers are 0-relative, so Jan=0, Feb=1,...Dec=11
-    private DateTest[] minuteTests = {
-            // Nov 4, 12am + 0 minutes = Nov 4, 12am
-            new DateTest(2007, 10, 4, 0, 0, 0, 2007, 10, 4, 0, 0),
-            // Nov 4, 12am + 60 minutes = Nov 4, 1am
-            new DateTest(2007, 10, 4, 0, 0, 60, 2007, 10, 4, 1, 0),
-            // Nov 5, 12am + 0 minutes = Nov 5, 12am
-            new DateTest(2007, 10, 5, 0, 0, 0, 2007, 10, 5, 0, 0),
-            // Nov 3, 12am + 60 minutes = Nov 3, 1am
-            new DateTest(2007, 10, 3, 0, 0, 60, 2007, 10, 3, 1, 0),
-            // Nov 4, 12am + 60 minutes = Nov 4, 1am
-            new DateTest(2007, 10, 4, 0, 0, 60, 2007, 10, 4, 1, 0),
-            // Nov 5, 12am + 60 minutes = Nov 5, 1am
-            new DateTest(2007, 10, 5, 0, 0, 60, 2007, 10, 5, 1, 0),
-            // Nov 3, 1am + 60 minutes = Nov 3, 2am
-            new DateTest(2007, 10, 3, 1, 0, 60, 2007, 10, 3, 2, 0),
-            // Nov 4, 12:59am (PDT) + 2 minutes = Nov 4, 1:01am (PDT)
-            new DateTest(2007, 10, 4, 0, 59, 2, 2007, 10, 4, 1, 1),
-            // Nov 4, 12:59am (PDT) + 62 minutes = Nov 4, 1:01am (PST)
-            new DateTest(2007, 10, 4, 0, 59, 62, 2007, 10, 4, 1, 1),
-            // Nov 4, 12:30am (PDT) + 120 minutes = Nov 4, 1:30am (PST)
-            new DateTest(2007, 10, 4, 0, 30, 120, 2007, 10, 4, 1, 30),
-            // Nov 4, 12:30am (PDT) + 90 minutes = Nov 4, 1:00am (PST)
-            new DateTest(2007, 10, 4, 0, 30, 90, 2007, 10, 4, 1, 0),
-            // Nov 4, 1am (PDT) + 30 minutes = Nov 4, 1:30am (PDT)
-            new DateTest(2007, 10, 4, 1, 0, 30, 2007, 10, 4, 1, 30),
-            // Nov 4, 1:30am (PDT) + 15 minutes = Nov 4, 1:45am (PDT)
-            new DateTest(2007, 10, 4, 1, 30, 15, 2007, 10, 4, 1, 45),
-            // Mar 11, 1:30am (PST) + 30 minutes = Mar 11, 3am (PDT)
-            new DateTest(2007, 2, 11, 1, 30, 30, 2007, 2, 11, 3, 0),
-            // Nov 4, 1:30am (PST) + 15 minutes = Nov 4, 1:45am (PST)
-            new DateTest(2007, 10, 4, 1, 30, 15, 2007, 10, 4, 1, 45),
-            // Nov 4, 1:30am (PST) + 30 minutes = Nov 4, 2:00am (PST)
-            new DateTest(2007, 10, 4, 1, 30, 30, 2007, 10, 4, 2, 0),
-            // Nov 5, 1am + 60 minutes = Nov 5, 2am
-            new DateTest(2007, 10, 5, 1, 0, 60, 2007, 10, 5, 2, 0),
-            // Nov 3, 2am + 60 minutes = Nov 3, 3am
-            new DateTest(2007, 10, 3, 2, 0, 60, 2007, 10, 3, 3, 0),
-            // Nov 4, 2am + 30 minutes = Nov 4, 2:30am
-            new DateTest(2007, 10, 4, 2, 0, 30, 2007, 10, 4, 2, 30),
-            // Nov 4, 2am + 60 minutes = Nov 4, 3am
-            new DateTest(2007, 10, 4, 2, 0, 60, 2007, 10, 4, 3, 0),
-            // Nov 5, 2am + 60 minutes = Nov 5, 3am
-            new DateTest(2007, 10, 5, 2, 0, 60, 2007, 10, 5, 3, 0),
-            // NOTE: Calendar assumes 1am PDT == 1am PST, the two are not distinct, hence why the transition boundary itself has no tests
-    };
-
-    @MediumTest
-    public void testNormalize_dst() {
-        Time local = new Time("America/Los_Angeles");
-
-        int len = dayTests.length;
-        for (int index = 0; index < len; index++) {
-            DateTest test = dayTests[index];
-            local.set(0, test.minute1, test.hour1, test.day1, test.month1, test.year1);
-            local.add(Time.MONTH_DAY, test.offset);
-            if (!test.equals(local)) {
-                String expectedTime = String.format("%d-%02d-%02d %02d:%02d",
-                        test.year2, test.month2, test.day2, test.hour2, test.minute2);
-                String actualTime = String.format("%d-%02d-%02d %02d:%02d",
-                        local.getYear(), local.getMonth(), local.getDay(), local.getHour(),
-                        local.getMinute());
-                fail("Expected: " + expectedTime + "; Actual: " + actualTime);
-            }
-
-            local.set(0, test.minute1, test.hour1, test.day1, test.month1, test.year1);
-            local.add(Time.MONTH_DAY, test.offset);
-            if (!test.equals(local)) {
-                String expectedTime = String.format("%d-%02d-%02d %02d:%02d",
-                        test.year2, test.month2, test.day2, test.hour2, test.minute2);
-                String actualTime = String.format("%d-%02d-%02d %02d:%02d",
-                        local.getYear(), local.getMonth(), local.getDay(), local.getHour(),
-                        local.getMinute());
-                fail("Expected: " + expectedTime + "; Actual: " + actualTime);
-            }
-        }
-
-        len = minuteTests.length;
-        for (int index = 0; index < len; index++) {
-            DateTest test = minuteTests[index];
-            local.set(0, test.minute1, test.hour1, test.day1, test.month1, test.year1);
-            local.add(Time.MINUTE, test.offset);
-            if (!test.equals(local)) {
-                String expectedTime = String.format("%d-%02d-%02d %02d:%02d",
-                        test.year2, test.month2, test.day2, test.hour2, test.minute2);
-                String actualTime = String.format("%d-%02d-%02d %02d:%02d",
-                        local.getYear(), local.getMonth(), local.getDay(), local.getHour(),
-                        local.getMinute());
-                fail("Expected: " + expectedTime + "; Actual: " + actualTime);
-            }
-
-            local.set(0, test.minute1, test.hour1, test.day1, test.month1, test.year1);
-            local.add(Time.MINUTE, test.offset);
-            if (!test.equals(local)) {
-                String expectedTime = String.format("%d-%02d-%02d %02d:%02d",
-                        test.year2, test.month2, test.day2, test.hour2, test.minute2);
-                String actualTime = String.format("%d-%02d-%02d %02d:%02d",
-                        local.getYear(), local.getMonth(), local.getDay(), local.getHour(),
-                        local.getMinute());
-                fail("Expected: " + expectedTime + "; Actual: " + actualTime);
-            }
-        }
-    }
-
-    @SmallTest
-    public void testNormalize_overflow() {
-        Time t = new Time(Time.TIMEZONE_UTC);
-        t.set(32, 0, 2020);
-        t.normalize();
-        assertEquals(1, t.getDay());
-        assertEquals(1, t.getMonth());
-    }
-
-    @SmallTest
-    public void testDstBehavior_addDays_ignoreDst() {
-        Time time = new Time("America/Los_Angeles");
-        time.set(4, 10, 2007);  // set to Nov 4, 2007, 12am
-        assertEquals(1194159600000L, time.normalize());
-        time.add(Time.MONTH_DAY, 1); // changes to Nov 5, 2007, 12am
-        assertEquals(1194249600000L, time.toMillis());
-
-        time = new Time("America/Los_Angeles");
-        time.set(11, 2, 2007);  // set to Mar 11, 2007, 12am
-        assertEquals(1173600000000L, time.normalize());
-        time.add(Time.MONTH_DAY, 1); // changes to Mar 12, 2007, 12am
-        assertEquals(1173682800000L, time.toMillis());
-    }
-
-    @SmallTest
-    public void testDstBehavior_addDays_applyDst() {
-        if (!Time.APPLY_DST_CHANGE_LOGIC) {
-            return;
-        }
-        Time time = new Time("America/Los_Angeles");
-        time.set(4, 10, 2007);  // set to Nov 4, 2007, 12am
-        assertEquals(1194159600000L, time.normalizeApplyDst());
-        time.add(Time.MONTH_DAY, 1); // changes to Nov 4, 2007, 11pm (fall back)
-        assertEquals(1194246000000L, time.toMillisApplyDst());
-
-        time = new Time("America/Los_Angeles");
-        time.set(11, 2, 2007);  // set to Mar 11, 2007, 12am
-        assertEquals(1173600000000L, time.normalizeApplyDst());
-        time.add(Time.MONTH_DAY, 1); // changes to Mar 12, 2007, 1am (roll forward)
-        assertEquals(1173686400000L, time.toMillisApplyDst());
-    }
-
-    @SmallTest
-    public void testDstBehavior_addHours_ignoreDst() {
-        // Note: by default, Calendar applies DST logic if adding hours or minutes but not if adding
-        // days, hence in this test, only if the APPLY_DST_CHANGE_LOGIC flag is false, then the time
-        // is adjusted with DST
-        Time time = new Time("America/Los_Angeles");
-        time.set(4, 10, 2007);  // set to Nov 4, 2007, 12am
-        assertEquals(1194159600000L, time.normalize());
-        time.add(Time.HOUR, 24); // changes to Nov 5, 2007, 12am
-        assertEquals(Time.APPLY_DST_CHANGE_LOGIC ? 1194249600000L : 1194246000000L,
-                        time.toMillis());
-
-        time = new Time("America/Los_Angeles");
-        time.set(11, 2, 2007);  // set to Mar 11, 2007, 12am
-        assertEquals(1173600000000L, time.normalize());
-        time.add(Time.HOUR, 24); // changes to Mar 12, 2007, 12am
-        assertEquals(Time.APPLY_DST_CHANGE_LOGIC ? 1173682800000L : 1173686400000L,
-                        time.toMillis());
-    }
-
-    @SmallTest
-    public void testDstBehavior_addHours_applyDst() {
-        if (!Time.APPLY_DST_CHANGE_LOGIC) {
-            return;
-        }
-        Time time = new Time("America/Los_Angeles");
-        time.set(4, 10, 2007);  // set to Nov 4, 2007, 12am
-        assertEquals(1194159600000L, time.normalizeApplyDst());
-        time.add(Time.HOUR, 24); // changes to Nov 4, 2007, 11pm (fall back)
-        assertEquals(1194246000000L, time.toMillisApplyDst());
-
-        time = new Time("America/Los_Angeles");
-        time.set(11, 2, 2007);  // set to Mar 11, 2007, 12am
-        assertEquals(1173600000000L, time.normalizeApplyDst());
-        time.add(Time.HOUR, 24); // changes to Mar 12, 2007, 1am (roll forward)
-        assertEquals(1173686400000L, time.toMillisApplyDst());
-    }
-
-    // Timezones that cover the world.
-    // Some GMT offsets occur more than once in case some cities decide to change their GMT offset.
-    private static final String[] mTimeZones = {
-            "Pacific/Kiritimati",
-            "Pacific/Enderbury",
-            "Pacific/Fiji",
-            "Antarctica/South_Pole",
-            "Pacific/Norfolk",
-            "Pacific/Ponape",
-            "Asia/Magadan",
-            "Australia/Lord_Howe",
-            "Australia/Sydney",
-            "Australia/Adelaide",
-            "Asia/Tokyo",
-            "Asia/Seoul",
-            "Asia/Taipei",
-            "Asia/Singapore",
-            "Asia/Hong_Kong",
-            "Asia/Saigon",
-            "Asia/Bangkok",
-            "Indian/Cocos",
-            "Asia/Rangoon",
-            "Asia/Omsk",
-            "Antarctica/Mawson",
-            "Asia/Colombo",
-            "Asia/Calcutta",
-            "Asia/Oral",
-            "Asia/Kabul",
-            "Asia/Dubai",
-            "Asia/Tehran",
-            "Europe/Moscow",
-            "Asia/Baghdad",
-            "Africa/Mogadishu",
-            "Europe/Athens",
-            "Africa/Cairo",
-            "Europe/Rome",
-            "Europe/Berlin",
-            "Europe/Amsterdam",
-            "Africa/Tunis",
-            "Europe/London",
-            "Europe/Dublin",
-            "Atlantic/St_Helena",
-            "Africa/Monrovia",
-            "Africa/Accra",
-            "Atlantic/Azores",
-            "Atlantic/South_Georgia",
-            "America/Noronha",
-            "America/Sao_Paulo",
-            "America/Cayenne",
-            "America/St_Johns",
-            "America/Puerto_Rico",
-            "America/Aruba",
-            "America/New_York",
-            "America/Chicago",
-            "America/Denver",
-            "America/Los_Angeles",
-            "America/Anchorage",
-            "Pacific/Marquesas",
-            "America/Adak",
-            "Pacific/Honolulu",
-            "Pacific/Midway",
-    };
-
-    @MediumTest
-    public void testGetJulianDay() {
-        Time time = new Time(Time.TIMEZONE_UTC);
-
-        // for 30 random days in the year 2020 and for a random timezone, get the Julian day for
-        // 12am and then check that if we change the time we get the same Julian day.
-        for (int i = 0; i < 30; i++) {
-            int monthDay = (int) (Math.random() * 365) + 1;
-            int zoneIndex = (int) (Math.random() * mTimeZones.length);
-            time.setTimezone(mTimeZones[zoneIndex]);
-            time.set(0, 0, 0, monthDay, 0, 2020);
-
-            int julianDay = Time.getJulianDay(time.normalize(), time.getGmtOffset());
-
-            // change the time during the day and check that we get the same Julian day.
-            for (int hour = 0; hour < 24; hour++) {
-                for (int minute = 0; minute < 60; minute += 15) {
-                    time.set(0, minute, hour, monthDay, 0, 2020);
-                    int day = Time.getJulianDay(time.normalize(), time.getGmtOffset());
-                    assertEquals(day, julianDay);
-                    time.clear(Time.TIMEZONE_UTC);
-                }
-            }
-        }
-    }
-
-    @MediumTest
-    public void testSetJulianDay() {
-        Time time = new Time(Time.TIMEZONE_UTC);
-
-        // for each day in the year 2020, pick a random timezone, and verify that we can
-        // set the Julian day correctly.
-        for (int monthDay = 1; monthDay <= 366; monthDay++) {
-            int zoneIndex = (int) (Math.random() * mTimeZones.length);
-            // leave the "month" as zero because we are changing the "monthDay" from 1 to 366.
-            // the call to normalize() will then change the "month" (but we don't really care).
-            time.set(0, 0, 0, monthDay, 0, 2020);
-            time.setTimezone(mTimeZones[zoneIndex]);
-            long millis = time.normalize();
-            int julianDay = Time.getJulianDay(millis, time.getGmtOffset());
-
-            time.setJulianDay(julianDay);
-
-            // some places change daylight saving time at 12am and so there is no 12am on some days
-            // in some timezones - in those cases, the time is set to 1am.
-            // some examples: Africa/Cairo, America/Sao_Paulo, Atlantic/Azores
-            assertTrue(time.getHour() == 0 || time.getHour() == 1);
-            assertEquals(0, time.getMinute());
-            assertEquals(0, time.getSecond());
-
-            millis = time.toMillis();
-            int day = Time.getJulianDay(millis, time.getGmtOffset());
-            assertEquals(day, julianDay);
-            time.clear(Time.TIMEZONE_UTC);
-        }
-    }
-}