diff options
author | Jesse Wilson <jessewilson@google.com> | 2011-06-17 13:46:06 -0700 |
---|---|---|
committer | Jesse Wilson <jessewilson@google.com> | 2011-06-17 13:46:06 -0700 |
commit | 25e769d476ae139ed576f20fe27fd7e38ab034bb (patch) | |
tree | 1fd22692f88afef28c7f35837dab9ff5961c27c8 | |
parent | d2dd676be7b9fc0ac49c90a9d0acc437d0010a6e (diff) | |
download | libcore-25e769d476ae139ed576f20fe27fd7e38ab034bb.zip libcore-25e769d476ae139ed576f20fe27fd7e38ab034bb.tar.gz libcore-25e769d476ae139ed576f20fe27fd7e38ab034bb.tar.bz2 |
Add tests for Calendar/SimpleDateFormat bugs
Change-Id: Ib9142a6926c9eb30b021977db9eec7b4f47dae38
http://b/4723412
-rw-r--r-- | expectations/knownfailures.txt | 5 | ||||
-rw-r--r-- | luni/src/main/java/java/text/SimpleDateFormat.java | 7 | ||||
-rw-r--r-- | luni/src/test/java/libcore/java/text/SimpleDateFormatTest.java | 44 | ||||
-rw-r--r-- | luni/src/test/java/libcore/java/util/CalendarTest.java | 29 |
4 files changed, 77 insertions, 8 deletions
diff --git a/expectations/knownfailures.txt b/expectations/knownfailures.txt index f784394..e169ffe 100644 --- a/expectations/knownfailures.txt +++ b/expectations/knownfailures.txt @@ -3,6 +3,11 @@ */ [ { + description: "SimpleDateFormat assumes DST always uses 60 minute offset; this fails for zones like Lord Howe Daylight Time", + name: "libcore.java.text.SimpleDateFormatTest#testDstZoneWithNonDstTimestampForNonHourDstZone", + bug: 4723412 +}, +{ description: "Encoded bytes don't match for EC elliptic curve keys created through KeyFactory.generatePrivate()", names: [ "org.apache.harmony.security.tests.java.security.KeyFactory2Test#test_generatePrivateLjava_security_spec_KeySpec", diff --git a/luni/src/main/java/java/text/SimpleDateFormat.java b/luni/src/main/java/java/text/SimpleDateFormat.java index d43b42d..1f9b694 100644 --- a/luni/src/main/java/java/text/SimpleDateFormat.java +++ b/luni/src/main/java/java/text/SimpleDateFormat.java @@ -1174,6 +1174,13 @@ public class SimpleDateFormat extends DateFormat { } int raw = zone.getRawOffset(); if (j == TimeZones.LONG_NAME_DST || j == TimeZones.SHORT_NAME_DST) { + /* + * TODO, http://b/4723412 + * We can't use TimeZone#getDSTSavings here because that + * will return 0 if the zone no longer uses DST. We + * should change this to use TimeZone.getOffset(long), + * which requires the complete date to be parsed first. + */ raw += 3600000; } calendar.setTimeZone(new SimpleTimeZone(raw, "")); diff --git a/luni/src/test/java/libcore/java/text/SimpleDateFormatTest.java b/luni/src/test/java/libcore/java/text/SimpleDateFormatTest.java index 2d95658..c6296ff 100644 --- a/luni/src/test/java/libcore/java/text/SimpleDateFormatTest.java +++ b/luni/src/test/java/libcore/java/text/SimpleDateFormatTest.java @@ -21,10 +21,15 @@ import java.text.ParsePosition; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; +import java.util.GregorianCalendar; import java.util.Locale; import java.util.TimeZone; public class SimpleDateFormatTest extends junit.framework.TestCase { + + private static final TimeZone AMERICA_LOS_ANGELES = TimeZone.getTimeZone("America/Los_Angeles"); + private static final TimeZone AUSTRALIA_LORD_HOWE = TimeZone.getTimeZone("Australia/Lord_Howe"); + // The RI fails this test. public void test2DigitYearStartIsCloned() throws Exception { // Test that get2DigitYearStart returns a clone. @@ -137,7 +142,7 @@ public class SimpleDateFormatTest extends junit.framework.TestCase { // We should see something appropriate to America/Chicago... assertEquals("1969-12-31 18:00:00 -0600", sdf.format(epoch)); // We can set any TimeZone we want: - sdf.setTimeZone(TimeZone.getTimeZone("America/Los_Angeles")); + sdf.setTimeZone(AMERICA_LOS_ANGELES); assertEquals("1969-12-31 16:00:00 -0800", sdf.format(epoch)); sdf.setTimeZone(TimeZone.getTimeZone("UTC")); assertEquals("1970-01-01 00:00:00 +0000", sdf.format(epoch)); @@ -149,7 +154,7 @@ public class SimpleDateFormatTest extends junit.framework.TestCase { // ...so our time zone here is "America/Chicago": assertEquals("1969-12-31 18:00:00 -0600", sdf.format(epoch)); // We can set any TimeZone we want: - sdf.setTimeZone(TimeZone.getTimeZone("America/Los_Angeles")); + sdf.setTimeZone(AMERICA_LOS_ANGELES); assertEquals("1969-12-31 16:00:00 -0800", sdf.format(epoch)); sdf.setTimeZone(TimeZone.getTimeZone("UTC")); assertEquals("1970-01-01 00:00:00 +0000", sdf.format(epoch)); @@ -159,7 +164,7 @@ public class SimpleDateFormatTest extends junit.framework.TestCase { Date date = sdf.parse("2010-07-08 02:44:48"); assertEquals(1278557088000L, date.getTime()); sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ"); - sdf.setTimeZone(TimeZone.getTimeZone("America/Los_Angeles")); + sdf.setTimeZone(AMERICA_LOS_ANGELES); assertEquals("2010-07-07T19:44:48-0700", sdf.format(date)); sdf.setTimeZone(TimeZone.getTimeZone("UTC")); assertEquals("2010-07-08T02:44:48+0000", sdf.format(date)); @@ -176,6 +181,39 @@ public class SimpleDateFormatTest extends junit.framework.TestCase { assertEquals(60 * 60 * 1000, normal.getTime() - dst.getTime()); } + public void testDstZoneNameWithNonDstTimestamp() throws Exception { + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm zzzz"); + Calendar calendar = new GregorianCalendar(AMERICA_LOS_ANGELES); + calendar.setTime(format.parse("2011-06-21T10:00 Pacific Standard Time")); // 18:00 GMT-8 + assertEquals(11, calendar.get(Calendar.HOUR_OF_DAY)); // 18:00 GMT-7 + assertEquals(0, calendar.get(Calendar.MINUTE)); + } + + public void testNonDstZoneNameWithDstTimestamp() throws Exception { + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm zzzz"); + Calendar calendar = new GregorianCalendar(AMERICA_LOS_ANGELES); + calendar.setTime(format.parse("2010-12-21T10:00 Pacific Daylight Time")); // 17:00 GMT-7 + assertEquals(9, calendar.get(Calendar.HOUR_OF_DAY)); // 17:00 GMT-8 + assertEquals(0, calendar.get(Calendar.MINUTE)); + } + + // http://b/4723412 + public void testDstZoneWithNonDstTimestampForNonHourDstZone() throws Exception { + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm zzzz"); + Calendar calendar = new GregorianCalendar(AUSTRALIA_LORD_HOWE); + calendar.setTime(format.parse("2011-06-21T20:00 Lord Howe Daylight Time")); // 9:00 GMT+11 + assertEquals(19, calendar.get(Calendar.HOUR_OF_DAY)); // 9:00 GMT+10:30 + assertEquals(30, calendar.get(Calendar.MINUTE)); + } + + public void testNonDstZoneWithDstTimestampForNonHourDstZone() throws Exception { + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm zzzz"); + Calendar calendar = new GregorianCalendar(AUSTRALIA_LORD_HOWE); + calendar.setTime(format.parse("2010-12-21T19:30 Lord Howe Standard Time")); //9:00 GMT+10:30 + assertEquals(20, calendar.get(Calendar.HOUR_OF_DAY)); // 9:00 GMT+11:00 + assertEquals(0, calendar.get(Calendar.MINUTE)); + } + public void testLocales() throws Exception { // Just run through them all. Handy as a poor man's benchmark, and a sanity check. for (Locale l : Locale.getAvailableLocales()) { diff --git a/luni/src/test/java/libcore/java/util/CalendarTest.java b/luni/src/test/java/libcore/java/util/CalendarTest.java index 8b9d29d..279fa90 100644 --- a/luni/src/test/java/libcore/java/util/CalendarTest.java +++ b/luni/src/test/java/libcore/java/util/CalendarTest.java @@ -35,6 +35,8 @@ public class CalendarTest extends junit.framework.TestCase { */ private static final TimeZone ASIA_KUALA_LUMPUR = TimeZone.getTimeZone("Asia/Kuala_Lumpur"); + private static final TimeZone ASIA_SEOUL = TimeZone.getTimeZone("Asia/Seoul"); + // http://code.google.com/p/android/issues/detail?id=6184 public void test_setTimeZone() { // The specific time zones don't matter; they just have to be different so we can see that @@ -127,13 +129,30 @@ public class CalendarTest extends junit.framework.TestCase { assertCalendarEquals(calendar, 2011, 9, 3, 2, 10); // 02:10 GMT+11:00; +47.5 hours } + // http://code.google.com/p/android/issues/detail?id=17741 + public void testNewCalendarKoreaIsSelfConsistent() { + testSetSelfConsistent(ASIA_SEOUL, 1921, 0, 1); + testSetSelfConsistent(ASIA_SEOUL, 1955, 0, 1); + testSetSelfConsistent(ASIA_SEOUL, 1962, 0, 1); + testSetSelfConsistent(ASIA_SEOUL, 2065, 0, 1); + } + + // http://code.google.com/p/android/issues/detail?id=15629 public void testSetTimeInZoneWhereDstIsNoLongerUsed() throws Exception { - Calendar calendar = new GregorianCalendar(ASIA_KUALA_LUMPUR, Locale.US); + testSetSelfConsistent(ASIA_KUALA_LUMPUR, 1970, 0, 1); + } + + private void testSetSelfConsistent(TimeZone timeZone, int year, int month, int day) { + int hour = 0; + int minute = 0; + Calendar calendar = new GregorianCalendar(timeZone); calendar.clear(); - calendar.set(Calendar.HOUR, 2); - calendar.set(Calendar.MINUTE, 0); - assertEquals(2, calendar.get(Calendar.HOUR)); - assertEquals(0, calendar.get(Calendar.MINUTE)); + calendar.set(year, month, day, hour, minute); + assertEquals(year, calendar.get(Calendar.YEAR)); + assertEquals(month, calendar.get(Calendar.MONTH)); + assertEquals(day, calendar.get(Calendar.DAY_OF_MONTH)); + assertEquals(hour, calendar.get(Calendar.HOUR_OF_DAY)); + assertEquals(minute, calendar.get(Calendar.MINUTE)); } private void assertCalendarEquals(Calendar calendar, |