提交 9ea58704 authored 作者: Evgenij Ryazanov's avatar Evgenij Ryazanov

Add more methods to org.h2.api.Interval

上级 3e1cc27f
...@@ -5,6 +5,10 @@ ...@@ -5,6 +5,10 @@
*/ */
package org.h2.api; package org.h2.api;
import static org.h2.util.DateTimeUtils.NANOS_PER_MINUTE;
import static org.h2.util.DateTimeUtils.NANOS_PER_SECOND;
import org.h2.message.DbException;
import org.h2.util.DateTimeUtils; import org.h2.util.DateTimeUtils;
/** /**
...@@ -21,54 +25,54 @@ public final class Interval { ...@@ -21,54 +25,54 @@ public final class Interval {
private final long remaining; private final long remaining;
/** /**
* Creates a new interval. * Creates a new INTERVAL YEAR.
* *
* @param years * @param years
* years * years, |years|&lt;10<sup>18</sup>
* @return interval * @return INTERVAL YEAR
*/ */
public static Interval ofYears(long years) { public static Interval ofYears(long years) {
return new Interval(IntervalQualifier.YEAR, years < 0, Math.abs(years), 0); return new Interval(IntervalQualifier.YEAR, years < 0, Math.abs(years), 0);
} }
/** /**
* Creates a new interval. * Creates a new INTERVAL MONTH.
* *
* @param months * @param months
* months * months, |months|&lt;10<sup>18</sup>
* @return interval * @return INTERVAL MONTH
*/ */
public static Interval ofMonths(long months) { public static Interval ofMonths(long months) {
return new Interval(IntervalQualifier.MONTH, months < 0, Math.abs(months), 0); return new Interval(IntervalQualifier.MONTH, months < 0, Math.abs(months), 0);
} }
/** /**
* Creates a new interval. * Creates a new INTERVAL DAY.
* *
* @param days * @param days
* days * days, |days|&lt;10<sup>18</sup>
* @return interval * @return INTERVAL DAY
*/ */
public static Interval ofDays(long days) { public static Interval ofDays(long days) {
return new Interval(IntervalQualifier.DAY, days < 0, Math.abs(days), 0); return new Interval(IntervalQualifier.DAY, days < 0, Math.abs(days), 0);
} }
/** /**
* Creates a new interval. * Creates a new INTERVAL HOUR.
* *
* @param hours * @param hours
* hours * hours, |hours|&lt;10<sup>18</sup>
* @return interval * @return INTERVAL HOUR
*/ */
public static Interval ofHours(long hours) { public static Interval ofHours(long hours) {
return new Interval(IntervalQualifier.HOUR, hours < 0, Math.abs(hours), 0); return new Interval(IntervalQualifier.HOUR, hours < 0, Math.abs(hours), 0);
} }
/** /**
* Creates a new interval. * Creates a new INTERVAL MINUTE.
* *
* @param minutes * @param minutes
* minutes * minutes, |minutes|&lt;10<sup>18</sup>
* @return interval * @return interval
*/ */
public static Interval ofMinutes(long minutes) { public static Interval ofMinutes(long minutes) {
...@@ -76,25 +80,331 @@ public final class Interval { ...@@ -76,25 +80,331 @@ public final class Interval {
} }
/** /**
* Creates a new interval. * Creates a new INTERVAL SECOND.
*
* @param seconds
* seconds, |seconds|&lt;10<sup>18</sup>
* @return INTERVAL SECOND
*/
public static Interval ofSeconds(long seconds) {
return new Interval(IntervalQualifier.SECOND, seconds < 0, Math.abs(seconds), 0);
}
/**
* Creates a new INTERVAL SECOND.
*
* <p>
* If both arguments are not equal to zero they should have the same sign.
* </p>
*
* @param seconds
* seconds, |seconds|&lt;10<sup>18</sup>
* @param nanos
* nanoseconds, |nanos|&lt;1,000,000,000
* @return INTERVAL SECOND
*/
public static Interval ofSeconds(long seconds, int nanos) {
boolean negative = (seconds | nanos) < 0;
if (negative) {
if (seconds > 0 || nanos > 0) {
throw new IllegalArgumentException();
}
seconds = -seconds;
nanos = -nanos;
}
return new Interval(IntervalQualifier.SECOND, negative, seconds, nanos);
}
/**
* Creates a new INTERVAL SECOND.
* *
* @param nanos * @param nanos
* nanoseconds (including seconds) * nanoseconds (including seconds)
* @return interval * @return INTERVAL SECOND
*/ */
public static Interval ofNanos(long nanos) { public static Interval ofNanos(long nanos) {
boolean negative = nanos < 0; boolean negative = nanos < 0;
if (negative) { if (negative) {
nanos = -nanos; nanos = -nanos;
if (nanos < 0) { if (nanos < 0) {
// Long.MIN_VALUE = -9_223_372_036_854_775_808L
return new Interval(IntervalQualifier.SECOND, true, 9_223_372_036L, 854_775_808);
}
}
return new Interval(IntervalQualifier.SECOND, negative, nanos / NANOS_PER_SECOND, nanos % NANOS_PER_SECOND);
}
/**
* Creates a new INTERVAL YEAR TO MONTH.
*
* <p>
* If both arguments are not equal to zero they should have the same sign.
* </p>
*
* @param years
* years, |years|&lt;10<sup>18</sup>
* @param months
* months, |months|&lt;12
* @return INTERVAL YEAR TO MONTH
*/
public static Interval ofYearsMonths(long years, int months) {
boolean negative = years < 0 || months < 0;
if (negative) {
if (years > 0 || months > 0) {
throw new IllegalArgumentException();
}
years = -years;
months = -months;
}
return new Interval(IntervalQualifier.YEAR_TO_MONTH, negative, years, months);
}
/**
* Creates a new INTERVAL DAY TO HOUR.
*
* <p>
* If both arguments are not equal to zero they should have the same sign.
* </p>
*
* @param days
* days, |days|&lt;10<sup>18</sup>
* @param hours
* hours, |hours|&lt;24
* @return INTERVAL DAY TO HOUR
*/
public static Interval ofDaysHours(long days, int hours) {
boolean negative = days < 0 || hours < 0;
if (negative) {
if (days > 0 || hours > 0) {
throw new IllegalArgumentException();
}
days = -days;
hours = -hours;
}
return new Interval(IntervalQualifier.DAY_TO_HOUR, negative, days, hours);
}
/**
* Creates a new INTERVAL DAY TO MINUTE.
*
* <p>
* Non-zero arguments should have the same sign.
* </p>
*
* @param days
* days, |days|&lt;10<sup>18</sup>
* @param hours
* hours, |hours|&lt;24
* @param minutes
* minutes, |minutes|&lt;60
* @return INTERVAL DAY TO MINUTE
*/
public static Interval ofDaysHoursMinutes(long days, int hours, int minutes) {
boolean negative = days < 0 || (hours | minutes) < 0;
if (negative) {
if (days > 0 || hours > 0 || minutes > 0) {
throw new IllegalArgumentException();
}
days = -days;
hours = -hours;
minutes = -minutes;
if ((hours | minutes) < 0) {
// Integer.MIN_VALUE
throw new IllegalArgumentException();
}
}
// Overflow in days or hours will be detected by constructor
if (minutes >= 60) {
throw new IllegalArgumentException();
}
return new Interval(IntervalQualifier.DAY_TO_MINUTE, negative, days, hours * 60L + minutes);
}
/**
* Creates a new INTERVAL DAY TO SECOND.
*
* <p>
* Non-zero arguments should have the same sign.
* </p>
*
* @param days
* days, |days|&lt;10<sup>18</sup>
* @param hours
* hours, |hours|&lt;24
* @param minutes
* minutes, |minutes|&lt;60
* @param seconds
* seconds, |seconds|&lt;60
* @return INTERVAL DAY TO SECOND
*/
public static Interval ofDaysHoursMinutesSeconds(long days, int hours, int minutes, int seconds) {
return ofDaysHoursMinutesNanos(days, hours, minutes, seconds * NANOS_PER_SECOND);
}
/**
* Creates a new INTERVAL DAY TO SECOND.
*
* <p>
* Non-zero arguments should have the same sign.
* </p>
*
* @param days
* days, |days|&lt;10<sup>18</sup>
* @param hours
* hours, |hours|&lt;24
* @param minutes
* minutes, |minutes|&lt;60
* @param nanos
* nanoseconds, |nanos|&lt;60,000,000,000
* @return INTERVAL DAY TO SECOND
*/
public static Interval ofDaysHoursMinutesNanos(long days, int hours, int minutes, long nanos) {
boolean negative = (days | nanos) < 0 || (hours | minutes) < 0;
if (negative) {
if (days > 0 || hours > 0 || minutes > 0 || nanos > 0) {
throw new IllegalArgumentException();
}
days = -days;
hours = -hours;
minutes = -minutes;
nanos = -nanos;
if ((hours | minutes) < 0 || nanos < 0) {
// Integer.MIN_VALUE, Long.MIN_VALUE
throw new IllegalArgumentException(); throw new IllegalArgumentException();
} }
} }
return new Interval(IntervalQualifier.SECOND, negative, nanos / 1_000_000_000, nanos % 1_000_000_000); if (hours >= 24 || minutes >= 60 || nanos >= NANOS_PER_MINUTE) {
throw new IllegalArgumentException();
}
return new Interval(IntervalQualifier.DAY_TO_SECOND, negative, days,
(hours * 60L + minutes) * NANOS_PER_MINUTE + nanos);
}
/**
* Creates a new INTERVAL HOUR TO MINUTE.
*
* <p>
* If both arguments are not equal to zero they should have the same sign.
* </p>
*
* @param hours
* hours, |hours|&lt;10<sup>18</sup>
* @param minutes
* minutes, |minutes|&lt;60
* @return INTERVAL HOUR TO MINUTE
*/
public static Interval ofHoursMinutes(long hours, int minutes) {
boolean negative = (hours | minutes) < 0;
if (negative) {
if (hours > 0 || minutes > 0) {
throw new IllegalArgumentException();
}
hours = -hours;
minutes = -minutes;
}
return new Interval(IntervalQualifier.HOUR_TO_MINUTE, negative, hours, minutes);
}
/**
* Creates a new INTERVAL HOUR TO SECOND.
*
* <p>
* Non-zero arguments should have the same sign.
* </p>
*
* @param hours
* hours, |hours|&lt;10<sup>18</sup>
* @param minutes
* minutes, |minutes|&lt;60
* @param seconds
* seconds, |seconds|&lt;60
* @return INTERVAL HOUR TO SECOND
*/
public static Interval ofHoursMinutesSeconds(long hours, int minutes, int seconds) {
return ofHoursMinutesNanos(hours, minutes, seconds * NANOS_PER_SECOND);
} }
/** /**
* Creates a new interval. * Creates a new INTERVAL HOUR TO SECOND.
*
* <p>
* Non-zero arguments should have the same sign.
* </p>
*
* @param hours
* hours, |hours|&lt;10<sup>18</sup>
* @param minutes
* minutes, |minutes|&lt;60
* @param nanos
* nanoseconds, |seconds|&lt;60,000,000,000
* @return INTERVAL HOUR TO SECOND
*/
public static Interval ofHoursMinutesNanos(long hours, int minutes, long nanos) {
boolean negative = (hours | nanos) < 0 || minutes < 0;
if (negative) {
if (hours > 0 || minutes > 0 || nanos > 0) {
throw new IllegalArgumentException();
}
hours = -hours;
minutes = -minutes;
nanos = -nanos;
if (minutes < 0 || nanos < 0) {
// Integer.MIN_VALUE, Long.MIN_VALUE
throw new IllegalArgumentException();
}
}
// Overflow in hours or minutes will be detected by constructor
if (nanos >= NANOS_PER_MINUTE) {
throw new IllegalArgumentException();
}
return new Interval(IntervalQualifier.HOUR_TO_SECOND, negative, hours, minutes * NANOS_PER_MINUTE + nanos);
}
/**
* Creates a new INTERVAL MINUTE TO SECOND
*
* <p>
* If both arguments are not equal to zero they should have the same sign.
* </p>
*
* @param minutes
* minutes, |minutes|&lt;10<sup>18</sup>
* @param seconds
* seconds, |seconds|&lt;60
* @return INTERVAL MINUTE TO SECOND
*/
public static Interval ofMinutesSeconds(long minutes, int seconds) {
return ofMinutesNanos(minutes, seconds * NANOS_PER_SECOND);
}
/**
* Creates a new INTERVAL MINUTE TO SECOND
*
* <p>
* If both arguments are not equal to zero they should have the same sign.
* </p>
*
* @param minutes
* minutes, |minutes|&lt;10<sup>18</sup>
* @param nanos
* nanoseconds, |nanos|&lt;60,000,000,000
* @return INTERVAL MINUTE TO SECOND
*/
public static Interval ofMinutesNanos(long minutes, long nanos) {
boolean negative = (minutes | nanos) < 0;
if (negative) {
if (minutes > 0 || nanos > 0) {
throw new IllegalArgumentException();
}
minutes = -minutes;
nanos = -nanos;
}
return new Interval(IntervalQualifier.MINUTE_TO_SECOND, negative, minutes, nanos);
}
/**
* Creates a new interval. Do not use this constructor, use static methods
* instead.
* *
* @param qualifier * @param qualifier
* qualifier * qualifier
...@@ -103,11 +413,15 @@ public final class Interval { ...@@ -103,11 +413,15 @@ public final class Interval {
* @param leading * @param leading
* value of leading field * value of leading field
* @param remaining * @param remaining
* values of all remaining fields * combined value of all remaining fields
*/ */
public Interval(IntervalQualifier qualifier, boolean negative, long leading, long remaining) { public Interval(IntervalQualifier qualifier, boolean negative, long leading, long remaining) {
this.qualifier = qualifier; this.qualifier = qualifier;
this.negative = DateTimeUtils.validateInterval(qualifier, negative, leading, remaining); try {
this.negative = DateTimeUtils.validateInterval(qualifier, negative, leading, remaining);
} catch (DbException e) {
throw new IllegalArgumentException();
}
this.leading = leading; this.leading = leading;
this.remaining = remaining; this.remaining = remaining;
} }
...@@ -151,6 +465,8 @@ public final class Interval { ...@@ -151,6 +465,8 @@ public final class Interval {
} }
/** /**
* Returns years value, if any.
*
* @return years, or 0 * @return years, or 0
*/ */
public long getYears() { public long getYears() {
...@@ -158,6 +474,8 @@ public final class Interval { ...@@ -158,6 +474,8 @@ public final class Interval {
} }
/** /**
* Returns months value, if any.
*
* @return months, or 0 * @return months, or 0
*/ */
public long getMonths() { public long getMonths() {
...@@ -165,6 +483,8 @@ public final class Interval { ...@@ -165,6 +483,8 @@ public final class Interval {
} }
/** /**
* Returns days value, if any.
*
* @return days, or 0 * @return days, or 0
*/ */
public long getDays() { public long getDays() {
...@@ -172,6 +492,8 @@ public final class Interval { ...@@ -172,6 +492,8 @@ public final class Interval {
} }
/** /**
* Returns hours value, if any.
*
* @return hours, or 0 * @return hours, or 0
*/ */
public long getHours() { public long getHours() {
...@@ -179,6 +501,8 @@ public final class Interval { ...@@ -179,6 +501,8 @@ public final class Interval {
} }
/** /**
* Returns minutes value, if any.
*
* @return minutes, or 0 * @return minutes, or 0
*/ */
public long getMinutes() { public long getMinutes() {
...@@ -186,9 +510,42 @@ public final class Interval { ...@@ -186,9 +510,42 @@ public final class Interval {
} }
/** /**
* Returns value of integer part of seconds, if any.
*
* @return seconds, or 0
*/
public long getSeconds() {
if (qualifier == IntervalQualifier.SECOND) {
return negative ? -leading : leading;
}
return getSecondsAndNanos() / NANOS_PER_SECOND;
}
/**
* Returns value of fractional part of seconds (in nanoseconds), if any.
*
* @return nanoseconds, or 0
*/
public long getNanosOfSecond() {
if (qualifier == IntervalQualifier.SECOND) {
return negative ? -remaining : remaining;
}
return getSecondsAndNanos() % NANOS_PER_SECOND;
}
/**
* Returns seconds value measured in nanoseconds, if any.
*
* <p>
* This method returns a long value that cannot fit all possible values of
* INTERVAL SECOND. For a very large intervals of this type use
* {@link #getSeconds()} and {@link #getNanosOfSecond()} instead. This
* method can be safely used for intervals of other day-time types.
* </p>
*
* @return nanoseconds (including seconds), or 0 * @return nanoseconds (including seconds), or 0
*/ */
public long getNanos() { public long getSecondsAndNanos() {
return DateTimeUtils.nanosFromInterval(qualifier, negative, leading, remaining); return DateTimeUtils.nanosFromInterval(qualifier, negative, leading, remaining);
} }
......
...@@ -5,14 +5,21 @@ ...@@ -5,14 +5,21 @@
*/ */
package org.h2.test.unit; package org.h2.test.unit;
import static org.h2.util.DateTimeUtils.NANOS_PER_SECOND;
import org.h2.api.Interval; import org.h2.api.Interval;
import org.h2.test.TestBase; import org.h2.test.TestBase;
import org.h2.util.StringUtils;
/** /**
* Test cases for Interval. * Test cases for Interval.
*/ */
public class TestInterval extends TestBase { public class TestInterval extends TestBase {
private static final long MAX = 999_999_999_999_999_999L;
private static final long MIN = -999_999_999_999_999_999L;
/** /**
* Run just this test. * Run just this test.
* *
...@@ -25,25 +32,585 @@ public class TestInterval extends TestBase { ...@@ -25,25 +32,585 @@ public class TestInterval extends TestBase {
@Override @Override
public void test() throws Exception { public void test() throws Exception {
Interval i; testOfYears();
i = Interval.ofYears(100); testOfMonths();
assertEquals(100, i.getYears()); testOfDays();
assertEquals("INTERVAL '100' YEAR", i.toString()); testOfHours();
i = Interval.ofMonths(100); testOfMinutes();
assertEquals(100, i.getMonths()); testOfSeconds();
assertEquals("INTERVAL '100' MONTH", i.toString()); testOfSeconds2();
i = Interval.ofDays(100); testOfNanos();
assertEquals(100, i.getDays()); testOfYearsMonths();
assertEquals("INTERVAL '100' DAY", i.toString()); testOfDaysHours();
i = Interval.ofHours(100); testOfDaysHoursMinutes();
assertEquals(100, i.getHours()); testOfDaysHoursMinutesSeconds();
assertEquals("INTERVAL '100' HOUR", i.toString()); testOfHoursMinutes();
i = Interval.ofMinutes(100); testOfHoursMinutesSeconds();
assertEquals(100, i.getMinutes()); testOfMinutesSeconds();
assertEquals("INTERVAL '100' MINUTE", i.toString()); }
i = Interval.ofNanos(100_123_456_789L);
assertEquals(100_123_456_789L, i.getNanos()); private void testOfYears() {
assertEquals("INTERVAL '100.123456789' SECOND", i.toString()); testOfYearsGood(0);
testOfYearsGood(100);
testOfYearsGood(-100);
testOfYearsGood(MAX);
testOfYearsGood(MIN);
testOfYearsBad(MAX + 1);
testOfYearsBad(MIN - 1);
testOfYearsBad(Long.MAX_VALUE);
testOfYearsBad(Long.MIN_VALUE);
}
private void testOfYearsGood(long years) {
Interval i = Interval.ofYears(years);
assertEquals(years, i.getYears());
assertEquals("INTERVAL '" + years + "' YEAR", i.toString());
}
private void testOfYearsBad(long years) {
try {
Interval.ofYears(years);
fail();
} catch (IllegalArgumentException e) {
// OK
}
}
private void testOfMonths() {
testOfMonthsGood(0);
testOfMonthsGood(100);
testOfMonthsGood(-100);
testOfMonthsGood(MAX);
testOfMonthsGood(MIN);
testOfMonthsBad(MAX + 1);
testOfMonthsBad(MIN - 1);
testOfMonthsBad(Long.MAX_VALUE);
testOfMonthsBad(Long.MIN_VALUE);
}
private void testOfMonthsGood(long months) {
Interval i = Interval.ofMonths(months);
assertEquals(months, i.getMonths());
assertEquals("INTERVAL '" + months + "' MONTH", i.toString());
}
private void testOfMonthsBad(long months) {
try {
Interval.ofMonths(months);
fail();
} catch (IllegalArgumentException e) {
// OK
}
}
private void testOfDays() {
testOfDaysGood(0);
testOfDaysGood(100);
testOfDaysGood(-100);
testOfDaysGood(MAX);
testOfDaysGood(MIN);
testOfDaysBad(MAX + 1);
testOfDaysBad(MIN - 1);
testOfDaysBad(Long.MAX_VALUE);
testOfDaysBad(Long.MIN_VALUE);
}
private void testOfDaysGood(long days) {
Interval i = Interval.ofDays(days);
assertEquals(days, i.getDays());
assertEquals("INTERVAL '" + days + "' DAY", i.toString());
}
private void testOfDaysBad(long days) {
try {
Interval.ofDays(days);
fail();
} catch (IllegalArgumentException e) {
// OK
}
}
private void testOfHours() {
testOfHoursGood(0);
testOfHoursGood(100);
testOfHoursGood(-100);
testOfHoursGood(MAX);
testOfHoursGood(MIN);
testOfHoursBad(MAX + 1);
testOfHoursBad(MIN - 1);
testOfHoursBad(Long.MAX_VALUE);
testOfHoursBad(Long.MIN_VALUE);
}
private void testOfHoursGood(long hours) {
Interval i = Interval.ofHours(hours);
assertEquals(hours, i.getHours());
assertEquals("INTERVAL '" + hours + "' HOUR", i.toString());
}
private void testOfHoursBad(long hours) {
try {
Interval.ofHours(hours);
fail();
} catch (IllegalArgumentException e) {
// OK
}
}
private void testOfMinutes() {
testOfMinutesGood(0);
testOfMinutesGood(100);
testOfMinutesGood(-100);
testOfMinutesGood(MAX);
testOfMinutesGood(MIN);
testOfMinutesBad(MAX + 1);
testOfMinutesBad(MIN - 1);
testOfMinutesBad(Long.MAX_VALUE);
testOfMinutesBad(Long.MIN_VALUE);
}
private void testOfMinutesGood(long minutes) {
Interval i = Interval.ofMinutes(minutes);
assertEquals(minutes, i.getMinutes());
assertEquals("INTERVAL '" + minutes + "' MINUTE", i.toString());
}
private void testOfMinutesBad(long minutes) {
try {
Interval.ofMinutes(minutes);
fail();
} catch (IllegalArgumentException e) {
// OK
}
}
private void testOfSeconds() {
testOfSecondsGood(0);
testOfSecondsGood(100);
testOfSecondsGood(-100);
testOfSecondsGood(MAX);
testOfSecondsGood(MIN);
testOfSecondsBad(MAX + 1);
testOfSecondsBad(MIN - 1);
testOfSecondsBad(Long.MAX_VALUE);
testOfSecondsBad(Long.MIN_VALUE);
}
private void testOfSecondsGood(long seconds) {
Interval i = Interval.ofSeconds(seconds);
assertEquals(seconds, i.getSeconds());
assertEquals("INTERVAL '" + seconds + "' SECOND", i.toString());
}
private void testOfSecondsBad(long seconds) {
try {
Interval.ofSeconds(seconds);
fail();
} catch (IllegalArgumentException e) {
// OK
}
}
private void testOfSeconds2() {
testOfSeconds2Good(0, 0);
testOfSeconds2Good(0, -2);
testOfSeconds2Good(100, 5);
testOfSeconds2Good(-100, -1);
testOfSeconds2Good(MAX, 999_999_999);
testOfSeconds2Good(MIN, -999_999_999);
testOfSeconds2Bad(0, 1_000_000_000);
testOfSeconds2Bad(0, -1_000_000_000);
testOfSeconds2Bad(MAX + 1, 0);
testOfSeconds2Bad(MIN - 1, 0);
testOfSeconds2Bad(Long.MAX_VALUE, 0);
testOfSeconds2Bad(Long.MIN_VALUE, 0);
testOfSeconds2Bad(0, Integer.MAX_VALUE);
testOfSeconds2Bad(0, Integer.MIN_VALUE);
}
private void testOfSeconds2Good(long seconds, int nanos) {
Interval i = Interval.ofSeconds(seconds, nanos);
assertEquals(seconds, i.getSeconds());
assertEquals(nanos, i.getNanosOfSecond());
if (Math.abs(seconds) < 9_000_000_000L) {
assertEquals(seconds * NANOS_PER_SECOND + nanos, i.getSecondsAndNanos());
}
StringBuilder b = new StringBuilder("INTERVAL '");
if (seconds < 0 || nanos < 0) {
b.append('-');
}
b.append(Math.abs(seconds));
if (nanos != 0) {
b.append('.');
StringUtils.appendZeroPadded(b, 9, Math.abs(nanos));
stripTrailingZeroes(b);
}
b.append("' SECOND");
assertEquals(b.toString(), i.toString());
}
private void testOfSeconds2Bad(long seconds, int nanos) {
try {
Interval.ofSeconds(seconds, nanos);
fail();
} catch (IllegalArgumentException e) {
// OK
}
}
private void testOfNanos() {
testOfNanosGood(0);
testOfNanosGood(100);
testOfNanosGood(-100);
testOfNanosGood(Long.MAX_VALUE);
testOfNanosGood(Long.MIN_VALUE);
}
private void testOfNanosGood(long nanos) {
Interval i = Interval.ofNanos(nanos);
long seconds = nanos / NANOS_PER_SECOND;
long nanosOfSecond = nanos % NANOS_PER_SECOND;
assertEquals(seconds, i.getSeconds());
assertEquals(nanosOfSecond, i.getNanosOfSecond());
assertEquals(nanos, i.getSecondsAndNanos());
StringBuilder b = new StringBuilder("INTERVAL '");
if (nanos < 0) {
b.append('-');
}
b.append(Math.abs(seconds));
if (nanosOfSecond != 0) {
b.append('.');
StringUtils.appendZeroPadded(b, 9, Math.abs(nanosOfSecond));
stripTrailingZeroes(b);
}
b.append("' SECOND");
assertEquals(b.toString(), i.toString());
}
private void testOfYearsMonths() {
testOfYearsMonthsGood(0, 0);
testOfYearsMonthsGood(0, -2);
testOfYearsMonthsGood(100, 5);
testOfYearsMonthsGood(-100, -1);
testOfYearsMonthsGood(MAX, 11);
testOfYearsMonthsGood(MIN, -11);
testOfYearsMonthsBad(0, 12);
testOfYearsMonthsBad(0, -12);
testOfYearsMonthsBad(MAX + 1, 0);
testOfYearsMonthsBad(MIN - 1, 0);
testOfYearsMonthsBad(Long.MAX_VALUE, 0);
testOfYearsMonthsBad(Long.MIN_VALUE, 0);
testOfYearsMonthsBad(0, Integer.MAX_VALUE);
testOfYearsMonthsBad(0, Integer.MIN_VALUE);
}
private void testOfYearsMonthsGood(long years, int months) {
Interval i = Interval.ofYearsMonths(years, months);
assertEquals(years, i.getYears());
assertEquals(months, i.getMonths());
StringBuilder b = new StringBuilder("INTERVAL '");
if (years < 0 || months < 0) {
b.append('-');
}
b.append(Math.abs(years)).append('-').append(Math.abs(months)).append("' YEAR TO MONTH");
assertEquals(b.toString(), i.toString());
}
private void testOfYearsMonthsBad(long years, int months) {
try {
Interval.ofYearsMonths(years, months);
fail();
} catch (IllegalArgumentException e) {
// OK
}
}
private void testOfDaysHours() {
testOfDaysHoursGood(0, 0);
testOfDaysHoursGood(0, -2);
testOfDaysHoursGood(100, 5);
testOfDaysHoursGood(-100, -1);
testOfDaysHoursGood(MAX, 23);
testOfDaysHoursGood(MIN, -23);
testOfDaysHoursBad(0, 24);
testOfDaysHoursBad(0, -24);
testOfDaysHoursBad(MAX + 1, 0);
testOfDaysHoursBad(MIN - 1, 0);
testOfDaysHoursBad(Long.MAX_VALUE, 0);
testOfDaysHoursBad(Long.MIN_VALUE, 0);
testOfDaysHoursBad(0, Integer.MAX_VALUE);
testOfDaysHoursBad(0, Integer.MIN_VALUE);
}
private void testOfDaysHoursGood(long days, int hours) {
Interval i = Interval.ofDaysHours(days, hours);
assertEquals(days, i.getDays());
assertEquals(hours, i.getHours());
StringBuilder b = new StringBuilder("INTERVAL '");
if (days < 0 || hours < 0) {
b.append('-');
}
b.append(Math.abs(days)).append(' ');
StringUtils.appendZeroPadded(b, 2, Math.abs(hours));
b.append("' DAY TO HOUR");
assertEquals(b.toString(), i.toString());
}
private void testOfDaysHoursBad(long days, int hours) {
try {
Interval.ofDaysHours(days, hours);
fail();
} catch (IllegalArgumentException e) {
// OK
}
}
private void testOfDaysHoursMinutes() {
testOfDaysHoursMinutesGood(0, 0, 0);
testOfDaysHoursMinutesGood(0, -2, 0);
testOfDaysHoursMinutesGood(0, 0, -2);
testOfDaysHoursMinutesGood(100, 5, 3);
testOfDaysHoursMinutesGood(-100, -1, -3);
testOfDaysHoursMinutesGood(MAX, 23, 59);
testOfDaysHoursMinutesGood(MIN, -23, -59);
testOfDaysHoursMinutesBad(0, 24, 0);
testOfDaysHoursMinutesBad(0, -24, 0);
testOfDaysHoursMinutesBad(0, 0, 60);
testOfDaysHoursMinutesBad(0, 0, -60);
testOfDaysHoursMinutesBad(MAX + 1, 0, 0);
testOfDaysHoursMinutesBad(MIN - 1, 0, 0);
testOfDaysHoursMinutesBad(Long.MAX_VALUE, 0, 0);
testOfDaysHoursMinutesBad(Long.MIN_VALUE, 0, 0);
testOfDaysHoursMinutesBad(0, Integer.MAX_VALUE, 0);
testOfDaysHoursMinutesBad(0, Integer.MIN_VALUE, 0);
testOfDaysHoursMinutesBad(0, 0, Integer.MAX_VALUE);
testOfDaysHoursMinutesBad(0, 0, Integer.MIN_VALUE);
}
private void testOfDaysHoursMinutesGood(long days, int hours, int minutes) {
Interval i = Interval.ofDaysHoursMinutes(days, hours, minutes);
assertEquals(days, i.getDays());
assertEquals(hours, i.getHours());
assertEquals(minutes, i.getMinutes());
StringBuilder b = new StringBuilder("INTERVAL '");
if (days < 0 || hours < 0 || minutes < 0) {
b.append('-');
}
b.append(Math.abs(days)).append(' ');
StringUtils.appendZeroPadded(b, 2, Math.abs(hours));
b.append(':');
StringUtils.appendZeroPadded(b, 2, Math.abs(minutes));
b.append("' DAY TO MINUTE");
assertEquals(b.toString(), i.toString());
}
private void testOfDaysHoursMinutesBad(long days, int hours, int minutes) {
try {
Interval.ofDaysHoursMinutes(days, hours, minutes);
fail();
} catch (IllegalArgumentException e) {
// OK
}
}
private void testOfDaysHoursMinutesSeconds() {
testOfDaysHoursMinutesSecondsGood(0, 0, 0, 0);
testOfDaysHoursMinutesSecondsGood(0, -2, 0, 0);
testOfDaysHoursMinutesSecondsGood(0, 0, -2, 0);
testOfDaysHoursMinutesSecondsGood(0, 0, 0, -2);
testOfDaysHoursMinutesSecondsGood(100, 5, 3, 4);
testOfDaysHoursMinutesSecondsGood(-100, -1, -3, -4);
testOfDaysHoursMinutesSecondsGood(MAX, 23, 59, 59);
testOfDaysHoursMinutesSecondsGood(MIN, -23, -59, -59);
testOfDaysHoursMinutesSecondsBad(0, 24, 0, 0);
testOfDaysHoursMinutesSecondsBad(0, -24, 0, 0);
testOfDaysHoursMinutesSecondsBad(0, 0, 60, 0);
testOfDaysHoursMinutesSecondsBad(0, 0, -60, 0);
testOfDaysHoursMinutesSecondsBad(0, 0, 0, 60);
testOfDaysHoursMinutesSecondsBad(0, 0, 0, -60);
testOfDaysHoursMinutesSecondsBad(MAX + 1, 0, 0, 0);
testOfDaysHoursMinutesSecondsBad(MIN - 1, 0, 0, 0);
testOfDaysHoursMinutesSecondsBad(Long.MAX_VALUE, 0, 0, 0);
testOfDaysHoursMinutesSecondsBad(Long.MIN_VALUE, 0, 0, 0);
testOfDaysHoursMinutesSecondsBad(0, Integer.MAX_VALUE, 0, 0);
testOfDaysHoursMinutesSecondsBad(0, Integer.MIN_VALUE, 0, 0);
testOfDaysHoursMinutesSecondsBad(0, 0, Integer.MAX_VALUE, 0);
testOfDaysHoursMinutesSecondsBad(0, 0, Integer.MIN_VALUE, 0);
testOfDaysHoursMinutesSecondsBad(0, 0, 0, Integer.MAX_VALUE);
testOfDaysHoursMinutesSecondsBad(0, 0, 0, Integer.MIN_VALUE);
}
private void testOfDaysHoursMinutesSecondsGood(long days, int hours, int minutes, int seconds) {
Interval i = Interval.ofDaysHoursMinutesSeconds(days, hours, minutes, seconds);
assertEquals(days, i.getDays());
assertEquals(hours, i.getHours());
assertEquals(minutes, i.getMinutes());
assertEquals(seconds, i.getSeconds());
assertEquals(0, i.getNanosOfSecond());
assertEquals(seconds * NANOS_PER_SECOND, i.getSecondsAndNanos());
StringBuilder b = new StringBuilder("INTERVAL '");
if (days < 0 || hours < 0 || minutes < 0 || seconds < 0) {
b.append('-');
}
b.append(Math.abs(days)).append(' ');
StringUtils.appendZeroPadded(b, 2, Math.abs(hours));
b.append(':');
StringUtils.appendZeroPadded(b, 2, Math.abs(minutes));
b.append(':');
StringUtils.appendZeroPadded(b, 2, Math.abs(seconds));
b.append("' DAY TO SECOND");
assertEquals(b.toString(), i.toString());
}
private void testOfDaysHoursMinutesSecondsBad(long days, int hours, int minutes, int seconds) {
try {
Interval.ofDaysHoursMinutesSeconds(days, hours, minutes, seconds);
fail();
} catch (IllegalArgumentException e) {
// OK
}
}
private void testOfHoursMinutes() {
testOfHoursMinutesGood(0, 0);
testOfHoursMinutesGood(0, -2);
testOfHoursMinutesGood(100, 5);
testOfHoursMinutesGood(-100, -1);
testOfHoursMinutesGood(MAX, 59);
testOfHoursMinutesGood(MIN, -59);
testOfHoursMinutesBad(0, 60);
testOfHoursMinutesBad(0, -60);
testOfHoursMinutesBad(MAX + 1, 0);
testOfHoursMinutesBad(MIN - 1, 0);
testOfHoursMinutesBad(Long.MAX_VALUE, 0);
testOfHoursMinutesBad(Long.MIN_VALUE, 0);
testOfHoursMinutesBad(0, Integer.MAX_VALUE);
testOfHoursMinutesBad(0, Integer.MIN_VALUE);
}
private void testOfHoursMinutesGood(long hours, int minutes) {
Interval i = Interval.ofHoursMinutes(hours, minutes);
assertEquals(hours, i.getHours());
assertEquals(minutes, i.getMinutes());
StringBuilder b = new StringBuilder("INTERVAL '");
if (hours < 0 || minutes < 0) {
b.append('-');
}
b.append(Math.abs(hours)).append(':');
StringUtils.appendZeroPadded(b, 2, Math.abs(minutes));
b.append("' HOUR TO MINUTE");
assertEquals(b.toString(), i.toString());
}
private void testOfHoursMinutesBad(long hours, int minutes) {
try {
Interval.ofHoursMinutes(hours, minutes);
fail();
} catch (IllegalArgumentException e) {
// OK
}
}
private void testOfHoursMinutesSeconds() {
testOfHoursMinutesSecondsGood(0, 0, 0);
testOfHoursMinutesSecondsGood(0, -2, 0);
testOfHoursMinutesSecondsGood(0, 0, -2);
testOfHoursMinutesSecondsGood(100, 5, 3);
testOfHoursMinutesSecondsGood(-100, -1, -3);
testOfHoursMinutesSecondsGood(MAX, 59, 59);
testOfHoursMinutesSecondsGood(MIN, -59, -59);
testOfHoursMinutesSecondsBad(0, 60, 0);
testOfHoursMinutesSecondsBad(0, -60, 0);
testOfHoursMinutesSecondsBad(0, 0, 60);
testOfHoursMinutesSecondsBad(0, 0, -60);
testOfHoursMinutesSecondsBad(MAX + 1, 0, 0);
testOfHoursMinutesSecondsBad(MIN - 1, 0, 0);
testOfHoursMinutesSecondsBad(Long.MAX_VALUE, 0, 0);
testOfHoursMinutesSecondsBad(Long.MIN_VALUE, 0, 0);
testOfHoursMinutesSecondsBad(0, Integer.MAX_VALUE, 0);
testOfHoursMinutesSecondsBad(0, Integer.MIN_VALUE, 0);
testOfHoursMinutesSecondsBad(0, 0, Integer.MAX_VALUE);
testOfHoursMinutesSecondsBad(0, 0, Integer.MIN_VALUE);
}
private void testOfHoursMinutesSecondsGood(long hours, int minutes, int seconds) {
Interval i = Interval.ofHoursMinutesSeconds(hours, minutes, seconds);
assertEquals(hours, i.getHours());
assertEquals(minutes, i.getMinutes());
assertEquals(seconds, i.getSeconds());
assertEquals(0, i.getNanosOfSecond());
assertEquals(seconds * NANOS_PER_SECOND, i.getSecondsAndNanos());
StringBuilder b = new StringBuilder("INTERVAL '");
if (hours < 0 || minutes < 0 || seconds < 0) {
b.append('-');
}
b.append(Math.abs(hours)).append(':');
StringUtils.appendZeroPadded(b, 2, Math.abs(minutes));
b.append(':');
StringUtils.appendZeroPadded(b, 2, Math.abs(seconds));
b.append("' HOUR TO SECOND");
assertEquals(b.toString(), i.toString());
}
private void testOfHoursMinutesSecondsBad(long hours, int minutes, int seconds) {
try {
Interval.ofHoursMinutesSeconds(hours, minutes, seconds);
fail();
} catch (IllegalArgumentException e) {
// OK
}
}
private void testOfMinutesSeconds() {
testOfMinutesSecondsGood(0, 0);
testOfMinutesSecondsGood(0, -2);
testOfMinutesSecondsGood(100, 5);
testOfMinutesSecondsGood(-100, -1);
testOfMinutesSecondsGood(MAX, 59);
testOfMinutesSecondsGood(MIN, -59);
testOfMinutesSecondsBad(0, 60);
testOfMinutesSecondsBad(0, -60);
testOfMinutesSecondsBad(MAX + 1, 0);
testOfMinutesSecondsBad(MIN - 1, 0);
testOfMinutesSecondsBad(Long.MAX_VALUE, 0);
testOfMinutesSecondsBad(Long.MIN_VALUE, 0);
testOfMinutesSecondsBad(0, Integer.MAX_VALUE);
testOfMinutesSecondsBad(0, Integer.MIN_VALUE);
}
private void testOfMinutesSecondsGood(long minutes, int seconds) {
Interval i = Interval.ofMinutesSeconds(minutes, seconds);
assertEquals(minutes, i.getMinutes());
assertEquals(seconds, i.getSeconds());
assertEquals(0, i.getNanosOfSecond());
assertEquals(seconds * NANOS_PER_SECOND, i.getSecondsAndNanos());
StringBuilder b = new StringBuilder("INTERVAL '");
if (minutes < 0 || seconds < 0) {
b.append('-');
}
b.append(Math.abs(minutes)).append(':');
StringUtils.appendZeroPadded(b, 2, Math.abs(seconds));
b.append("' MINUTE TO SECOND");
assertEquals(b.toString(), i.toString());
}
private void testOfMinutesSecondsBad(long minutes, int seconds) {
try {
Interval.ofMinutesSeconds(minutes, seconds);
fail();
} catch (IllegalArgumentException e) {
// OK
}
}
private static void stripTrailingZeroes(StringBuilder b) {
int i = b.length() - 1;
if (b.charAt(i) == '0') {
while (b.charAt(--i) == '0') {
// do nothing
}
b.setLength(i + 1);
}
} }
} }
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论