mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-23 08:34:11 -08:00
Further work on SimpleTimeZone
This commit is contained in:
parent
71bfaa9d66
commit
bfd97bcae7
|
@ -92,6 +92,9 @@ public class CLDRHelper {
|
||||||
|
|
||||||
public static String getTimeZoneName(String language, String country, String id) {
|
public static String getTimeZoneName(String language, String country, String id) {
|
||||||
String locale = getCode(language, country);
|
String locale = getCode(language, country);
|
||||||
|
if (!getTimeZoneLocalizationMap().has(locale)) {
|
||||||
|
locale = language;
|
||||||
|
}
|
||||||
if (!getTimeZoneLocalizationMap().has(locale)) {
|
if (!getTimeZoneLocalizationMap().has(locale)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,6 +48,7 @@ public abstract class TDateFormat extends TFormat {
|
||||||
public final static int TIMEZONE_FIELD = 17;
|
public final static int TIMEZONE_FIELD = 17;
|
||||||
|
|
||||||
protected TDateFormat() {
|
protected TDateFormat() {
|
||||||
|
calendar = TCalendar.getInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -96,6 +97,14 @@ public abstract class TDateFormat extends TFormat {
|
||||||
return calendar;
|
return calendar;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public TTimeZone getTimeZone() {
|
||||||
|
return calendar.getTimeZone();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTimeZone(TTimeZone timeZone) {
|
||||||
|
calendar.setTimeZone(timeZone);
|
||||||
|
}
|
||||||
|
|
||||||
public static TDateFormat getDateInstance() {
|
public static TDateFormat getDateInstance() {
|
||||||
return getDateInstance(DEFAULT);
|
return getDateInstance(DEFAULT);
|
||||||
}
|
}
|
||||||
|
|
|
@ -345,6 +345,7 @@ abstract class TDateFormatElement {
|
||||||
|
|
||||||
public static class GeneralTimezone extends TDateFormatElement {
|
public static class GeneralTimezone extends TDateFormatElement {
|
||||||
private static Map<TLocale, GeneralTimezone> cache;
|
private static Map<TLocale, GeneralTimezone> cache;
|
||||||
|
private static TrieNode idSearchTrie;
|
||||||
private TLocale locale;
|
private TLocale locale;
|
||||||
private TrieNode searchTrie;
|
private TrieNode searchTrie;
|
||||||
|
|
||||||
|
@ -370,7 +371,7 @@ abstract class TDateFormatElement {
|
||||||
if (tz.getID().startsWith("GMT")) {
|
if (tz.getID().startsWith("GMT")) {
|
||||||
int minutes = tz.getRawOffset() / 60_000;
|
int minutes = tz.getRawOffset() / 60_000;
|
||||||
buffer.append("GMT");
|
buffer.append("GMT");
|
||||||
if (minutes > 0) {
|
if (minutes >= 0) {
|
||||||
buffer.append('+');
|
buffer.append('+');
|
||||||
} else {
|
} else {
|
||||||
minutes = -minutes;
|
minutes = -minutes;
|
||||||
|
@ -399,23 +400,24 @@ abstract class TDateFormatElement {
|
||||||
if (position.getIndex() + 1 < text.length()) {
|
if (position.getIndex() + 1 < text.length()) {
|
||||||
|
|
||||||
}
|
}
|
||||||
TTimeZone tz = match(text, position);
|
TTimeZone tz = match(searchTrie, text, position);
|
||||||
|
if (tz != null) {
|
||||||
|
date.setTimeZone(tz);
|
||||||
|
} else {
|
||||||
|
prepareIdTrie();
|
||||||
|
tz = match(idSearchTrie, text, position);
|
||||||
if (tz != null) {
|
if (tz != null) {
|
||||||
date.setTimeZone(tz);
|
date.setTimeZone(tz);
|
||||||
} else {
|
} else {
|
||||||
position.setErrorIndex(position.getIndex());
|
position.setErrorIndex(position.getIndex());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseHoursMinutes(String text, TCalendar date, TParsePosition position) {
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public TTimeZone match(String text, TParsePosition position) {
|
public TTimeZone match(TrieNode node, String text, TParsePosition position) {
|
||||||
prepareTrie();
|
prepareTrie();
|
||||||
int start = position.getIndex();
|
int start = position.getIndex();
|
||||||
int index = start;
|
int index = start;
|
||||||
TrieNode node = searchTrie;
|
|
||||||
int lastMatch = start;
|
int lastMatch = start;
|
||||||
TTimeZone tz = null;
|
TTimeZone tz = null;
|
||||||
while (node.childNodes.length > 0) {
|
while (node.childNodes.length > 0) {
|
||||||
|
@ -426,7 +428,7 @@ abstract class TDateFormatElement {
|
||||||
if (index >= text.length()) {
|
if (index >= text.length()) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
int next = Arrays.binarySearch(node.chars, text.charAt(index++));
|
int next = Arrays.binarySearch(node.chars, Character.toLowerCase(text.charAt(index++)));
|
||||||
if (next < 0) {
|
if (next < 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -445,7 +447,58 @@ abstract class TDateFormatElement {
|
||||||
TTimeZone tz = TTimeZone.getTimeZone(tzId);
|
TTimeZone tz = TTimeZone.getTimeZone(tzId);
|
||||||
builder.add(tz.getDisplayName(locale), tz);
|
builder.add(tz.getDisplayName(locale), tz);
|
||||||
}
|
}
|
||||||
|
searchTrie = builder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void prepareIdTrie() {
|
||||||
|
if (idSearchTrie != null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
TrieBuilder builder = new TrieBuilder();
|
||||||
|
for (String tzId : TTimeZone.getAvailableIDs()) {
|
||||||
|
TTimeZone tz = TTimeZone.getTimeZone(tzId);
|
||||||
|
builder.add(tz.getID(), tz);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void parseHoursMinutes(String text, TCalendar date, TParsePosition position) {
|
||||||
|
int index = position.getIndex() + 3;
|
||||||
|
int sign = text.charAt(index++) == '-' ? -1 : 1;
|
||||||
|
if (index >= text.length() || !Character.isDigit(text.charAt(index))) {
|
||||||
|
position.setErrorIndex(index);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int hours = Character.digit(text.charAt(index++), 10);
|
||||||
|
if (index >= text.length()) {
|
||||||
|
position.setErrorIndex(index);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (text.charAt(index) != ':') {
|
||||||
|
if (!Character.isDigit(text.charAt(index))) {
|
||||||
|
position.setErrorIndex(index);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
hours = 10 * hours + Character.digit(text.charAt(index), 10);
|
||||||
|
}
|
||||||
|
if (index >= text.length() || text.charAt(index) != ':') {
|
||||||
|
position.setErrorIndex(index);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (index + 2 > text.length() || !Character.isDigit(text.charAt(index)) ||
|
||||||
|
!Character.isDigit(text.charAt(index + 1))) {
|
||||||
|
position.setErrorIndex(index);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int minutes = Character.digit(text.charAt(index), 10) * 10 + Character.digit(text.charAt(index), 10);
|
||||||
|
position.setIndex(index + 2);
|
||||||
|
TTimeZone tz = getStaticTimeZone(sign * hours, minutes);
|
||||||
|
date.setTimeZone(tz);
|
||||||
|
}
|
||||||
|
|
||||||
|
static TTimeZone getStaticTimeZone(int hours, int minutes) {
|
||||||
|
return TTimeZone.getTimeZone("GMT" + (hours) + ":" + (minutes / 10) + (minutes % 10));
|
||||||
}
|
}
|
||||||
|
|
||||||
static class TrieNode {
|
static class TrieNode {
|
||||||
|
@ -461,7 +514,7 @@ abstract class TDateFormatElement {
|
||||||
int index = 0;
|
int index = 0;
|
||||||
TrieNodeBuilder node = root;
|
TrieNodeBuilder node = root;
|
||||||
while (index < text.length()) {
|
while (index < text.length()) {
|
||||||
char c = text.charAt(index);
|
char c = Character.toLowerCase(text.charAt(index));
|
||||||
while (node.ch != c) {
|
while (node.ch != c) {
|
||||||
if (node.ch == '\0') {
|
if (node.ch == '\0') {
|
||||||
node.ch = c;
|
node.ch = c;
|
||||||
|
@ -478,7 +531,11 @@ abstract class TDateFormatElement {
|
||||||
node.tz = tz;
|
node.tz = tz;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TrieNode build(TrieNodeBuilder builder) {
|
public TrieNode build() {
|
||||||
|
return build(root);
|
||||||
|
}
|
||||||
|
|
||||||
|
TrieNode build(TrieNodeBuilder builder) {
|
||||||
TrieNode node = new TrieNode();
|
TrieNode node = new TrieNode();
|
||||||
node.tz = builder.tz;
|
node.tz = builder.tz;
|
||||||
List<TrieNodeBuilder> builders = new ArrayList<>();
|
List<TrieNodeBuilder> builders = new ArrayList<>();
|
||||||
|
|
|
@ -59,6 +59,7 @@ public class TSimpleDateFormat extends TDateFormat {
|
||||||
public StringBuffer format(TDate date, StringBuffer buffer, TFieldPosition field) {
|
public StringBuffer format(TDate date, StringBuffer buffer, TFieldPosition field) {
|
||||||
TCalendar calendar = new TGregorianCalendar(locale);
|
TCalendar calendar = new TGregorianCalendar(locale);
|
||||||
calendar.setTime(date);
|
calendar.setTime(date);
|
||||||
|
calendar.setTimeZone(this.calendar.getTimeZone());
|
||||||
for (TDateFormatElement element : elements) {
|
for (TDateFormatElement element : elements) {
|
||||||
element.format(calendar, buffer);
|
element.format(calendar, buffer);
|
||||||
}
|
}
|
||||||
|
@ -71,7 +72,7 @@ public class TSimpleDateFormat extends TDateFormat {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void reparsePattern() {
|
private void reparsePattern() {
|
||||||
TSimpleDatePatternParser parser = new TSimpleDatePatternParser(dateFormatSymbols);
|
TSimpleDatePatternParser parser = new TSimpleDatePatternParser(dateFormatSymbols, locale);
|
||||||
parser.parsePattern(pattern);
|
parser.parsePattern(pattern);
|
||||||
elements = parser.getElements().toArray(new TDateFormatElement[0]);
|
elements = parser.getElements().toArray(new TDateFormatElement[0]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@ package org.teavm.classlib.java.text;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import org.teavm.classlib.java.util.TCalendar;
|
import org.teavm.classlib.java.util.TCalendar;
|
||||||
|
import org.teavm.classlib.java.util.TLocale;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -25,12 +26,14 @@ import org.teavm.classlib.java.util.TCalendar;
|
||||||
*/
|
*/
|
||||||
class TSimpleDatePatternParser {
|
class TSimpleDatePatternParser {
|
||||||
private TDateFormatSymbols symbols;
|
private TDateFormatSymbols symbols;
|
||||||
|
private TLocale locale;
|
||||||
private List<TDateFormatElement> elements = new ArrayList<>();
|
private List<TDateFormatElement> elements = new ArrayList<>();
|
||||||
private int index;
|
private int index;
|
||||||
private String pattern;
|
private String pattern;
|
||||||
|
|
||||||
public TSimpleDatePatternParser(TDateFormatSymbols symbols) {
|
public TSimpleDatePatternParser(TDateFormatSymbols symbols, TLocale locale) {
|
||||||
this.symbols = symbols;
|
this.symbols = symbols;
|
||||||
|
this.locale = locale;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<TDateFormatElement> getElements() {
|
public List<TDateFormatElement> getElements() {
|
||||||
|
@ -148,6 +151,11 @@ class TSimpleDatePatternParser {
|
||||||
elements.add(new TDateFormatElement.Numeric(TCalendar.MILLISECOND, rep));
|
elements.add(new TDateFormatElement.Numeric(TCalendar.MILLISECOND, rep));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case 'z': {
|
||||||
|
parseRepetitions();
|
||||||
|
elements.add(TDateFormatElement.GeneralTimezone.get(locale));
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
if (isControl(c)) {
|
if (isControl(c)) {
|
||||||
parseRepetitions();
|
parseRepetitions();
|
||||||
|
|
|
@ -26,10 +26,13 @@ class TIANATimeZone extends TTimeZone {
|
||||||
private static final long serialVersionUID = -8196006595542230951L;
|
private static final long serialVersionUID = -8196006595542230951L;
|
||||||
private DateTimeZone underlyingZone;
|
private DateTimeZone underlyingZone;
|
||||||
private int rawOffset;
|
private int rawOffset;
|
||||||
|
private int diff;
|
||||||
|
|
||||||
public TIANATimeZone(DateTimeZone underlyingZone) {
|
public TIANATimeZone(DateTimeZone underlyingZone) {
|
||||||
super(underlyingZone.getID());
|
super(underlyingZone.getID());
|
||||||
this.underlyingZone = underlyingZone;
|
this.underlyingZone = underlyingZone;
|
||||||
|
rawOffset = underlyingZone.getStandardOffset(System.currentTimeMillis());
|
||||||
|
diff = -rawOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -43,7 +46,7 @@ class TIANATimeZone extends TTimeZone {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getOffset(long time) {
|
public int getOffset(long time) {
|
||||||
return rawOffset + underlyingZone.getOffset(time);
|
return rawOffset + diff + underlyingZone.getOffset(time);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -63,7 +66,7 @@ class TIANATimeZone extends TTimeZone {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean useDaylightTime() {
|
public boolean useDaylightTime() {
|
||||||
return underlyingZone.isFixed();
|
return !underlyingZone.isFixed();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -69,7 +69,7 @@ public final class TLocale implements TCloneable, TSerializable {
|
||||||
static {
|
static {
|
||||||
String localeName = CLDRHelper.getDefaultLocale().getValue();
|
String localeName = CLDRHelper.getDefaultLocale().getValue();
|
||||||
int countryIndex = localeName.indexOf('_');
|
int countryIndex = localeName.indexOf('_');
|
||||||
defaultLocale = new TLocale(localeName.substring(0, countryIndex), localeName.substring(countryIndex) + 1, "");
|
defaultLocale = new TLocale(localeName.substring(0, countryIndex), localeName.substring(countryIndex + 1), "");
|
||||||
}
|
}
|
||||||
|
|
||||||
private transient String countryCode;
|
private transient String countryCode;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user