From 9c8d137e90deba4bb36f21fe89483e553533c7bf Mon Sep 17 00:00:00 2001 From: konsoletyper Date: Wed, 25 Jun 2014 18:05:31 +0400 Subject: [PATCH] Adds tests for several fields in SimpleDateFormat --- .../classlib/impl/unicode/CLDRReader.java | 2 +- .../classlib/java/text/TSimpleDateFormat.java | 10 ++- .../java/util/TGregorianCalendar.java | 11 +-- .../java/text/SimpleDateTimeFormatTest.java | 68 ++++++++++++++++++- 4 files changed, 76 insertions(+), 15 deletions(-) diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/impl/unicode/CLDRReader.java b/teavm-classlib/src/main/java/org/teavm/classlib/impl/unicode/CLDRReader.java index f821df429..6a9ad990b 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/impl/unicode/CLDRReader.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/impl/unicode/CLDRReader.java @@ -144,7 +144,7 @@ public class CLDRReader { private void readEras(String localeCode, CLDRLocale locale, JsonObject root) { JsonObject erasJson = root.get("main").getAsJsonObject().get(localeCode).getAsJsonObject() .get("dates").getAsJsonObject().get("calendars").getAsJsonObject() - .get("gregorian").getAsJsonObject().get("eras").getAsJsonObject().get("eraNames").getAsJsonObject(); + .get("gregorian").getAsJsonObject().get("eras").getAsJsonObject().get("eraAbbr").getAsJsonObject(); String bc = erasJson.get("0").getAsString(); String ac = erasJson.get("1").getAsString(); locale.eras = new String[] { bc, ac }; diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/text/TSimpleDateFormat.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/text/TSimpleDateFormat.java index 9810a4ade..16ac9732d 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/text/TSimpleDateFormat.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/text/TSimpleDateFormat.java @@ -29,6 +29,7 @@ public class TSimpleDateFormat extends TDateFormat { private TDateFormatSymbols dateFormatSymbols; private TDateFormatElement[] elements; private String pattern; + private TLocale locale; public TSimpleDateFormat() { this(getDefaultPattern()); @@ -45,16 +46,18 @@ public class TSimpleDateFormat extends TDateFormat { public TSimpleDateFormat(String pattern, TLocale locale) { this(pattern, new TDateFormatSymbols(locale)); + this.locale = locale; } public TSimpleDateFormat(String pattern, TDateFormatSymbols dateFormatSymbols) { - dateFormatSymbols = (TDateFormatSymbols)dateFormatSymbols.clone(); + this.dateFormatSymbols = (TDateFormatSymbols)dateFormatSymbols.clone(); + locale = TLocale.getDefault(); applyPattern(pattern); } @Override public StringBuffer format(TDate date, StringBuffer buffer, TFieldPosition field) { - TCalendar calendar = new TGregorianCalendar(); + TCalendar calendar = new TGregorianCalendar(locale); calendar.setTime(date); for (TDateFormatElement element : elements) { element.format(calendar, buffer); @@ -75,8 +78,9 @@ public class TSimpleDateFormat extends TDateFormat { @Override public TDate parse(String string, TParsePosition position) { - TCalendar calendar = new TGregorianCalendar(); + TCalendar calendar = new TGregorianCalendar(locale); calendar.set(0, 0, 0, 0, 0, 0); + calendar.set(TCalendar.MILLISECOND, 0); for (TDateFormatElement element : elements) { if (position.getIndex() > string.length()) { position.setErrorIndex(position.getErrorIndex()); 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 27fd2290e..3159017e4 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 @@ -303,7 +303,7 @@ public class TGregorianCalendar extends TCalendar { } private static int getTimeZoneOffset(double time) { - return TDate.getTimezoneOffset(time); + return -TDate.getTimezoneOffset(time) * 1000 * 60; } @Override @@ -517,7 +517,7 @@ public class TGregorianCalendar extends TCalendar { } if (isSet[WEEK_OF_MONTH] && lastDateFieldSet != DAY_OF_WEEK_IN_MONTH) { int skew = mod7(days - 3 - (getFirstDayOfWeek() - 1)); - days += (fields[WEEK_OF_MONTH] - 1) * 7 + mod7(skew + dayOfWeek - (days - 3)) - skew; + days += (fields[WEEK_OF_MONTH] - 1) * 7 + mod7(skew + dayOfWeek - (days - 2)) - skew; } else if (isSet[DAY_OF_WEEK_IN_MONTH]) { if (fields[DAY_OF_WEEK_IN_MONTH] >= 0) { days += mod7(dayOfWeek - (days - 3)) + (fields[DAY_OF_WEEK_IN_MONTH] - 1) * 7; @@ -567,12 +567,7 @@ public class TGregorianCalendar extends TCalendar { timeVal -= julianError() * 86400000L; } - long timeValWithoutDST = timeVal - getTimeZoneOffset(timeVal); - this.time = timeVal; - if (timeValWithoutDST != timeVal) { - computeFields(); - areFieldsSet = true; - } + this.time = timeVal - getTimeZoneOffset(timeVal); } private int computeYearAndDay(long dayCount, long localTime) { diff --git a/teavm-classlib/src/test/java/org/teavm/classlib/java/text/SimpleDateTimeFormatTest.java b/teavm-classlib/src/test/java/org/teavm/classlib/java/text/SimpleDateTimeFormatTest.java index be94da5fd..88311cafb 100644 --- a/teavm-classlib/src/test/java/org/teavm/classlib/java/text/SimpleDateTimeFormatTest.java +++ b/teavm-classlib/src/test/java/org/teavm/classlib/java/text/SimpleDateTimeFormatTest.java @@ -15,9 +15,13 @@ */ package org.teavm.classlib.java.text; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; +import java.text.ParseException; import java.text.SimpleDateFormat; +import java.util.Calendar; import java.util.Date; +import java.util.GregorianCalendar; +import java.util.Locale; import org.junit.Test; /** @@ -25,9 +29,67 @@ import org.junit.Test; * @author Alexey Andreev */ public class SimpleDateTimeFormatTest { + @Test + public void firstDayOfWeekMatches() { + assertEquals(Calendar.SUNDAY, new GregorianCalendar(Locale.ENGLISH).getFirstDayOfWeek()); + assertEquals(1, new GregorianCalendar(Locale.ENGLISH).getMinimalDaysInFirstWeek()); + } + @Test public void fieldsFormatted() { - SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - assertEquals("2014-06-24 17:33:49", format.format(new Date(1403616829504L))); + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.ENGLISH); + assertEquals("2014-06-24 17:33:49", format.format(getDateWithZoneOffset(1403602429504L))); + } + + @Test + public void fieldsParsed() throws ParseException { + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.ENGLISH); + assertEquals(1403602429000L, getTimeWithoutZoneOffset(format.parse("2014-06-24 17:33:49"))); + } + + @Test + public void eraHandled() throws ParseException { + SimpleDateFormat format = new SimpleDateFormat("G yyyy-MM-dd HH:mm:ss", Locale.ENGLISH); + assertEquals("AD 2014-06-24 17:33:49", format.format(getDateWithZoneOffset(1403602429504L))); + assertEquals(1403602429000L, getTimeWithoutZoneOffset(format.parse("AD 2014-06-24 17:33:49"))); + } + + @Test + public void shortYearHandled() throws ParseException { + SimpleDateFormat format = new SimpleDateFormat("yy-MM-dd HH:mm:ss", Locale.ENGLISH); + assertEquals("14-06-24 17:33:49", format.format(getDateWithZoneOffset(1403602429504L))); + assertEquals(1403602429000L, getTimeWithoutZoneOffset(format.parse("14-06-24 17:33:49"))); + } + + @Test + public void weekInYearHandled() throws ParseException { + long day = 24 * 3600 * 1000; + SimpleDateFormat format = new SimpleDateFormat("yy-MM-dd HH:mm:ss www", Locale.ENGLISH); + assertEquals("14-06-24 17:33:49 026", format.format(getDateWithZoneOffset(1403602429504L))); + assertEquals("14-06-28 17:33:49 026", format.format(getDateWithZoneOffset(1403602429504L + day * 4))); + assertEquals("14-06-29 17:33:49 027", format.format(getDateWithZoneOffset(1403602429504L + day * 5))); + assertEquals(1403602429000L, getTimeWithoutZoneOffset(format.parse("14-06-24 17:33:49 026"))); + assertEquals(1403602429000L + day * 4, getTimeWithoutZoneOffset(format.parse("14-06-28 17:33:49 026"))); + assertEquals(1403602429000L + day * 5, getTimeWithoutZoneOffset(format.parse("14-06-29 17:33:49 027"))); + } + + @Test + public void weekInMonthHandled() throws ParseException { + SimpleDateFormat format = new SimpleDateFormat("yy-MM-dd HH:mm:ss WW", Locale.ENGLISH); + assertEquals("14-06-24 17:33:49 04", format.format(getDateWithZoneOffset(1403602429504L))); + assertEquals(1403602429000L, getTimeWithoutZoneOffset(format.parse("14-06-24 17:33:49 04"))); + } + + private Date getDateWithZoneOffset(long milliseconds) { + Calendar calendar = new GregorianCalendar(Locale.ENGLISH); + calendar.setTimeInMillis(milliseconds); + milliseconds += calendar.get(Calendar.ZONE_OFFSET); + return new Date(milliseconds); + } + + private long getTimeWithoutZoneOffset(Date date) { + Calendar calendar = new GregorianCalendar(Locale.ENGLISH); + calendar.setTime(date); + return calendar.getTimeInMillis() - calendar.get(Calendar.ZONE_OFFSET); } }