提交 43fbbf1e authored 作者: Thomas Mueller's avatar Thomas Mueller

Date, time, and timestamp data type processing has been re-implemented.

上级 891cef2f
......@@ -350,8 +350,8 @@ public class SysProperties {
/**
* System property <code>h2.storeLocalTime</code> (default: false).<br />
* Store the local time in milliseconds since 1970 in the database file. If
* disabled, the daylight saving offset is not taken into account.
* Store the local time. If disabled, the daylight saving offset is not
* taken into account.
*/
public static final boolean STORE_LOCAL_TIME = Utils.getProperty("h2.storeLocalTime", false);
......
......@@ -471,7 +471,12 @@ public class Data {
case Value.TIME:
if (SysProperties.STORE_LOCAL_TIME) {
writeByte((byte) LOCAL_TIME);
writeVarLong(((ValueTime) v).getNanos());
ValueTime t = (ValueTime) v;
long nanos = t.getNanos();
long millis = nanos / 1000000;
nanos -= millis * 1000000;
writeVarLong(millis);
writeVarLong(nanos);
} else {
writeByte((byte) type);
writeVarLong(DateTimeUtils.getTimeLocalWithoutDst(v.getTime()));
......@@ -494,8 +499,11 @@ public class Data {
writeByte((byte) LOCAL_TIMESTAMP);
ValueTimestamp ts = (ValueTimestamp) v;
long dateValue = ts.getDateValue();
long nanos = ts.getNanos();
writeVarLong(dateValue);
long nanos = ts.getNanos();
long millis = nanos / 1000000;
nanos -= millis * 1000000;
writeVarLong(millis);
writeVarLong(nanos);
} else {
Timestamp ts = v.getTimestamp();
......@@ -683,21 +691,23 @@ public class Data {
return ValueDecimal.get(new BigDecimal(b, scale));
}
case LOCAL_DATE: {
return ValueDate.get(readVarLong());
return ValueDate.fromDateValue(readVarLong());
}
case Value.DATE: {
long x = readVarLong() * MILLIS_PER_MINUTE;
return ValueDate.get(new Date(DateTimeUtils.getTimeUTCWithoutDst(x)));
}
case LOCAL_TIME:
return ValueTime.get(readVarLong());
case LOCAL_TIME: {
long nanos = readVarLong() * 1000000 + readVarLong();
return ValueTime.fromNanos(nanos);
}
case Value.TIME:
// need to normalize the year, month and day
return ValueTime.get(new Time(DateTimeUtils.getTimeUTCWithoutDst(readVarLong())));
case LOCAL_TIMESTAMP: {
long dateValue = readVarLong();
long nanos = readVarLong();
return ValueTimestamp.get(dateValue, nanos);
long nanos = readVarLong() * 1000000 + readVarLong();
return ValueTimestamp.fromDateValueAndNanos(dateValue, nanos);
}
case Value.TIMESTAMP: {
Timestamp ts = new Timestamp(DateTimeUtils.getTimeUTCWithoutDst(readVarLong()));
......@@ -895,7 +905,10 @@ public class Data {
}
case Value.TIME:
if (SysProperties.STORE_LOCAL_TIME) {
return 1 + getVarLongLen(((ValueTime) v).getNanos());
long nanos = ((ValueTime) v).getNanos();
long millis = nanos / 1000000;
nanos -= millis * 1000000;
return 1 + getVarLongLen(millis) + getVarLongLen(nanos);
}
return 1 + getVarLongLen(DateTimeUtils.getTimeLocalWithoutDst(v.getTime()));
case Value.DATE: {
......@@ -911,7 +924,9 @@ public class Data {
ValueTimestamp ts = (ValueTimestamp) v;
long dateValue = ts.getDateValue();
long nanos = ts.getNanos();
return 1 + getVarLongLen(dateValue) + getVarLongLen(nanos);
long millis = nanos / 1000000;
nanos -= millis * 1000000;
return 1 + getVarLongLen(dateValue) + getVarLongLen(millis) + getVarLongLen(nanos);
}
Timestamp ts = v.getTimestamp();
return 1 + getVarLongLen(DateTimeUtils.getTimeLocalWithoutDst(ts)) + getVarIntLen(ts.getNanos());
......
......@@ -6,8 +6,8 @@
*/
package org.h2.table;
import java.sql.Date;
import java.sql.ResultSetMetaData;
import java.sql.Time;
import java.sql.Timestamp;
import org.h2.command.Parser;
import org.h2.constant.ErrorCode;
......@@ -27,6 +27,7 @@ import org.h2.util.MathUtils;
import org.h2.util.StringUtils;
import org.h2.value.DataType;
import org.h2.value.Value;
import org.h2.value.ValueDate;
import org.h2.value.ValueInt;
import org.h2.value.ValueLong;
import org.h2.value.ValueNull;
......@@ -284,15 +285,11 @@ public class Column {
if (dt.decimal) {
value = ValueInt.get(0).convertTo(type);
} else if (dt.type == Value.TIMESTAMP) {
// TODO
value = ValueTimestamp.get(new Timestamp(System.currentTimeMillis()));
value = ValueTimestamp.get(new Timestamp(session.getTransactionStart()));
} else if (dt.type == Value.TIME) {
// TODO
// need to normalize
value = ValueTime.get(Time.valueOf("0:0:0"));
value = ValueTime.fromNanos(0);
} else if (dt.type == Value.DATE) {
// TODO
value = ValueTimestamp.get(new Timestamp(System.currentTimeMillis())).convertTo(dt.type);
value = ValueDate.get(new Date(session.getTransactionStart()));
} else {
value = ValueString.get("").convertTo(type);
}
......
......@@ -626,7 +626,7 @@ public class DateTimeUtils {
nanos -= d * NANOS_PER_DAY;
absoluteDay += d;
}
return ValueTimestamp.get(dateValueFromAbsoluteDay(absoluteDay), nanos);
return ValueTimestamp.fromDateValueAndNanos(dateValueFromAbsoluteDay(absoluteDay), nanos);
}
public static long absoluteDayFromDateValue(long dateValue) {
......
......@@ -471,21 +471,21 @@ public class Transfer {
return ValueByte.get(readByte());
case Value.DATE:
if (version >= Constants.TCP_PROTOCOL_VERSION_9) {
return ValueDate.get(readLong());
return ValueDate.fromDateValue(readLong());
} else if (version >= Constants.TCP_PROTOCOL_VERSION_7) {
return ValueDate.get(new Date(DateTimeUtils.getTimeUTCWithoutDst(readLong())));
}
return ValueDate.get(new Date(readLong()));
case Value.TIME:
if (version >= Constants.TCP_PROTOCOL_VERSION_9) {
return ValueTime.get(readLong());
return ValueTime.fromNanos(readLong());
} else if (version >= Constants.TCP_PROTOCOL_VERSION_7) {
return ValueTime.get(new Time(DateTimeUtils.getTimeUTCWithoutDst(readLong())));
}
return ValueTime.get(new Time(readLong()));
case Value.TIMESTAMP: {
if (version >= Constants.TCP_PROTOCOL_VERSION_9) {
return ValueTimestamp.get(readLong(), readLong());
return ValueTimestamp.fromDateValueAndNanos(readLong(), readLong());
} else if (version >= Constants.TCP_PROTOCOL_VERSION_7) {
Timestamp ts = new Timestamp(DateTimeUtils.getTimeUTCWithoutDst(readLong()));
ts.setNanos(readInt());
......
......@@ -684,9 +684,9 @@ public abstract class Value {
case TIME:
// because the time has set the date to 1970-01-01,
// this will be the result
return ValueDate.get(DateTimeUtils.dateValue(1970, 1, 1));
return ValueDate.fromDateValue(DateTimeUtils.dateValue(1970, 1, 1));
case TIMESTAMP:
return ValueDate.get(((ValueTimestamp) this).getDateValue());
return ValueDate.fromDateValue(((ValueTimestamp) this).getDateValue());
}
break;
}
......@@ -695,9 +695,9 @@ public abstract class Value {
case DATE:
// need to normalize the year, month and day
// because a date has the time set to 0, the result will be 0
return ValueTime.get(0);
return ValueTime.fromNanos(0);
case TIMESTAMP:
return ValueTime.get(((ValueTimestamp) this).getNanos());
return ValueTime.fromNanos(((ValueTimestamp) this).getNanos());
}
break;
}
......@@ -706,7 +706,7 @@ public abstract class Value {
case TIME:
return DateTimeUtils.normalizeTimestamp(0, ((ValueTime) this).getNanos());
case DATE:
return ValueTimestamp.get(((ValueDate) this).getDateValue(), 0);
return ValueTimestamp.fromDateValueAndNanos(((ValueDate) this).getDateValue(), 0);
}
break;
}
......
......@@ -37,6 +37,26 @@ public class ValueDate extends Value {
this.dateValue = dateValue;
}
/**
* Get or create a date value for the given date.
*
* @param dateValue the date value
* @return the value
*/
public static ValueDate fromDateValue(long dateValue) {
return (ValueDate) Value.cache(new ValueDate(dateValue));
}
/**
* Get or create a date value for the given date.
*
* @param date the date
* @return the value
*/
public static ValueDate get(Date date) {
return fromDateValue(DateTimeUtils.dateValueFromDate(date.getTime()));
}
/**
* Parse a string to a ValueDate.
*
......@@ -45,84 +65,64 @@ public class ValueDate extends Value {
*/
public static ValueDate parse(String s) {
try {
return get(DateTimeUtils.parseDateValue(s, 0, s.length()));
return fromDateValue(DateTimeUtils.parseDateValue(s, 0, s.length()));
} catch (Exception e) {
throw DbException.get(ErrorCode.INVALID_DATETIME_CONSTANT_2,
e, "DATE", s);
}
}
public Date getDate() {
return DateTimeUtils.convertDateValueToDate(dateValue);
}
public long getDateValue() {
return dateValue;
}
public String getSQL() {
return "DATE '" + getString() + "'";
public Date getDate() {
return DateTimeUtils.convertDateValueToDate(dateValue);
}
public int getType() {
return Value.DATE;
}
protected int compareSecure(Value o, CompareMode mode) {
return MathUtils.compareLong(dateValue, ((ValueDate) o).dateValue);
}
public String getString() {
StringBuilder buff = new StringBuilder(DISPLAY_SIZE);
appendDate(buff, dateValue);
return buff.toString();
}
public long getPrecision() {
return PRECISION;
public String getSQL() {
return "DATE '" + getString() + "'";
}
public int hashCode() {
return (int) (dateValue ^ (dateValue >>> 32));
public long getPrecision() {
return PRECISION;
}
public Object getObject() {
return getDate();
public int getDisplaySize() {
return DISPLAY_SIZE;
}
public void set(PreparedStatement prep, int parameterIndex) throws SQLException {
prep.setDate(parameterIndex, getDate());
protected int compareSecure(Value o, CompareMode mode) {
return MathUtils.compareLong(dateValue, ((ValueDate) o).dateValue);
}
/**
* Get or create a date value for the given date.
*
* @param date the date
* @return the value
*/
public static ValueDate get(Date date) {
return get(DateTimeUtils.dateValueFromDate(date.getTime()));
public boolean equals(Object other) {
if (this == other) {
return true;
}
return other instanceof ValueDate && dateValue == (((ValueDate) other).dateValue);
}
/**
* Get or create a date value for the given date.
*
* @param dateValue the date value
* @return the value
*/
public static ValueDate get(long dateValue) {
return (ValueDate) Value.cache(new ValueDate(dateValue));
public int hashCode() {
return (int) (dateValue ^ (dateValue >>> 32));
}
public int getDisplaySize() {
return DISPLAY_SIZE;
public Object getObject() {
return getDate();
}
public boolean equals(Object other) {
if (this == other) {
return true;
}
return other instanceof ValueDate && dateValue == (((ValueDate) other).dateValue);
public void set(PreparedStatement prep, int parameterIndex) throws SQLException {
prep.setDate(parameterIndex, getDate());
}
static void appendDate(StringBuilder buff, long dateValue) {
......
......@@ -37,6 +37,26 @@ public class ValueTime extends Value {
this.nanos = nanos;
}
/**
* Get or create a time value.
*
* @param nanos the nanoseconds
* @return the value
*/
public static ValueTime fromNanos(long nanos) {
return (ValueTime) Value.cache(new ValueTime(nanos));
}
/**
* Get or create a time value for the given time.
*
* @param time the time
* @return the value
*/
public static ValueTime get(Time time) {
return fromNanos(DateTimeUtils.nanosFromDate(time.getTime()));
}
/**
* Parse a string to a ValueTime.
*
......@@ -46,102 +66,82 @@ public class ValueTime extends Value {
public static ValueTime parse(String s) {
try {
return get(DateTimeUtils.parseTimeNanos(s, 0, s.length(), false));
return fromNanos(DateTimeUtils.parseTimeNanos(s, 0, s.length(), false));
} catch (Exception e) {
throw DbException.get(ErrorCode.INVALID_DATETIME_CONSTANT_2,
e, "TIME", s);
}
}
public Time getTime() {
return DateTimeUtils.convertNanoToTime(nanos);
}
public long getNanos() {
return nanos;
}
public String getSQL() {
return "TIME '" + getString() + "'";
public Time getTime() {
return DateTimeUtils.convertNanoToTime(nanos);
}
public int getType() {
return Value.TIME;
}
protected int compareSecure(Value o, CompareMode mode) {
return MathUtils.compareLong(nanos, ((ValueTime) o).nanos);
}
public String getString() {
StringBuilder buff = new StringBuilder(DISPLAY_SIZE);
appendTime(buff, nanos, false);
return buff.toString();
}
public long getPrecision() {
return PRECISION;
public String getSQL() {
return "TIME '" + getString() + "'";
}
public int hashCode() {
return (int) (nanos ^ (nanos >>> 32));
public long getPrecision() {
return PRECISION;
}
public Object getObject() {
return getTime();
public int getDisplaySize() {
return DISPLAY_SIZE;
}
public void set(PreparedStatement prep, int parameterIndex) throws SQLException {
prep.setTime(parameterIndex, getTime());
protected int compareSecure(Value o, CompareMode mode) {
return MathUtils.compareLong(nanos, ((ValueTime) o).nanos);
}
/**
* Get or create a time value for the given time.
*
* @param time the time
* @return the value
*/
public static ValueTime get(Time time) {
return get(DateTimeUtils.nanosFromDate(time.getTime()));
public boolean equals(Object other) {
if (this == other) {
return true;
}
return other instanceof ValueTime && nanos == (((ValueTime) other).nanos);
}
/**
* Get or create a time value.
*
* @param nanos the nanoseconds
* @return the value
*/
public static ValueTime get(long nanos) {
return (ValueTime) Value.cache(new ValueTime(nanos));
public int hashCode() {
return (int) (nanos ^ (nanos >>> 32));
}
public int getDisplaySize() {
return DISPLAY_SIZE;
public Object getObject() {
return getTime();
}
public boolean equals(Object other) {
if (this == other) {
return true;
}
return other instanceof ValueTime && nanos == (((ValueTime) other).nanos);
public void set(PreparedStatement prep, int parameterIndex) throws SQLException {
prep.setTime(parameterIndex, getTime());
}
public Value add(Value v) {
ValueTime t = (ValueTime) v.convertTo(Value.TIME);
return ValueTime.get(nanos + t.getNanos());
return ValueTime.fromNanos(nanos + t.getNanos());
}
public Value subtract(Value v) {
ValueTime t = (ValueTime) v.convertTo(Value.TIME);
return ValueTime.get(nanos - t.getNanos());
return ValueTime.fromNanos(nanos - t.getNanos());
}
public Value multiply(Value v) {
return ValueTime.get((long) (nanos * v.getDouble()));
return ValueTime.fromNanos((long) (nanos * v.getDouble()));
}
public Value divide(Value v) {
return ValueTime.get((long) (nanos / v.getDouble()));
return ValueTime.fromNanos((long) (nanos / v.getDouble()));
}
public int getSignum() {
......@@ -149,7 +149,7 @@ public class ValueTime extends Value {
}
public Value negate() {
return ValueTime.get(-nanos);
return ValueTime.fromNanos(-nanos);
}
static void appendTime(StringBuilder buff, long n, boolean alwaysAddMillis) {
......
......@@ -47,22 +47,6 @@ public class ValueTimestamp extends Value {
this.nanos = nanos;
}
public Timestamp getTimestamp() {
return DateTimeUtils.convertDateValueToTimestamp(dateValue, nanos);
}
public long getDateValue() {
return dateValue;
}
public long getNanos() {
return nanos;
}
public String getSQL() {
return "TIMESTAMP '" + getString() + "'";
}
/**
* Get or create a date value for the given date.
*
......@@ -70,10 +54,24 @@ public class ValueTimestamp extends Value {
* @param nanos the nanoseconds
* @return the value
*/
public static ValueTimestamp get(long dateValue, long nanos) {
public static ValueTimestamp fromDateValueAndNanos(long dateValue, long nanos) {
return (ValueTimestamp) Value.cache(new ValueTimestamp(dateValue, nanos));
}
/**
* Get or create a timestamp value for the given timestamp.
*
* @param timestamp the timestamp
* @return the value
*/
public static ValueTimestamp get(Timestamp timestamp) {
long ms = timestamp.getTime();
long dateValue = DateTimeUtils.dateValueFromDate(ms);
long nanos = DateTimeUtils.nanosFromDate(ms);
nanos += timestamp.getNanos() % 1000000;
return fromDateValueAndNanos(dateValue, nanos);
}
/**
* Parse a string to a ValueTimestamp. This method supports the format
* +/-year-month-day hour:minute:seconds.fractional and an optional timezone
......@@ -93,7 +91,7 @@ public class ValueTimestamp extends Value {
private static ValueTimestamp parseTry(String s) {
int dateEnd = s.indexOf(' ');
if (dateEnd <= 0) {
if (dateEnd < 0) {
// ISO 8601 compatibility
dateEnd = s.indexOf('T');
}
......@@ -114,9 +112,6 @@ public class ValueTimestamp extends Value {
if (s.endsWith("Z")) {
tz = TimeZone.getTimeZone("UTC");
timeEnd--;
while (s.charAt(timeEnd - 1) == ' ') {
timeEnd--;
}
} else {
int timeZoneStart = s.indexOf('+', dateEnd);
if (timeZoneStart < 0) {
......@@ -129,8 +124,15 @@ public class ValueTimestamp extends Value {
throw new IllegalArgumentException(tzName);
}
timeEnd = timeZoneStart;
while (s.charAt(timeEnd - 1) == ' ') {
timeEnd--;
} else {
timeZoneStart = s.indexOf(' ', dateEnd + 1);
if (timeZoneStart > 0) {
String tzName = s.substring(timeZoneStart + 1);
tz = TimeZone.getTimeZone(tzName);
if (!tz.getID().startsWith(tzName)) {
throw new IllegalArgumentException(tzName);
}
timeEnd = timeZoneStart;
}
}
}
......@@ -153,24 +155,26 @@ public class ValueTimestamp extends Value {
nanos += (ms - DateTimeUtils.absoluteDayFromDateValue(dateValue) * DateTimeUtils.MILLIS_PER_DAY) * 1000000;
}
}
return ValueTimestamp.get(dateValue, nanos);
return ValueTimestamp.fromDateValueAndNanos(dateValue, nanos);
}
public int getType() {
return Value.TIMESTAMP;
public long getDateValue() {
return dateValue;
}
protected int compareSecure(Value o, CompareMode mode) {
ValueTimestamp t = (ValueTimestamp) o;
int c = MathUtils.compareLong(dateValue, t.dateValue);
if (c != 0) {
return c;
}
return MathUtils.compareLong(nanos, t.nanos);
public long getNanos() {
return nanos;
}
public Timestamp getTimestamp() {
return DateTimeUtils.convertDateValueToTimestamp(dateValue, nanos);
}
public int getType() {
return Value.TIMESTAMP;
}
public String getString() {
// TODO verify display size
StringBuilder buff = new StringBuilder(DISPLAY_SIZE);
ValueDate.appendDate(buff, dateValue);
buff.append(' ');
......@@ -178,6 +182,10 @@ public class ValueTimestamp extends Value {
return buff.toString();
}
public String getSQL() {
return "TIMESTAMP '" + getString() + "'";
}
public long getPrecision() {
return PRECISION;
}
......@@ -186,30 +194,8 @@ public class ValueTimestamp extends Value {
return DEFAULT_SCALE;
}
public int hashCode() {
return (int) (dateValue ^ (dateValue >>> 32) ^ nanos ^ (nanos >>> 32));
}
public Object getObject() {
return getTimestamp();
}
public void set(PreparedStatement prep, int parameterIndex) throws SQLException {
prep.setTimestamp(parameterIndex, getTimestamp());
}
/**
* Get or create a timestamp value for the given timestamp.
*
* @param timestamp the timestamp
* @return the value
*/
public static ValueTimestamp get(Timestamp timestamp) {
long ms = timestamp.getTime();
long dateValue = DateTimeUtils.dateValueFromDate(ms);
long nanos = DateTimeUtils.nanosFromDate(ms);
nanos += timestamp.getNanos() % 1000000;
return get(dateValue, nanos);
public int getDisplaySize() {
return DISPLAY_SIZE;
}
public Value convertScale(boolean onlyToSmallerScale, int targetScale) {
......@@ -228,11 +214,16 @@ public class ValueTimestamp extends Value {
if (n2 == n) {
return this;
}
return get(dateValue, n2);
return fromDateValueAndNanos(dateValue, n2);
}
public int getDisplaySize() {
return DISPLAY_SIZE;
protected int compareSecure(Value o, CompareMode mode) {
ValueTimestamp t = (ValueTimestamp) o;
int c = MathUtils.compareLong(dateValue, t.dateValue);
if (c != 0) {
return c;
}
return MathUtils.compareLong(nanos, t.nanos);
}
public boolean equals(Object other) {
......@@ -245,8 +236,19 @@ public class ValueTimestamp extends Value {
return dateValue == x.dateValue && nanos == x.nanos;
}
public int hashCode() {
return (int) (dateValue ^ (dateValue >>> 32) ^ nanos ^ (nanos >>> 32));
}
public Object getObject() {
return getTimestamp();
}
public void set(PreparedStatement prep, int parameterIndex) throws SQLException {
prep.setTimestamp(parameterIndex, getTimestamp());
}
public Value add(Value v) {
// TODO test sum of timestamps, dates, times
ValueTimestamp t = (ValueTimestamp) v.convertTo(Value.TIMESTAMP);
long d1 = DateTimeUtils.absoluteDayFromDateValue(dateValue);
long d2 = DateTimeUtils.absoluteDayFromDateValue(t.dateValue);
......@@ -254,7 +256,6 @@ public class ValueTimestamp extends Value {
}
public Value subtract(Value v) {
// TODO test sum of timestamps, dates, times
ValueTimestamp t = (ValueTimestamp) v.convertTo(Value.TIMESTAMP);
long d1 = DateTimeUtils.absoluteDayFromDateValue(dateValue);
long d2 = DateTimeUtils.absoluteDayFromDateValue(t.dateValue);
......
......@@ -42,7 +42,6 @@ public class TestDateStorage extends TestBase {
testCurrentTimeZone();
}
private void testMoveDatabaseToAnotherTimezone() throws SQLException {
if (config.memory) {
return;
......
......@@ -385,7 +385,7 @@ select count(scriptSimple.public.test.id) from scriptSimple.public.test;
update scriptSimple.public.test set scriptSimple.public.test.id=1;
drop table scriptSimple.public.test;
select year(timestamp '2007-07-26 18:44:26.109000 +02:00');
select year(timestamp '2007-07-26T18:44:26.109000+02:00');
> 2007;
create table test(id int primary key);
......
......@@ -15,11 +15,11 @@ import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.TimeZone;
import org.h2.constant.SysProperties;
import org.h2.message.DbException;
import org.h2.store.Data;
import org.h2.test.TestBase;
import org.h2.util.DateTimeUtils;
import org.h2.util.New;
import org.h2.util.Profiler;
import org.h2.value.Value;
import org.h2.value.ValueDate;
import org.h2.value.ValueDouble;
......@@ -48,24 +48,19 @@ public class TestDate extends TestBase {
}
public void test() throws SQLException {
int test;
//Profiler prof = new Profiler();
//prof.startCollecting();
testValueDate();
testValueTime();
testValueTimestamp();
testValidDate();
testAbsoluteDay();
testCalculateLocalMillis();
testTimeOperationsAcrossTimeZones();
testDateTimeUtils();
//System.out.println(prof.getTop(5));
}
private void testValueDate() {
assertEquals("2000-01-01", ValueDate.get(Date.valueOf("2000-01-01")).getString());
assertEquals("0-00-00", ValueDate.get(0).getString());
assertEquals("0-00-00", ValueDate.fromDateValue(0).getString());
assertEquals("9999-12-31", ValueDate.parse("9999-12-31").getString());
assertEquals("-9999-12-31", ValueDate.parse("-9999-12-31").getString());
assertEquals(
......@@ -121,7 +116,7 @@ int test;
private void testValueTime() {
assertEquals("10:20:30", ValueTime.get(Time.valueOf("10:20:30")).getString());
assertEquals("00:00:00", ValueTime.get(0).getString());
assertEquals("00:00:00", ValueTime.fromNanos(0).getString());
assertEquals("23:59:59", ValueTime.parse("23:59:59").getString());
assertEquals("99:59:59", ValueTime.parse("99:59:59").getString());
assertEquals("-99:02:03.001002003", ValueTime.parse("-99:02:03.001002003").getString());
......@@ -184,7 +179,7 @@ int test;
Timestamp.valueOf("2001-02-03 04:05:06")).getString());
assertEquals("2001-02-03 04:05:06.001002003", ValueTimestamp.get(
Timestamp.valueOf("2001-02-03 04:05:06.001002003")).getString());
assertEquals("0-00-00 00:00:00.0", ValueTimestamp.get(0, 0).getString());
assertEquals("0-00-00 00:00:00.0", ValueTimestamp.fromDateValueAndNanos(0, 0).getString());
assertEquals("9999-12-31 23:59:59.0",
ValueTimestamp.parse("9999-12-31 23:59:59").getString());
......@@ -262,6 +257,25 @@ int test;
assertEquals("-1010-10-10 00:00:00.0",
ValueTimestamp.parse("-1010-10-10 10:10:10").subtract(
ValueTime.parse("10:10:10")).getString());
assertEquals(0, DateTimeUtils.absoluteDayFromDateValue(ValueTimestamp.parse("1970-01-01").getDateValue()));
assertEquals(0, ValueTimestamp.parse("1970-01-01").getNanos());
assertEquals(0, ValueTimestamp.parse("1970-01-01 00:00:00.000 UTC").getTimestamp().getTime());
assertEquals(0, ValueTimestamp.parse("+1970-01-01T00:00:00.000Z").getTimestamp().getTime());
assertEquals(0, ValueTimestamp.parse("1970-01-01T00:00:00.000+00:00").getTimestamp().getTime());
assertEquals(0, ValueTimestamp.parse("1970-01-01T00:00:00.000-00:00").getTimestamp().getTime());
try {
ValueTimestamp.parse("1970-01-01 00:00:00.000 ABC");
fail();
} catch (DbException e) {
// expected
}
try {
ValueTimestamp.parse("1970-01-01T00:00:00.000+ABC");
fail();
} catch (DbException e) {
// expected
}
}
private void testAbsoluteDay() {
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论