Fix parsing dates without delimiters using SimpleDateFormat

This commit is contained in:
Alexey Andreev 2019-11-18 13:58:32 +03:00
parent 6a196c2f32
commit 780a3a8cca
3 changed files with 26 additions and 18 deletions

View File

@ -17,7 +17,7 @@ package org.teavm.classlib.java.text;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Comparator;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -239,10 +239,12 @@ abstract class TDateFormatElement {
public static class Numeric extends TDateFormatElement { public static class Numeric extends TDateFormatElement {
private int field; private int field;
private int length; private int length;
private int maxLength;
public Numeric(int field, int length) { public Numeric(int field, int length, int maxLength) {
this.field = field; this.field = field;
this.length = length; this.length = length;
this.maxLength = Math.max(length, maxLength);
} }
@Override @Override
@ -260,7 +262,7 @@ abstract class TDateFormatElement {
int num = 0; int num = 0;
int i = 0; int i = 0;
int pos = position.getIndex(); int pos = position.getIndex();
while (pos < text.length()) { while (pos < text.length() && i < maxLength) {
char c = text.charAt(pos); char c = text.charAt(pos);
if (c >= '0' && c <= '9') { if (c >= '0' && c <= '9') {
num = num * 10 + (c - '0'); num = num * 10 + (c - '0');
@ -306,7 +308,7 @@ abstract class TDateFormatElement {
public static class NumericMonth extends Numeric { public static class NumericMonth extends Numeric {
public NumericMonth(int length) { public NumericMonth(int length) {
super(TCalendar.MONTH, length); super(TCalendar.MONTH, length, 2);
} }
@Override @Override
@ -322,7 +324,7 @@ abstract class TDateFormatElement {
public static class NumericWeekday extends Numeric { public static class NumericWeekday extends Numeric {
public NumericWeekday(int length) { public NumericWeekday(int length) {
super(TCalendar.DAY_OF_WEEK, length); super(TCalendar.DAY_OF_WEEK, length, 1);
} }
@Override @Override
@ -340,7 +342,7 @@ abstract class TDateFormatElement {
private int limit; private int limit;
public NumericHour(int field, int length, int limit) { public NumericHour(int field, int length, int limit) {
super(field, length); super(field, length, 2);
this.limit = limit; this.limit = limit;
} }
@ -856,7 +858,7 @@ abstract class TDateFormatElement {
builders.add(tmp); builders.add(tmp);
tmp = tmp.sibling; tmp = tmp.sibling;
} }
Collections.sort(builders, (o1, o2) -> Character.compare(o1.ch, o2.ch)); builders.sort(Comparator.comparingInt(o -> o.ch));
node.chars = new char[builders.size()]; node.chars = new char[builders.size()];
node.childNodes = new TrieNode[builders.size()]; node.childNodes = new TrieNode[builders.size()];
for (int i = 0; i < node.chars.length; ++i) { for (int i = 0; i < node.chars.length; ++i) {

View File

@ -57,7 +57,7 @@ class TSimpleDatePatternParser {
if (rep == 2) { if (rep == 2) {
elements.add(new TDateFormatElement.Year(TCalendar.YEAR)); elements.add(new TDateFormatElement.Year(TCalendar.YEAR));
} else { } else {
elements.add(new TDateFormatElement.Numeric(TCalendar.YEAR, rep)); elements.add(new TDateFormatElement.Numeric(TCalendar.YEAR, rep, 8));
} }
break; break;
} }
@ -73,27 +73,27 @@ class TSimpleDatePatternParser {
} }
case 'w': { case 'w': {
int rep = parseRepetitions(); int rep = parseRepetitions();
elements.add(new TDateFormatElement.Numeric(TCalendar.WEEK_OF_YEAR, rep)); elements.add(new TDateFormatElement.Numeric(TCalendar.WEEK_OF_YEAR, rep, 2));
break; break;
} }
case 'W': { case 'W': {
int rep = parseRepetitions(); int rep = parseRepetitions();
elements.add(new TDateFormatElement.Numeric(TCalendar.WEEK_OF_MONTH, rep)); elements.add(new TDateFormatElement.Numeric(TCalendar.WEEK_OF_MONTH, rep, 1));
break; break;
} }
case 'D': { case 'D': {
int rep = parseRepetitions(); int rep = parseRepetitions();
elements.add(new TDateFormatElement.Numeric(TCalendar.DAY_OF_YEAR, rep)); elements.add(new TDateFormatElement.Numeric(TCalendar.DAY_OF_YEAR, rep, 3));
break; break;
} }
case 'd': { case 'd': {
int rep = parseRepetitions(); int rep = parseRepetitions();
elements.add(new TDateFormatElement.Numeric(TCalendar.DAY_OF_MONTH, rep)); elements.add(new TDateFormatElement.Numeric(TCalendar.DAY_OF_MONTH, rep, 2));
break; break;
} }
case 'F': { case 'F': {
int rep = parseRepetitions(); int rep = parseRepetitions();
elements.add(new TDateFormatElement.Numeric(TCalendar.DAY_OF_WEEK_IN_MONTH, rep)); elements.add(new TDateFormatElement.Numeric(TCalendar.DAY_OF_WEEK_IN_MONTH, rep, 2));
break; break;
} }
case 'E': case 'E':
@ -114,7 +114,7 @@ class TSimpleDatePatternParser {
} }
case 'H': { case 'H': {
int rep = parseRepetitions(); int rep = parseRepetitions();
elements.add(new TDateFormatElement.Numeric(TCalendar.HOUR_OF_DAY, rep)); elements.add(new TDateFormatElement.Numeric(TCalendar.HOUR_OF_DAY, rep, 2));
break; break;
} }
case 'k': { case 'k': {
@ -124,7 +124,7 @@ class TSimpleDatePatternParser {
} }
case 'K': { case 'K': {
int rep = parseRepetitions(); int rep = parseRepetitions();
elements.add(new TDateFormatElement.Numeric(TCalendar.HOUR, rep)); elements.add(new TDateFormatElement.Numeric(TCalendar.HOUR, rep, 2));
break; break;
} }
case 'h': { case 'h': {
@ -134,17 +134,17 @@ class TSimpleDatePatternParser {
} }
case 'm': { case 'm': {
int rep = parseRepetitions(); int rep = parseRepetitions();
elements.add(new TDateFormatElement.Numeric(TCalendar.MINUTE, rep)); elements.add(new TDateFormatElement.Numeric(TCalendar.MINUTE, rep, 2));
break; break;
} }
case 's': { case 's': {
int rep = parseRepetitions(); int rep = parseRepetitions();
elements.add(new TDateFormatElement.Numeric(TCalendar.SECOND, rep)); elements.add(new TDateFormatElement.Numeric(TCalendar.SECOND, rep, 2));
break; break;
} }
case 'S': { case 'S': {
int rep = parseRepetitions(); int rep = parseRepetitions();
elements.add(new TDateFormatElement.Numeric(TCalendar.MILLISECOND, rep)); elements.add(new TDateFormatElement.Numeric(TCalendar.MILLISECOND, rep, 3));
break; break;
} }
case 'z': { case 'z': {

View File

@ -159,4 +159,10 @@ public class SimpleDateFormatTest {
calendar.setTime(date); calendar.setTime(date);
return calendar.getTimeInMillis(); return calendar.getTimeInMillis();
} }
@Test
public void fieldsParsedWithoutDelimiters() throws ParseException {
SimpleDateFormat format = new SimpleDateFormat("yyMMddHHmm", Locale.ENGLISH);
assertEquals(1403602380000L, getTimeWithoutZoneOffset(format.parse("1406240933")));
}
} }