Skip to content

Commit

Permalink
Adding helper methods handling different levels of date-time granularity
Browse files Browse the repository at this point in the history
  • Loading branch information
ethlo committed Mar 9, 2022
1 parent 0c24dda commit 1c7b379
Show file tree
Hide file tree
Showing 28 changed files with 542 additions and 59 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>com.ethlo.time</groupId>
<artifactId>itu</artifactId>
<version>1.6.0</version>
<version>1.6.1-SNAPSHOT</version>
<name>Internet Time Utility</name>
<description>Extremely fast date/time parser and formatter - RFC 3339 (ISO 8601 profile) and W3C format
</description>
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/com/ethlo/time/AbstractRfc3339.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@
* 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.
Expand Down
34 changes: 20 additions & 14 deletions src/main/java/com/ethlo/time/DateTime.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.time.YearMonth;
import java.util.Optional;

/**
* Holder class for parsed data. The {@link #getField()} contains the last found field, like MONTH, MINUTE, SECOND.
Expand All @@ -47,22 +48,13 @@ public DateTime(final Field field, final int year, final int month, final int da
this.year = year;
this.month = assertSize(month, 1, 12, Field.MONTH);
this.day = assertSize(day, 1, 31, Field.DAY);
this.hour = assertSize(hour, 0, 24, Field.HOUR);
this.minute = assertSize(minute, 0, 60, Field.MINUTE);
this.hour = assertSize(hour, 0, 23, Field.HOUR);
this.minute = assertSize(minute, 0, 59, Field.MINUTE);
this.second = assertSize(second, 0, 60, Field.SECOND);
this.nano = assertSize(nano, 0, 999_999_999, Field.NANO);
this.offset = offset;
}

private int assertSize(int value, int min, int max, Field field)
{
if (value > max)
{
throw new DateTimeException("Field " + field.name() + " out of bounds. Expected " + min + "-" + max + ", got " + value);
}
return value;
}

public static DateTime of(int year, int month, int day, int hour, int minute, int second, int nanos, TimezoneOffset offset)
{
return new DateTime(Field.SECOND, year, month, day, hour, minute, second, nanos, offset);
Expand Down Expand Up @@ -93,6 +85,20 @@ public static DateTime of(OffsetDateTime dateTime)
return DateTime.of(dateTime.getYear(), dateTime.getMonthValue(), dateTime.getDayOfMonth(), dateTime.getHour(), dateTime.getMinute(), dateTime.getSecond(), dateTime.getNano(), TimezoneOffset.of(dateTime.getOffset()));
}

private int assertSize(int value, int min, int max, Field field)
{
if (value > max)
{
throw new DateTimeException("Field " + field.name() + " out of bounds. Expected " + min + "-" + max + ", got " + value);
}
return value;
}

public boolean includesGranularity(Field field)
{
return field.ordinal() <= this.field.ordinal();
}

public int getYear()
{
return year;
Expand Down Expand Up @@ -133,9 +139,9 @@ public long getNano()
*
* @return the time offset, if available
*/
public TimezoneOffset getOffset()
public Optional<TimezoneOffset> getOffset()
{
return offset;
return Optional.ofNullable(offset);
}

/**
Expand Down Expand Up @@ -210,7 +216,7 @@ public Field getField()

public DateTime assertMinGranularity(Field field)
{
if (this.field.ordinal() < field.ordinal())
if (!includesGranularity(field))
{
throw new DateTimeException("No " + field.name() + " field found");
}
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/com/ethlo/time/DefaultLeapSecondHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@
* 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.
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/com/ethlo/time/EthloITU.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@
import java.util.Arrays;
import java.util.Date;

import com.ethlo.time.jdk.JdkRfc3339;

public class EthloITU extends AbstractRfc3339 implements W3cDateTimeUtil
{
private static final EthloITU instance = new EthloITU();
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/com/ethlo/time/Field.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@
* 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.
Expand Down
123 changes: 123 additions & 0 deletions src/main/java/com/ethlo/time/ITU.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,11 @@
*/

import java.time.DateTimeException;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.time.Year;
import java.time.YearMonth;

