From 2bc1a99d53ffc541a239d9f98a72c2694f71189d Mon Sep 17 00:00:00 2001 From: Steve Hannah Date: Thu, 9 Apr 2015 16:54:08 -0700 Subject: [PATCH] Added tests for timezone and calendar from Apache Harmony. --- .../teavm/classlib/java/util/TCalendar.java | 6 + .../java/util/TGregorianCalendar.java | 5 + .../teavm/classlib/java/util/TTimeZone.java | 142 ++- .../resources/org/teavm/javascript/runtime.js | 43 - .../org/teavm/platform/PlatformTimezone.java | 64 + .../classlib/java/util/CalendarTest.java | 1118 +++++++++++++++++ .../classlib/java/util/TimeZoneTest.java | 383 ++++++ 7 files changed, 1700 insertions(+), 61 deletions(-) create mode 100644 teavm-platform/src/main/java/org/teavm/platform/PlatformTimezone.java create mode 100644 teavm-tests/src/test/java/org/teavm/classlib/java/util/CalendarTest.java diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TCalendar.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TCalendar.java index 4a1cdecdc..675f69ad4 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TCalendar.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TCalendar.java @@ -321,6 +321,10 @@ public abstract class TCalendar implements TSerializable, TCloneable, TComparabl public static TCalendar getInstance(TTimeZone zone){ return new TGregorianCalendar(zone); } + + public static TCalendar getInstance(TTimeZone zone, TLocale locale){ + return new TGregorianCalendar(zone, locale); + } abstract public int getLeastMaximum(int field); @@ -392,6 +396,8 @@ public abstract class TCalendar implements TSerializable, TCloneable, TComparabl lastTimeFieldSet = HOUR; } } + + public final void set(int year, int month, int day) { set(YEAR, year); diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TGregorianCalendar.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TGregorianCalendar.java index c3063dba4..48e0c993e 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TGregorianCalendar.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TGregorianCalendar.java @@ -83,6 +83,11 @@ public class TGregorianCalendar extends TCalendar { super(locale); setTimeInMillis(System.currentTimeMillis()); } + + public TGregorianCalendar(TTimeZone zone, TLocale locale){ + this(locale); + setTimeZone(zone); + } TGregorianCalendar(@SuppressWarnings("unused") boolean ignored) { setFirstDayOfWeek(SUNDAY); diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TTimeZone.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TTimeZone.java index d67dc73d7..293e4b085 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TTimeZone.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TTimeZone.java @@ -15,7 +15,11 @@ */ package org.teavm.classlib.java.util; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; import org.teavm.jso.JSBody; +import org.teavm.platform.PlatformTimezone; /** * TimeZone represents a time zone offset, and also figures out daylight savings. @@ -28,6 +32,76 @@ import org.teavm.jso.JSBody; */ public abstract class TTimeZone { + + public static class GMT extends PlatformTimezone { + + @Override + public String getTimezoneId() { + return "GMT"; + } + + @Override + public int getTimezoneOffset(int year, int month, int day, int timeOfDayMillis) { + return 0; + } + + @Override + public int getTimezoneRawOffset() { + return 0; + } + + @Override + public boolean isTimezoneDST(long millis) { + return false; + } + + } + + public static class Local extends PlatformTimezone { + + @Override + public String getTimezoneId() { + return "Local"; + } + + @Override + public int getTimezoneOffset(int year, int month, int day, int timeOfDayMillis) { + int hours = (int)Math.floor(timeOfDayMillis/1000/60/60); + int minutes = (int)Math.floor(timeOfDayMillis/1000/60)%60; + int seconds = (int)Math.floor(timeOfDayMillis/1000)%60; + TDate d = new TDate(year, month, day, hours, minutes, seconds); + return -TDate.getTimezoneOffset(d.getTime()) * 1000 * 60; + } + + @Override + public int getTimezoneRawOffset() { + TDate now = new TDate(); + TDate jan = new TDate(now.getYear(), 0, 1); + TDate jul = new TDate(now.getYear(), 6, 1); + if (isTimezoneDST(jan.getTime())){ + return jul.getTimezoneOffset(); + } else { + return jan.getTimezoneOffset(); + } + } + + @Override + public boolean isTimezoneDST(long millis) { + + TDate now = new TDate(); + TDate jan = new TDate(now.getYear(), 0, 1); + TDate jul = new TDate(now.getYear(), 6, 1); + int maxOffset = Math.max(jan.getTimezoneOffset(), jul.getTimezoneOffset()); + return new Date(millis).getTimezoneOffset() out = new ArrayList(); + for (String id : getAvailableIDs()){ + PlatformTimezone tz = PlatformTimezone.getTimezone(id); + if (tz.getTimezoneRawOffset()==rawOffset){ + out.add(id); + } + } + return out.toArray(new String[out.size()]); + } + private static String getTimezoneId(){ + return PlatformTimezone.getPlatformTimezoneId(); + } - @JSBody(params="name", - script="return $rt_getTimezoneRawOffset(name)") - private static native int getTimezoneRawOffset(String name); - @JSBody(params={"name","millis"}, script="return $rt_isTimezoneDST(name,millis)") - private static native boolean isTimezoneDST(String name, long millis); + private static int getTimezoneOffset(String name, int year, int month, int day, int timeOfDayMillis){ + PlatformTimezone tz = PlatformTimezone.getTimezone(name); + if (tz==null){ + throw new RuntimeException("Timezone not found: "+name); + } + return tz.getTimezoneOffset(year, month, day, timeOfDayMillis); + } + + private static int getTimezoneRawOffset(String name){ + PlatformTimezone tz = PlatformTimezone.getTimezone(name); + if (tz==null){ + throw new RuntimeException("Timezone not found: "+name); + } + return tz.getTimezoneRawOffset(); + } + + private static boolean isTimezoneDST(String name, long millis){ + PlatformTimezone tz = PlatformTimezone.getTimezone(name); + if (tz==null){ + throw new RuntimeException("Timezone not found: "+name); + } + return tz.isTimezoneDST(millis); + } /** * Gets the default TimeZone for this host. The source of the default TimeZone may vary with implementation. @@ -110,6 +203,10 @@ public abstract class TTimeZone { } return defaultTimeZone; } + + public void setDefault(TTimeZone tz){ + defaultTimeZone=tz; + } int getDSTSavings() { return useDaylightTime() ? 3600000 : 0; @@ -127,6 +224,15 @@ public abstract class TTimeZone { return ID; } + public int getOffset(long millis){ + Date d = new Date(millis); + d.setHours(0); + d.setMinutes(0); + d.setSeconds(0); + + return getOffset(0, d.getYear(), d.getMonth(), d.getDate(), d.getDay(), (int)(millis-d.getTime())); + } + /** * Gets offset, for current date, modified in case of daylight savings. This is the offset to add *to* GMT to get local time. Gets the time zone offset, for current date, modified in case of daylight savings. This is the offset to add *to* GMT to get local time. Assume that the start and end month are distinct. This method may return incorrect results for rules that start at the end of February (e.g., last Sunday in February) or the beginning of March (e.g., March 1). */ diff --git a/teavm-core/src/main/resources/org/teavm/javascript/runtime.js b/teavm-core/src/main/resources/org/teavm/javascript/runtime.js index dff1691cc..2cd5da424 100644 --- a/teavm-core/src/main/resources/org/teavm/javascript/runtime.js +++ b/teavm-core/src/main/resources/org/teavm/javascript/runtime.js @@ -529,49 +529,6 @@ function $rt_nativeThread() { function $rt_invalidPointer() { throw new Error("Invalid recorded state"); } -function $rt_getTimezoneId(){ - return "LOCAL"; -} -function $rt_getTimezoneOffset(name, year, month, day, timeOfDayMillis){ - if ($rt_getTimezoneId()===name){ - var hours = Math.floor(timeOfDayMillis/1000/60/60); - var minutes = Math.floor(timeOfDayMillis/1000/60)%60; - var seconds = Math.floor(timeOfDayMillis/1000)%60; - var millis = timeOfDayMillis % 1000; - return -(new Date(year, month, day, hours, minutes, seconds, millis).getTimezoneOffset()*1000*60); - } else if ("UTC"===name || "GMT"===name){ - return 0; - } else { - throw new Error("Unsupported Timezone: "+name); - } -} -function $rt_getTimezoneRawOffset(name){ - if ($rt_getTimezoneId()===name){ - var millis = new Date().getTime(); - var i=0; - var addDays = 1000 * 60 *60 * 24 * 200; // Check 200 days later - while ($rt_isTimezoneDST(name, millis) && i++<4){ - millis += addDays; - } - return -(new Date(millis).getTimezoneOffset()*1000*60); - } else if (name==='GMT' || name==='UTC'){ - return 0; - } else { - throw new Error("Unsupported Timezone: "+name); - } -} -function $rt_isTimezoneDST(name, millis){ - if ($rt_getTimezoneId()===name){ - var jan = new Date(this.getFullYear(), 0, 1); - var jul = new Date(this.getFullYear(), 6, 1); - var maxOff = Math.max(jan.getTimezoneOffset(), jul.getTimezoneOffset()); - return new Date(millis).getTimezoneOffset() timezones; + private static Map timezones(){ + if (timezones==null){ + timezones = new HashMap(); + } + return timezones; + } + public static PlatformTimezone getTimezone(String id){ + return timezones().get(id); + } + + public static void addTimezone(String id, PlatformTimezone tz){ + timezones().put(id, tz); + } + + public static String[] getAvailableIds(){ + Set keys = timezones().keySet(); + return keys.toArray(new String[keys.size()]); + } + + public static void setPlatformTimezoneId(String id){ + platformTimezoneId=id; + } + + public static String getPlatformTimezoneId(){ + return platformTimezoneId; + } + + public abstract String getTimezoneId(); + public abstract int getTimezoneOffset(int year, int month, int day, int timeOfDayMillis); + public abstract int getTimezoneRawOffset(); + public abstract boolean isTimezoneDST(long millis); + + +} diff --git a/teavm-tests/src/test/java/org/teavm/classlib/java/util/CalendarTest.java b/teavm-tests/src/test/java/org/teavm/classlib/java/util/CalendarTest.java new file mode 100644 index 000000000..50a29f681 --- /dev/null +++ b/teavm-tests/src/test/java/org/teavm/classlib/java/util/CalendarTest.java @@ -0,0 +1,1118 @@ +/* + * Copyright 2015 shannah. + * + * 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 org.teavm.classlib.java.util; + +import java.util.Calendar; +import java.util.Date; +import java.util.GregorianCalendar; +import java.util.Locale; +import java.util.TimeZone; +import org.junit.Test; +import org.teavm.platform.PlatformTimezone; + +/** + * + * @author shannah + */ +public class CalendarTest extends junit.framework.TestCase { + + static { + if (PlatformTimezone.getTimezone("EST")==null){ + PlatformTimezone.addTimezone("EST", new TimeZoneTest.EST()); + } + } + Locale defaultLocale; + + /** + * @tests java.util.Calendar#set(int, int) + */ + @Test + public void test_setII() { + // Test for correct result defined by the last set field + Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("EST")); + + cal.clear(); + cal.set(Calendar.YEAR, 2002); + assertTrue("Incorrect result 0: " + cal.getTime().getTime(), cal + .getTime().getTime() == 1009861200000L); + + cal.clear(); + cal.set(Calendar.YEAR, 2002); + cal.set(Calendar.MONTH, Calendar.MARCH); + assertTrue("Incorrect result 0a: " + cal.getTime(), cal.getTime() + .getTime() == 1014958800000L); + + cal.clear(); + cal.set(Calendar.YEAR, 2002); + cal.set(Calendar.DATE, 24); + assertTrue("Incorrect result 0b: " + cal.getTime(), cal.getTime() + .getTime() == 1011848400000L); + + cal.set(Calendar.MONTH, Calendar.OCTOBER); + cal.set(Calendar.DATE, 31); + cal.set(Calendar.MONTH, Calendar.NOVEMBER); + cal.set(Calendar.DATE, 26); + assertTrue("Incorrect month: " + cal.get(Calendar.MONTH), cal + .get(Calendar.MONTH) == Calendar.NOVEMBER); + + int dow = cal.get(Calendar.DAY_OF_WEEK); + cal.set(Calendar.DATE, 27); + assertTrue("Incorrect DAY_OF_WEEK: " + cal.get(Calendar.DAY_OF_WEEK) + + " expected: " + dow, cal.get(Calendar.DAY_OF_WEEK) != dow); + + cal.clear(); + cal.set(Calendar.YEAR, 2002); + cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY); + assertTrue("Incorrect result 0c1: " + cal.getTime().getTime(), cal + .getTime().getTime() == 1010379600000L); + + cal.clear(); + cal.set(Calendar.YEAR, 2002); + cal.set(Calendar.DAY_OF_WEEK, Calendar.TUESDAY); + assertTrue("Incorrect result 0c2: " + cal.getTime().getTime(), cal + .getTime().getTime() == 1009861200000L); + + cal.clear(); + cal.set(Calendar.YEAR, 2002); + cal.set(Calendar.DAY_OF_WEEK, Calendar.THURSDAY); + assertTrue("Incorrect result 0c3: " + cal.getTime(), cal.getTime() + .getTime() == 1010034000000L); + + cal.clear(); + cal.set(Calendar.YEAR, 2002); + cal.set(Calendar.WEEK_OF_MONTH, 2); + assertTrue("Incorrect result 0d: " + cal.getTime(), cal.getTime() + .getTime() == 1010293200000L); + + cal.clear(); + cal.set(Calendar.YEAR, 2002); + cal.set(Calendar.DAY_OF_WEEK_IN_MONTH, 2); + assertTrue("Incorrect result 0e: " + cal.getTime(), cal.getTime() + .getTime() == 1010898000000L); + + cal.clear(); + cal.set(Calendar.YEAR, 2002); + cal.set(Calendar.WEEK_OF_YEAR, 11); + assertTrue("Incorrect result 0f: " + cal.getTime(), cal.getTime() + .getTime() == 1015736400000L); + + cal.clear(); + cal.set(Calendar.YEAR, 2002); + cal.set(Calendar.DATE, 24); + cal.set(Calendar.WEEK_OF_YEAR, 11); + assertTrue("Incorrect result 0g: " + cal.getTime(), cal.getTime() + .getTime() == 1011848400000L); + + cal.clear(); + cal.set(Calendar.YEAR, 2002); + cal.get(Calendar.WEEK_OF_YEAR); // Force fields to compute + cal.set(Calendar.WEEK_OF_YEAR, 11); + assertTrue("Incorrect result 0h: " + cal.getTime(), cal.getTime() + .getTime() == 1015909200000L); + + // WEEK_OF_YEAR has priority over MONTH/DATE + cal.clear(); + cal.set(Calendar.YEAR, 2002); + cal.set(Calendar.DAY_OF_YEAR, 170); + cal.set(Calendar.WEEK_OF_YEAR, 11); + cal.set(Calendar.MONTH, Calendar.JANUARY); + cal.set(Calendar.DATE, 5); + cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY); + assertTrue("Incorrect result 1: " + cal.getTime(), cal.getTime() + .getTime() == 1015822800000L); + + // WEEK_OF_YEAR has priority over MONTH/DATE + cal.clear(); + cal.set(Calendar.YEAR, 2002); + cal.set(Calendar.WEEK_OF_YEAR, 11); + cal.set(Calendar.MONTH, Calendar.JANUARY); + cal.set(Calendar.DATE, 5); + cal.set(Calendar.DAY_OF_YEAR, 170); + cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY); + assertTrue("Incorrect result 1a: " + cal.getTime(), cal.getTime() + .getTime() == 1015822800000L); + + // DAY_OF_WEEK has no effect when other fields not set + cal.clear(); + cal.set(Calendar.YEAR, 2002); + cal.set(Calendar.MONTH, Calendar.MARCH); + cal.set(Calendar.DATE, 11); + cal.set(Calendar.DAY_OF_WEEK, Calendar.TUESDAY); + assertTrue("Incorrect result 1b: " + cal.getTime(), cal.getTime() + .getTime() == 1015822800000L); + // Regression for HARMONY-4384 + // Set DAY_OF_WEEK without DATE + cal.clear(); + cal.set(Calendar.YEAR, 2002); + cal.set(Calendar.MONTH, Calendar.MARCH); + cal.set(Calendar.DAY_OF_WEEK, Calendar.TUESDAY); + assertEquals("Incorrect result 1b: " + cal.getTime(), 1015304400000L, cal.getTime() + .getTime()); + + // WEEK_OF_MONTH has priority + cal.clear(); + cal.set(Calendar.YEAR, 2002); + cal.set(Calendar.WEEK_OF_YEAR, 12); + cal.set(Calendar.DAY_OF_WEEK_IN_MONTH, 1); + cal.set(Calendar.WEEK_OF_MONTH, 3); + cal.set(Calendar.MONTH, Calendar.MARCH); + cal.set(Calendar.DATE, 5); + cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY); + assertTrue("Incorrect result 2: " + cal.getTime(), cal.getTime() + .getTime() == 1015822800000L); + + // DAY_OF_WEEK_IN_MONTH has priority over WEEK_OF_YEAR + cal.clear(); + cal.set(Calendar.YEAR, 2002); + cal.set(Calendar.WEEK_OF_YEAR, 12); + cal.set(Calendar.DAY_OF_WEEK_IN_MONTH, 2); + cal.set(Calendar.MONTH, Calendar.MARCH); + cal.set(Calendar.DATE, 5); + cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY); + assertTrue("Incorrect result 3: " + cal.getTime(), cal.getTime() + .getTime() == 1015822800000L); + + // WEEK_OF_MONTH has priority, MONTH not set + cal.clear(); + cal.set(Calendar.YEAR, 2002); + cal.set(Calendar.WEEK_OF_YEAR, 12); + cal.set(Calendar.DAY_OF_WEEK_IN_MONTH, 1); + cal.set(Calendar.WEEK_OF_MONTH, 3); + cal.set(Calendar.DATE, 25); + cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY); + assertTrue("Incorrect result 4: " + cal.getTime(), cal.getTime() + .getTime() == 1010984400000L); + + // WEEK_OF_YEAR has priority when MONTH set last and DAY_OF_WEEK set + cal.clear(); + cal.set(Calendar.YEAR, 2002); + cal.set(Calendar.WEEK_OF_YEAR, 11); + cal.set(Calendar.DATE, 25); + cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY); + cal.set(Calendar.MONTH, Calendar.JANUARY); + assertTrue("Incorrect result 5: " + cal.getTime(), cal.getTime() + .getTime() == 1015822800000L); + + // Use MONTH/DATE when WEEK_OF_YEAR set but not DAY_OF_WEEK + cal.clear(); + cal.set(Calendar.YEAR, 2002); + cal.set(Calendar.WEEK_OF_YEAR, 12); + cal.set(Calendar.DATE, 11); + cal.set(Calendar.MONTH, Calendar.MARCH); + assertTrue("Incorrect result 5a: " + cal.getTime(), cal.getTime() + .getTime() == 1015822800000L); + + // Use MONTH/DATE when DAY_OF_WEEK is not set + cal.clear(); + cal.set(Calendar.YEAR, 2002); + cal.set(Calendar.WEEK_OF_YEAR, 12); + cal.set(Calendar.DATE, 11); + cal.set(Calendar.WEEK_OF_MONTH, 1); + cal.set(Calendar.MONTH, Calendar.MARCH); + assertTrue("Incorrect result 5b: " + cal.getTime(), cal.getTime() + .getTime() == 1015822800000L); + + // WEEK_OF_MONTH has priority + cal.clear(); + cal.set(Calendar.YEAR, 2002); + cal.set(Calendar.WEEK_OF_YEAR, 12); + cal.set(Calendar.DATE, 5); + cal.set(Calendar.WEEK_OF_MONTH, 3); + cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY); + cal.set(Calendar.MONTH, Calendar.MARCH); + assertTrue("Incorrect result 5c: " + cal.getTime(), cal.getTime() + .getTime() == 1015822800000L); + + // DATE has priority when set last + cal.clear(); + cal.set(Calendar.YEAR, 2002); + cal.set(Calendar.WEEK_OF_YEAR, 12); + cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY); + cal.set(Calendar.MONTH, Calendar.MARCH); + cal.set(Calendar.DATE, 11); + assertTrue("Incorrect result 6: " + cal.getTime(), cal.getTime() + .getTime() == 1015822800000L); + + // DATE has priority when set last, MONTH not set + cal.clear(); + cal.set(Calendar.YEAR, 2002); + cal.set(Calendar.WEEK_OF_YEAR, 12); + cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY); + cal.set(Calendar.DATE, 14); + assertTrue("Incorrect result 7: " + cal.getTime(), cal.getTime() + .getTime() == 1010984400000L); + + // DAY_OF_YEAR has priority when MONTH set last and DATE not set + cal.clear(); + cal.set(Calendar.YEAR, 2002); + cal.set(Calendar.DAY_OF_YEAR, 70); + cal.set(Calendar.MONTH, Calendar.JANUARY); + assertTrue("Incorrect result 8: " + cal.getTime(), cal.getTime() + .getTime() == 1015822800000L); + + // DAY/MONTH has priority when DATE set after DAY_OF_YEAR + cal.clear(); + cal.set(Calendar.YEAR, 2002); + cal.set(Calendar.DAY_OF_YEAR, 170); + cal.set(Calendar.DATE, 11); + cal.set(Calendar.MONTH, Calendar.MARCH); + assertTrue("Incorrect result 8a: " + cal.getTime(), cal.getTime() + .getTime() == 1015822800000L); + + // DAY_OF_YEAR has priority when set after DATE + cal.clear(); + cal.set(Calendar.YEAR, 2002); + cal.set(Calendar.DATE, 15); + cal.set(Calendar.DAY_OF_YEAR, 70); + cal.set(Calendar.MONTH, Calendar.JANUARY); + assertTrue("Incorrect result 8b: " + cal.getTime(), cal.getTime() + .getTime() == 1015822800000L); + + // DATE has priority when set last + cal.clear(); + cal.set(Calendar.YEAR, 2002); + cal.set(Calendar.DAY_OF_YEAR, 70); + cal.set(Calendar.DATE, 14); + assertTrue("Incorrect result 9: " + cal.getTime(), cal.getTime() + .getTime() == 1010984400000L); + + // DATE has priority when set last + cal.clear(); + cal.set(Calendar.YEAR, 2002); + cal.set(Calendar.WEEK_OF_YEAR, 15); + cal.set(Calendar.DAY_OF_WEEK, Calendar.THURSDAY); + cal.set(Calendar.DATE, 14); + assertTrue("Incorrect result 9a: " + cal.getTime(), cal.getTime() + .getTime() == 1010984400000L); + + cal.clear(); + cal.set(Calendar.YEAR, 2002); + cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY); + cal.set(Calendar.DATE, 14); + cal.set(Calendar.WEEK_OF_YEAR, 11); + assertTrue("Incorrect result 9b: " + cal.getTime(), cal.getTime() + .getTime() == 1015822800000L); + + cal.clear(); + cal.set(Calendar.YEAR, 2002); + cal.set(Calendar.DATE, 14); + cal.set(Calendar.WEEK_OF_YEAR, 11); + assertTrue("Incorrect result 9c: " + cal.getTime(), cal.getTime() + .getTime() == 1010984400000L); + + cal.clear(); + cal.set(Calendar.YEAR, 2002); + cal.set(Calendar.WEEK_OF_MONTH, 1); + cal.set(Calendar.DAY_OF_WEEK, Calendar.THURSDAY); + cal.set(Calendar.MONTH, Calendar.MARCH); + cal.set(Calendar.DATE, 11); + assertTrue("Incorrect result 9d: " + cal.getTime(), cal.getTime() + .getTime() == 1015822800000L); + + // DAY_OF_YEAR has priority when DAY_OF_MONTH set last and other fields + // not set + cal.clear(); + cal.set(Calendar.YEAR, 2002); + cal.set(Calendar.DAY_OF_YEAR, 70); + cal.set(Calendar.DAY_OF_WEEK, Calendar.TUESDAY); + assertTrue("Incorrect result 10: " + cal.getTime(), cal.getTime() + .getTime() == 1015822800000L); + + // MONTH/DATE has priority when DAY_OF_WEEK_IN_MONTH set last but + // DAY_OF_WEEK not set + cal.clear(); + cal.set(Calendar.YEAR, 2002); + cal.set(Calendar.DATE, 11); + cal.set(Calendar.MONTH, Calendar.MARCH); + cal.set(Calendar.DAY_OF_WEEK_IN_MONTH, 1); + assertTrue("Incorrect result 11: " + cal.getTime(), cal.getTime() + .getTime() == 1015822800000L); + + // MONTH/DATE has priority when WEEK_OF_YEAR set last but DAY_OF_WEEK + // not set + cal.clear(); + cal.set(Calendar.YEAR, 2002); + cal.set(Calendar.DATE, 11); + cal.set(Calendar.MONTH, Calendar.MARCH); + cal.set(Calendar.WEEK_OF_YEAR, 15); + assertTrue("Incorrect result 12: " + cal.getTime(), cal.getTime() + .getTime() == 1015822800000L); + + // MONTH/DATE has priority when WEEK_OF_MONTH set last but DAY_OF_WEEK + // not set + cal.clear(); + cal.set(Calendar.YEAR, 2002); + cal.set(Calendar.DATE, 11); + cal.set(Calendar.MONTH, Calendar.MARCH); + cal.set(Calendar.WEEK_OF_MONTH, 1); + assertTrue("Incorrect result 13: " + cal.getTime(), cal.getTime() + .getTime() == 1015822800000L); + + // Ensure last date field set is reset after computing + cal.clear(); + cal.set(Calendar.YEAR, 2002); + cal.set(Calendar.DAY_OF_YEAR, 111); + cal.get(Calendar.YEAR); + cal.set(Calendar.MONTH, Calendar.MARCH); + cal.set(Calendar.AM_PM, Calendar.AM); + assertTrue("Incorrect result 14: " + cal.getTime(), cal.getTime() + .getTime() == 1016686800000L); + + int hour = cal.get(Calendar.HOUR); + cal.set(Calendar.HOUR, hour); + cal.set(Calendar.AM_PM, Calendar.PM); + assertEquals("AM_PM not changed", Calendar.PM, cal.get(Calendar.AM_PM)); + // setting AM_PM without HOUR should not have any affect + cal.set(Calendar.AM_PM, Calendar.AM); + assertEquals("AM_PM was changed 1", + Calendar.AM, cal.get(Calendar.AM_PM)); + int hourOfDay = cal.get(Calendar.HOUR_OF_DAY); + hour = cal.get(Calendar.HOUR); + cal.set(Calendar.AM_PM, Calendar.PM); + assertEquals("AM_PM was changed 2", + Calendar.PM, cal.get(Calendar.AM_PM)); + assertEquals(hour, cal.get(Calendar.HOUR)); + assertEquals(hourOfDay + 12, cal.get(Calendar.HOUR_OF_DAY)); + + // regression test for Harmony-2122 + cal = Calendar.getInstance(); + int oldValue = cal.get(Calendar.AM_PM); + int newValue = (oldValue == Calendar.AM) ? Calendar.PM : Calendar.AM; + cal.set(Calendar.AM_PM, newValue); + newValue = cal.get(Calendar.AM_PM); + assertTrue(newValue != oldValue); + } + + /** + * @tests java.util.Calendar#setTime(java.util.Date) + */ + @Test + public void test_setTimeLjava_util_Date() { + Calendar cal = Calendar.getInstance(); + // Use millisecond time for testing in Core + cal.setTime(new Date(884581200000L)); // (98, Calendar.JANUARY, 12) + assertEquals("incorrect millis", 884581200000L, cal.getTime().getTime()); + cal.setTimeZone(TimeZone.getTimeZone("EST")); + cal.setTime(new Date(943506000000L)); // (99, Calendar.NOVEMBER, 25) + assertTrue("incorrect fields", cal.get(Calendar.YEAR) == 1999 + && cal.get(Calendar.MONTH) == Calendar.NOVEMBER + && cal.get(Calendar.DATE) == 25); + } + + /** + * @tests java.util.Calendar#compareTo(Calendar) + */ + @Test + public void test_compareToLjava_util_Calendar_null() { + Calendar cal = Calendar.getInstance(); + try { + cal.compareTo(null); + fail("should throw NullPointerException"); + } catch (NullPointerException e) { + // expected + } + } + + /** + * @tests java.util.Calendar#compareTo(Calendar) + */ + @Test + public void test_compareToLjava_util_Calendar() { + Calendar cal = Calendar.getInstance(); + cal.clear(); + cal.set(1997, 12, 13, 23, 57); + + Calendar anotherCal = Calendar.getInstance(); + anotherCal.clear(); + anotherCal.set(1997, 12, 13, 23, 57); + assertEquals(0, cal.compareTo(anotherCal)); + + anotherCal = Calendar.getInstance(); + anotherCal.clear(); + anotherCal.set(1997, 11, 13, 24, 57); + assertEquals(1, cal.compareTo(anotherCal)); + + anotherCal = Calendar.getInstance(); + anotherCal.clear(); + anotherCal.set(1997, 12, 13, 23, 58); + assertEquals(-1, cal.compareTo(anotherCal)); + } + + /** + * @tests java.util.Calendar#clone() + */ + @Test + public void test_clone() { + // Regression for HARMONY-475 + Calendar cal = Calendar.getInstance(); + cal.set(2006, 5, 6, 11, 35); + Calendar anotherCal = (Calendar) cal.clone(); + // should be deep clone + assertNotSame("getTimeZone", cal.getTimeZone(), anotherCal + .getTimeZone()); + } + + /** + * @tests java.util.Calendar#getTimeInMillis() + */ + @Test + public void test_getTimeInMillis() { + Calendar cal = Calendar.getInstance(); + + int year = Integer.MIN_VALUE + 71; + cal.setTimeZone(TimeZone.getTimeZone("GMT")); + cal.set(Calendar.YEAR, year + 1900); + cal.set(Calendar.MONTH, Calendar.JANUARY); + cal.set(Calendar.DATE, 1); + cal.set(Calendar.HOUR_OF_DAY, 0); + cal.set(Calendar.MINUTE, 0); + cal.set(Calendar.SECOND, 0); + cal.set(Calendar.MILLISECOND, 0); + + assertEquals(6017546357372606464L, cal.getTimeInMillis()); + } + + private static final Locale[] locales = new Locale[]{Locale.getDefault(), + Locale.US, Locale.UK, Locale.TAIWAN, Locale.PRC, Locale.KOREA, + Locale.JAPAN, Locale.ITALIAN, Locale.GERMAN, Locale.ENGLISH, + Locale.CHINA, Locale.CANADA, Locale.FRANCE}; + + /** + * @tests java.util.Calendar#before(Object) + * @tests java.util.Calendar#after(Object) + */ + @Test + public void test_before_after() { + Calendar early = Calendar.getInstance(); + Calendar late = Calendar.getInstance(); + // test by second + early.set(2008, 3, 20, 17, 28, 12); + late.set(2008, 3, 20, 17, 28, 22); + // test before() + assertTrue(early.before(late)); + assertFalse(early.before(early)); + assertFalse(late.before(early)); + // test after(); + assertTrue(late.after(early)); + assertFalse(late.after(late)); + assertFalse(early.after(late)); + + // test by minute + early.set(2008, 3, 20, 17, 18, 12); + late.set(2008, 3, 20, 17, 28, 12); + // test before() + assertTrue(early.before(late)); + assertFalse(early.before(early)); + assertFalse(late.before(early)); + // test after(); + assertTrue(late.after(early)); + assertFalse(late.after(late)); + assertFalse(early.after(late)); + + // test by hour + early.set(2008, 3, 20, 17, 28, 12); + late.set(2008, 3, 20, 27, 28, 12); + // test before() + assertTrue(early.before(late)); + assertFalse(early.before(early)); + assertFalse(late.before(early)); + // test after(); + assertTrue(late.after(early)); + assertFalse(late.after(late)); + assertFalse(early.after(late)); + + // test by day + early.set(2008, 3, 10, 17, 28, 12); + late.set(2008, 3, 20, 17, 28, 12); + // test before() + assertTrue(early.before(late)); + assertFalse(early.before(early)); + assertFalse(late.before(early)); + // test after(); + assertTrue(late.after(early)); + assertFalse(late.after(late)); + assertFalse(early.after(late)); + + // test by month + early.set(2008, 2, 20, 17, 28, 12); + late.set(2008, 3, 20, 17, 28, 12); + // test before() + assertTrue(early.before(late)); + assertFalse(early.before(early)); + assertFalse(late.before(early)); + // test after(); + assertTrue(late.after(early)); + assertFalse(late.after(late)); + assertFalse(early.after(late)); + + // test by year + early.set(2007, 3, 20, 17, 28, 12); + late.set(2008, 3, 20, 17, 28, 12); + // test before() + assertTrue(early.before(late)); + assertFalse(early.before(early)); + assertFalse(late.before(early)); + // test after(); + assertTrue(late.after(early)); + assertFalse(late.after(late)); + assertFalse(early.after(late)); + } + + /** + * @tests java.util.Calendar#clear() + * @tests java.util.Calendar#clear(int) + */ + @Test + public void test_clear() { + Calendar calendar = Calendar.getInstance(); + + int count = 6; + int[] fields = new int[count]; + int[] defaults = new int[count]; + + fields[0] = Calendar.YEAR; + fields[1] = Calendar.MONTH; + fields[2] = Calendar.DATE; + fields[3] = Calendar.HOUR_OF_DAY; + fields[4] = Calendar.MINUTE; + fields[5] = Calendar.SECOND; + + defaults[0] = 1970; + defaults[1] = 0; + defaults[2] = 1; + defaults[3] = 0; + defaults[4] = 0; + defaults[5] = 0; + + calendar.set(2008, 3, 20, 17, 28, 12); + + // test clear(int) + for (int i = 0; i < fields.length; i++) { + int index = fields[i]; + calendar.clear(index); + if (5 == index) { + // RI also doesn't change the value of DATE + assertEquals("Field " + index + " Should equal to 20.", 20, + calendar.get(index)); + } else if (11 == index) { + // RI also doesn't change the value of HOUR + assertEquals("Field " + index + " Should equal to 17.", 17, + calendar.get(index)); + } else { + // Other have been set to default values + assertEquals("Field " + index + " Should equal to " + + defaults[i] + ".", defaults[i], calendar.get(index)); + } + } + + // test clear() + calendar.set(2008, 3, 20, 17, 28, 12); + + calendar.clear(); + + for (int i = 0; i < fields.length; i++) { + int index = fields[i]; + assertEquals("Field " + index + " Should equal to " + + defaults[i] + ".", defaults[i], calendar.get(index)); + } + } + + /** + * @tests java.util.Calendar#isSet(int) + */ + @Test + public void test_isSet() { + Calendar calendar = Calendar.getInstance(); + calendar.clear(); + for (int i = 0; i < Calendar.FIELD_COUNT; i++) { + assertFalse(calendar.isSet(i)); + } + } + + /** + * @tests java.util.Calendar#getAvailableLocales() + */ + @Test + public void test_getAvailableLocales() { + Locale[] locales = Calendar.getAvailableLocales(); + boolean exist = false; + for (int i = 0; i < locales.length; i++) { + Locale l = locales[i]; + if (Locale.US.equals(l)) { + exist = true; + break; + } + } + assertTrue(exist); + } + + /** + * @tests java.util.Calendar#getInstance(Locale) + * @tests java.util.Calendar#getInstance(TimeZone, Locale) + */ + @Test + public void test_getInstance() { + // test getInstance(Locale) + Calendar us_calendar = Calendar.getInstance(Locale.US); + //Calendar ch_calendar = Calendar.getInstance(Locale.CHINESE); + assertEquals(Calendar.SUNDAY, us_calendar + .getFirstDayOfWeek()); + //assertEquals(Calendar.MONDAY, ch_calendar + // .getFirstDayOfWeek()); + + // test getInstance(Locale, TimeZone) + Calendar gmt_calendar = Calendar.getInstance(TimeZone + .getTimeZone("GMT"), Locale.US); + assertEquals(TimeZone.getTimeZone("GMT"), + gmt_calendar.getTimeZone()); + Calendar est_calendar = Calendar.getInstance(TimeZone + .getTimeZone("EST"), Locale.US); + assertEquals(TimeZone.getTimeZone("EST") + .getID(), est_calendar.getTimeZone().getID()); + } + + /** + * @tests java.util.Calendar#internalGet(int) + */ + @Test + public void test_internalGet() { + MockGregorianCalendar c = new MockGregorianCalendar(); + c.clear(Calendar.YEAR); + assertEquals(0, c.internal_get(Calendar.YEAR)); + } + + /** + * @tests java.util.Calendar#hashCode() + */ + @Test + public void test_hashcode() { + Calendar calendar = Calendar.getInstance(Locale.JAPAN); + assertTrue(calendar.hashCode() == calendar.hashCode()); + } + + /** + * @tests java.util.Calendar#roll(int, int) + */ + @Test + public void test_roll() { + Calendar calendar = Calendar.getInstance(); + calendar.set(2008, 3, 20, 17, 28, 12); + + // roll up + calendar.roll(Calendar.DATE, 5); + assertEquals(25, calendar.get(Calendar.DATE)); + + // roll down + calendar.roll(Calendar.DATE, -5); + assertEquals(20, calendar.get(Calendar.DATE)); + + // roll 0 + calendar.roll(Calendar.DATE, 0); + assertEquals(20, calendar.get(Calendar.DATE)); + + // roll overweight + calendar.set(2008, 1, 31, 17, 28, 12); + calendar.roll(Calendar.MONTH, 1); + assertEquals(2, calendar.get(Calendar.DATE)); + + } + + /** + * @tests java.util.Calendar#toString() + */ + @Test + public void test_toString() { + Calendar calendar = Calendar.getInstance(); + //Should be the current time with no interrogation in the string. + assertTrue(calendar.toString() instanceof String); + assertEquals(-1, calendar.toString().indexOf("?")); + calendar.clear(); + assertTrue(calendar.toString() instanceof String); + assertTrue(0 <= calendar.toString().indexOf("?")); + } + + /** + * @tests serialization/deserialization. + */ + //public void testSerializationSelf() throws Exception { + // Calendar calendar = Calendar.getInstance(); + // calendar.set(2008, 3, 20, 17, 28, 12); + // + // SerializationTest.verifySelf(calendar); + //} + + private class MockGregorianCalendar extends GregorianCalendar { + + public int internal_get(int field) { + return super.internalGet(field); + } + } + + private class MockCalendar extends Calendar { + + public MockCalendar() { + super(); + } + + @Override + public void add(int field, int value) { + } + + @Override + protected void computeFields() { + } + + @Override + protected void computeTime() { + } + + @Override + public int getGreatestMinimum(int field) { + return 0; + } + + @Override + public int getLeastMaximum(int field) { + return 0; + } + + @Override + public int getMaximum(int field) { + return 0; + } + + @Override + public int getMinimum(int field) { + return 0; + } + + @Override + public void roll(int field, boolean increment) { + } + } + + /** + * @tests {@link java.util.Calendar#getDisplayName(int, int, Locale)} + * @since 1.6 + */ +// public void test_getDisplayNameIILjava_util_Locale() { +// Calendar cal = Calendar.getInstance(); +// for (int field = 0; field < Calendar.FIELD_COUNT; field++) { +// for (Locale locale : locales) { +// DateFormatSymbols symbols = new DateFormatSymbols(locale); +// String value = null; +// switch (field) { +// case Calendar.AM_PM: +// cal.set(Calendar.AM_PM, Calendar.AM); +// value = symbols.getAmPmStrings()[0]; +// assertEquals(cal.getDisplayName(field, Calendar.SHORT, +// locale), value); +// assertEquals(cal.getDisplayName(field, Calendar.LONG, +// locale), value); +// cal.set(Calendar.AM_PM, Calendar.PM); +// value = symbols.getAmPmStrings()[1]; +// assertEquals(cal.getDisplayName(field, Calendar.SHORT, +// locale), value); +// assertEquals(cal.getDisplayName(field, Calendar.LONG, +// locale), value); +// break; +// case Calendar.ERA: +// cal.set(Calendar.ERA, GregorianCalendar.BC); +// value = symbols.getEras()[0]; +// assertEquals(cal.getDisplayName(field, Calendar.SHORT, +// locale), value); +// assertEquals(cal.getDisplayName(field, Calendar.LONG, +// locale), value); +// cal.set(Calendar.ERA, GregorianCalendar.AD); +// value = symbols.getEras()[1]; +// assertEquals(cal.getDisplayName(field, Calendar.SHORT, +// locale), value); +// assertEquals(cal.getDisplayName(field, Calendar.LONG, +// locale), value); +// break; +// case Calendar.MONTH: +// cal.set(Calendar.DAY_OF_MONTH, 1); +// for (int month = 0; month <= 11; month++) { +// cal.set(Calendar.MONTH, month); +// value = symbols.getShortMonths()[month]; +// assertEquals(cal.getDisplayName(field, Calendar.SHORT, +// locale), value); +// value = symbols.getMonths()[month]; +// assertEquals(cal.getDisplayName(field, Calendar.LONG, +// locale), value); +// } +// break; +// case Calendar.DAY_OF_WEEK: +// for (int day = 1; day <= 7; day++) { +// cal.set(Calendar.DAY_OF_WEEK, day); +// value = symbols.getShortWeekdays()[day]; +// assertEquals(cal.getDisplayName(field, Calendar.SHORT, +// locale), value); +// value = symbols.getWeekdays()[day]; +// assertEquals(cal.getDisplayName(field, Calendar.LONG, +// locale), value); +// } +// break; +// default: +// assertNull(cal +// .getDisplayName(field, Calendar.SHORT, locale)); +// assertNull(cal.getDisplayName(field, Calendar.LONG, locale)); +// } +// } +// } +// +// cal.setLenient(true); +// +// try { +// cal.getDisplayName(-1, Calendar.SHORT, Locale.US); +// fail("Should throw IllegalArgumentException"); +// } catch (IllegalArgumentException e) { +// // expected +// } +// try { +// cal.getDisplayName(Calendar.FIELD_COUNT, Calendar.LONG, Locale.US); +// fail("Should throw IllegalArgumentException"); +// } catch (IllegalArgumentException e) { +// // expected +// } +// try { +// cal.getDisplayName(Calendar.MONTH, -1, Locale.US); +// fail("Should throw IllegalArgumentException"); +// } catch (IllegalArgumentException e) { +// // expected +// } +// try { +// cal.getDisplayName(Calendar.MONTH, 3, Locale.US); +// fail("Should throw IllegalArgumentException"); +// } catch (IllegalArgumentException e) { +// // expected +// } +// try { +// cal.getDisplayName(Calendar.MONTH, Calendar.SHORT, null); +// fail("Should throw NullPointerException"); +// } catch (NullPointerException e) { +// // expected +// } +// try { +// cal.getDisplayName(-1, Calendar.SHORT, null); +// fail("Should throw IllegalArgumentException"); +// } catch (IllegalArgumentException e) { +// // expected +// } +// try { +// cal.getDisplayName(Calendar.MONTH, -1, null); +// fail("Should throw IllegalArgumentException"); +// } catch (IllegalArgumentException e) { +// // expected +// } +// // in lenient mode, following cases pass +// cal.set(Calendar.SECOND, 999); +// cal.getDisplayName(Calendar.MONTH, Calendar.SHORT, Locale.US); +// // test for ALL_STYLES, it is equal to use SHORT +// for (int field = 0; field < Calendar.FIELD_COUNT; field++) { +// for (Locale locale : locales) { +// String result = cal.getDisplayName(field, Calendar.ALL_STYLES, +// locale); +// if (field == Calendar.AM_PM || field == Calendar.ERA +// || field == Calendar.MONTH +// || field == Calendar.DAY_OF_WEEK) { +// assertEquals(result, cal.getDisplayName(field, +// Calendar.SHORT, locale)); +// } else { +// assertNull(result); +// } +// } +// } +// +// // invalid value for an un-related field when the calendar is not +// // lenient +// cal.setLenient(false); +// assertNotNull(cal.getDisplayName(Calendar.MONTH, Calendar.SHORT, +// Locale.US)); +// cal.set(Calendar.SECOND, 999); +// try { +// cal.getDisplayName(Calendar.MONTH, Calendar.SHORT, Locale.US); +// fail("Should throw IllegalArgumentException"); +// } catch (IllegalArgumentException e) { +// // expected +// } +// try { +// cal.getDisplayName(Calendar.MONTH, Calendar.ALL_STYLES, Locale.US); +// fail("Should throw IllegalArgumentException"); +// } catch (IllegalArgumentException e) { +// // expected +// } +// } + + /** + * @tests {@link java.util.Calendar#getDisplayNames(int, int, Locale)} + * @since 1.6 + */ +// public void test_getDisplayNamesIILjava_util_Locale() { +// assertEquals(0, Calendar.ALL_STYLES); +// assertEquals(1, Calendar.SHORT); +// assertEquals(2, Calendar.LONG); +// +// Calendar cal = Calendar.getInstance(Locale.US); +// +// for (int field = 0; field < Calendar.FIELD_COUNT; field++) { +// for (Locale locale : locales) { +// Map shortResult = cal.getDisplayNames(field, +// Calendar.SHORT, locale); +// Map longResult = cal.getDisplayNames(field, +// Calendar.LONG, locale); +// Map allResult = cal.getDisplayNames(field, +// Calendar.ALL_STYLES, locale); +// DateFormatSymbols symbols = new DateFormatSymbols(locale); +// String[] values = null; +// switch (field) { +// case Calendar.AM_PM: +// case Calendar.ERA: +// values = (field == Calendar.AM_PM) ? symbols +// .getAmPmStrings() : symbols.getEras(); +// assertDisplayNameMap(values, shortResult, 0); +// assertDisplayNameMap(values, longResult, 0); +// assertDisplayNameMap(values, allResult, 0); +// break; +// case Calendar.MONTH: +// values = symbols.getShortMonths(); +// assertDisplayNameMap(values, shortResult, 0); +// values = symbols.getMonths(); +// assertDisplayNameMap(values, longResult, 0); +// assertTrue(allResult.size() >= shortResult.size()); +// assertTrue(allResult.size() >= longResult.size()); +// assertTrue(allResult.size() <= shortResult.size() +// + longResult.size()); +// break; +// case Calendar.DAY_OF_WEEK: +// values = symbols.getShortWeekdays(); +// assertDisplayNameMap(values, shortResult, 1); +// values = symbols.getWeekdays(); +// assertDisplayNameMap(values, longResult, 1); +// assertTrue(allResult.size() >= shortResult.size()); +// assertTrue(allResult.size() >= longResult.size()); +// assertTrue(allResult.size() <= shortResult.size() +// + longResult.size()); +// break; +// default: +// assertNull(shortResult); +// assertNull(longResult); +// assertNull(allResult); +// } +// } +// } +// +// cal.setLenient(true); +// +// try { +// cal.getDisplayNames(-1, Calendar.SHORT, Locale.US); +// fail("Should throw IllegalArgumentException"); +// } catch (IllegalArgumentException e) { +// // expected +// } +// try { +// cal.getDisplayNames(Calendar.FIELD_COUNT, Calendar.LONG, Locale.US); +// fail("Should throw IllegalArgumentException"); +// } catch (IllegalArgumentException e) { +// // expected +// } +// try { +// cal.getDisplayNames(Calendar.MONTH, -1, Locale.US); +// fail("Should throw IllegalArgumentException"); +// } catch (IllegalArgumentException e) { +// // expected +// } +// try { +// cal.getDisplayNames(Calendar.MONTH, 3, Locale.US); +// fail("Should throw IllegalArgumentException"); +// } catch (IllegalArgumentException e) { +// // expected +// } +// try { +// cal.getDisplayNames(Calendar.MONTH, Calendar.SHORT, null); +// fail("Should throw NullPointerException"); +// } catch (NullPointerException e) { +// // expected +// } +// try { +// cal.getDisplayNames(-1, Calendar.SHORT, null); +// fail("Should throw IllegalArgumentException"); +// } catch (IllegalArgumentException e) { +// // expected +// } +// try { +// cal.getDisplayNames(Calendar.MONTH, -1, null); +// fail("Should throw IllegalArgumentException"); +// } catch (IllegalArgumentException e) { +// // expected +// } +// cal.set(Calendar.SECOND, 999); +// cal.getDisplayNames(Calendar.MONTH, Calendar.SHORT, Locale.US); +// +// // RI fails here +// // invalid value for an un-related field when the calendar is not +// // lenient +// cal.setLenient(false); +// cal.set(Calendar.SECOND, 999); +// try { +// cal.getDisplayNames(Calendar.MONTH, Calendar.SHORT, Locale.US); +// fail("Should throw IllegalArgumentException"); +// } catch (IllegalArgumentException e) { +// // expected +// } +// } +// +// private void assertDisplayNameMap(String[] values, +// Map result, int shift) { +// List trimValue = new ArrayList(); +// for (String value : values) { +// if (value.trim().length() > 0) { +// trimValue.add(value); +// } +// } +// assertEquals(trimValue.size(), result.size()); +// for (int i = 0; i < trimValue.size(); i++) { +// assertEquals(i + shift, result.get(trimValue.get(i)).intValue()); +// } +// } + + /** + * @tests {@link java.util.Calendar#getActualMaximum(int)} + */ + @Test + public void test_getActualMaximum_I() { + Calendar c = new MockCalendar(); + assertEquals("should be equal to 0", 0, c.getActualMaximum(0)); + } + + /** + * @tests {@link java.util.Calendar#getActualMinimum(int)} + */ + @Test + public void test_getActualMinimum_I() { + Calendar c = new MockCalendar(); + assertEquals("should be equal to 0", 0, c.getActualMinimum(0)); + } + + protected void setUp() { + defaultLocale = Locale.getDefault(); + Locale.setDefault(Locale.US); + } + + protected void tearDown() { + Locale.setDefault(defaultLocale); + } +} diff --git a/teavm-tests/src/test/java/org/teavm/classlib/java/util/TimeZoneTest.java b/teavm-tests/src/test/java/org/teavm/classlib/java/util/TimeZoneTest.java index 0bbf4e899..67af35c9b 100644 --- a/teavm-tests/src/test/java/org/teavm/classlib/java/util/TimeZoneTest.java +++ b/teavm-tests/src/test/java/org/teavm/classlib/java/util/TimeZoneTest.java @@ -15,10 +15,393 @@ */ package org.teavm.classlib.java.util; +import java.util.Arrays; +import java.util.Calendar; +import java.util.Date; +import java.util.GregorianCalendar; +import java.util.List; +import static org.junit.Assert.*; +import java.util.Locale; +import java.util.SimpleTimeZone; +import java.util.TimeZone; +import org.junit.Test; +import org.teavm.platform.PlatformTimezone; + /** * * @author shannah */ public class TimeZoneTest { + + private static final int ONE_HOUR = 3600000; + static class EST extends PlatformTimezone { + + @Override + public String getTimezoneId() { + return "EST"; + } + + @Override + public int getTimezoneOffset(int year, int month, int day, int timeOfDayMillis) { + return -5*ONE_HOUR; + } + + @Override + public int getTimezoneRawOffset() { + return -5*ONE_HOUR; + } + + @Override + public boolean isTimezoneDST(long millis) { + return false; + } + + } + + private static class PlatformSupportTimezone extends PlatformTimezone { + private String id; + private long offset; + private boolean dst; + + PlatformSupportTimezone(String id, long offset, boolean dst){ + this.id=id; + this.offset=offset; + this.dst=dst; + } + + @Override + public String getTimezoneId() { + return id; + } + + @Override + public int getTimezoneOffset(int year, int month, int day, int timeOfDayMillis) { + return (int)(offset + (dst?ONE_HOUR:0)); + } + + @Override + public int getTimezoneRawOffset() { + return (int)offset; + } + + @Override + public boolean isTimezoneDST(long millis) { + return dst; + } + + } + + private static class Support_TimeZone extends TimeZone { + + int rawOffset; + + boolean useDaylightTime; + + public Support_TimeZone(int rawOffset, boolean useDaylightTime) { + this.rawOffset = rawOffset; + this.useDaylightTime = useDaylightTime; + } + + @Override + public int getRawOffset() { + return rawOffset; + } + + /** + * let's assume this timezone has daylight savings from the 4th month till + * the 10th month of the year to ame things simple. + */ + @Override + public boolean inDaylightTime(java.util.Date p1) { + if (!useDaylightTime) { + return false; + } + GregorianCalendar cal = new GregorianCalendar(); + cal.setTime(p1); + int month = cal.get(Calendar.MONTH); + + if (month > 4 && month < 10) { + return true; + } + return false; + } + + @Override + public boolean useDaylightTime() { + return useDaylightTime; + } + + /* + * return 0 to keep it simple, since this subclass is not used to test this + * method.. + */ + @Override + public int getOffset(int p1, int p2, int p3, int p4, int p5, int p6) { + return 0; + } + + @Override + public void setRawOffset(int p1) { + rawOffset = p1; + } + + } + + static { + if (PlatformTimezone.getTimezone("EST")==null){ + PlatformTimezone.addTimezone("EST", new EST()); + } + } + + /** + * @tests java.util.TimeZone#getDefault() + */ + @Test + public void test_getDefault() { + assertNotSame("returns identical", + TimeZone.getDefault(), TimeZone.getDefault()); + } + + /** + * @tests java.util.TimeZone#getDSTSavings() + */ + @Test + public void test_getDSTSavings() { + // Test for method int java.util.TimeZone.getDSTSavings() + + // test on subclass SimpleTimeZone + TimeZone st1 = TimeZone.getTimeZone("EST"); + assertEquals("T1A. Incorrect daylight savings returned", + 0, st1.getDSTSavings()); + + // a SimpleTimeZone with daylight savings different then 1 hour + st1 = TimeZone.getTimeZone("Australia/Lord_Howe"); + assertEquals("T1B. Incorrect daylight savings returned", + 1800000, st1.getDSTSavings()); + + // test on subclass Support_TimeZone, an instance with daylight savings + TimeZone tz1 = new Support_TimeZone(-5 * ONE_HOUR, true); + assertEquals("T2. Incorrect daylight savings returned", + ONE_HOUR, tz1.getDSTSavings()); + + // an instance without daylight savings + tz1 = new Support_TimeZone(3 * ONE_HOUR, false); + assertEquals("T3. Incorrect daylight savings returned, ", + 0, tz1.getDSTSavings()); + } + + /** + * @tests java.util.TimeZone#getOffset(long) + */ + @Test + public void test_getOffset_long() { + // Test for method int java.util.TimeZone.getOffset(long time) + + // test on subclass SimpleTimeZone + TimeZone st1 = TimeZone.getTimeZone("EST"); + long time1 = new GregorianCalendar(1998, Calendar.NOVEMBER, 11) + .getTimeInMillis(); + assertEquals("T1. Incorrect offset returned", + -(5 * ONE_HOUR), st1.getOffset(time1)); + + long time2 = new GregorianCalendar(1998, Calendar.JUNE, 11) + .getTimeInMillis(); + st1 = TimeZone.getTimeZone("EST"); + assertEquals("T2. Incorrect offset returned", + -(5 * ONE_HOUR), st1.getOffset(time2)); + + // test on subclass Support_TimeZone, an instance with daylight savings + TimeZone tz1 = new Support_TimeZone(-5 * ONE_HOUR, true); + assertEquals("T3. Incorrect offset returned, ", + -(5 * ONE_HOUR), tz1.getOffset(time1)); + assertEquals("T4. Incorrect offset returned, ", + -(4 * ONE_HOUR), tz1.getOffset(time2)); + + // an instance without daylight savings + tz1 = new Support_TimeZone(3 * ONE_HOUR, false); + assertEquals("T5. Incorrect offset returned, ", + (3 * ONE_HOUR), tz1.getOffset(time1)); + assertEquals("T6. Incorrect offset returned, ", + (3 * ONE_HOUR), tz1.getOffset(time2)); + } + + /** + * @tests java.util.TimeZone#getTimeZone(java.lang.String) + */ + @Test + public void test_getTimeZoneLjava_lang_String() { + assertEquals("Must return GMT when given an invalid TimeZone id SMT-8.", + "GMT", TimeZone.getTimeZone("SMT-8").getID()); + assertEquals("Must return GMT when given an invalid TimeZone time GMT+28:70.", + "GMT", TimeZone.getTimeZone("GMT+28:70").getID()); + assertEquals("Must return GMT when given an invalid TimeZone time GMT+28:30.", + "GMT", TimeZone.getTimeZone("GMT+28:30").getID()); + assertEquals("Must return GMT when given an invalid TimeZone time GMT+8:70.", + "GMT", TimeZone.getTimeZone("GMT+8:70").getID()); + assertEquals("Must return GMT when given an invalid TimeZone time GMT+3:.", + "GMT", TimeZone.getTimeZone("GMT+3:").getID()); + assertEquals("Must return GMT when given an invalid TimeZone time GMT+3:0.", + "GMT", TimeZone.getTimeZone("GMT+3:0").getID()); + assertEquals("Must return GMT when given an invalid TimeZone time GMT+2360.", + "GMT", TimeZone.getTimeZone("GMT+2360").getID()); + assertEquals("Must return GMT when given an invalid TimeZone time GMT+892.", + "GMT", TimeZone.getTimeZone("GMT+892").getID()); + assertEquals("Must return GMT when given an invalid TimeZone time GMT+082.", + "GMT", TimeZone.getTimeZone("GMT+082").getID()); + assertEquals("Must return GMT when given an invalid TimeZone time GMT+28.", + "GMT", TimeZone.getTimeZone("GMT+28").getID()); + assertEquals("Must return GMT when given an invalid TimeZone time GMT+30.", + "GMT", TimeZone.getTimeZone("GMT+30").getID()); + assertEquals("Must return GMT when given TimeZone GMT.", + "GMT", TimeZone.getTimeZone("GMT").getID()); + assertEquals("Must return GMT when given TimeZone GMT+.", + "GMT", TimeZone.getTimeZone("GMT+").getID()); + assertEquals("Must return GMT when given TimeZone GMT-.", + "GMT", TimeZone.getTimeZone("GMT-").getID()); + assertEquals("Must return GMT when given an invalid TimeZone time GMT-8.45.", + "GMT", TimeZone.getTimeZone("GMT-8.45").getID()); + assertEquals("Must return GMT when given an invalid TimeZone time GMT-123:23.", + "GMT", TimeZone.getTimeZone("GMT-123:23").getID()); + assertEquals("Must return proper GMT formatted string for GMT+8:30 (eg. GMT+08:20).", + "GMT+08:30", TimeZone.getTimeZone("GMT+8:30").getID()); + assertEquals("Must return proper GMT formatted string for GMT+3 (eg. GMT+08:20).", + "GMT+03:00", TimeZone.getTimeZone("GMT+3").getID()); + assertEquals("Must return proper GMT formatted string for GMT+3:02 (eg. GMT+08:20).", + "GMT+03:02", TimeZone.getTimeZone("GMT+3:02").getID()); + assertEquals("Must return proper GMT formatted string for GMT+2359 (eg. GMT+08:20).", + "GMT+23:59", TimeZone.getTimeZone("GMT+2359").getID()); + assertEquals("Must return proper GMT formatted string for GMT+520 (eg. GMT+08:20).", + "GMT+05:20", TimeZone.getTimeZone("GMT+520").getID()); + assertEquals("Must return proper GMT formatted string for GMT+052 (eg. GMT+08:20).", + "GMT+00:52", TimeZone.getTimeZone("GMT+052").getID()); + // GMT-0 is an available ID in ICU, so replace it with GMT-00 + assertEquals("Must return proper GMT formatted string for GMT-00 (eg. GMT+08:20).", + "GMT-00:00", TimeZone.getTimeZone("GMT-00").getID()); + } + + /** + * @tests java.util.TimeZone#setDefault(java.util.TimeZone) + */ + public void test_setDefaultLjava_util_TimeZone() { + TimeZone oldDefault = TimeZone.getDefault(); + TimeZone zone = new SimpleTimeZone(45, "TEST"); + TimeZone.setDefault(zone); + assertEquals("timezone not set", zone, TimeZone.getDefault()); + TimeZone.setDefault(null); + assertEquals("default not restored", + oldDefault, TimeZone.getDefault()); + } + + /** + * @tests java.util.TimeZone#getDisplayName(java.util.Locale) + */ + //@Test + //public void test_getDisplayNameLjava_util_Locale() { + // TimeZone timezone = TimeZone.getTimeZone("Asia/Shanghai"); + // assertEquals("\u4e2d\u56fd\u6807\u51c6\u65f6\u95f4", timezone + // .getDisplayName(Locale.CHINA)); + // } + + /** + * @tests java.util.TimeZone#getDisplayName(boolean, int, java.util.Locale) + */ + //@Test + //public void test_getDisplayNameZILjava_util_Locale() { + // TimeZone timezone = TimeZone.getTimeZone("Asia/Shanghai"); + // assertEquals("\u683c\u6797\u5c3c\u6cbb\u6807\u51c6\u65f6\u95f4+0800", + // timezone.getDisplayName(false, TimeZone.SHORT, Locale.CHINA)); + // try { + // timezone.getDisplayName(false, 100, Locale.CHINA); + // fail("should throw IllegalArgumentException"); + // } catch (IllegalArgumentException e) { + // // expected + // } + //} + + /* + * Regression for HARMONY-5860 + */ + @Test + public void test_GetTimezoneOffset() { + // America/Toronto is lazy initialized + TimeZone.setDefault(TimeZone.getTimeZone("America/Toronto")); + Date date = new Date(07, 2, 24); + assertEquals(300, date.getTimezoneOffset()); + date = new Date(99, 8, 1); + assertEquals(240, date.getTimezoneOffset()); + } + + protected void setUp() { + } + + protected void tearDown() { + } + + /** + * @add test {@link java.util.TimeZone#getAvailableIDs(int)} + */ + @Test + public void test_getAvailableIDs_I() { + TimeZone tz = TimeZone.getTimeZone("Asia/Shanghai"); + int rawoffset = tz.getRawOffset(); + String[] ids = TimeZone.getAvailableIDs(rawoffset); + List idList = Arrays.asList(ids); + assertTrue("Asia/shanghai and Hongkong should have the same rawoffset", + idList.contains("Hongkong")); + } + + /** + * @add test {@link java.util.TimeZone#getDisplayName()} + */ + //@Test + //public void test_getDisplayName() { + // TimeZone defaultZone = TimeZone.getDefault(); + // Locale defaulLocal = Locale.getDefault(); + // String defaultName = defaultZone.getDisplayName(); + // String expectedName = defaultZone.getDisplayName(defaulLocal); + // assertEquals( + // "getDispalyName() did not return the default Locale suitable name", + // expectedName, defaultName); + //} + + /** + * @add test {@link java.util.TimeZone#getDisplayName(boolean, int)} + */ + //@Test + //public void test_getDisplayName_ZI() { + // TimeZone defaultZone = TimeZone.getDefault(); + // Locale defaultLocale = Locale.getDefault(); + // String actualName = defaultZone.getDisplayName(false, TimeZone.LONG); + // String expectedName = defaultZone.getDisplayName(false, TimeZone.LONG, + // defaultLocale); + // assertEquals( + // "getDisplayName(daylight,style) did not return the default locale suitable name", + // expectedName, actualName); + //} + + /** + * @add test {@link java.util.TimeZone#hasSameRules(TimeZone)} + */ + //@Test + //public void test_hasSameRules_Ljava_util_TimeZone() { + // TimeZone tz = TimeZone.getTimeZone("Asia/Shanghai"); + // int offset = tz.getRawOffset(); + // + // String[] ids = TimeZone.getAvailableIDs(offset); + // int i = 0; + // if (ids.length != 0) { + // while (true) { + // if (!(ids[i].equalsIgnoreCase(tz.getID()))) { + // TimeZone sameZone = TimeZone.getTimeZone(ids[i]); + // assertTrue(tz.hasSameRules(sameZone)); + // break; + // } else { + // i++; + // } + // } + // } + // assertFalse("should return false when parameter is null", tz + // .hasSameRules(null)); + //} }