Unverified 提交 e85ffecb authored 作者: Evgenij Ryazanov's avatar Evgenij Ryazanov 提交者: GitHub

Merge pull request #1378 from katzyn/datetime

Add more methods to Interval and remove h2.unlimitedTimeRange
...@@ -383,38 +383,6 @@ public class SysProperties { ...@@ -383,38 +383,6 @@ public class SysProperties {
*/ */
public static final boolean RETURN_OFFSET_DATE_TIME = Utils.getProperty("h2.returnOffsetDateTime", PREVIEW); public static final boolean RETURN_OFFSET_DATE_TIME = Utils.getProperty("h2.returnOffsetDateTime", PREVIEW);
/**
* System property {@code h2.unlimitedTimeRange}, {@code false} by default.
*
* <p>
* Controls limits of TIME data type.
* </p>
*
* <table>
* <thead>
* <tr>
* <th>h2.unlimitedTimeRange</th>
* <th>Minimum TIME value</th>
* <th>Maximum TIME value</th>
* </tr>
* </thead>
* <tbody>
* <tr>
* <td>false</td>
* <td>00:00:00.000000000</td>
* <td>23:59:59.999999999</td>
* </tr>
* <tr>
* <td>true</td>
* <td>-2562047:47:16.854775808</td>
* <td>2562047:47:16.854775807</td>
* </tr>
* </tbody>
* </table>
*/
public static final boolean UNLIMITED_TIME_RANGE =
Utils.getProperty("h2.unlimitedTimeRange", false);
/** /**
* System property <code>h2.pgClientEncoding</code> (default: UTF-8).<br /> * System property <code>h2.pgClientEncoding</code> (default: UTF-8).<br />
* Default client encoding for PG server. It is used if the client does not * Default client encoding for PG server. It is used if the client does not
......
...@@ -364,21 +364,17 @@ public class DateTimeUtils { ...@@ -364,21 +364,17 @@ public class DateTimeUtils {
} }
/** /**
* Parse a time string. The format is: [-]hour:minute:second[.nanos] or * Parse a time string. The format is: hour:minute:second[.nanos] or
* alternatively [-]hour.minute.second[.nanos]. * alternatively hour.minute.second[.nanos].
* *
* @param s the string to parse * @param s the string to parse
* @param start the parse index start * @param start the parse index start
* @param end the parse index end * @param end the parse index end
* @param timeOfDay whether the result need to be within 0 (inclusive) and 1
* day (exclusive)
* @return the time in nanoseconds * @return the time in nanoseconds
* @throws IllegalArgumentException if there is a problem * @throws IllegalArgumentException if there is a problem
*/ */
public static long parseTimeNanos(String s, int start, int end, public static long parseTimeNanos(String s, int start, int end) {
boolean timeOfDay) { int hour, minute, second, nanos;
int hour = 0, minute = 0, second = 0;
long nanos = 0;
int s1 = s.indexOf(':', start); int s1 = s.indexOf(':', start);
int s2 = s.indexOf(':', s1 + 1); int s2 = s.indexOf(':', s1 + 1);
int s3 = s.indexOf('.', s2 + 1); int s3 = s.indexOf('.', s2 + 1);
...@@ -388,41 +384,26 @@ public class DateTimeUtils { ...@@ -388,41 +384,26 @@ public class DateTimeUtils {
s1 = s.indexOf('.', start); s1 = s.indexOf('.', start);
s2 = s.indexOf('.', s1 + 1); s2 = s.indexOf('.', s1 + 1);
s3 = s.indexOf('.', s2 + 1); s3 = s.indexOf('.', s2 + 1);
if (s1 <= 0 || s2 <= s1) { if (s1 <= 0 || s2 <= s1) {
throw new IllegalArgumentException(s); throw new IllegalArgumentException(s);
} }
} }
boolean negative;
hour = Integer.parseInt(s.substring(start, s1)); hour = Integer.parseInt(s.substring(start, s1));
if (hour < 0 || hour == 0 && s.charAt(0) == '-') { if (hour < 0 || hour == 0 && s.charAt(0) == '-' || hour >= 24) {
if (timeOfDay) { throw new IllegalArgumentException(s);
/*
* This also forbids -00:00:00 and similar values.
*/
throw new IllegalArgumentException(s);
}
negative = true;
hour = -hour;
} else {
negative = false;
} }
minute = Integer.parseInt(s.substring(s1 + 1, s2)); minute = Integer.parseInt(s.substring(s1 + 1, s2));
if (s3 < 0) { if (s3 < 0) {
second = Integer.parseInt(s.substring(s2 + 1, end)); second = Integer.parseInt(s.substring(s2 + 1, end));
nanos = 0;
} else { } else {
second = Integer.parseInt(s.substring(s2 + 1, s3)); second = Integer.parseInt(s.substring(s2 + 1, s3));
nanos = parseNanos(s, s3 + 1, end); nanos = parseNanos(s, s3 + 1, end);
} }
if (hour >= 2_000_000 || minute < 0 || minute >= 60 || second < 0 if (minute < 0 || minute >= 60 || second < 0 || second >= 60) {
|| second >= 60) {
throw new IllegalArgumentException(s);
}
if (timeOfDay && hour >= 24) {
throw new IllegalArgumentException(s); throw new IllegalArgumentException(s);
} }
nanos += ((((hour * 60L) + minute) * 60) + second) * NANOS_PER_SECOND; return ((((hour * 60L) + minute) * 60) + second) * NANOS_PER_SECOND + nanos;
return negative ? -nanos : nanos;
} }
private static int parseNanos(String s, int start, int end) { private static int parseNanos(String s, int start, int end) {
...@@ -514,7 +495,7 @@ public class DateTimeUtils { ...@@ -514,7 +495,7 @@ public class DateTimeUtils {
} }
} }
} }
nanos = parseTimeNanos(s, dateEnd + 1, timeEnd, true); nanos = parseTimeNanos(s, dateEnd + 1, timeEnd);
if (tz != null) { if (tz != null) {
if (withTimeZone) { if (withTimeZone) {
if (tz != UTC) { if (tz != UTC) {
......
...@@ -9,7 +9,6 @@ import java.sql.PreparedStatement; ...@@ -9,7 +9,6 @@ import java.sql.PreparedStatement;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.Time; import java.sql.Time;
import org.h2.api.ErrorCode; import org.h2.api.ErrorCode;
import org.h2.engine.SysProperties;
import org.h2.message.DbException; import org.h2.message.DbException;
import org.h2.util.DateTimeUtils; import org.h2.util.DateTimeUtils;
...@@ -69,13 +68,11 @@ public class ValueTime extends Value { ...@@ -69,13 +68,11 @@ public class ValueTime extends Value {
* @return the value * @return the value
*/ */
public static ValueTime fromNanos(long nanos) { public static ValueTime fromNanos(long nanos) {
if (!SysProperties.UNLIMITED_TIME_RANGE) { if (nanos < 0L || nanos >= DateTimeUtils.NANOS_PER_DAY) {
if (nanos < 0L || nanos >= DateTimeUtils.NANOS_PER_DAY) { StringBuilder builder = new StringBuilder();
StringBuilder builder = new StringBuilder(); DateTimeUtils.appendTime(builder, nanos);
DateTimeUtils.appendTime(builder, nanos); throw DbException.get(ErrorCode.INVALID_DATETIME_CONSTANT_2,
throw DbException.get(ErrorCode.INVALID_DATETIME_CONSTANT_2, "TIME", builder.toString());
"TIME", builder.toString());
}
} }
return (ValueTime) Value.cache(new ValueTime(nanos)); return (ValueTime) Value.cache(new ValueTime(nanos));
} }
...@@ -109,7 +106,7 @@ public class ValueTime extends Value { ...@@ -109,7 +106,7 @@ public class ValueTime extends Value {
*/ */
public static ValueTime parse(String s) { public static ValueTime parse(String s) {
try { try {
return fromNanos(DateTimeUtils.parseTimeNanos(s, 0, s.length(), false)); return fromNanos(DateTimeUtils.parseTimeNanos(s, 0, s.length()));
} catch (Exception e) { } catch (Exception e) {
throw DbException.get(ErrorCode.INVALID_DATETIME_CONSTANT_2, throw DbException.get(ErrorCode.INVALID_DATETIME_CONSTANT_2,
e, "TIME", s); e, "TIME", s);
......
...@@ -15,7 +15,6 @@ import java.util.GregorianCalendar; ...@@ -15,7 +15,6 @@ import java.util.GregorianCalendar;
import java.util.TimeZone; import java.util.TimeZone;
import org.h2.api.ErrorCode; import org.h2.api.ErrorCode;
import org.h2.engine.SysProperties;
import org.h2.message.DbException; import org.h2.message.DbException;
import org.h2.test.TestBase; import org.h2.test.TestBase;
import org.h2.test.utils.AssertThrows; import org.h2.test.utils.AssertThrows;
...@@ -119,36 +118,17 @@ public class TestDate extends TestBase { ...@@ -119,36 +118,17 @@ public class TestDate extends TestBase {
assertEquals("00:00:00", ValueTime.fromNanos(0).getString()); assertEquals("00:00:00", ValueTime.fromNanos(0).getString());
assertEquals("23:59:59", ValueTime.parse("23:59:59").getString()); assertEquals("23:59:59", ValueTime.parse("23:59:59").getString());
assertEquals("11:22:33.444555666", ValueTime.parse("11:22:33.444555666").getString()); assertEquals("11:22:33.444555666", ValueTime.parse("11:22:33.444555666").getString());
if (SysProperties.UNLIMITED_TIME_RANGE) { try {
assertEquals("99:59:59", ValueTime.parse("99:59:59").getString()); ValueTime.parse("-00:00:00.000000001");
assertEquals("-00:10:10", ValueTime.parse("-00:10:10").getString()); fail();
assertEquals("-99:02:03.001002003", } catch (DbException ex) {
ValueTime.parse("-99:02:03.001002003").getString()); assertEquals(ErrorCode.INVALID_DATETIME_CONSTANT_2, ex.getErrorCode());
assertEquals("-99:02:03.001002", }
ValueTime.parse("-99:02:03.001002000").getString()); try {
assertEquals("-99:02:03", ValueTime.parse("24:00:00");
ValueTime.parse("-99:02:03.0000000000001").getString()); fail();
assertEquals("1999999:59:59.999999999", } catch (DbException ex) {
ValueTime.parse("1999999:59:59.999999999").getString()); assertEquals(ErrorCode.INVALID_DATETIME_CONSTANT_2, ex.getErrorCode());
assertEquals("-1999999:59:59.999999999",
ValueTime.parse("-1999999:59:59.999999999").getString());
assertEquals("2562047:47:16.854775807",
ValueTime.fromNanos(Long.MAX_VALUE).getString());
assertEquals("-2562047:47:16.854775808",
ValueTime.fromNanos(Long.MIN_VALUE).getString());
} else {
try {
ValueTime.parse("-00:00:00.000000001");
fail();
} catch (DbException ex) {
assertEquals(ErrorCode.INVALID_DATETIME_CONSTANT_2, ex.getErrorCode());
}
try {
ValueTime.parse("24:00:00");
fail();
} catch (DbException ex) {
assertEquals(ErrorCode.INVALID_DATETIME_CONSTANT_2, ex.getErrorCode());
}
} }
ValueTime t1 = ValueTime.parse("11:11:11"); ValueTime t1 = ValueTime.parse("11:11:11");
assertEquals("11:11:11", t1.getTime().toString()); assertEquals("11:11:11", t1.getTime().toString());
...@@ -182,24 +162,6 @@ public class TestDate extends TestBase { ...@@ -182,24 +162,6 @@ public class TestDate extends TestBase {
assertFalse(t2.equals(t1)); assertFalse(t2.equals(t1));
assertEquals(-1, t1.compareTo(t2, null, null)); assertEquals(-1, t1.compareTo(t2, null, null));
assertEquals(1, t2.compareTo(t1, null, null)); assertEquals(1, t2.compareTo(t1, null, null));
if (SysProperties.UNLIMITED_TIME_RANGE) {
assertEquals(-1, t1.negate().getSignum());
assertEquals("-11:11:11", t1.negate().getString());
assertEquals("11:11:11", t1.negate().negate().getString());
assertEquals("33:33:33", t1.add(t2).getString());
assertEquals("33:33:33", t1.multiply(ValueInt.get(4)).subtract(t1).getString());
// can't convert using java.util.Date
assertEquals(
"1969-12-31 23:00:00.0",
ValueTime.parse("-1:00:00").
convertTo(Value.TIMESTAMP).getString());
assertEquals(
"1970-01-01",
ValueTime.parse("-1:00:00").
convertTo(Value.DATE).getString());
}
} }
private void testValueTimestampWithTimezone() { private void testValueTimestampWithTimezone() {
...@@ -323,15 +285,6 @@ public class TestDate extends TestBase { ...@@ -323,15 +285,6 @@ public class TestDate extends TestBase {
ValueTimestamp.parse("-1010-10-10 10:10:10").subtract( ValueTimestamp.parse("-1010-10-10 10:10:10").subtract(
ValueTime.parse("10:10:10")).getString()); ValueTime.parse("10:10:10")).getString());
if (SysProperties.UNLIMITED_TIME_RANGE) {
assertEquals("2001-01-02 01:01:01",
ValueTimestamp.parse("2001-01-01").add(
ValueTime.parse("25:01:01")).getString());
assertEquals("1010-10-10 10:00:00",
ValueTimestamp.parse("1010-10-11 10:10:10").subtract(
ValueTime.parse("24:10:10")).getString());
}
assertEquals(0, DateTimeUtils.absoluteDayFromDateValue( assertEquals(0, DateTimeUtils.absoluteDayFromDateValue(
ValueTimestamp.parse("1970-01-01").getDateValue())); ValueTimestamp.parse("1970-01-01").getDateValue()));
assertEquals(0, ValueTimestamp.parse( assertEquals(0, ValueTimestamp.parse(
......
...@@ -53,11 +53,11 @@ public class TestDateTimeUtils extends TestBase { ...@@ -53,11 +53,11 @@ public class TestDateTimeUtils extends TestBase {
} }
private void testParseTimeNanosDB2Format() { private void testParseTimeNanosDB2Format() {
assertEquals(3723004000000L, DateTimeUtils.parseTimeNanos("01:02:03.004", 0, 12, true)); assertEquals(3723004000000L, DateTimeUtils.parseTimeNanos("01:02:03.004", 0, 12));
assertEquals(3723004000000L, DateTimeUtils.parseTimeNanos("01.02.03.004", 0, 12, true)); assertEquals(3723004000000L, DateTimeUtils.parseTimeNanos("01.02.03.004", 0, 12));
assertEquals(3723000000000L, DateTimeUtils.parseTimeNanos("01:02:03", 0, 8, true)); assertEquals(3723000000000L, DateTimeUtils.parseTimeNanos("01:02:03", 0, 8));
assertEquals(3723000000000L, DateTimeUtils.parseTimeNanos("01.02.03", 0, 8, true)); assertEquals(3723000000000L, DateTimeUtils.parseTimeNanos("01.02.03", 0, 8));
} }
/** /**
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论