Skip to content

Commit

Permalink
apacheGH-38578: [Java][FlightSQL] Remove joda usage from flight-sql l…
Browse files Browse the repository at this point in the history
…ibrary (apache#38579)

### Rationale for this change

[joda](https://www.joda.org/joda-time/) is a very popular date/time manipulation library for java but the introduction of `java.time` package makes it obsolete and author actually recommends using `java.time` over `joda`

> Note that from Java SE 8 onwards, users are asked to migrate to java.time (JSR-310) - a core part of the JDK which replaces this project.

### What changes are included in this PR?

Change include the use of `java.time` classes over `joda` classes and the removal of `joda` library as a dependency

### Are these changes tested?

As there is no behavior change, it is covered by the existing tests
* Closes: apache#38578

Authored-by: Laurent Goujon <[email protected]>
Signed-off-by: David Li <[email protected]>
  • Loading branch information
laurentgo authored Nov 6, 2023
1 parent b55d8d5 commit 02d8bd2
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 53 deletions.
6 changes: 0 additions & 6 deletions java/flight/flight-sql-jdbc-core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -136,12 +136,6 @@
<artifactId>bcpkix-jdk15on</artifactId>
<version>1.61</version>
</dependency>

<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>2.10.14</version>
</dependency>
</dependencies>

<build>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
import static org.apache.arrow.vector.util.DateUtility.yearsToMonths;

import java.sql.SQLException;
import java.time.Duration;
import java.time.Period;
import java.util.function.IntSupplier;

import org.apache.arrow.driver.jdbc.accessor.ArrowFlightJdbcAccessor;
Expand All @@ -31,7 +33,6 @@
import org.apache.arrow.vector.IntervalYearVector;
import org.apache.arrow.vector.holders.NullableIntervalDayHolder;
import org.apache.arrow.vector.holders.NullableIntervalYearHolder;
import org.joda.time.Period;

/**
* Accessor for the Arrow type {@link IntervalDayVector}.
Expand Down Expand Up @@ -62,7 +63,7 @@ public ArrowFlightJdbcIntervalVectorAccessor(IntervalDayVector vector,
} else {
final int days = holder.days;
final int millis = holder.milliseconds;
return formatIntervalDay(new Period().plusDays(days).plusMillis(millis));
return formatIntervalDay(Duration.ofDays(days).plusMillis(millis));
}
};
objectClass = java.time.Duration.class;
Expand All @@ -89,7 +90,7 @@ public ArrowFlightJdbcIntervalVectorAccessor(IntervalYearVector vector,
final int interval = holder.value;
final int years = (interval / yearsToMonths);
final int months = (interval % yearsToMonths);
return formatIntervalYear(new Period().plusYears(years).plusMonths(months));
return formatIntervalYear(Period.ofYears(years).plusMonths(months));
}
};
objectClass = java.time.Period.class;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@

package org.apache.arrow.driver.jdbc.utils;

import java.time.Duration;
import java.time.Period;

import org.apache.arrow.vector.util.DateUtility;
import org.joda.time.Period;

/**
* Utility class to format periods similar to Oracle's representation
Expand All @@ -36,7 +38,7 @@ private IntervalStringUtils( ) {}
* For example, the string "+21-02" defines an interval of 21 years and 2 months.
*/
public static String formatIntervalYear(final Period p) {
long months = p.getYears() * (long) DateUtility.yearsToMonths + p.getMonths();
long months = p.toTotalMonths();
boolean neg = false;
if (months < 0) {
months = -months;
Expand All @@ -53,8 +55,8 @@ public static String formatIntervalYear(final Period p) {
* For example, the string "-001 18:25:16.766" defines an interval of
* - 1 day 18 hours 25 minutes 16 seconds and 766 milliseconds.
*/
public static String formatIntervalDay(final Period p) {
long millis = p.getDays() * (long) DateUtility.daysToStandardMillis + millisFromPeriod(p);
public static String formatIntervalDay(final Duration d) {
long millis = d.toMillis();

boolean neg = false;
if (millis < 0) {
Expand All @@ -76,9 +78,4 @@ public static String formatIntervalDay(final Period p) {

return String.format("%c%03d %02d:%02d:%02d.%03d", neg ? '-' : '+', days, hours, minutes, seconds, millis);
}

public static int millisFromPeriod(Period period) {
return period.getHours() * DateUtility.hoursToMillis + period.getMinutes() * DateUtility.minutesToMillis +
period.getSeconds() * DateUtility.secondsToMillis + period.getMillis();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
import static org.apache.arrow.driver.jdbc.utils.IntervalStringUtils.formatIntervalYear;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.is;
import static org.joda.time.Period.parse;

import java.time.Duration;
import java.time.Period;
Expand Down Expand Up @@ -142,57 +141,62 @@ private String getStringOnVector(ValueVector vector, int index) {
if (object == null) {
return null;
} else if (vector instanceof IntervalDayVector) {
return formatIntervalDay(parse(object));
return formatIntervalDay(Duration.parse(object));
} else if (vector instanceof IntervalYearVector) {
return formatIntervalYear(parse(object));
return formatIntervalYear(Period.parse(object));
}
return null;
}

@Test
public void testShouldGetIntervalYear( ) {
Assert.assertEquals("-002-00", formatIntervalYear(parse("P-2Y")));
Assert.assertEquals("-001-01", formatIntervalYear(parse("P-1Y-1M")));
Assert.assertEquals("-001-02", formatIntervalYear(parse("P-1Y-2M")));
Assert.assertEquals("-002-03", formatIntervalYear(parse("P-2Y-3M")));
Assert.assertEquals("-002-04", formatIntervalYear(parse("P-2Y-4M")));
Assert.assertEquals("-011-01", formatIntervalYear(parse("P-11Y-1M")));
Assert.assertEquals("+002-00", formatIntervalYear(parse("P+2Y")));
Assert.assertEquals("+001-01", formatIntervalYear(parse("P+1Y1M")));
Assert.assertEquals("+001-02", formatIntervalYear(parse("P+1Y2M")));
Assert.assertEquals("+002-03", formatIntervalYear(parse("P+2Y3M")));
Assert.assertEquals("+002-04", formatIntervalYear(parse("P+2Y4M")));
Assert.assertEquals("+011-01", formatIntervalYear(parse("P+11Y1M")));
Assert.assertEquals("-002-00", formatIntervalYear(Period.parse("P-2Y")));
Assert.assertEquals("-001-01", formatIntervalYear(Period.parse("P-1Y-1M")));
Assert.assertEquals("-001-02", formatIntervalYear(Period.parse("P-1Y-2M")));
Assert.assertEquals("-002-03", formatIntervalYear(Period.parse("P-2Y-3M")));
Assert.assertEquals("-002-04", formatIntervalYear(Period.parse("P-2Y-4M")));
Assert.assertEquals("-011-01", formatIntervalYear(Period.parse("P-11Y-1M")));
Assert.assertEquals("+002-00", formatIntervalYear(Period.parse("P+2Y")));
Assert.assertEquals("+001-01", formatIntervalYear(Period.parse("P+1Y1M")));
Assert.assertEquals("+001-02", formatIntervalYear(Period.parse("P+1Y2M")));
Assert.assertEquals("+002-03", formatIntervalYear(Period.parse("P+2Y3M")));
Assert.assertEquals("+002-04", formatIntervalYear(Period.parse("P+2Y4M")));
Assert.assertEquals("+011-01", formatIntervalYear(Period.parse("P+11Y1M")));
}

@Test
public void testShouldGetIntervalDay( ) {
Assert.assertEquals("-001 00:00:00.000", formatIntervalDay(parse("PT-24H")));
Assert.assertEquals("+001 00:00:00.000", formatIntervalDay(parse("PT+24H")));
Assert.assertEquals("-000 01:00:00.000", formatIntervalDay(parse("PT-1H")));
Assert.assertEquals("-000 01:00:00.001", formatIntervalDay(parse("PT-1H-0M-00.001S")));
Assert.assertEquals("-000 01:01:01.000", formatIntervalDay(parse("PT-1H-1M-1S")));
Assert.assertEquals("-000 02:02:02.002", formatIntervalDay(parse("PT-2H-2M-02.002S")));
Assert.assertEquals("-000 23:59:59.999", formatIntervalDay(parse("PT-23H-59M-59.999S")));
Assert.assertEquals("-000 11:59:00.100", formatIntervalDay(parse("PT-11H-59M-00.100S")));
Assert.assertEquals("-000 05:02:03.000", formatIntervalDay(parse("PT-5H-2M-3S")));
Assert.assertEquals("-000 22:22:22.222", formatIntervalDay(parse("PT-22H-22M-22.222S")));
Assert.assertEquals("+000 01:00:00.000", formatIntervalDay(parse("PT+1H")));
Assert.assertEquals("+000 01:00:00.001", formatIntervalDay(parse("PT+1H0M00.001S")));
Assert.assertEquals("+000 01:01:01.000", formatIntervalDay(parse("PT+1H1M1S")));
Assert.assertEquals("+000 02:02:02.002", formatIntervalDay(parse("PT+2H2M02.002S")));
Assert.assertEquals("+000 23:59:59.999", formatIntervalDay(parse("PT+23H59M59.999S")));
Assert.assertEquals("+000 11:59:00.100", formatIntervalDay(parse("PT+11H59M00.100S")));
Assert.assertEquals("+000 05:02:03.000", formatIntervalDay(parse("PT+5H2M3S")));
Assert.assertEquals("+000 22:22:22.222", formatIntervalDay(parse("PT+22H22M22.222S")));
Assert.assertEquals("-001 00:00:00.000", formatIntervalDay(Duration.parse("PT-24H")));
Assert.assertEquals("+001 00:00:00.000", formatIntervalDay(Duration.parse("PT+24H")));
Assert.assertEquals("-000 01:00:00.000", formatIntervalDay(Duration.parse("PT-1H")));
// "JDK-8054978: java.time.Duration.parse() fails for negative duration with 0 seconds and nanos" not fixed on JDK8
//Assert.assertEquals("-000 01:00:00.001", formatIntervalDay(Duration.parse("PT-1H-0M-00.001S")));
Assert.assertEquals("-000 01:00:00.001", formatIntervalDay(Duration.ofHours(-1).minusMillis(1)));
Assert.assertEquals("-000 01:01:01.000", formatIntervalDay(Duration.parse("PT-1H-1M-1S")));
Assert.assertEquals("-000 02:02:02.002", formatIntervalDay(Duration.parse("PT-2H-2M-02.002S")));
Assert.assertEquals("-000 23:59:59.999", formatIntervalDay(Duration.parse("PT-23H-59M-59.999S")));
// "JDK-8054978: java.time.Duration.parse() fails for negative duration with 0 seconds and nanos" not fixed on JDK8
//Assert.assertEquals("-000 11:59:00.100", formatIntervalDay(Duration.parse("PT-11H-59M-00.100S")));
Assert.assertEquals("-000 11:59:00.100",
formatIntervalDay(Duration.ofHours(-11).minusMinutes(59).minusMillis(100)));
Assert.assertEquals("-000 05:02:03.000", formatIntervalDay(Duration.parse("PT-5H-2M-3S")));
Assert.assertEquals("-000 22:22:22.222", formatIntervalDay(Duration.parse("PT-22H-22M-22.222S")));
Assert.assertEquals("+000 01:00:00.000", formatIntervalDay(Duration.parse("PT+1H")));
Assert.assertEquals("+000 01:00:00.001", formatIntervalDay(Duration.parse("PT+1H0M00.001S")));
Assert.assertEquals("+000 01:01:01.000", formatIntervalDay(Duration.parse("PT+1H1M1S")));
Assert.assertEquals("+000 02:02:02.002", formatIntervalDay(Duration.parse("PT+2H2M02.002S")));
Assert.assertEquals("+000 23:59:59.999", formatIntervalDay(Duration.parse("PT+23H59M59.999S")));
Assert.assertEquals("+000 11:59:00.100", formatIntervalDay(Duration.parse("PT+11H59M00.100S")));
Assert.assertEquals("+000 05:02:03.000", formatIntervalDay(Duration.parse("PT+5H2M3S")));
Assert.assertEquals("+000 22:22:22.222", formatIntervalDay(Duration.parse("PT+22H22M22.222S")));
}

@Test
public void testIntervalDayWithJodaPeriodObject() {
Assert.assertEquals("+1567 00:00:00.000",
formatIntervalDay(new org.joda.time.Period().plusDays(1567)));
formatIntervalDay(Duration.ofDays(1567)));
Assert.assertEquals("-1567 00:00:00.000",
formatIntervalDay(new org.joda.time.Period().minusDays(1567)));
formatIntervalDay(Duration.ofDays(-1567)));
}

@Test
Expand Down

0 comments on commit 02d8bd2

Please sign in to comment.