提交 c81f6743 authored 作者: Evgenij Ryazanov's avatar Evgenij Ryazanov

Add some helper methods to Interval class

上级 dbc68eae
......@@ -20,6 +20,67 @@ public final class Interval {
private final long remaining;
/**
* @param years
* years
* @return interval
*/
public static Interval ofYears(long years) {
return new Interval(IntervalQualifier.YEAR, years < 0, Math.abs(years), 0);
}
/**
* @param months
* months
* @return interval
*/
public static Interval ofMonths(long months) {
return new Interval(IntervalQualifier.MONTH, months < 0, Math.abs(months), 0);
}
/**
* @param days
* days
* @return interval
*/
public static Interval ofDays(long days) {
return new Interval(IntervalQualifier.DAY, days < 0, Math.abs(days), 0);
}
/**
* @param hours
* hours
* @return interval
*/
public static Interval ofHours(long hours) {
return new Interval(IntervalQualifier.HOUR, hours < 0, Math.abs(hours), 0);
}
/**
* @param minutes
* minutes
* @return interval
*/
public static Interval ofMinutes(long minutes) {
return new Interval(IntervalQualifier.MINUTE, minutes < 0, Math.abs(minutes), 0);
}
/**
* @param nanos
* nanoseconds (including seconds)
* @return interval
*/
public static Interval ofNanos(long nanos) {
boolean negative = nanos < 0;
if (negative) {
nanos = -nanos;
if (nanos < 0) {
throw new IllegalArgumentException();
}
}
return new Interval(IntervalQualifier.SECOND, negative, nanos / 1_000_000_000, nanos % 1_000_000_000);
}
/**
* @param qualifier
* qualifier
......@@ -83,6 +144,48 @@ public final class Interval {
return remaining;
}
/**
* @return years, or 0
*/
public long getYears() {
return DateTimeUtils.yearsFromInterval(qualifier, negative, leading, remaining);
}
/**
* @return months, or 0
*/
public long getMonths() {
return DateTimeUtils.monthsFromInterval(qualifier, negative, leading, remaining);
}
/**
* @return days, or 0
*/
public long getDays() {
return DateTimeUtils.daysFromInterval(qualifier, negative, leading, remaining);
}
/**
* @return hours, or 0
*/
public long getHours() {
return DateTimeUtils.hoursFromInterval(qualifier, negative, leading, remaining);
}
/**
* @return minutes, or 0
*/
public long getMinutes() {
return DateTimeUtils.minutesFromInterval(qualifier, negative, leading, remaining);
}
/**
* @return nanoseconds (including seconds), or 0
*/
public long getNanos() {
return DateTimeUtils.nanosFromInterval(qualifier, negative, leading, remaining);
}
@Override
public int hashCode() {
final int prime = 31;
......
......@@ -35,9 +35,9 @@ import java.util.HashMap;
import java.util.Locale;
import java.util.TimeZone;
import org.h2.api.ErrorCode;
import org.h2.api.IntervalQualifier;
import org.h2.expression.Function;
import org.h2.message.DbException;
import org.h2.value.DataType;
import org.h2.value.Value;
import org.h2.value.ValueDate;
import org.h2.value.ValueDecimal;
......@@ -623,36 +623,39 @@ public final class DateTimeFunctions {
public static int getIntDatePart(Value date, int field) {
if (date instanceof ValueInterval) {
ValueInterval interval = (ValueInterval) date;
IntervalQualifier qualifier = interval.getQualifier();
boolean negative = interval.isNegative();
long leading = interval.getLeading(), remaining = interval.getRemaining();
long v;
switch (field) {
case YEAR:
v = DateTimeUtils.yearsFromInterval(interval);
v = DateTimeUtils.yearsFromInterval(qualifier, negative, leading, remaining);
break;
case MONTH:
v = DateTimeUtils.monthFromInterval(interval);
v = DateTimeUtils.monthsFromInterval(qualifier, negative, leading, remaining);
break;
case DAY_OF_MONTH:
case DAY_OF_WEEK:
case DAY_OF_YEAR:
v = DateTimeUtils.daysFromInterval(interval);
v = DateTimeUtils.daysFromInterval(qualifier, negative, leading, remaining);
break;
case HOUR:
v = DateTimeUtils.hoursFromInterval(interval);
v = DateTimeUtils.hoursFromInterval(qualifier, negative, leading, remaining);
break;
case MINUTE:
v = DateTimeUtils.minutesFromInterval(interval);
v = DateTimeUtils.minutesFromInterval(qualifier, negative, leading, remaining);
break;
case SECOND:
v = DateTimeUtils.nanosFromInterval(interval) / 1_000_000_000;
v = DateTimeUtils.nanosFromInterval(qualifier, negative, leading, remaining) / 1_000_000_000;
break;
case MILLISECOND:
v = DateTimeUtils.nanosFromInterval(interval) / 1_000_000 % 1_000;
v = DateTimeUtils.nanosFromInterval(qualifier, negative, leading, remaining) / 1_000_000 % 1_000;
break;
case MICROSECOND:
v = DateTimeUtils.nanosFromInterval(interval) / 1_000 % 1_000_000;
v = DateTimeUtils.nanosFromInterval(qualifier, negative, leading, remaining) / 1_000 % 1_000_000;
break;
case NANOSECOND:
v = DateTimeUtils.nanosFromInterval(interval) % 1_000_000_000;
v = DateTimeUtils.nanosFromInterval(qualifier, negative, leading, remaining) % 1_000_000_000;
break;
default:
throw DbException.getUnsupportedException("getDatePart(" + date + ", " + field + ')');
......
......@@ -2040,14 +2040,20 @@ public class DateTimeUtils {
}
/**
* @param value interval
* @param qualifier
* qualifier
* @param negative
* whether interval is negative
* @param leading
* value of leading field
* @param remaining
* values of all remaining fields
* @return years, or 0
*/
public static long yearsFromInterval(ValueInterval value) {
IntervalQualifier qualifier = value.getQualifier();
public static long yearsFromInterval(IntervalQualifier qualifier, boolean negative, long leading, long remaining) {
if (qualifier == IntervalQualifier.YEAR || qualifier == IntervalQualifier.YEAR_TO_MONTH) {
long v = value.getLeading();
if (value.isNegative()) {
long v = leading;
if (negative) {
v = -v;
}
return v;
......@@ -2057,37 +2063,50 @@ public class DateTimeUtils {
}
/**
* @param value interval
* @param qualifier
* qualifier
* @param negative
* whether interval is negative
* @param leading
* value of leading field
* @param remaining
* values of all remaining fields
* @return months, or 0
*/
public static long monthFromInterval(ValueInterval value) {
IntervalQualifier qualifier = value.getQualifier();
public static long monthsFromInterval(IntervalQualifier qualifier, boolean negative, long leading, long remaining) {
long v;
if (qualifier == IntervalQualifier.MONTH) {
v = value.getLeading();
v = leading;
} else if (qualifier == IntervalQualifier.YEAR_TO_MONTH){
v = value.getRemaining();
v = remaining;
} else {
return 0;
}
if (value.isNegative()) {
if (negative) {
v = -v;
}
return v;
}
/**
* @param value interval
* @param qualifier
* qualifier
* @param negative
* whether interval is negative
* @param leading
* value of leading field
* @param remaining
* values of all remaining fields
* @return months, or 0
*/
public static long daysFromInterval(ValueInterval value) {
switch (value.getQualifier()) {
public static long daysFromInterval(IntervalQualifier qualifier, boolean negative, long leading, long remaining) {
switch (qualifier) {
case DAY:
case DAY_TO_HOUR:
case DAY_TO_MINUTE:
case DAY_TO_SECOND:
long v = value.getLeading();
if (value.isNegative()) {
long v = leading;
if (negative) {
v = -v;
}
return v;
......@@ -2097,88 +2116,110 @@ public class DateTimeUtils {
}
/**
* @param value interval
* @param qualifier
* qualifier
* @param negative
* whether interval is negative
* @param leading
* value of leading field
* @param remaining
* values of all remaining fields
* @return hours, or 0
*/
public static long hoursFromInterval(ValueInterval value) {
public static long hoursFromInterval(IntervalQualifier qualifier, boolean negative, long leading, long remaining) {
long v;
switch (value.getQualifier()) {
switch (qualifier) {
case HOUR:
case HOUR_TO_MINUTE:
case HOUR_TO_SECOND:
v = value.getLeading();
v = leading;
break;
case DAY_TO_HOUR:
v = value.getRemaining();
v = remaining;
break;
case DAY_TO_MINUTE:
v = value.getRemaining() / 60;
v = remaining / 60;
break;
case DAY_TO_SECOND:
v = value.getRemaining() / 3_600_000_000_000L;
v = remaining / 3_600_000_000_000L;
break;
default:
return 0;
}
if (value.isNegative()) {
if (negative) {
v = -v;
}
return v;
}
/**
* @param value interval
* @param qualifier
* qualifier
* @param negative
* whether interval is negative
* @param leading
* value of leading field
* @param remaining
* values of all remaining fields
* @return minutes, or 0
*/
public static long minutesFromInterval(ValueInterval value) {
public static long minutesFromInterval(IntervalQualifier qualifier, boolean negative, long leading, long remaining)
{
long v;
switch (value.getQualifier()) {
switch (qualifier) {
case MINUTE:
case MINUTE_TO_SECOND:
v = value.getLeading();
v = leading;
break;
case DAY_TO_MINUTE:
v = value.getRemaining() % 60;
v = remaining % 60;
break;
case DAY_TO_SECOND:
v = value.getRemaining() / 60_000_000_000L % 60;
v = remaining / 60_000_000_000L % 60;
break;
case HOUR_TO_MINUTE:
v = value.getRemaining();
v = remaining;
break;
case HOUR_TO_SECOND:
v = value.getRemaining() / 60_000_000_000L;
v = remaining / 60_000_000_000L;
break;
default:
return 0;
}
if (value.isNegative()) {
if (negative) {
v = -v;
}
return v;
}
/**
* @param value interval
* @param qualifier
* qualifier
* @param negative
* whether interval is negative
* @param leading
* value of leading field
* @param remaining
* values of all remaining fields
* @return nanoseconds, or 0
*/
public static long nanosFromInterval(ValueInterval value) {
public static long nanosFromInterval(IntervalQualifier qualifier, boolean negative, long leading, long remaining) {
long v;
switch (value.getQualifier()) {
switch (qualifier) {
case SECOND:
v = value.getLeading() * 1_000_000_000 + value.getRemaining();
v = leading * 1_000_000_000 + remaining;
break;
case DAY_TO_SECOND:
case HOUR_TO_SECOND:
v = value.getRemaining() % 60_000_000_000L;
v = remaining % 60_000_000_000L;
break;
case MINUTE_TO_SECOND:
v = value.getRemaining();
v = remaining;
break;
default:
return 0;
}
if (value.isNegative()) {
if (negative) {
v = -v;
}
return v;
......
......@@ -190,6 +190,7 @@ import org.h2.test.unit.TestFtp;
import org.h2.test.unit.TestIntArray;
import org.h2.test.unit.TestIntIntHashMap;
import org.h2.test.unit.TestIntPerfectHash;
import org.h2.test.unit.TestInterval;
import org.h2.test.unit.TestJmx;
import org.h2.test.unit.TestLocale;
import org.h2.test.unit.TestMathUtils;
......@@ -957,6 +958,7 @@ kill -9 `jps -l | grep "org.h2.test." | cut -d " " -f 1`
addTest(new TestDateIso8601());
addTest(new TestFile());
addTest(new TestFtp());
addTest(new TestInterval());
addTest(new TestIntArray());
addTest(new TestIntIntHashMap());
addTest(new TestIntPerfectHash());
......
/*
* Copyright 2004-2018 H2 Group. Multiple-Licensed under the MPL 2.0,
* and the EPL 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.test.unit;
import org.h2.api.Interval;
import org.h2.test.TestBase;
/**
* Test cases for Interval.
*/
public class TestInterval extends TestBase {
/**
* Run just this test.
*
* @param a
* ignored
*/
public static void main(String... a) throws Exception {
TestBase.createCaller().init().test();
}
@Override
public void test() throws Exception {
Interval i;
i = Interval.ofYears(100);
assertEquals(100, i.getYears());
assertEquals("INTERVAL '100' YEAR", i.toString());
i = Interval.ofMonths(100);
assertEquals(100, i.getMonths());
assertEquals("INTERVAL '100' MONTH", i.toString());
i = Interval.ofDays(100);
assertEquals(100, i.getDays());
assertEquals("INTERVAL '100' DAY", i.toString());
i = Interval.ofHours(100);
assertEquals(100, i.getHours());
assertEquals("INTERVAL '100' HOUR", i.toString());
i = Interval.ofMinutes(100);
assertEquals(100, i.getMinutes());
assertEquals("INTERVAL '100' MINUTE", i.toString());
i = Interval.ofNanos(100_123_456_789L);
assertEquals(100_123_456_789L, i.getNanos());
assertEquals("INTERVAL '100.123456789' SECOND", i.toString());
}
}
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论