add support for ISO-like date formats
Recommind is using a pseudo ISO date format for their log files. It uses a comma instead of a dot for the second to milli second separator and it does not add a timezone. Dates without timezone are assumed to be UTC.
This commit is contained in:
@@ -39,7 +39,8 @@ public class FastISODateParser {
|
||||
final int nanos = nanosAndCharsRead[0];
|
||||
final int offsetTimezone = 19 + nanosAndCharsRead[1];
|
||||
|
||||
final ZoneOffset offset = date.charAt(offsetTimezone) == 'Z' ? ZoneOffset.UTC
|
||||
final ZoneOffset offset = offsetTimezone >= date.length() || date.charAt(offsetTimezone) == 'Z'
|
||||
? ZoneOffset.UTC
|
||||
: parseZone(date.subSequence(offsetTimezone, date.length()));
|
||||
return OffsetDateTime.of(year, month, dayOfMonth, hour, minute, second, nanos, offset);
|
||||
} catch (final RuntimeException e) {
|
||||
@@ -61,7 +62,7 @@ public class FastISODateParser {
|
||||
final long nanos = nanosAndCharsRead[0];
|
||||
final int offsetTimezone = 19 + nanosAndCharsRead[1];
|
||||
|
||||
final long zoneOffsetMillis = date.charAt(offsetTimezone) == 'Z' ? 0
|
||||
final long zoneOffsetMillis = offsetTimezone >= date.length() || date.charAt(offsetTimezone) == 'Z' ? 0
|
||||
: parseZoneToMillis(date.subSequence(offsetTimezone, date.length()));
|
||||
|
||||
final int epochMilliMonthOffsetKey = (int) (year * 12 + month - 1);
|
||||
@@ -116,21 +117,28 @@ public class FastISODateParser {
|
||||
|
||||
private int[] parseMilliseconds(final String date, final int start) {
|
||||
int result = 0;
|
||||
int readChars = 0;
|
||||
int i = start;
|
||||
|
||||
char c = date.charAt(i);
|
||||
if (c != '.' && c != ',') {
|
||||
return new int[] { result, readChars };
|
||||
}
|
||||
i++;
|
||||
readChars++;
|
||||
|
||||
while (i < date.length()) {
|
||||
final char c = date.charAt(i);
|
||||
c = date.charAt(i);
|
||||
i++;
|
||||
if (c == '.') {
|
||||
continue;
|
||||
}
|
||||
if (c < '0' || c > '9') {
|
||||
i--;
|
||||
break;
|
||||
}
|
||||
result = result * 10 + (c - '0');
|
||||
readChars++;
|
||||
}
|
||||
final int readChars = i - start - 1;
|
||||
|
||||
while (i <= start + 10) {
|
||||
while (i <= start + 9) {
|
||||
result *= 10;
|
||||
i++;
|
||||
}
|
||||
|
||||
@@ -68,6 +68,34 @@ public class FastISODateParserTest {
|
||||
Assert.assertEquals(actualDate, expectedDate.toInstant().toEpochMilli());
|
||||
}
|
||||
|
||||
@DataProvider(name = "providerPseudoISODate")
|
||||
public Object[][] providerPseudoISODate() {
|
||||
return new Object[][] { //
|
||||
{ "2018-11-18T14:42:49,123Z", "2018-11-18T14:42:49.123Z" }, // with comman instead of dot
|
||||
{ "2018-11-18T14:42:49,123+12:34", "2018-11-18T14:42:49.123+12:34" }, // with comman instead of dot
|
||||
{ "2018-11-18T14:42:49.123", "2018-11-18T14:42:49.123Z" }, // without timezone
|
||||
{ "2018-11-18T14:42:49,123", "2018-11-18T14:42:49.123Z" }, // with command, without timezone
|
||||
};
|
||||
}
|
||||
|
||||
@Test(dataProvider = "providerPseudoISODate")
|
||||
public void testParsePseudoISODate(final String date, final String expectedDate) {
|
||||
|
||||
final OffsetDateTime actualDate = new FastISODateParser().parse(date);
|
||||
|
||||
final OffsetDateTime expected = OffsetDateTime.from(DateTimeFormatter.ISO_DATE_TIME.parse(expectedDate));
|
||||
Assert.assertEquals(actualDate, expected);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "providerPseudoISODate")
|
||||
public void testParsePseudoISODateAsEpochMilli(final String date, final String expectedDate) {
|
||||
|
||||
final long actualDate = new FastISODateParser().parseAsEpochMilli(date);
|
||||
|
||||
final OffsetDateTime expected = OffsetDateTime.from(DateTimeFormatter.ISO_DATE_TIME.parse(expectedDate));
|
||||
Assert.assertEquals(actualDate, expected.toInstant().toEpochMilli());
|
||||
}
|
||||
|
||||
@DataProvider(name = "providerParseInvalidDate")
|
||||
public Object[][] providerParseInvalidDate() {
|
||||
return new Object[][] { //
|
||||
|
||||
Reference in New Issue
Block a user