Unverified 提交 cee57f6c authored 作者: Noel Grandin's avatar Noel Grandin 提交者: GitHub

Merge pull request #891 from katzyn/datetime

Update documentation of date-time types and clean up related code a bit
...@@ -2437,9 +2437,11 @@ REAL ...@@ -2437,9 +2437,11 @@ REAL
"Data Types","TIME Type"," "Data Types","TIME Type","
TIME TIME
"," ","
The time data type. The format is hh:mm:ss. The time data type. The format is hh:mm:ss[.nnnnnnnnn].
Mapped to ""java.sql.Time"". When converted to a ""java.sql.Date"", the date is set to ""1970-01-01"". Mapped to ""java.sql.Time"". When converted to a ""java.sql.Date"", the date is set to ""1970-01-01"".
""java.time.LocalTime"" is also supported on Java 8 and later versions.
Resolution of ""java.sql.Time"" is limited to milliseconds, use ""String"" or ""java.time.LocalTime"" if you need nanosecond resolution.
"," ","
TIME TIME
" "
...@@ -2451,6 +2453,7 @@ The date data type. The format is yyyy-MM-dd. ...@@ -2451,6 +2453,7 @@ The date data type. The format is yyyy-MM-dd.
Mapped to ""java.sql.Date"", with the time set to ""00:00:00"" Mapped to ""java.sql.Date"", with the time set to ""00:00:00""
(or to the next possible time if midnight doesn't exist for the given date and timezone due to a daylight saving change). (or to the next possible time if midnight doesn't exist for the given date and timezone due to a daylight saving change).
""java.time.LocalDate"" is also supported on Java 8 and later versions.
"," ","
DATE DATE
" "
...@@ -2459,9 +2462,10 @@ DATE ...@@ -2459,9 +2462,10 @@ DATE
{ TIMESTAMP | DATETIME | SMALLDATETIME } { TIMESTAMP | DATETIME | SMALLDATETIME }
"," ","
The timestamp data type. The format is yyyy-MM-dd hh:mm:ss[.nnnnnnnnn]. The timestamp data type. The format is yyyy-MM-dd hh:mm:ss[.nnnnnnnnn].
Stored internally as a BCD-encoded date, and nano-seconds since midnight. Stored internally as a BCD-encoded date, and nanoseconds since midnight.
Mapped to ""java.sql.Timestamp"" (""java.util.Date"" is also supported). Mapped to ""java.sql.Timestamp"" (""java.util.Date"" may be used too).
""java.time.LocalDateTime"" is also supported on Java 8 and later versions.
"," ","
TIMESTAMP TIMESTAMP
" "
...@@ -2469,12 +2473,16 @@ TIMESTAMP ...@@ -2469,12 +2473,16 @@ TIMESTAMP
"Data Types","TIMESTAMP WITH TIME ZONE Type"," "Data Types","TIMESTAMP WITH TIME ZONE Type","
TIMESTAMP WITH TIME ZONE TIMESTAMP WITH TIME ZONE
"," ","
VERY MUCH STILL IN TESTING.
The timestamp with time zone data type. The timestamp with time zone data type.
Stored internally as a BCD-encoded date, nano-seconds since midnight, and timezone offset in minutes. Stored internally as a BCD-encoded date, nanoseconds since midnight, and time zone offset in minutes.
Note that range queries on this datatype may do some weird stuff close to DST boundaries.
Mapped to ""org.h2.api.TimestampWithTimeZone"" Mapped to ""org.h2.api.TimestampWithTimeZone"".
""java.time.OffsetDateTime"" and ""java.time.Instant"" are also supported on Java 8 and later versions.
Values of this data type are compared by UTC values. It means that ""2010-01-01 10:00:00+01"" is greater than ""2010-01-01 11:00:00+03"".
Conversion to ""TIMESTAMP"" uses time zone offset to get UTC time and converts it to local time using the system time zone.
Conversion from ""TIMESTAMP"" does the same operations in reverse and sets time zone offset to offset of the system time zone.
"," ","
TIMESTAMP WITH TIME ZONE TIMESTAMP WITH TIME ZONE
" "
......
...@@ -1553,17 +1553,12 @@ public class Function extends Expression implements FunctionCall { ...@@ -1553,17 +1553,12 @@ public class Function extends Expression implements FunctionCall {
null : v2 == ValueNull.INSTANCE ? null : v2.getString(); null : v2 == ValueNull.INSTANCE ? null : v2.getString();
String tz = v3 == null ? String tz = v3 == null ?
null : v3 == ValueNull.INSTANCE ? null : v3.getString(); null : v3 == ValueNull.INSTANCE ? null : v3.getString();
java.util.Date date;
if (v0 instanceof ValueTimestampTimeZone) { if (v0 instanceof ValueTimestampTimeZone) {
ValueTimestampTimeZone ts = (ValueTimestampTimeZone) v0; tz = DateTimeUtils.timeZoneNameFromOffsetMins(
tz = DateTimeUtils.timeZoneNameFromOffsetMins(ts.getTimeZoneOffsetMins()); ((ValueTimestampTimeZone) v0).getTimeZoneOffsetMins());
date = DateTimeUtils.convertTimestampTimeZoneToTimestamp(
ts.getDateValue(), ts.getTimeNanos(), ts.getTimeZoneOffsetMins());
} else {
date = v0.getTimestamp();
} }
result = ValueString.get(DateTimeUtils.formatDateTime( result = ValueString.get(DateTimeUtils.formatDateTime(
date, v1.getString(), locale, tz), v0.getTimestamp(), v1.getString(), locale, tz),
database.getMode().treatEmptyStringsAsNull); database.getMode().treatEmptyStringsAsNull);
} }
break; break;
......
...@@ -98,8 +98,7 @@ public class DateTimeUtils { ...@@ -98,8 +98,7 @@ public class DateTimeUtils {
* use a fixed value throughout the duration of the JVM's life, rather than * use a fixed value throughout the duration of the JVM's life, rather than
* have this offset change, possibly midway through a long-running query. * have this offset change, possibly midway through a long-running query.
*/ */
private static int zoneOffsetMillis = DateTimeUtils.createGregorianCalendar() private static int zoneOffsetMillis = createGregorianCalendar().get(Calendar.ZONE_OFFSET);
.get(Calendar.ZONE_OFFSET);
private DateTimeUtils() { private DateTimeUtils() {
// utility class // utility class
...@@ -125,7 +124,7 @@ public class DateTimeUtils { ...@@ -125,7 +124,7 @@ public class DateTimeUtils {
public static void resetCalendar() { public static void resetCalendar() {
CACHED_CALENDAR.remove(); CACHED_CALENDAR.remove();
timeZone = null; timeZone = null;
zoneOffsetMillis = DateTimeUtils.createGregorianCalendar().get(Calendar.ZONE_OFFSET); zoneOffsetMillis = createGregorianCalendar().get(Calendar.ZONE_OFFSET);
} }
/** /**
...@@ -136,7 +135,7 @@ public class DateTimeUtils { ...@@ -136,7 +135,7 @@ public class DateTimeUtils {
public static GregorianCalendar getCalendar() { public static GregorianCalendar getCalendar() {
GregorianCalendar c = CACHED_CALENDAR.get(); GregorianCalendar c = CACHED_CALENDAR.get();
if (c == null) { if (c == null) {
c = DateTimeUtils.createGregorianCalendar(); c = createGregorianCalendar();
CACHED_CALENDAR.set(c); CACHED_CALENDAR.set(c);
} }
c.clear(); c.clear();
...@@ -152,7 +151,7 @@ public class DateTimeUtils { ...@@ -152,7 +151,7 @@ public class DateTimeUtils {
private static GregorianCalendar getCalendar(TimeZone tz) { private static GregorianCalendar getCalendar(TimeZone tz) {
GregorianCalendar c = CACHED_CALENDAR_NON_DEFAULT_TIMEZONE.get(); GregorianCalendar c = CACHED_CALENDAR_NON_DEFAULT_TIMEZONE.get();
if (c == null || !c.getTimeZone().equals(tz)) { if (c == null || !c.getTimeZone().equals(tz)) {
c = DateTimeUtils.createGregorianCalendar(tz); c = createGregorianCalendar(tz);
CACHED_CALENDAR_NON_DEFAULT_TIMEZONE.set(c); CACHED_CALENDAR_NON_DEFAULT_TIMEZONE.set(c);
} }
c.clear(); c.clear();
...@@ -1201,19 +1200,19 @@ public class DateTimeUtils { ...@@ -1201,19 +1200,19 @@ public class DateTimeUtils {
* @return timestamp with time zone * @return timestamp with time zone
*/ */
public static ValueTimestampTimeZone timestampTimeZoneFromLocalDateValueAndNanos(long dateValue, long timeNanos) { public static ValueTimestampTimeZone timestampTimeZoneFromLocalDateValueAndNanos(long dateValue, long timeNanos) {
int timeZoneOffset = DateTimeUtils.getTimeZoneOffsetMillis(null, dateValue, timeNanos); int timeZoneOffset = getTimeZoneOffsetMillis(null, dateValue, timeNanos);
int offsetMins = timeZoneOffset / 60_000; int offsetMins = timeZoneOffset / 60_000;
int correction = timeZoneOffset % 60_000; int correction = timeZoneOffset % 60_000;
if (correction != 0) { if (correction != 0) {
timeNanos -= correction; timeNanos -= correction;
if (timeNanos < 0) { if (timeNanos < 0) {
timeNanos += DateTimeUtils.NANOS_PER_DAY; timeNanos += NANOS_PER_DAY;
dateValue = DateTimeUtils dateValue = DateTimeUtils
.dateValueFromAbsoluteDay(DateTimeUtils.absoluteDayFromDateValue(dateValue) - 1); .dateValueFromAbsoluteDay(absoluteDayFromDateValue(dateValue) - 1);
} else if (timeNanos >= DateTimeUtils.NANOS_PER_DAY) { } else if (timeNanos >= NANOS_PER_DAY) {
timeNanos -= DateTimeUtils.NANOS_PER_DAY; timeNanos -= NANOS_PER_DAY;
dateValue = DateTimeUtils dateValue = DateTimeUtils
.dateValueFromAbsoluteDay(DateTimeUtils.absoluteDayFromDateValue(dateValue) + 1); .dateValueFromAbsoluteDay(absoluteDayFromDateValue(dateValue) + 1);
} }
} }
return ValueTimestampTimeZone.fromDateValueAndNanos(dateValue, timeNanos, (short) offsetMins); return ValueTimestampTimeZone.fromDateValueAndNanos(dateValue, timeNanos, (short) offsetMins);
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论