aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2022-04-08 16:02:17 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2022-04-08 16:02:17 +0000
commit96f0303a37cb1a27e77bcfd22e84dff0644d1a1c (patch)
tree22fabdf2db0179ed308c4e72ce902bebd5fda3c0
parent1777389d688492b11fec84a82ff16139340b0b99 (diff)
parent6e29ad1dfe9b353af1c41a30101673bf01d7a144 (diff)
downloadcalendar-aml_tz2_305400100.tar.gz
Change-Id: Ie2b1811eb5f583f2a44fbeeb34cd4d795a87e3d1
-rw-r--r--Android.bp4
-rw-r--r--src/com/android/calendarcommon2/EventRecurrence.java6
-rw-r--r--src/com/android/calendarcommon2/RecurrenceProcessor.java156
-rw-r--r--src/com/android/calendarcommon2/RecurrenceSet.java44
-rw-r--r--src/com/android/calendarcommon2/Time.java532
-rw-r--r--tests/Android.bp4
-rw-r--r--tests/src/com/android/calendarcommon2/RRuleTest.java4
-rw-r--r--tests/src/com/android/calendarcommon2/RecurrenceProcessorTest.java35
-rw-r--r--tests/src/com/android/calendarcommon2/TimeTest.java762
9 files changed, 135 insertions, 1412 deletions
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 @@ public class EventRecurrence {
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 @@ public class EventRecurrence {
// 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 @@ public class RecurrenceProcessor
} 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 @@ public class RecurrenceProcessor
// 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 @@ public class RecurrenceProcessor
// 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 @@ public class RecurrenceProcessor
// 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 @@ public class RecurrenceProcessor
// 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 @@ byday:
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 @@ byday:
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 @@ byday:
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 @@ byday:
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 @@ bysetpos:
* (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 @@ bysetpos:
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 @@ bysetpos:
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 @@ bysetpos:
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 @@ bysetpos:
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 @@ bysetpos:
* 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 @@ bysetpos:
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 @@ bysetpos:
* @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 @@ bysetpos:
// 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 @@ bysetpos:
// 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 @@ bysetpos:
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 @@ bysetpos:
* 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 @@ bysetpos:
// 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 @@ bysetpos:
if (freqField != Time.YEAR && freqField != Time.MONTH) {
break;
}
- if (iterator.getDay() == oldDay) {
+ if (iterator.monthDay == oldDay) {
break;
}
n++;
@@ -1120,12 +1136,12 @@ bysetpos:
* 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 @@ bysetpos:
// 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 @@ bysetpos:
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.content.ContentValues;
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 @@ public class RecurrenceSet {
// 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 @@ public class RecurrenceSet {
// 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 @@ public class RecurrenceSet {
}
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 @@ public class RecurrenceSet {
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 @@ public class RecurrenceSet {
// 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 @@ public static boolean populateComponent(ContentValues values,
// 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 @@ public static boolean populateComponent(ContentValues values,
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 com.android.calendarcommon2.RecurrenceSet;
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 @@ public class RRuleTest extends TestCase {
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.LargeTest;
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 @@ public class RecurrenceProcessorTest extends TestCase {
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 @@ public class RecurrenceProcessorTest extends TestCase {
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 @@ public class RecurrenceProcessorTest extends TestCase {
"20060219T100000"
}, "20060220T020001");
fail("Bad UNTIL string failed to throw exception");
- } catch (IllegalArgumentException e) {
+ } catch (TimeFormatException e) {
// expected
}
}
@@ -2457,8 +2460,8 @@ public class RecurrenceProcessorTest extends TestCase {
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 @@ public class RecurrenceProcessorTest extends TestCase {
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 @@ public class RecurrenceProcessorTest extends TestCase {
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);
- }
- }
-}