Skip to content

Commit

Permalink
Fix issue where parsing leniently with ParsePosition and non-zero off…
Browse files Browse the repository at this point in the history
…set would return wrong position after parsing.
  • Loading branch information
Morten Haraldsen committed Jan 31, 2024
1 parent ef10d59 commit 891e648
Show file tree
Hide file tree
Showing 3 changed files with 218 additions and 136 deletions.
16 changes: 8 additions & 8 deletions src/main/java/com/ethlo/time/internal/ITUParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -168,23 +168,23 @@ public static DateTime parseLenient(final String chars, final ParseConfig parseC
final int years = parsePositiveInt(chars, offset, offset + 4);
if (4 == availableLength)
{
return DateTime.ofYear(years);
return new DateTime(Field.YEAR, years, 0, 0, 0, 0, 0, 0, null, 0, availableLength);
}

// MONTH
assertPositionContains(Field.MONTH, chars, offset + 4, DATE_SEPARATOR);
final int months = parsePositiveInt(chars, offset + 5, offset + 7);
final int month = parsePositiveInt(chars, offset + 5, offset + 7);
if (7 == availableLength)
{
return DateTime.ofYearMonth(years, months);
return new DateTime(Field.MONTH, years, month, 0, 0, 0, 0, 0, null, 0, availableLength);
}

// DAY
assertPositionContains(Field.DAY, chars, offset + 7, DATE_SEPARATOR);
final int days = parsePositiveInt(chars, offset + 8, offset + 10);
if (10 == availableLength)
{
return DateTime.ofDate(years, months, days);
return new DateTime(Field.DAY, years, month, days, 0, 0, 0, 0, null, 0, availableLength);
}

// HOURS
Expand All @@ -197,11 +197,11 @@ public static DateTime parseLenient(final String chars, final ParseConfig parseC
if (availableLength == 16)
{
// Have only minutes
return DateTime.of(years, months, days, hours, minutes, null);
return new DateTime(Field.MINUTE, years, month, days, hours, minutes, 0, 0, null, 0, 16);
}

// SECONDS or TIMEZONE
return handleTime(offset, parseConfig, chars, years, months, days, hours, minutes);
return handleTime(offset, parseConfig, chars, years, month, days, hours, minutes);
}

private static DateTime handleTimeResolution(final int offset, ParseConfig parseConfig, int year, int month, int day, int hour, int minute, String chars)
Expand Down Expand Up @@ -229,10 +229,10 @@ else if (c == PLUS || c == MINUS)
throw raiseUnexpectedCharacter(chars, offset + 19);
}
}
else if (length == offset + 19)
else if (length == 19)
{
final int seconds = parsePositiveInt(chars, offset + 17, offset + 19);
return DateTime.of(year, month, day, hour, minute, seconds, null);
return new DateTime(Field.SECOND, year, month, day, hour, minute, seconds, 0, null, 0, length);
}

throw raiseUnexpectedEndOfText(chars, offset + 16);
Expand Down
128 changes: 0 additions & 128 deletions src/test/java/com/ethlo/time/ITUTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -336,134 +336,6 @@ void testParseCommaFractionSeparator()
assertThat(pos.getIndex()).isEqualTo(23);
}

@Test
void testParseUnparseable()
{
final ParsePosition pos = new ParsePosition(0);
assertThrows(DateTimeParseException.class, () -> ITU.parseLenient("1999-11-22|11:22:1", ParseConfig.DEFAULT, pos));
assertThat(pos.getErrorIndex()).isEqualTo(10);
assertThat(pos.getIndex()).isEqualTo(10);
}

@Test
void testParsePosition()
{
final ParsePosition pos = new ParsePosition(10);
ITU.parseLenient("123456789,1999-11-22T11:22:17Z,22222222222", ParseConfig.STRICT, pos);
assertThat(pos.getIndex()).isEqualTo(30);
}

@Test
void testParsePositionDateTime()
{
final ParsePosition pos = new ParsePosition(0);
ITU.parseDateTime("1999-11-22T11:22:17.191Z", pos);
assertThat(pos.getIndex()).isEqualTo(24);
assertThat(pos.getErrorIndex()).isEqualTo(-1);
}

