Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 66 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@

An extremely fast parser and formatter of ISO-8601 date-times. Handle
[RFC-3339 Timestamps](https://www.ietf.org/rfc/rfc3339.txt) and W3C [Date and Time Formats](https://www.w3.org/TR/NOTE-datetime) with ease!
Now also supports a subset of duration strings!

## Features

* Low ceremony, high productivity with a very easy to use API.
Low ceremony, high productivity with a very easy to use API.
* [Well-documented](https://javadoc.io/doc/com.ethlo.time/itu/latest/com/ethlo/time/ITU.html).
* Aim for 100% specification compliance.
* Handling leap-seconds.
Expand All @@ -34,7 +35,7 @@ Add dependency
<dependency>
<groupId>com.ethlo.time</groupId>
<artifactId>itu</artifactId>
<version>1.13.0</version>
<version>1.14.0-SNAPSHOT</version>
</dependency>
```

Expand Down Expand Up @@ -240,6 +241,69 @@ try
```


## Duration Parser

Parses a duration string, a strict subset of ISO 8601 durations.

### Supported Units
This method supports time-based durations with the following units:

- **Weeks** (`W`)
- **Days** (`D`)
- **Hours** (`H`)
- **Minutes** (`M`)
- **Seconds** (`S`), including fractional seconds up to nanosecond precision

#### Not Allowed Units
The following units are **explicitly not allowed** to avoid ambiguity:

- **Years** (`Y`)
- **Months** (`M` in the date section)

### Negative Durations
Negative durations are supported and must be prefixed with `-P`, as specified in ISO 8601.
The parsed duration will be represented using:

- A **`long`** for total seconds
- An **`int`** for nanosecond precision

The nanosecond component is always positive, with the sign absorbed by the seconds field,
following Java and ISO 8601 conventions.

### Examples

#### Valid Input
- `P2DT3H4M5.678901234S` → 2 days, 3 hours, 4 minutes, 5.678901234 seconds
- `PT5M30S` → 5 minutes, 30 seconds
- `-PT2.5S` → Negative 2.5 seconds
- `-P1D` → Negative 1 day

#### Invalid Input
- `P1Y2M3DT4H` → Contains `Y` and `M`
- `PT` → Missing time values after `T`
- `P-1D` → Incorrect negative placement



#### simple
<smaller style="float:right;">[source &raquo;](src/test/java/samples/durationparsing/DurationParsingSamples.java#L32C5-L37C6)</smaller>


```java
final Duration duration = ITU.parseDuration("P4W");
assertThat(duration.getSeconds()).isEqualTo(2_419_200L);
```

#### fullNotNormalizedToNormalized
<smaller style="float:right;">[source &raquo;](src/test/java/samples/durationparsing/DurationParsingSamples.java#L39C5-L44C6)</smaller>


```java
final Duration duration = ITU.parseDuration("P4W10DT28H122M1.123456S");
assertThat(duration.normalized()).isEqualTo("P5W4DT6H2M1.123456S");
```


## Q & A

### Why this little project?
Expand Down
17 changes: 12 additions & 5 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ limitations under the License.
<groupId>com.ethlo.time</groupId>
<packaging>bundle</packaging>
<artifactId>itu</artifactId>
<version>1.13.0</version>
<version>1.14.0-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 Expand Up @@ -51,19 +51,25 @@ limitations under the License.
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.10.1</version>
<version>5.9.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-params</artifactId>
<version>5.10.1</version>
<version>5.9.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.16.1</version>
<version>2.18.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.code-intelligence</groupId>
<artifactId>jazzer-junit</artifactId>
<version>0.24.0</version>
<scope>test</scope>
</dependency>
<dependency>
Expand Down Expand Up @@ -131,7 +137,7 @@ limitations under the License.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.2.3</version>
<version>3.5.2</version>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
Expand Down Expand Up @@ -330,6 +336,7 @@ limitations under the License.
<source>src/test/java/samples/parsing</source>
<source>src/test/java/samples/formatting</source>
<source>src/test/java/samples/leapsecond</source>
<source>src/test/java/samples/durationparsing</source>
</sources>
</configuration>
<executions>
Expand Down
Loading
Loading