提交 1105b977 authored 作者: Evgenij Ryazanov's avatar Evgenij Ryazanov

Add support for TIMESTAMP WITH TIME ZONE to FORMATDATETIME

上级 47ed036f
...@@ -3759,6 +3759,8 @@ Formats a date, time or timestamp as a string. ...@@ -3759,6 +3759,8 @@ Formats a date, time or timestamp as a string.
The most important format characters are: The most important format characters are:
y year, M month, d day, H hour, m minute, s second. y year, M month, d day, H hour, m minute, s second.
For details of the format, see ""java.text.SimpleDateFormat"". For details of the format, see ""java.text.SimpleDateFormat"".
timeZoneString may be specified if timestamp is a DATE, TIME or TIMESTAMP.
timeZoneString is ignored if timestamp is TIMESTAMP WITH TIME ZONE.
This method returns a string. This method returns a string.
"," ","
CALL FORMATDATETIME(TIMESTAMP '2001-02-03 04:05:06', CALL FORMATDATETIME(TIMESTAMP '2001-02-03 04:05:06',
......
...@@ -1553,8 +1553,17 @@ public class Function extends Expression implements FunctionCall { ...@@ -1553,8 +1553,17 @@ 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) {
ValueTimestampTimeZone ts = (ValueTimestampTimeZone) v0;
tz = DateTimeUtils.timeZoneNameFromOffsetMins(ts.getTimeZoneOffsetMins());
date = DateTimeUtils.convertTimestampTimeZoneToTimestamp(
ts.getDateValue(), ts.getTimeNanos(), ts.getTimeZoneOffsetMins());
} else {
date = v0.getTimestamp();
}
result = ValueString.get(DateTimeUtils.formatDateTime( result = ValueString.get(DateTimeUtils.formatDateTime(
v0.getTimestamp(), v1.getString(), locale, tz), date, v1.getString(), locale, tz),
database.getMode().treatEmptyStringsAsNull); database.getMode().treatEmptyStringsAsNull);
} }
break; break;
......
...@@ -955,9 +955,25 @@ public class DateTimeUtils { ...@@ -955,9 +955,25 @@ public class DateTimeUtils {
*/ */
public static Timestamp convertDateValueToTimestamp(long dateValue, public static Timestamp convertDateValueToTimestamp(long dateValue,
long timeNanos) { long timeNanos) {
Timestamp ts = new Timestamp(convertDateTimeValueToMillis(null, dateValue, timeNanos / 1000000)); Timestamp ts = new Timestamp(convertDateTimeValueToMillis(null, dateValue, timeNanos / 1_000_000));
// This method expects the complete nanoseconds value including milliseconds // This method expects the complete nanoseconds value including milliseconds
ts.setNanos((int) (timeNanos % 1000000000)); ts.setNanos((int) (timeNanos % 1_000_000_000));
return ts;
}
/**
* Convert an encoded date value / time value to a timestamp using the specified
* time zone offset.
*
* @param dateValue the date value
* @param timeNanos the nanoseconds since midnight
* @param offsetMins time zone offset in minutes
* @return the timestamp
*/
public static Timestamp convertTimestampTimeZoneToTimestamp(long dateValue, long timeNanos, short offsetMins) {
Timestamp ts = new Timestamp(absoluteDayFromDateValue(dateValue) * MILLIS_PER_DAY
+ timeNanos / 1_000_000 - offsetMins * 60_000);
ts.setNanos((int) (timeNanos % 1_000_000_000));
return ts; return ts;
} }
...@@ -1338,4 +1354,29 @@ public class DateTimeUtils { ...@@ -1338,4 +1354,29 @@ public class DateTimeUtils {
return buff.toString(); return buff.toString();
} }
/**
* Generates time zone name for the specified offset in minutes.
*
* @param offsetMins
* offset in minutes
* @return time zone name
*/
public static String timeZoneNameFromOffsetMins(int offsetMins) {
if (offsetMins == 0) {
return "UTC";
}
StringBuilder b = new StringBuilder(9);
b.append("GMT");
if (offsetMins < 0) {
b.append('-');
offsetMins = -offsetMins;
} else {
b.append('+');
}
StringUtils.appendZeroPadded(b, 2, offsetMins / 60);
b.append(':');
StringUtils.appendZeroPadded(b, 2, offsetMins % 60);
return b.toString();
}
} }
...@@ -496,22 +496,7 @@ public class ToChar { ...@@ -496,22 +496,7 @@ public class ToChar {
} }
return tz.getID(); return tz.getID();
} }
int offset = ((ValueTimestampTimeZone) value).getTimeZoneOffsetMins(); return DateTimeUtils.timeZoneNameFromOffsetMins(((ValueTimestampTimeZone) value).getTimeZoneOffsetMins());
if (offset == 0) {
return "UTC";
}
StringBuilder b = new StringBuilder(9);
b.append("GMT");
if (offset < 0) {
b.append('-');
offset = - offset;
} else {
b.append('+');
}
StringUtils.appendZeroPadded(b, 2, offset / 60);
b.append(':');
StringUtils.appendZeroPadded(b, 2, offset % 60);
return b.toString();
} }
/** /**
......
...@@ -32,3 +32,15 @@ CALL FORMATDATETIME(PARSEDATETIME('Sat, 3 Feb 2001 04:05:06 GMT', 'EEE, d MMM yy ...@@ -32,3 +32,15 @@ CALL FORMATDATETIME(PARSEDATETIME('Sat, 3 Feb 2001 04:05:06 GMT', 'EEE, d MMM yy
> --------------------- > ---------------------
> 2001-02-03 04:05:06 > 2001-02-03 04:05:06
> rows: 1 > rows: 1
SELECT FORMATDATETIME(TIMESTAMP WITH TIME ZONE '2010-05-06 07:08:09.123Z', 'yyyy-MM-dd HH:mm:ss.SSS z') AS S;
> S
> ---------------------------
> 2010-05-06 07:08:09.123 UTC
> rows: 1
SELECT FORMATDATETIME(TIMESTAMP WITH TIME ZONE '2010-05-06 07:08:09.123+13:30', 'yyyy-MM-dd HH:mm:ss.SSS z') AS S;
> S
> ---------------------------------
> 2010-05-06 07:08:09.123 GMT+13:30
> rows: 1
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论