@Test
void testParsePositionDateTimeInvalid()
{
final ParsePosition pos = new ParsePosition(0);
assertThrows(DateTimeException.class, () -> ITU.parseDateTime("1999-11-22X11:22:17.191Z", pos));
assertThat(pos.getIndex()).isEqualTo(10);
assertThat(pos.getErrorIndex()).isEqualTo(10);
}

@Test
void testParsePositionNotZeroDateTimeValidWithMillis()
{
final ParsePosition pos = new ParsePosition(8);
ITU.parseDateTime("1234567,1999-11-22T11:22:17.191Z,some-other-data", pos);
assertThat(pos.getIndex()).isEqualTo(32);
assertThat(pos.getErrorIndex()).isEqualTo(-1);
}

@Test
void testParsePositionNotZeroDateTimeValidZeroOffsetWithMillis()
{
final ParsePosition pos = new ParsePosition(8);
ITU.parseDateTime("1234567,1999-11-22T11:22:17.191+00:00,some-other-data", pos);
assertThat(pos.getIndex()).isEqualTo(37);
assertThat(pos.getErrorIndex()).isEqualTo(-1);
}

@Test
void testParsePositionNotZeroDateTimeValidNonZuluOffsetWithMillis()
{
final ParsePosition pos = new ParsePosition(8);
ITU.parseDateTime("1234567,1999-11-22T11:22:17.191+05:00,some-other-data", pos);
assertThat(pos.getIndex()).isEqualTo(37);
assertThat(pos.getErrorIndex()).isEqualTo(-1);
}

@Test
void testParsePositionNotZeroDateTimeValidNonZuluOffsetWithSecond()
{
final ParsePosition pos = new ParsePosition(8);
ITU.parseDateTime("1234567,1999-11-22T11:22:17+05:00,some-other-data", pos);
assertThat(pos.getIndex()).isEqualTo(33);
assertThat(pos.getErrorIndex()).isEqualTo(-1);
}

@Test
void testParsePositionNotZeroDateTimeValidNonZuluOffsetWithMinute()
{
final ParsePosition pos = new ParsePosition(8);
ITU.parseDateTime("1234567,1999-11-22T11:22+05:00,some-other-data", pos);
assertThat(pos.getIndex()).isEqualTo(30);
assertThat(pos.getErrorIndex()).isEqualTo(-1);
}

@Test
void testParsePositionRfc3339Zulu()
{
final ParsePosition pos = new ParsePosition(8);
ITU.parseDateTime("1234567,1999-11-22T11:22:00Z,some-other-data", pos);
assertThat(pos.getIndex()).isEqualTo(28);
assertThat(pos.getErrorIndex()).isEqualTo(-1);
}

@Test
void testParsePositionRfc3339Offset()
{
final ParsePosition pos = new ParsePosition(10);
final String input = "some-data,1999-11-22T11:22:00+05:30,some-other-data";
ITU.parseDateTime(input, pos);
assertThat(pos.getIndex()).isEqualTo(35);
assertThat(pos.getErrorIndex()).isEqualTo(-1);
assertThat(input.substring(pos.getIndex())).isEqualTo(",some-other-data");
}

@Test
void testParsePositionSubsequent()
{
final ParsePosition pos = new ParsePosition(4);
final String input = "abc,2004-11-21T00:00Z1999-11-22T11:22+05:00,some-other-data";

ITU.parseDateTime(input, pos);
assertThat(pos.getIndex()).isEqualTo(21);
assertThat(pos.getErrorIndex()).isEqualTo(-1);

ITU.parseDateTime(input, pos);
assertThat(pos.getIndex()).isEqualTo(43);
assertThat(pos.getErrorIndex()).isEqualTo(-1);
}

@Test
void testParseOutOfBoundsPosition()
{
final ParsePosition pos = new ParsePosition(40);
assertThrows(IndexOutOfBoundsException.class, () -> ITU.parseDateTime("123", pos));
}

@Test
void testParseOutOfBoundsPositionNegative()
{
final ParsePosition pos = new ParsePosition(-3);
assertThrows(IndexOutOfBoundsException.class, () -> ITU.parseDateTime("123", pos));
}

@Test
void testParseWithStrictConfig()
Expand Down
Loading

0 comments on commit 891e648

Please sign in to comment.