Skip to content

Commit

Permalink
Code coverage (#29)
Browse files Browse the repository at this point in the history
  • Loading branch information
ethlo authored Jan 31, 2024
1 parent e5e114d commit d7c2dc9
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 12 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
[![javadoc](https://javadoc.io/badge2/com.ethlo.time/itu/javadoc.svg)](https://javadoc.io/doc/com.ethlo.time/itu/latest/com/ethlo/time/ITU.html)
[![Hex.pm](https://img.shields.io/hexpm/l/plug.svg)](LICENSE)
[![Codacy Badge](https://app.codacy.com/project/badge/Grade/598913bc1fe9405c82be73d9a4f105c8)](https://app.codacy.com/gh/ethlo/itu/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade)
[![codecov](https://codecov.io/gh/ethlo/itu/graph/badge.svg?token=V3H15LKC5V)](https://codecov.io/gh/ethlo/itu)

An extremely fast parser and formatter of specific ISO-8601 format date and date-times.

Expand Down
56 changes: 44 additions & 12 deletions src/main/java/com/ethlo/time/internal/ITUParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ public class ITUParser
static final char ZULU_UPPER = 'Z';
private static final char ZULU_LOWER = 'z';
public static final int MAX_FRACTION_DIGITS = 9;
public static final int RADIX = 10;
public static final int DIGITS_IN_NANO = 9;

private ITUParser()
{
Expand Down Expand Up @@ -165,35 +167,35 @@ public static DateTime parseLenient(final String chars, final ParseConfig parseC
// Date portion

// YEAR
final int years = parsePositiveInt(chars, offset, offset + 4);
final int years = parseYears(chars, offset);
if (4 == availableLength)
{
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 month = parsePositiveInt(chars, offset + 5, offset + 7);
final int month = parseMonth(chars, offset);
if (7 == availableLength)
{
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);
final int days = parseDays(chars, offset);
if (10 == availableLength)
{
return new DateTime(Field.DAY, years, month, days, 0, 0, 0, 0, null, 0, availableLength);
}

// HOURS
assertAllowedDateTimeSeparator(offset, chars, parseConfig);
final int hours = parsePositiveInt(chars, offset + 11, offset + 13);
final int hours = parseHours(chars, offset);

// MINUTES
assertPositionContains(Field.MINUTE, chars, offset + 13, TIME_SEPARATOR);
final int minutes = parsePositiveInt(chars, offset + 14, offset + 16);
final int minutes = parseMinutes(chars, offset);
if (availableLength == 16)
{
// Have only minutes
Expand All @@ -204,6 +206,36 @@ public static DateTime parseLenient(final String chars, final ParseConfig parseC
return handleTime(offset, parseConfig, chars, years, month, days, hours, minutes);
}

private static int parseSeconds(int offset, String chars)
{
return parsePositiveInt(chars, offset + 17, offset + 19);
}

private static int parseMinutes(String chars, int offset)
{
return parsePositiveInt(chars, offset + 14, offset + 16);
}

private static int parseHours(String chars, int offset)
{
return parsePositiveInt(chars, offset + 11, offset + 13);
}

private static int parseDays(String chars, int offset)
{
return parsePositiveInt(chars, offset + 8, offset + 10);
}

private static int parseMonth(String chars, int offset)
{
return parsePositiveInt(chars, offset + 5, offset + 7);
}

private static int parseYears(String chars, int offset)
{
return parsePositiveInt(chars, offset, offset + 4);
}

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

Expand All @@ -240,7 +272,7 @@ else if (length == 19)

private static DateTime handleSecondResolution(int offset, int year, int month, int day, int hour, int minute, String chars, TimezoneOffset timezoneOffset)
{
final int seconds = parsePositiveInt(chars, offset + 17, offset + 19);
final int seconds = parseSeconds(offset, chars);
final int charLength = Field.SECOND.getRequiredLength() + (timezoneOffset != null ? timezoneOffset.getRequiredLength() : 0);
return new DateTime(Field.SECOND, year, month, day, hour, minute, seconds, 0, timezoneOffset, 0, charLength);
}
Expand All @@ -260,24 +292,24 @@ private static DateTime handleFractionalSeconds(int offset, ParseConfig parseCon
else
{
fractionDigits++;
nanos = nanos * 10 + (c - ZERO);
nanos = nanos * RADIX + (c - ZERO);
idx++;
}
}

assertFractionDigits(chars, fractionDigits, offset + (idx - 1));

// Scale to nanos
// Scale to nanoseconds
int pos = fractionDigits;
while (pos < 9)
while (pos < DIGITS_IN_NANO)
{
nanos *= 10;
nanos *= RADIX;
pos++;
}

final TimezoneOffset timezoneOffset = parseTimezone(offset, parseConfig, chars, idx);
final int charLength = (idx + (timezoneOffset != null ? timezoneOffset.getRequiredLength() : 0)) - offset;
final int second = parsePositiveInt(chars, offset + 17, offset + 19);
final int second = parseSeconds(offset, chars);
return new DateTime(Field.NANO, year, month, day, hour, minute, second, nanos, timezoneOffset, fractionDigits, charLength);
}

Expand Down
20 changes: 20 additions & 0 deletions src/test/java/com/ethlo/time/ParsePositionTest.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,25 @@
package com.ethlo.time;

/*-
* #%L
* Internet Time Utility
* %%
* Copyright (C) 2017 - 2024 Morten Haraldsen (ethlo)
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/

import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertThrows;

Expand Down

0 comments on commit d7c2dc9

Please sign in to comment.