Skip to content

Commit 96d3b25

Browse files
committed
Simplified toString() for duration
Previously it normalized duration in order to expose a more human-friendly string. For example, 7 days would become a week, 12 months would become a year. It seems nice but might create a false impression that it is possible to retrieve weeks and years from an `IsoDuration` object. However, it only supports months, days, seconds and nanoseconds. Also, other drivers do not normalize durations. This commit makes `IsoDuration#toString()` simply concatenate all values into a string as is. Resulting string will only contain months, days, seconds and nanoseconds. Zero values are not filtered out. So returned ISO strings represent exactly same durations but in different format.
1 parent bccc234 commit 96d3b25

File tree

2 files changed

+11
-68
lines changed

2 files changed

+11
-68
lines changed

driver/src/main/java/org/neo4j/driver/internal/InternalIsoDuration.java

Lines changed: 1 addition & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,6 @@
3838
public class InternalIsoDuration implements IsoDuration
3939
{
4040
private static final List<TemporalUnit> SUPPORTED_UNITS = unmodifiableList( asList( MONTHS, DAYS, SECONDS, NANOS ) );
41-
private static final InternalIsoDuration ZERO = new InternalIsoDuration( 0, 0, 0, 0 );
42-
public static final long NANOS_PER_SECOND = 1_000_000_000L;
4341

4442
private final long months;
4543
private final long days;
@@ -195,65 +193,6 @@ public int hashCode()
195193
@Override
196194
public String toString()
197195
{
198-
// print the duration in iso standard format.
199-
if ( this.equals( ZERO ) )
200-
{
201-
return "PT0S"; // no need to allocate a string builder if we know the result
202-
}
203-
StringBuilder str = new StringBuilder().append( "P" );
204-
append( str, months / 12, 'Y' );
205-
append( str, months % 12, 'M' );
206-
append( str, days / 7, 'W' );
207-
append( str, days % 7, 'D' );
208-
if ( seconds != 0 || nanoseconds != 0 )
209-
{
210-
str.append( 'T' );
211-
long s = seconds % 3600;
212-
append( str, seconds / 3600, 'H' );
213-
append( str, s / 60, 'M' );
214-
s %= 60;
215-
if ( s != 0 )
216-
{
217-
str.append( s );
218-
if ( nanoseconds != 0 )
219-
{
220-
nanos( str );
221-
}
222-
str.append( 'S' );
223-
}
224-
else if ( nanoseconds != 0 )
225-
{
226-
if ( nanoseconds < 0 )
227-
{
228-
str.append( '-' );
229-
}
230-
str.append( '0' );
231-
nanos( str );
232-
str.append( 'S' );
233-
}
234-
}
235-
if ( str.length() == 1 )
236-
{ // this was all zeros (but not ZERO for some reason), ensure well formed output:
237-
str.append( "T0S" );
238-
}
239-
return str.toString();
240-
}
241-
242-
private static void append( StringBuilder str, long quantity, char unit )
243-
{
244-
if ( quantity != 0 )
245-
{
246-
str.append( quantity ).append( unit );
247-
}
248-
}
249-
250-
private void nanos( StringBuilder str )
251-
{
252-
str.append( '.' );
253-
int n = nanoseconds < 0 ? -nanoseconds : nanoseconds;
254-
for ( int mod = (int)NANOS_PER_SECOND; mod > 1 && n > 0; n %= mod )
255-
{
256-
str.append( n / (mod /= 10) );
257-
}
196+
return String.format( "P%sM%sDT%s.%sS", months, days, seconds, String.format( "%09d", nanoseconds ) );
258197
}
259198
}

driver/src/test/java/org/neo4j/driver/internal/InternalIsoDurationTest.java

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -156,13 +156,17 @@ public void shouldCreateFromDuration()
156156
@Test
157157
public void toStringShouldPrintInIsoStandardFormat() throws Throwable
158158
{
159-
assertThat( new InternalIsoDuration( 0, 0, 0, 0 ).toString(), equalTo( "PT0S" ) );
160-
assertThat( new InternalIsoDuration( Period.parse( "P356D" ) ).toString(), equalTo( "P50W6D" ) );
161-
assertThat( new InternalIsoDuration( Duration.parse( "PT45S" ) ).toString(), equalTo( "PT45S" ) );
159+
assertThat( new InternalIsoDuration( 0, 0, 0, 0 ).toString(), equalTo( "P0M0DT0.000000000S" ) );
160+
assertThat( new InternalIsoDuration( 2, 45, 59, 11 ).toString(), equalTo( "P2M45DT59.000000011S" ) );
161+
assertThat( new InternalIsoDuration( 4, -101, 1, 999 ).toString(), equalTo( "P4M-101DT1.000000999S" ) );
162+
assertThat( new InternalIsoDuration( -1, 12, -19, 1 ).toString(), equalTo( "P-1M12DT-19.000000001S" ) );
162163

163-
assertThat( new InternalIsoDuration( Period.parse( "P14D" ), Duration.parse( "PT16H12M" ) ).toString(), equalTo( "P2WT16H12M" ) );
164-
assertThat( new InternalIsoDuration( Period.parse( "P5M1D" ), Duration.parse( "PT12H" ) ).toString(), equalTo( "P5M1DT12H" ) );
165-
assertThat( new InternalIsoDuration( Period.parse( "P2W3D" ), Duration.parse( "PT12H" ) ).toString(), equalTo( "P2W3DT12H" ) );
164+
assertThat( new InternalIsoDuration( Period.parse( "P356D" ) ).toString(), equalTo( "P0M356DT0.000000000S" ) );
165+
assertThat( new InternalIsoDuration( Duration.parse( "PT45S" ) ).toString(), equalTo( "P0M0DT45.000000000S" ) );
166+
167+
assertThat( new InternalIsoDuration( Period.parse( "P14D" ), Duration.parse( "PT16H12M" ) ).toString(), equalTo( "P0M14DT58320.000000000S" ) );
168+
assertThat( new InternalIsoDuration( Period.parse( "P5M1D" ), Duration.parse( "PT12H" ) ).toString(), equalTo( "P5M1DT43200.000000000S" ) );
169+
assertThat( new InternalIsoDuration( Period.parse( "P2W3D" ), Duration.parse( "PT2H0.111222333S" ) ).toString(), equalTo( "P0M17DT7200.111222333S" ) );
166170
}
167171

168172
private static IsoDuration newDuration( long months, long days, long seconds, int nanoseconds )

0 commit comments

Comments
 (0)