Completes DateTimeFormat support

This commit is contained in:
konsoletyper 2014-06-26 18:06:31 +04:00
parent 52ed32e9aa
commit b94d711732
11 changed files with 230 additions and 101 deletions

View File

@ -0,0 +1,50 @@
/*
* 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;
/**
*
* @author Alexey Andreev
*/
public class CLDRDateFormats {
private String shortFormat;
private String mediumFormat;
private String longFormat;
private String fullFormat;
CLDRDateFormats(String shortFormat, String mediumFormat, String longFormat, String fullFormat) {
this.shortFormat = shortFormat;
this.mediumFormat = mediumFormat;
this.longFormat = longFormat;
this.fullFormat = fullFormat;
}
public String getShortFormat() {
return shortFormat;
}
public String getMediumFormat() {
return mediumFormat;
}
public String getLongFormat() {
return longFormat;
}
public String getFullFormat() {
return fullFormat;
}
}

View File

@ -108,33 +108,26 @@ public class CLDRHelper {
@MetadataProvider(FirstDayOfWeekMetadataGenerator.class)
public static native ResourceMap<IntResource> getFirstDayOfWeek();
public static String resolveDateFormat(String language, String country) {
return resolveFormatSymbols(getDateFormatMap(), language, country);
public static DateFormatCollection resolveDateFormats(String language, String country) {
return resolveDateFormats(getDateFormatMap(), language, country);
}
@MetadataProvider(DateFormatMetadataGenerator.class)
private static native ResourceMap<StringResource> getDateFormatMap();
private static native ResourceMap<DateFormatCollection> getDateFormatMap();
public static String resolveFullDateFormat(String language, String country) {
return resolveFormatSymbols(getFullDateFormatMap(), language, country);
public static DateFormatCollection resolveTimeFormats(String language, String country) {
return resolveDateFormats(getTimeFormatMap(), language, country);
}
@MetadataProvider(DateFormatMetadataGenerator.class)
private static native ResourceMap<StringResource> getFullDateFormatMap();
private static native ResourceMap<DateFormatCollection> getTimeFormatMap();
public static String resolveLongDateFormat(String language, String country) {
return resolveFormatSymbols(getLongDateFormatMap(), language, country);
public static DateFormatCollection resolveDateTimeFormats(String language, String country) {
return resolveDateFormats(getDateTimeFormatMap(), language, country);
}
@MetadataProvider(DateFormatMetadataGenerator.class)
private static native ResourceMap<StringResource> getLongDateFormatMap();
public static String resolveShortDateFormat(String language, String country) {
return resolveFormatSymbols(getShortDateFormatMap(), language, country);
}
@MetadataProvider(DateFormatMetadataGenerator.class)
private static native ResourceMap<StringResource> getShortDateFormatMap();
private static native ResourceMap<DateFormatCollection> getDateTimeFormatMap();
public static String resolveNumberFormat(String language, String country) {
return resolveFormatSymbols(getNumberFormatMap(), language, country);
@ -154,6 +147,12 @@ public class CLDRHelper {
private static native ResourceMap<StringResource> getPercentFormatMap();
private static DateFormatCollection resolveDateFormats(ResourceMap<DateFormatCollection> map,
String language, String country) {
String localeCode = getCode(language, country);
return map.has(localeCode) ? map.get(localeCode) : map.has(language) ? map.get(language) : map.get("root");
}
private static String resolveFormatSymbols(ResourceMap<StringResource> map, String language, String country) {
String localeCode = getCode(language, country);
StringResource res = map.has(localeCode) ? map.get(localeCode) : map.has(language) ? map.get(language) :

View File

@ -33,10 +33,9 @@ public class CLDRLocale {
String[] shortMonths;
String[] weekdays;
String[] shortWeekdays;
String shortDateFormat;
String mediumDateFormat;
String longDateFormat;
String fullDateFormat;
CLDRDateFormats dateFormats;
CLDRDateFormats timeFormats;
CLDRDateFormats dateTimeFormats;
public Map<String, String> getLanguages() {
return Collections.unmodifiableMap(languages);
@ -70,19 +69,15 @@ public class CLDRLocale {
return Arrays.copyOf(shortWeekdays, shortWeekdays.length);
}
public String getShortDateFormat() {
return shortDateFormat;
public CLDRDateFormats getDateFormats() {
return dateFormats;
}
public String getMediumDateFormat() {
return mediumDateFormat;
public CLDRDateFormats getTimeFormats() {
return timeFormats;
}
public String getLongDateFormat() {
return longDateFormat;
}
public String getFullDateFormat() {
return fullDateFormat;
public CLDRDateFormats getDateTimeFormats() {
return dateTimeFormats;
}
}

View File

@ -109,6 +109,8 @@ public class CLDRReader {
readWeekdays(localeName, localeInfo, root);
readShortWeekdays(localeName, localeInfo, root);
readDateFormats(localeName, localeInfo, root);
readTimeFormats(localeName, localeInfo, root);
readDateTimeFormats(localeName, localeInfo, root);
break;
}
}
@ -209,10 +211,27 @@ public class CLDRReader {
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();
locale.dateFormats = new CLDRDateFormats(formatsJson.get("short").getAsString(),
formatsJson.get("medium").getAsString(), formatsJson.get("long").getAsString(),
formatsJson.get("full").getAsString());
}
private void readTimeFormats(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("timeFormats").getAsJsonObject();
locale.timeFormats = new CLDRDateFormats(formatsJson.get("short").getAsString(),
formatsJson.get("medium").getAsString(), formatsJson.get("long").getAsString(),
formatsJson.get("full").getAsString());
}
private void readDateTimeFormats(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("dateTimeFormats").getAsJsonObject();
locale.dateTimeFormats = new CLDRDateFormats(formatsJson.get("short").getAsString(),
formatsJson.get("medium").getAsString(), formatsJson.get("long").getAsString(),
formatsJson.get("full").getAsString());
}
private void readWeekData(InputStream input) {

View File

@ -0,0 +1,40 @@
/*
* 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 org.teavm.platform.metadata.Resource;
/**
*
* @author Alexey Andreev
*/
public interface DateFormatCollection extends Resource {
String getShortFormat();
void setShortFormat(String format);
String getMediumFormat();
void setMediumFormat(String format);
String getLongFormat();
void setLongFormat(String format);
String getFullFormat();
void setFullFormat(String format);
}

View File

@ -29,26 +29,20 @@ public class DateFormatMetadataGenerator implements MetadataGenerator {
switch (method.getName()) {
case "getDateFormatMap":
return getDateFormatMap(context, new FormatExtractor() {
@Override public String extract(CLDRLocale locale) {
return locale.getMediumDateFormat();
@Override public CLDRDateFormats extract(CLDRLocale locale) {
return locale.getDateFormats();
}
});
case "getShortDateFormatMap":
case "getTimeFormatMap":
return getDateFormatMap(context, new FormatExtractor() {
@Override public String extract(CLDRLocale locale) {
return locale.getShortDateFormat();
@Override public CLDRDateFormats extract(CLDRLocale locale) {
return locale.getTimeFormats();
}
});
case "getLongDateFormatMap":
case "getDateTimeFormatMap":
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();
@Override public CLDRDateFormats extract(CLDRLocale locale) {
return locale.getDateTimeFormats();
}
});
default:
@ -58,16 +52,20 @@ public class DateFormatMetadataGenerator implements MetadataGenerator {
private Resource getDateFormatMap(MetadataGeneratorContext context, FormatExtractor extractor) {
CLDRReader reader = context.getService(CLDRReader.class);
ResourceMap<StringResource> result = context.createResourceMap();
ResourceMap<DateFormatCollection> result = context.createResourceMap();
for (Map.Entry<String, CLDRLocale> entry : reader.getKnownLocales().entrySet()) {
StringResource formatRes = context.createResource(StringResource.class);
formatRes.setValue(extractor.extract(entry.getValue()));
DateFormatCollection formatRes = context.createResource(DateFormatCollection.class);
CLDRDateFormats formats = extractor.extract(entry.getValue());
formatRes.setShortFormat(formats.getShortFormat());
formatRes.setMediumFormat(formats.getMediumFormat());
formatRes.setLongFormat(formats.getLongFormat());
formatRes.setFullFormat(formats.getFullFormat());
result.put(entry.getKey(), formatRes);
}
return result;
}
interface FormatExtractor {
String extract(CLDRLocale locale);
CLDRDateFormats extract(CLDRLocale locale);
}
}

View File

@ -400,7 +400,7 @@ public class TString extends TObject implements TSerializable, TComparable<TStri
int sz = length() - target.length();
int i = 0;
outer:
for (; i < sz; ++i) {
for (; i <= sz; ++i) {
for (int j = 0; j < target.length(); ++j) {
if (charAt(i + j) != target.charAt(j)) {
sb.append(charAt(i));

View File

@ -18,6 +18,7 @@
package org.teavm.classlib.java.text;
import org.teavm.classlib.impl.unicode.CLDRHelper;
import org.teavm.classlib.impl.unicode.DateFormatCollection;
import org.teavm.classlib.java.util.*;
public abstract class TDateFormat extends TFormat {
@ -95,52 +96,63 @@ public abstract class TDateFormat extends TFormat {
return calendar;
}
public final static TDateFormat getDateInstance() {
public static TDateFormat getDateInstance() {
return getDateInstance(DEFAULT);
}
public final static TDateFormat getDateInstance(int style) {
checkDateStyle(style);
public static TDateFormat getDateInstance(int style) {
return getDateInstance(style, TLocale.getDefault());
}
public final static TDateFormat getDateInstance(int style, TLocale locale) {
public static TDateFormat getDateInstance(int style, TLocale locale) {
return new TSimpleDateFormat(getDateFormatString(style, locale), locale);
}
private static String getDateFormatString(int style, TLocale locale) {
DateFormatCollection formats = CLDRHelper.resolveDateFormats(locale.getLanguage(), locale.getCountry());
switch (style) {
case SHORT:
return new TSimpleDateFormat(CLDRHelper.resolveShortDateFormat(
locale.getLanguage(), locale.getCountry()), locale);
return formats.getShortFormat();
case MEDIUM:
return new TSimpleDateFormat(CLDRHelper.resolveDateFormat(
locale.getLanguage(), locale.getCountry()), locale);
return formats.getMediumFormat();
case LONG:
return new TSimpleDateFormat(CLDRHelper.resolveLongDateFormat(
locale.getLanguage(), locale.getCountry()), locale);
return formats.getLongFormat();
case FULL:
return new TSimpleDateFormat(CLDRHelper.resolveFullDateFormat(
locale.getLanguage(), locale.getCountry()), locale);
return formats.getFullFormat();
default:
throw new IllegalArgumentException("Unknown style: " + style);
}
}
public final static TDateFormat getDateTimeInstance() {
public static TDateFormat getDateTimeInstance() {
return getDateTimeInstance(DEFAULT, DEFAULT);
}
public final static TDateFormat getDateTimeInstance(int dateStyle, int timeStyle) {
checkTimeStyle(timeStyle);
checkDateStyle(dateStyle);
public static TDateFormat getDateTimeInstance(int dateStyle, int timeStyle) {
return getDateTimeInstance(dateStyle, timeStyle, TLocale.getDefault());
}
public final static TDateFormat getDateTimeInstance(int dateStyle, int timeStyle, TLocale locale) {
/*checkTimeStyle(timeStyle);
checkDateStyle(dateStyle);
com.ibm.icu.text.DateFormat icuFormat = com.ibm.icu.text.DateFormat.getDateTimeInstance(dateStyle, timeStyle,
locale);
return new SimpleDateFormat(locale, (com.ibm.icu.text.SimpleDateFormat) icuFormat);*/
// TODO: implement
return null;
public static TDateFormat getDateTimeInstance(int dateStyle, int timeStyle, TLocale locale) {
String pattern = getDateTimeFormatString(Math.max(dateStyle, timeStyle), locale);
pattern = pattern.replace("{0}", getTimeFormatString(dateStyle, locale))
.replace("{1}", getDateFormatString(timeStyle, locale));
return new TSimpleDateFormat(pattern, locale);
}
public static String getDateTimeFormatString(int style, TLocale locale) {
DateFormatCollection formats = CLDRHelper.resolveDateTimeFormats(locale.getLanguage(), locale.getCountry());
switch (style) {
case SHORT:
return formats.getShortFormat();
case MEDIUM:
return formats.getMediumFormat();
case LONG:
return formats.getLongFormat();
case FULL:
return formats.getFullFormat();
default:
throw new IllegalArgumentException("Unknown style: " + style);
}
}
public final static TDateFormat getInstance() {
@ -172,19 +184,29 @@ public abstract class TDateFormat extends TFormat {
return getTimeInstance(DEFAULT);
}
public final static TDateFormat getTimeInstance(int style) {
checkTimeStyle(style);
public static TDateFormat getTimeInstance(int style) {
return getTimeInstance(style, TLocale.getDefault());
}
public final static TDateFormat getTimeInstance(int style, TLocale locale) {
/*checkTimeStyle(style);
com.ibm.icu.text.DateFormat icuFormat = com.ibm.icu.text.DateFormat.getTimeInstance(style, locale);
return new SimpleDateFormat(locale, (com.ibm.icu.text.SimpleDateFormat) icuFormat);*/
// TODO: implement
return null;
public static TDateFormat getTimeInstance(int style, TLocale locale) {
return new TSimpleDateFormat(getTimeFormatString(style, locale), locale);
}
private static String getTimeFormatString(int style, TLocale locale) {
DateFormatCollection formats = CLDRHelper.resolveTimeFormats(locale.getLanguage(), locale.getCountry());
switch (style) {
case SHORT:
return formats.getShortFormat();
case MEDIUM:
return formats.getMediumFormat();
case LONG:
return formats.getLongFormat();
case FULL:
return formats.getFullFormat();
default:
throw new IllegalArgumentException("Unknown style: " + style);
}
}
@Override
public int hashCode() {
@ -263,16 +285,4 @@ public abstract class TDateFormat extends TFormat {
return table.get(new Integer(calendarField));
}
}
private static void checkDateStyle(int style) {
if (!(style == SHORT || style == MEDIUM || style == LONG || style == FULL || style == DEFAULT)) {
throw new IllegalArgumentException("Illegal date style: " + style);
}
}
private static void checkTimeStyle(int style) {
if (!(style == SHORT || style == MEDIUM || style == LONG || style == FULL || style == DEFAULT)) {
throw new IllegalArgumentException("Illegal time style: " + style);
}
}
}

View File

@ -37,7 +37,7 @@ public class TSimpleDateFormat extends TDateFormat {
private static String getDefaultPattern() {
TLocale locale = TLocale.getDefault();
return CLDRHelper.resolveDateFormat(locale.getLanguage(), locale.getCountry());
return CLDRHelper.resolveDateFormats(locale.getLanguage(), locale.getCountry()).getMediumFormat();
}
public TSimpleDateFormat(String pattern) {

View File

@ -55,7 +55,7 @@ class TSimpleDatePatternParser {
case 'y':
case 'Y': {
int rep = parseRepetitions();
if (rep <= 2) {
if (rep == 2) {
elements.add(new TDateFormatElement.Year(TCalendar.YEAR));
} else {
elements.add(new TDateFormatElement.Numeric(TCalendar.YEAR, rep));

View File

@ -612,6 +612,24 @@ LongInt_add = function(a, b) {
a.hi = (a_hilo & 0xFFFF) | (a_hihi << 16);
a.sup = sup;
}
LongInt_inc = function(a) {
a.lo = (a.lo + 1) | 0;
if (a.lo == 0) {
a.hi = (a.hi + 1) | 0;
if (a.hi == 0) {
a.sup = (a.sup + 1) | 0xFFFF;
}
}
}
LongInt_dec = function(a) {
a.lo = (a.lo - 1) | 0;
if (a.lo == -1) {
a.hi = (a.hi - 1) | 0;
if (a.hi == -1) {
a.sup = (a.sup - 1) | 0xFFFF;
}
}
}
LongInt_ucompare = function(a, b) {
var r = (a.sup - b.sup);
if (r != 0) {
@ -696,7 +714,7 @@ LongInt_div = function(a, b) {
if (LongInt_ucompare(t, a) >= 0) {
while (LongInt_ucompare(t, a) > 0) {
LongInt_sub(t, b);
q = (q - 1) | 0;
--digit;
}
} else {
while (true) {
@ -706,7 +724,7 @@ LongInt_div = function(a, b) {
break;
}
t = nextT;
q = (q + 1) | 0;
++digit;
}
}
LongInt_sub(a, t);