From 780a3a8cca23620c4d0397042cbd7ab7f9ca833d Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Mon, 18 Nov 2019 13:58:32 +0300 Subject: [PATCH] Fix parsing dates without delimiters using SimpleDateFormat --- .../java/text/TDateFormatElement.java | 16 ++++++++------ .../java/text/TSimpleDatePatternParser.java | 22 +++++++++---------- .../java/text/SimpleDateFormatTest.java | 6 +++++ 3 files changed, 26 insertions(+), 18 deletions(-) diff --git a/classlib/src/main/java/org/teavm/classlib/java/text/TDateFormatElement.java b/classlib/src/main/java/org/teavm/classlib/java/text/TDateFormatElement.java index 337e5ab77..ed7f4e83f 100644 --- a/classlib/src/main/java/org/teavm/classlib/java/text/TDateFormatElement.java +++ b/classlib/src/main/java/org/teavm/classlib/java/text/TDateFormatElement.java @@ -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) { diff --git a/classlib/src/main/java/org/teavm/classlib/java/text/TSimpleDatePatternParser.java b/classlib/src/main/java/org/teavm/classlib/java/text/TSimpleDatePatternParser.java index 809c7fda3..a173cee36 100644 --- a/classlib/src/main/java/org/teavm/classlib/java/text/TSimpleDatePatternParser.java +++ b/classlib/src/main/java/org/teavm/classlib/java/text/TSimpleDatePatternParser.java @@ -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': { diff --git a/tests/src/test/java/org/teavm/classlib/java/text/SimpleDateFormatTest.java b/tests/src/test/java/org/teavm/classlib/java/text/SimpleDateFormatTest.java index 5de92eba7..77f791254 100644 --- a/tests/src/test/java/org/teavm/classlib/java/text/SimpleDateFormatTest.java +++ b/tests/src/test/java/org/teavm/classlib/java/text/SimpleDateFormatTest.java @@ -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"))); + } }