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

View File

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

View File

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