diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/impl/unicode/CLDRHelper.java b/teavm-classlib/src/main/java/org/teavm/classlib/impl/unicode/CLDRHelper.java index 24bdf861e..91058d6fe 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/impl/unicode/CLDRHelper.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/impl/unicode/CLDRHelper.java @@ -112,24 +112,28 @@ public class CLDRHelper { return resolveFormatSymbols(getDateFormatMap(), language, country); } + @MetadataProvider(DateFormatMetadataGenerator.class) private static native ResourceMap getDateFormatMap(); public static String resolveFullDateFormat(String language, String country) { return resolveFormatSymbols(getFullDateFormatMap(), language, country); } + @MetadataProvider(DateFormatMetadataGenerator.class) private static native ResourceMap getFullDateFormatMap(); public static String resolveLongDateFormat(String language, String country) { return resolveFormatSymbols(getLongDateFormatMap(), language, country); } + @MetadataProvider(DateFormatMetadataGenerator.class) private static native ResourceMap getLongDateFormatMap(); public static String resolveShortDateFormat(String language, String country) { return resolveFormatSymbols(getShortDateFormatMap(), language, country); } + @MetadataProvider(DateFormatMetadataGenerator.class) private static native ResourceMap getShortDateFormatMap(); public static String resolveNumberFormat(String language, String country) { diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/impl/unicode/CLDRLocale.java b/teavm-classlib/src/main/java/org/teavm/classlib/impl/unicode/CLDRLocale.java index 398f6c6b7..ebb359f60 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/impl/unicode/CLDRLocale.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/impl/unicode/CLDRLocale.java @@ -33,6 +33,10 @@ public class CLDRLocale { String[] shortMonths; String[] weekdays; String[] shortWeekdays; + String shortDateFormat; + String mediumDateFormat; + String longDateFormat; + String fullDateFormat; public Map getLanguages() { return Collections.unmodifiableMap(languages); @@ -65,4 +69,20 @@ public class CLDRLocale { public String[] getShortWeekdays() { return Arrays.copyOf(shortWeekdays, shortWeekdays.length); } + + public String getShortDateFormat() { + return shortDateFormat; + } + + public String getMediumDateFormat() { + return mediumDateFormat; + } + + public String getLongDateFormat() { + return longDateFormat; + } + + public String getFullDateFormat() { + return fullDateFormat; + } } 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 6a9ad990b..73d2317a5 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 @@ -108,6 +108,7 @@ public class CLDRReader { readShortMonths(localeName, localeInfo, root); readWeekdays(localeName, localeInfo, root); readShortWeekdays(localeName, localeInfo, root); + readDateFormats(localeName, localeInfo, root); break; } } @@ -183,27 +184,37 @@ public class CLDRReader { } private void readWeekdays(String localeCode, CLDRLocale locale, JsonObject root) { - JsonObject monthsJson = root.get("main").getAsJsonObject().get(localeCode).getAsJsonObject() + JsonObject weekdaysJson = root.get("main").getAsJsonObject().get(localeCode).getAsJsonObject() .get("dates").getAsJsonObject().get("calendars").getAsJsonObject() .get("gregorian").getAsJsonObject().get("days").getAsJsonObject() .get("format").getAsJsonObject().get("wide").getAsJsonObject(); locale.weekdays = new String[7]; for (int i = 0; i < 7; ++i) { - locale.weekdays[i] = monthsJson.get(weekdayKeys[i]).getAsString(); + locale.weekdays[i] = weekdaysJson.get(weekdayKeys[i]).getAsString(); } } private void readShortWeekdays(String localeCode, CLDRLocale locale, JsonObject root) { - JsonObject monthsJson = root.get("main").getAsJsonObject().get(localeCode).getAsJsonObject() + JsonObject weekdaysJson = root.get("main").getAsJsonObject().get(localeCode).getAsJsonObject() .get("dates").getAsJsonObject().get("calendars").getAsJsonObject() .get("gregorian").getAsJsonObject().get("days").getAsJsonObject() - .get("format").getAsJsonObject().get("short").getAsJsonObject(); + .get("format").getAsJsonObject().get("abbreviated").getAsJsonObject(); locale.shortWeekdays = new String[7]; for (int i = 0; i < 7; ++i) { - locale.shortWeekdays[i] = monthsJson.get(weekdayKeys[i]).getAsString(); + locale.shortWeekdays[i] = weekdaysJson.get(weekdayKeys[i]).getAsString(); } } + private void readDateFormats(String localeCode, CLDRLocale locale, JsonObject root) { + JsonObject formatsJson = root.get("main").getAsJsonObject().get(localeCode).getAsJsonObject() + .get("dates").getAsJsonObject().get("calendars").getAsJsonObject() + .get("gregorian").getAsJsonObject().get("dateFormats").getAsJsonObject(); + locale.shortDateFormat = formatsJson.get("short").getAsString(); + locale.mediumDateFormat = formatsJson.get("medium").getAsString(); + locale.longDateFormat = formatsJson.get("long").getAsString(); + locale.fullDateFormat = formatsJson.get("full").getAsString(); + } + private void readWeekData(InputStream input) { JsonObject root = (JsonObject)new JsonParser().parse(new InputStreamReader(input)); JsonObject weekJson = root.get("supplemental").getAsJsonObject().get("weekData").getAsJsonObject(); diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/impl/unicode/DateFormatMetadataGenerator.java b/teavm-classlib/src/main/java/org/teavm/classlib/impl/unicode/DateFormatMetadataGenerator.java new file mode 100644 index 000000000..78eb6d3e4 --- /dev/null +++ b/teavm-classlib/src/main/java/org/teavm/classlib/impl/unicode/DateFormatMetadataGenerator.java @@ -0,0 +1,73 @@ +/* + * Copyright 2014 Alexey Andreev. + * + * 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.impl.unicode; + +import java.util.Map; +import org.teavm.model.MethodReference; +import org.teavm.platform.metadata.*; + +/** + * + * @author Alexey Andreev + */ +public class DateFormatMetadataGenerator implements MetadataGenerator { + @Override + public Resource generateMetadata(MetadataGeneratorContext context, MethodReference method) { + switch (method.getName()) { + case "getDateFormatMap": + return getDateFormatMap(context, new FormatExtractor() { + @Override public String extract(CLDRLocale locale) { + return locale.getMediumDateFormat(); + } + }); + case "getShortDateFormatMap": + return getDateFormatMap(context, new FormatExtractor() { + @Override public String extract(CLDRLocale locale) { + return locale.getShortDateFormat(); + } + }); + case "getLongDateFormatMap": + return getDateFormatMap(context, new FormatExtractor() { + @Override public String extract(CLDRLocale locale) { + return locale.getLongDateFormat(); + } + }); + case "getFullDateFormatMap": + return getDateFormatMap(context, new FormatExtractor() { + @Override public String extract(CLDRLocale locale) { + return locale.getFullDateFormat(); + } + }); + default: + throw new IllegalArgumentException("Method is not supported: " + method); + } + } + + private Resource getDateFormatMap(MetadataGeneratorContext context, FormatExtractor extractor) { + CLDRReader reader = context.getService(CLDRReader.class); + ResourceMap result = context.createResourceMap(); + for (Map.Entry entry : reader.getKnownLocales().entrySet()) { + StringResource formatRes = context.createResource(StringResource.class); + formatRes.setValue(extractor.extract(entry.getValue())); + result.put(entry.getKey(), formatRes); + } + return result; + } + + interface FormatExtractor { + String extract(CLDRLocale locale); + } +} diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/text/TDateFormat.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/text/TDateFormat.java index e231e06e0..27db4d34d 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/text/TDateFormat.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/text/TDateFormat.java @@ -22,7 +22,6 @@ import org.teavm.classlib.java.util.*; public abstract class TDateFormat extends TFormat { protected TCalendar calendar; - //protected NumberFormat numberFormat; public final static int DEFAULT = 2; public final static int FULL = 0; public final static int LONG = 1; @@ -54,30 +53,22 @@ public abstract class TDateFormat extends TFormat { public Object clone() { TDateFormat clone = (TDateFormat) super.clone(); clone.calendar = (TCalendar) calendar.clone(); - // TODO: implement - //clone.numberFormat = (NumberFormat) numberFormat.clone(); return clone; } - // TODO: implement - /* @Override public boolean equals(Object object) { if (this == object) { return true; } - if (!(object instanceof DateFormat)) { + if (!(object instanceof TDateFormat)) { return false; } - DateFormat dateFormat = (DateFormat) object; - return numberFormat.equals(dateFormat.numberFormat) && - calendar.getFirstDayOfWeek() == dateFormat.calendar.getFirstDayOfWeek() && + TDateFormat dateFormat = (TDateFormat) object; + return calendar.getFirstDayOfWeek() == dateFormat.calendar.getFirstDayOfWeek() && calendar.getMinimalDaysInFirstWeek() == dateFormat.calendar.getMinimalDaysInFirstWeek() && calendar.isLenient() == dateFormat.calendar.isLenient(); - - return false; } - */ @Override public final StringBuffer format(Object object, StringBuffer buffer, TFieldPosition field) { @@ -156,10 +147,6 @@ public abstract class TDateFormat extends TFormat { return getDateTimeInstance(SHORT, SHORT); } - /*public NumberFormat getNumberFormat() { - return numberFormat; - }*/ - static String getStyleName(int style) { String styleName; switch (style) { @@ -199,14 +186,11 @@ public abstract class TDateFormat extends TFormat { } - // TODO: implement - /*@Override + @Override public int hashCode() { return calendar.getFirstDayOfWeek() + calendar.getMinimalDaysInFirstWeek() + - (calendar.isLenient() ? 1231 : 1237) + numberFormat.hashCode(); - - return 0; - }*/ + (calendar.isLenient() ? 1231 : 1237); + } public boolean isLenient() { return calendar.isLenient(); @@ -236,10 +220,6 @@ public abstract class TDateFormat extends TFormat { calendar.setLenient(value); } - /*public void setNumberFormat(NumberFormat format) { - numberFormat = format; - }*/ - public static class Field extends TFormat.Field { private static THashMap table = new THashMap<>(); public final static Field ERA = new Field("era", TCalendar.ERA); diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/text/TDateFormatElement.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/text/TDateFormatElement.java index 7455fdad1..b7cc8fdab 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/text/TDateFormatElement.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/text/TDateFormatElement.java @@ -93,7 +93,7 @@ abstract class TDateFormatElement { @Override public void format(TCalendar date, StringBuffer buffer) { - int weekday = date.get(TCalendar.DAY_OF_WEEK); + int weekday = date.get(TCalendar.DAY_OF_WEEK) - 1; buffer.append(abbreviated ? shortWeeks[weekday] : weeks[weekday]); } @@ -183,7 +183,7 @@ abstract class TDateFormatElement { int num = 0; int i = 0; int pos = position.getIndex(); - while (position.getIndex() < text.length() && i < length) { + while (pos < text.length()) { char c = text.charAt(pos); if (c >= '0' && c <= '9') { num = num * 10 + (c - '0'); @@ -193,7 +193,7 @@ abstract class TDateFormatElement { break; } } - if (i == 0) { + if (i < length) { position.setErrorIndex(position.getIndex()); return; } diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/text/TDecimalFormat.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/text/TDecimalFormat.java index ac94ff1e4..50d16ad12 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/text/TDecimalFormat.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/text/TDecimalFormat.java @@ -47,7 +47,7 @@ public class TDecimalFormat extends TNumberFormat { super.setMinimumIntegerDigits(decimalData.getMinimumIntegerDigits()); } - public void applyPattern(String pattern) { + public void applyPattern(@SuppressWarnings("unused") String pattern) { } diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/text/TNumberFormat.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/text/TNumberFormat.java index 7fd558fa5..545185fe2 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/text/TNumberFormat.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/text/TNumberFormat.java @@ -155,7 +155,6 @@ public abstract class TNumberFormat extends TFormat { TParsePosition pos = new TParsePosition(0); Number number = parse(string, pos); if (pos.getIndex() == 0) { - // text.1D=: {0} throw new TParseException("Unparseable number: " + string, pos.getErrorIndex()); } return number; 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 16ac9732d..a2fa83ce4 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 @@ -79,8 +79,7 @@ public class TSimpleDateFormat extends TDateFormat { @Override public TDate parse(String string, TParsePosition position) { TCalendar calendar = new TGregorianCalendar(locale); - calendar.set(0, 0, 0, 0, 0, 0); - calendar.set(TCalendar.MILLISECOND, 0); + calendar.clear(); for (TDateFormatElement element : elements) { if (position.getIndex() > string.length()) { position.setErrorIndex(position.getErrorIndex()); diff --git a/teavm-classlib/src/test/java/org/teavm/classlib/java/text/DateFormatTest.java b/teavm-classlib/src/test/java/org/teavm/classlib/java/text/DateFormatTest.java new file mode 100644 index 000000000..a6f94de8c --- /dev/null +++ b/teavm-classlib/src/test/java/org/teavm/classlib/java/text/DateFormatTest.java @@ -0,0 +1,72 @@ +/* + * Copyright 2014 Alexey Andreev. + * + * 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.text; + +import static org.junit.Assert.*; +import java.text.DateFormat; +import java.text.ParseException; +import java.util.Calendar; +import java.util.Date; +import java.util.GregorianCalendar; +import java.util.Locale; +import org.junit.Test; + +/** + * + * @author Alexey Andreev + */ +public class DateFormatTest { + @Test + public void shortDateFormatHandled() throws ParseException { + DateFormat format = DateFormat.getDateInstance(DateFormat.SHORT, Locale.ENGLISH); + assertEquals("6/24/14", format.format(getDateWithZoneOffset(1403539200000L))); + assertEquals(1403539200000L, getTimeWithoutZoneOffset(format.parse("6/24/14"))); + } + + @Test + public void mediumDateFormatHandled() throws ParseException { + DateFormat format = DateFormat.getDateInstance(DateFormat.MEDIUM, Locale.ENGLISH); + assertEquals("Jun 24, 2014", format.format(getDateWithZoneOffset(1403539200000L))); + assertEquals(1403539200000L, getTimeWithoutZoneOffset(format.parse("Jun 24, 2014"))); + } + + @Test + public void longDateFormatHandled() throws ParseException { + DateFormat format = DateFormat.getDateInstance(DateFormat.LONG, Locale.ENGLISH); + assertEquals("June 24, 2014", format.format(getDateWithZoneOffset(1403539200000L))); + assertEquals(1403539200000L, getTimeWithoutZoneOffset(format.parse("June 24, 2014"))); + } + + @Test + public void fullDateFormatHandled() throws ParseException { + DateFormat format = DateFormat.getDateInstance(DateFormat.FULL, Locale.ENGLISH); + assertEquals("Tuesday, June 24, 2014", format.format(getDateWithZoneOffset(1403539200000L))); + assertEquals(1403539200000L, getTimeWithoutZoneOffset(format.parse("Tuesday, June 24, 2014"))); + } + + 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); + } +} diff --git a/teavm-classlib/src/test/java/org/teavm/classlib/java/text/SimpleDateFormatTest.java b/teavm-classlib/src/test/java/org/teavm/classlib/java/text/SimpleDateFormatTest.java new file mode 100644 index 000000000..8859ac4c0 --- /dev/null +++ b/teavm-classlib/src/test/java/org/teavm/classlib/java/text/SimpleDateFormatTest.java @@ -0,0 +1,151 @@ +/* + * Copyright 2014 Alexey Andreev. + * + * 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.text; + +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; + +/** + * + * @author Alexey Andreev + */ +public class SimpleDateFormatTest { + @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", 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("yyyy-MM-dd HH:mm:ss www", Locale.ENGLISH); + assertEquals("2014-06-24 17:33:49 026", format.format(getDateWithZoneOffset(1403602429504L))); + assertEquals("2014-06-28 17:33:49 026", format.format(getDateWithZoneOffset(1403602429504L + day * 4))); + assertEquals("2014-06-29 17:33:49 027", format.format(getDateWithZoneOffset(1403602429504L + day * 5))); + assertEquals(1403602429000L, getTimeWithoutZoneOffset(format.parse("2014-06-24 17:33:49 026"))); + assertEquals(1403602429000L + day * 4, getTimeWithoutZoneOffset(format.parse("2014-06-28 17:33:49 026"))); + assertEquals(1403602429000L + day * 5, getTimeWithoutZoneOffset(format.parse("2014-06-29 17:33:49 027"))); + } + + @Test + public void weekInMonthHandled() throws ParseException { + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss WW", Locale.ENGLISH); + assertEquals("2014-06-24 17:33:49 04", format.format(getDateWithZoneOffset(1403602429504L))); + assertEquals(1403602429000L, getTimeWithoutZoneOffset(format.parse("2014-06-24 17:33:49 04"))); + } + + @Test + public void dayInYearHandled() throws ParseException { + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss DD", Locale.ENGLISH); + assertEquals("2014-06-24 17:33:49 175", format.format(getDateWithZoneOffset(1403602429504L))); + assertEquals(1403602429000L, getTimeWithoutZoneOffset(format.parse("2014-06-24 17:33:49 175"))); + } + + @Test + public void weekdayInMonthHandled() throws ParseException { + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss F", Locale.ENGLISH); + assertEquals("2014-06-24 17:33:49 4", format.format(getDateWithZoneOffset(1403602429504L))); + assertEquals(1403602429000L, getTimeWithoutZoneOffset(format.parse("2014-06-24 17:33:49 4"))); + } + + @Test + public void shortWeekdayHandled() throws ParseException { + SimpleDateFormat format = new SimpleDateFormat("E yyyy-MM-dd HH:mm:ss", Locale.ENGLISH); + assertEquals("Tue 2014-06-24 17:33:49", format.format(getDateWithZoneOffset(1403602429504L))); + assertEquals(1403602429000L, getTimeWithoutZoneOffset(format.parse("Tue 2014-06-24 17:33:49"))); + } + + @Test + public void longWeekdayHandled() throws ParseException { + SimpleDateFormat format = new SimpleDateFormat("EEEE, yyyy-MM-dd HH:mm:ss", Locale.ENGLISH); + assertEquals("Tuesday, 2014-06-24 17:33:49", format.format(getDateWithZoneOffset(1403602429504L))); + assertEquals(1403602429000L, getTimeWithoutZoneOffset(format.parse("Tuesday, 2014-06-24 17:33:49"))); + } + + @Test + public void numericWeekdayHandled() throws ParseException { + SimpleDateFormat format = new SimpleDateFormat("u yyyy-MM-dd HH:mm:ss", Locale.ENGLISH); + assertEquals("2 2014-06-24 17:33:49", format.format(getDateWithZoneOffset(1403602429504L))); + assertEquals(1403602429000L, getTimeWithoutZoneOffset(format.parse("2 2014-06-24 17:33:49"))); + } + + @Test + public void amPmHandled() throws ParseException { + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd 'at' hh:mm:ss a", Locale.ENGLISH); + assertEquals("2014-06-24 at 05:33:49 PM", format.format(getDateWithZoneOffset(1403602429504L))); + assertEquals(1403602429000L, getTimeWithoutZoneOffset(format.parse("2014-06-24 at 05:33:49 PM"))); + } + + @Test + public void shortMonthHandled() throws ParseException { + SimpleDateFormat format = new SimpleDateFormat("MMM, dd yyyy HH:mm:ss", Locale.ENGLISH); + assertEquals("Jun, 24 2014 17:33:49", format.format(getDateWithZoneOffset(1403602429504L))); + assertEquals(1403602429000L, getTimeWithoutZoneOffset(format.parse("Jun, 24 2014 17:33:49"))); + } + + @Test + public void longMonthHandled() throws ParseException { + SimpleDateFormat format = new SimpleDateFormat("MMMM, dd yyyy HH:mm:ss", Locale.ENGLISH); + assertEquals("June, 24 2014 17:33:49", format.format(getDateWithZoneOffset(1403602429504L))); + assertEquals(1403602429000L, getTimeWithoutZoneOffset(format.parse("June, 24 2014 17:33:49"))); + } + + 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); + } +} 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 deleted file mode 100644 index 88311cafb..000000000 --- a/teavm-classlib/src/test/java/org/teavm/classlib/java/text/SimpleDateTimeFormatTest.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright 2014 Alexey Andreev. - * - * 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.text; - -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; - -/** - * - * @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", 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); - } -}