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

Merge pull request #878 from katzyn/datetime

Fix IYYY in TO_CHAR and reimplement TRUNCATE without a Calendar
......@@ -17,7 +17,6 @@ import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.Locale;
......@@ -1233,32 +1232,16 @@ public class Function extends Expression implements FunctionCall {
}
case TRUNCATE: {
if (v0.getType() == Value.TIMESTAMP) {
java.sql.Timestamp d = v0.getTimestamp();
Calendar c = DateTimeUtils.createGregorianCalendar();
c.setTime(d);
c.set(Calendar.HOUR_OF_DAY, 0);
c.set(Calendar.MINUTE, 0);
c.set(Calendar.SECOND, 0);
c.set(Calendar.MILLISECOND, 0);
result = ValueTimestamp.fromMillis(c.getTimeInMillis());
result = ValueTimestamp.fromDateValueAndNanos(((ValueTimestamp) v0).getDateValue(), 0);
} else if (v0.getType() == Value.DATE) {
ValueDate vd = (ValueDate) v0;
Calendar c = DateTimeUtils.createGregorianCalendar();
c.setTime(vd.getDate());
c.set(Calendar.HOUR_OF_DAY, 0);
c.set(Calendar.MINUTE, 0);
c.set(Calendar.SECOND, 0);
c.set(Calendar.MILLISECOND, 0);
result = ValueTimestamp.fromMillis(c.getTimeInMillis());
result = ValueTimestamp.fromDateValueAndNanos(((ValueDate) v0).getDateValue(), 0);
} else if (v0.getType() == Value.TIMESTAMP_TZ) {
ValueTimestampTimeZone ts = (ValueTimestampTimeZone) v0;
result = ValueTimestampTimeZone.fromDateValueAndNanos(ts.getDateValue(), 0,
ts.getTimeZoneOffsetMins());
} else if (v0.getType() == Value.STRING) {
ValueString vd = (ValueString) v0;
Calendar c = DateTimeUtils.createGregorianCalendar();
c.setTime(ValueTimestamp.parse(vd.getString(), session.getDatabase().getMode()).getDate());
c.set(Calendar.HOUR_OF_DAY, 0);
c.set(Calendar.MINUTE, 0);
c.set(Calendar.SECOND, 0);
c.set(Calendar.MILLISECOND, 0);
result = ValueTimestamp.fromMillis(c.getTimeInMillis());
ValueTimestamp ts = ValueTimestamp.parse(v0.getString(), session.getDatabase().getMode());
result = ValueTimestamp.fromDateValueAndNanos(ts.getDateValue(), 0);
} else {
double d = v0.getDouble();
int p = v1 == null ? 0 : v1.getInt();
......
......@@ -15,6 +15,7 @@ import org.h2.api.ErrorCode;
import org.h2.api.TimestampWithTimeZone;
import org.h2.message.DbException;
import org.h2.util.DateTimeUtils;
import org.h2.util.StringUtils;
/**
* Implementation of the TIMESTAMP WITH TIME ZONE data type.
......@@ -158,7 +159,18 @@ public class ValueTimestampTimeZone extends Value {
if (offset == 0) {
return DateTimeUtils.UTC;
}
return new SimpleTimeZone(offset * 60000, Integer.toString(offset));
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 new SimpleTimeZone(offset * 60000, b.toString());
}
@Override
......
......@@ -1486,6 +1486,17 @@ public class TestFunctions extends TestBase implements AggregateFunction {
assertResult("0 BC", stat,
"SELECT TO_CHAR(X, 'Y BC') FROM U");
assertResult("1979 A.D.", stat, "SELECT TO_CHAR(X, 'YYYY B.C.') FROM T");
assertResult("2013", stat, "SELECT TO_CHAR(DATE '2013-12-30', 'YYYY') FROM DUAL");
assertResult("013", stat, "SELECT TO_CHAR(DATE '2013-12-30', 'YYY') FROM DUAL");
assertResult("13", stat, "SELECT TO_CHAR(DATE '2013-12-30', 'YY') FROM DUAL");
assertResult("3", stat, "SELECT TO_CHAR(DATE '2013-12-30', 'Y') FROM DUAL");
// ISO week year
assertResult("2014", stat, "SELECT TO_CHAR(DATE '2013-12-30', 'IYYY') FROM DUAL");
assertResult("014", stat, "SELECT TO_CHAR(DATE '2013-12-30', 'IYY') FROM DUAL");
assertResult("14", stat, "SELECT TO_CHAR(DATE '2013-12-30', 'IY') FROM DUAL");
assertResult("4", stat, "SELECT TO_CHAR(DATE '2013-12-30', 'I') FROM DUAL");
assertResult("0001", stat, "SELECT TO_CHAR(DATE '-0001-01-01', 'IYYY') FROM DUAL");
assertResult("0005", stat, "SELECT TO_CHAR(DATE '-0004-01-01', 'IYYY') FROM DUAL");
assertResult("08:12 AM", stat, "SELECT TO_CHAR(X, 'HH:MI AM') FROM T");
assertResult("08:12 A.M.", stat, "SELECT TO_CHAR(X, 'HH:MI A.M.') FROM T");
assertResult("02:04 P.M.", stat, "SELECT TO_CHAR(X, 'HH:MI A.M.') FROM U");
......@@ -1608,6 +1619,10 @@ public class TestFunctions extends TestBase implements AggregateFunction {
assertResult(expected, stat, "SELECT TO_CHAR(X, 'TS') FROM T");
assertResult(tzLongName, stat, "SELECT TO_CHAR(X, 'TZR') FROM T");
assertResult(tzShortName, stat, "SELECT TO_CHAR(X, 'TZD') FROM T");
assertResult("GMT+10:30", stat,
"SELECT TO_CHAR(TIMESTAMP WITH TIME ZONE '2010-01-01 0:00:00+10:30', 'TZR')");
assertResult("GMT+10:30", stat,
"SELECT TO_CHAR(TIMESTAMP WITH TIME ZONE '2010-01-01 0:00:00+10:30', 'TZD')");
expected = String.format("%f", 1.1).substring(1, 2);
assertResult(expected, stat, "SELECT TO_CHAR(X, 'X') FROM T");
expected = String.format("%,d", 1979);
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论