public class ITU
{
Expand Down Expand Up @@ -83,4 +87,123 @@ public static String formatUtcNano(OffsetDateTime date)
{
return delegate.formatUtcNano(date);
}

public static void parse(String text, TemporalConsumer temporalConsumer)
{
final DateTime dateTime = delegate.parse(text);
if (dateTime.includesGranularity(Field.MINUTE))
{
if (dateTime.getOffset().isPresent())
{
temporalConsumer.handle(dateTime.toOffsetDatetime());
}
else
{
temporalConsumer.handle(dateTime.toLocalDatetime());
}
}
else if (dateTime.includesGranularity(Field.DAY))
{
temporalConsumer.handle(dateTime.toLocalDate());
}
else if (dateTime.includesGranularity(Field.MONTH))
{
temporalConsumer.handle(dateTime.toYearMonth());
}
else
{
temporalConsumer.handle(Year.of(dateTime.getYear()));
}
}

public static <T> T parse(String text, TemporalHandler<T> temporalHandler)
{
final DateTime dateTime = delegate.parse(text);
if (dateTime.includesGranularity(Field.MINUTE))
{
if (dateTime.getOffset().isPresent())
{
return temporalHandler.handle(dateTime.toOffsetDatetime());
}
else
{
return temporalHandler.handle(dateTime.toLocalDatetime());
}
}
else if (dateTime.includesGranularity(Field.DAY))
{
return temporalHandler.handle(dateTime.toLocalDate());
}
else if (dateTime.includesGranularity(Field.MONTH))
{
return temporalHandler.handle(dateTime.toYearMonth());
}
else
{
return temporalHandler.handle(Year.of(dateTime.getYear()));
}
}

public static boolean isValid(final String text, TemporalType... types)
{
try
{
return ITU.parse(text, new TemporalHandler<Boolean>()
{
@Override
public Boolean handle(final LocalDate localDate)
{
return isAllowed(TemporalType.LOCAL_DATE, types);
}

@Override
public Boolean handle(final OffsetDateTime offsetDateTime)
{
return isAllowed(TemporalType.OFFSET_DATE_TIME, types);
}

@Override
public Boolean handle(final LocalDateTime localDateTime)
{
return isAllowed(TemporalType.LOCAL_DATE_TIME, types);
}

@Override
public Boolean handle(final YearMonth yearMonth)
{
return isAllowed(TemporalType.YEAR_MONTH, types);
}

@Override
public Boolean handle(final Year year)
{
return isAllowed(TemporalType.YEAR, types);
}
});
}
catch (DateTimeException exc)
{
return false;
}
}

private static void assertIsAllowed(TemporalType needle, TemporalType... allowed)
{
if (!isAllowed(needle, allowed))
{
throw new DateTimeException("Is not a valid representation of " + needle);
}
}

private static boolean isAllowed(TemporalType needle, TemporalType... allowed)
{
for (TemporalType t : allowed)
{
if (t.equals(needle))
{
return true;
}
}
return false;
}
}
4 changes: 2 additions & 2 deletions src/main/java/com/ethlo/time/LeapSecondException.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@
* 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.
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/com/ethlo/time/LeapSecondHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@
* 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.
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/com/ethlo/time/Rfc3339.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@
* 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.
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/com/ethlo/time/Rfc3339Formatter.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@
* 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.
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/com/ethlo/time/Rfc3339Parser.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@
* 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.
Expand Down
61 changes: 61 additions & 0 deletions src/main/java/com/ethlo/time/TemporalConsumer.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package com.ethlo.time;

/*-
* #%L
* Internet Time Utility
* %%
* Copyright (C) 2017 - 2022 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 java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.time.Year;
import java.time.YearMonth;
import java.time.temporal.Temporal;

public interface TemporalConsumer
{
default void handle(LocalDateTime localDateTime)
{
fallback(localDateTime);
}

default void handle(LocalDate localDate)
{
fallback(localDate);
}

default void handle(YearMonth yearMonth)
{
fallback(yearMonth);
}

default void handle(Year year)
{
fallback(year);
}

default void handle(OffsetDateTime offsetDateTime)
{
fallback(offsetDateTime);
}

default void fallback(final Temporal temporal)
{
throw new UnsupportedOperationException("Unhandled type " + temporal.getClass());
}
}
Loading

0 comments on commit 1c7b379

Please sign in to comment.