提交 25e6a14d authored 作者: Evgenij Ryazanov's avatar Evgenij Ryazanov

Use CURRENT_TIMESTAMP in ToDateParser

上级 c85578fc
......@@ -1433,19 +1433,16 @@ public class Function extends Expression implements FunctionCall {
}
break;
case TO_DATE:
result = ToDateParser.toDate(v0.getString(),
v1 == null ? null : v1.getString());
result = ToDateParser.toDate(session, v0.getString(), v1 == null ? null : v1.getString());
break;
case TO_TIMESTAMP:
result = ToDateParser.toTimestamp(v0.getString(),
v1 == null ? null : v1.getString());
result = ToDateParser.toTimestamp(session, v0.getString(), v1 == null ? null : v1.getString());
break;
case ADD_MONTHS:
result = DateTimeFunctions.dateadd("MONTH", v1.getInt(), v0);
break;
case TO_TIMESTAMP_TZ:
result = ToDateParser.toTimestampTz(v0.getString(),
v1 == null ? null : v1.getString());
result = ToDateParser.toTimestampTz(session, v0.getString(), v1 == null ? null : v1.getString());
break;
case TRANSLATE: {
String matching = v1.getString();
......
......@@ -7,11 +7,10 @@ package org.h2.expression.function;
import static java.lang.String.format;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.TimeZone;
import org.h2.engine.Session;
import org.h2.util.DateTimeUtils;
import org.h2.value.ValueTimestamp;
import org.h2.value.ValueTimestampTimeZone;
......@@ -21,6 +20,8 @@ import org.h2.value.ValueTimestampTimeZone;
* This class holds and handles the input data form the TO_DATE-method
*/
public class ToDateParser {
private final Session session;
private final String unmodifiedInputStr;
private final String unmodifiedFormatStr;
private final ConfigParam functionName;
......@@ -52,12 +53,14 @@ public class ToDateParser {
private int currentYear, currentMonth;
/**
* @param input the input date with the date-time info
* @param format the format of date-time info
* @param session the database session
* @param functionName one of [TO_DATE, TO_TIMESTAMP] (both share the same
* code)
* @param input the input date with the date-time info
* @param format the format of date-time info
*/
private ToDateParser(ConfigParam functionName, String input, String format) {
private ToDateParser(Session session, ConfigParam functionName, String input, String format) {
this.session = session;
this.functionName = functionName;
inputStr = input.trim();
// Keep a copy
......@@ -72,8 +75,8 @@ public class ToDateParser {
unmodifiedFormatStr = formatStr;
}
private static ToDateParser getTimestampParser(ConfigParam param, String input, String format) {
ToDateParser result = new ToDateParser(param, input, format);
private static ToDateParser getTimestampParser(Session session, ConfigParam param, String input, String format) {
ToDateParser result = new ToDateParser(session, param, input, format);
parse(result);
return result;
}
......@@ -145,10 +148,10 @@ public class ToDateParser {
}
private void queryCurrentYearAndMonth() {
GregorianCalendar gc = DateTimeUtils.getCalendar();
gc.setTimeInMillis(System.currentTimeMillis());
currentYear = gc.get(Calendar.YEAR);
currentMonth = gc.get(Calendar.MONTH) + 1;
long dateValue = (session.getDatabase().getMode().dateTimeValueWithinTransaction
? session.getTransactionStart() : session.getCurrentCommandStart()).getDateValue();
currentYear = DateTimeUtils.yearFromDateValue(dateValue);
currentMonth = DateTimeUtils.monthFromDateValue(dateValue);
}
int getCurrentYear() {
......@@ -319,36 +322,39 @@ public class ToDateParser {
/**
* Parse a string as a timestamp with the given format.
*
* @param session the database session
* @param input the input
* @param format the format
* @return the timestamp
*/
public static ValueTimestamp toTimestamp(String input, String format) {
ToDateParser parser = getTimestampParser(ConfigParam.TO_TIMESTAMP, input, format);
public static ValueTimestamp toTimestamp(Session session, String input, String format) {
ToDateParser parser = getTimestampParser(session, ConfigParam.TO_TIMESTAMP, input, format);
return parser.getResultingValue();
}
/**
* Parse a string as a timestamp with the given format.
*
* @param session the database session
* @param input the input
* @param format the format
* @return the timestamp
*/
public static ValueTimestampTimeZone toTimestampTz(String input, String format) {
ToDateParser parser = getTimestampParser(ConfigParam.TO_TIMESTAMP_TZ, input, format);
public static ValueTimestampTimeZone toTimestampTz(Session session, String input, String format) {
ToDateParser parser = getTimestampParser(session, ConfigParam.TO_TIMESTAMP_TZ, input, format);
return parser.getResultingValueWithTimeZone();
}
/**
* Parse a string as a date with the given format.
*
* @param session the database session
* @param input the input
* @param format the format
* @return the date as a timestamp
*/
public static ValueTimestamp toDate(String input, String format) {
ToDateParser parser = getTimestampParser(ConfigParam.TO_DATE, input, format);
public static ValueTimestamp toDate(Session session, String input, String format) {
ToDateParser parser = getTimestampParser(session, ConfigParam.TO_DATE, input, format);
return parser.getResultingValue();
}
......
......@@ -46,8 +46,10 @@ import org.h2.api.Aggregate;
import org.h2.api.AggregateFunction;
import org.h2.api.ErrorCode;
import org.h2.engine.Constants;
import org.h2.engine.Session;
import org.h2.expression.function.ToDateParser;
import org.h2.expression.function.ToChar.Capitalization;
import org.h2.jdbc.JdbcConnection;
import org.h2.message.DbException;
import org.h2.store.fs.FileUtils;
import org.h2.test.TestBase;
......@@ -84,8 +86,13 @@ public class TestFunctions extends TestDb implements AggregateFunction {
deleteDb("functions");
testOverrideAlias();
testIfNull();
testToDate();
testToDateException();
if (!config.networked) {
JdbcConnection conn = (JdbcConnection) getConnection("functions");
Session session = (Session) conn.getSession();
testToDate(session);
testToDateException(session);
conn.close();
}
testDataType();
testVersion();
testFunctionTable();
......@@ -1328,22 +1335,22 @@ public class TestFunctions extends TestDb implements AggregateFunction {
conn.close();
}
private void testToDateException() {
private void testToDateException(Session session) {
try {
ToDateParser.toDate("1979-ThisWillFail-12", "YYYY-MM-DD");
ToDateParser.toDate(session, "1979-ThisWillFail-12", "YYYY-MM-DD");
} catch (Exception e) {
assertEquals(DbException.class.getSimpleName(), e.getClass().getSimpleName());
}
try {
ToDateParser.toDate("1-DEC-0000", "DD-MON-RRRR");
ToDateParser.toDate(session, "1-DEC-0000", "DD-MON-RRRR");
fail("Oracle to_date should reject year 0 (ORA-01841)");
} catch (Exception e) {
// expected
}
}
private void testToDate() throws ParseException {
private void testToDate(Session session) throws ParseException {
GregorianCalendar calendar = DateTimeUtils.createGregorianCalendar();
int year = calendar.get(Calendar.YEAR);
int month = calendar.get(Calendar.MONTH) + 1;
......@@ -1351,133 +1358,135 @@ public class TestFunctions extends TestDb implements AggregateFunction {
String defDate = year + "-" + month + "-1 ";
ValueTimestamp date = null;
date = ValueTimestamp.parse("1979-11-12");
assertEquals(date, ToDateParser.toDate("1979-11-12T00:00:00Z", "YYYY-MM-DD\"T\"HH24:MI:SS\"Z\""));
assertEquals(date, ToDateParser.toDate("1979*foo*1112", "YYYY\"*foo*\"MM\"\"DD"));
assertEquals(date, ToDateParser.toDate("1979-11-12", "YYYY-MM-DD"));
assertEquals(date, ToDateParser.toDate("1979/11/12", "YYYY/MM/DD"));
assertEquals(date, ToDateParser.toDate("1979,11,12", "YYYY,MM,DD"));
assertEquals(date, ToDateParser.toDate("1979.11.12", "YYYY.MM.DD"));
assertEquals(date, ToDateParser.toDate("1979;11;12", "YYYY;MM;DD"));
assertEquals(date, ToDateParser.toDate("1979:11:12", "YYYY:MM:DD"));
assertEquals(date, ToDateParser.toDate(session, "1979-11-12T00:00:00Z", "YYYY-MM-DD\"T\"HH24:MI:SS\"Z\""));
assertEquals(date, ToDateParser.toDate(session, "1979*foo*1112", "YYYY\"*foo*\"MM\"\"DD"));
assertEquals(date, ToDateParser.toDate(session, "1979-11-12", "YYYY-MM-DD"));
assertEquals(date, ToDateParser.toDate(session, "1979/11/12", "YYYY/MM/DD"));
assertEquals(date, ToDateParser.toDate(session, "1979,11,12", "YYYY,MM,DD"));
assertEquals(date, ToDateParser.toDate(session, "1979.11.12", "YYYY.MM.DD"));
assertEquals(date, ToDateParser.toDate(session, "1979;11;12", "YYYY;MM;DD"));
assertEquals(date, ToDateParser.toDate(session, "1979:11:12", "YYYY:MM:DD"));
date = ValueTimestamp.parse("1979-" + month + "-01");
assertEquals(date, ToDateParser.toDate("1979", "YYYY"));
assertEquals(date, ToDateParser.toDate("1979 AD", "YYYY AD"));
assertEquals(date, ToDateParser.toDate("1979 A.D.", "YYYY A.D."));
assertEquals(date, ToDateParser.toDate("1979 A.D.", "YYYY BC"));
assertEquals(date, ToDateParser.toDate("+1979", "SYYYY"));
assertEquals(date, ToDateParser.toDate("79", "RRRR"));
assertEquals(date, ToDateParser.toDate(session, "1979", "YYYY"));
assertEquals(date, ToDateParser.toDate(session, "1979 AD", "YYYY AD"));
assertEquals(date, ToDateParser.toDate(session, "1979 A.D.", "YYYY A.D."));
assertEquals(date, ToDateParser.toDate(session, "1979 A.D.", "YYYY BC"));
assertEquals(date, ToDateParser.toDate(session, "+1979", "SYYYY"));
assertEquals(date, ToDateParser.toDate(session, "79", "RRRR"));
date = ValueTimestamp.parse(defDate + "00:12:00");
assertEquals(date, ToDateParser.toDate("12", "MI"));
assertEquals(date, ToDateParser.toDate(session, "12", "MI"));
date = ValueTimestamp.parse("1970-11-01");
assertEquals(date, ToDateParser.toDate("11", "MM"));
assertEquals(date, ToDateParser.toDate("11", "Mm"));
assertEquals(date, ToDateParser.toDate("11", "mM"));
assertEquals(date, ToDateParser.toDate("11", "mm"));
assertEquals(date, ToDateParser.toDate("XI", "RM"));
assertEquals(date, ToDateParser.toDate(session, "11", "MM"));
assertEquals(date, ToDateParser.toDate(session, "11", "Mm"));
assertEquals(date, ToDateParser.toDate(session, "11", "mM"));
assertEquals(date, ToDateParser.toDate(session, "11", "mm"));
assertEquals(date, ToDateParser.toDate(session, "XI", "RM"));
int y = (year / 10) * 10 + 9;
date = ValueTimestamp.parse(y + "-" + month + "-01");
assertEquals(date, ToDateParser.toDate("9", "Y"));
assertEquals(date, ToDateParser.toDate(session, "9", "Y"));
y = (year / 100) * 100 + 79;
date = ValueTimestamp.parse(y + "-" + month + "-01");
assertEquals(date, ToDateParser.toDate("79", "YY"));
assertEquals(date, ToDateParser.toDate(session, "79", "YY"));
y = (year / 1_000) * 1_000 + 979;
date = ValueTimestamp.parse(y + "-" + month + "-01");
assertEquals(date, ToDateParser.toDate("979", "YYY"));
assertEquals(date, ToDateParser.toDate(session, "979", "YYY"));
// Gregorian calendar does not have a year 0.
// 0 = 0001 BC, -1 = 0002 BC, ... so we adjust
date = ValueTimestamp.parse("-99-" + month + "-01");
assertEquals(date, ToDateParser.toDate("0100 BC", "YYYY BC"));
assertEquals(date, ToDateParser.toDate("0100 B.C.", "YYYY B.C."));
assertEquals(date, ToDateParser.toDate("-0100", "SYYYY"));
assertEquals(date, ToDateParser.toDate("-0100", "YYYY"));
assertEquals(date, ToDateParser.toDate(session, "0100 BC", "YYYY BC"));
assertEquals(date, ToDateParser.toDate(session, "0100 B.C.", "YYYY B.C."));
assertEquals(date, ToDateParser.toDate(session, "-0100", "SYYYY"));
assertEquals(date, ToDateParser.toDate(session, "-0100", "YYYY"));
// Gregorian calendar does not have a year 0.
// 0 = 0001 BC, -1 = 0002 BC, ... so we adjust
y = -((year / 1_000) * 1_000 + 99);
date = ValueTimestamp.parse(y + "-" + month + "-01");
assertEquals(date, ToDateParser.toDate("100 BC", "YYY BC"));
assertEquals(date, ToDateParser.toDate(session, "100 BC", "YYY BC"));
// Gregorian calendar does not have a year 0.
// 0 = 0001 BC, -1 = 0002 BC, ... so we adjust
y = -((year / 100) * 100);
date = ValueTimestamp.parse(y + "-" + month + "-01");
assertEquals(date, ToDateParser.toDate("01 BC", "YY BC"));
assertEquals(date, ToDateParser.toDate(session, "01 BC", "YY BC"));
y = -((year / 10) * 10);
date = ValueTimestamp.parse(y + "-" + month + "-01");
assertEquals(date, ToDateParser.toDate("1 BC", "Y BC"));
assertEquals(date, ToDateParser.toDate(session, "1 BC", "Y BC"));
date = ValueTimestamp.parse(defDate + "08:12:00");
assertEquals(date, ToDateParser.toDate("08:12 AM", "HH:MI AM"));
assertEquals(date, ToDateParser.toDate("08:12 A.M.", "HH:MI A.M."));
assertEquals(date, ToDateParser.toDate("08:12", "HH24:MI"));
assertEquals(date, ToDateParser.toDate(session, "08:12 AM", "HH:MI AM"));
assertEquals(date, ToDateParser.toDate(session, "08:12 A.M.", "HH:MI A.M."));
assertEquals(date, ToDateParser.toDate(session, "08:12", "HH24:MI"));
date = ValueTimestamp.parse(defDate + "08:12:00");
assertEquals(date, ToDateParser.toDate("08:12", "HH:MI"));
assertEquals(date, ToDateParser.toDate("08:12", "HH12:MI"));
assertEquals(date, ToDateParser.toDate(session, "08:12", "HH:MI"));
assertEquals(date, ToDateParser.toDate(session, "08:12", "HH12:MI"));
date = ValueTimestamp.parse(defDate + "08:12:34");
assertEquals(date, ToDateParser.toDate("08:12:34", "HH:MI:SS"));
assertEquals(date, ToDateParser.toDate(session, "08:12:34", "HH:MI:SS"));
date = ValueTimestamp.parse(defDate + "12:00:00");
assertEquals(date, ToDateParser.toDate("12:00:00 PM", "HH12:MI:SS AM"));
assertEquals(date, ToDateParser.toDate(session, "12:00:00 PM", "HH12:MI:SS AM"));
date = ValueTimestamp.parse(defDate + "00:00:00");
assertEquals(date, ToDateParser.toDate("12:00:00 AM", "HH12:MI:SS AM"));
assertEquals(date, ToDateParser.toDate(session, "12:00:00 AM", "HH12:MI:SS AM"));
date = ValueTimestamp.parse(defDate + "00:00:34");
assertEquals(date, ToDateParser.toDate("34", "SS"));
assertEquals(date, ToDateParser.toDate(session, "34", "SS"));
date = ValueTimestamp.parse(defDate + "08:12:34");
assertEquals(date, ToDateParser.toDate("29554", "SSSSS"));
assertEquals(date, ToDateParser.toDate(session, "29554", "SSSSS"));
date = ValueTimestamp.parse(defDate + "08:12:34.550");
assertEquals(date, ToDateParser.toDate("08:12:34 550", "HH:MI:SS FF"));
assertEquals(date, ToDateParser.toDate("08:12:34 55", "HH:MI:SS FF2"));
assertEquals(date, ToDateParser.toDate(session, "08:12:34 550", "HH:MI:SS FF"));
assertEquals(date, ToDateParser.toDate(session, "08:12:34 55", "HH:MI:SS FF2"));
date = ValueTimestamp.parse(defDate + "14:04:00");
assertEquals(date, ToDateParser.toDate("02:04 P.M.", "HH:MI p.M."));
assertEquals(date, ToDateParser.toDate("02:04 PM", "HH:MI PM"));
assertEquals(date, ToDateParser.toDate(session, "02:04 P.M.", "HH:MI p.M."));
assertEquals(date, ToDateParser.toDate(session, "02:04 PM", "HH:MI PM"));
date = ValueTimestamp.parse("1970-" + month + "-12");
assertEquals(date, ToDateParser.toDate("12", "DD"));
assertEquals(date, ToDateParser.toDate(session, "12", "DD"));
date = ValueTimestamp.parse(year + (calendar.isLeapYear(year) ? "11-11" : "-11-12"));
assertEquals(date, ToDateParser.toDate("316", "DDD"));
assertEquals(date, ToDateParser.toDate("316", "DdD"));
assertEquals(date, ToDateParser.toDate("316", "dDD"));
assertEquals(date, ToDateParser.toDate("316", "ddd"));
assertEquals(date, ToDateParser.toDate(session, "316", "DDD"));
assertEquals(date, ToDateParser.toDate(session, "316", "DdD"));
assertEquals(date, ToDateParser.toDate(session, "316", "dDD"));
assertEquals(date, ToDateParser.toDate(session, "316", "ddd"));
date = ValueTimestamp.parse("2013-01-29");
assertEquals(date, ToDateParser.toDate("2456322", "J"));
assertEquals(date, ToDateParser.toDate(session, "2456322", "J"));
if (Locale.getDefault().getLanguage().equals("en")) {
date = ValueTimestamp.parse("9999-12-31 23:59:59");
assertEquals(date, ToDateParser.toDate("31-DEC-9999 23:59:59", "DD-MON-YYYY HH24:MI:SS"));
assertEquals(date, ToDateParser.toDate("31-DEC-9999 23:59:59", "DD-MON-RRRR HH24:MI:SS"));
assertEquals(ValueTimestamp.parse("0001-03-01"), ToDateParser.toDate("1-MAR-0001", "DD-MON-RRRR"));
assertEquals(ValueTimestamp.parse("9999-03-01"), ToDateParser.toDate("1-MAR-9999", "DD-MON-RRRR"));
assertEquals(ValueTimestamp.parse("2000-03-01"), ToDateParser.toDate("1-MAR-000", "DD-MON-RRRR"));
assertEquals(ValueTimestamp.parse("1999-03-01"), ToDateParser.toDate("1-MAR-099", "DD-MON-RRRR"));
assertEquals(ValueTimestamp.parse("0100-03-01"), ToDateParser.toDate("1-MAR-100", "DD-MON-RRRR"));
assertEquals(ValueTimestamp.parse("2000-03-01"), ToDateParser.toDate("1-MAR-00", "DD-MON-RRRR"));
assertEquals(ValueTimestamp.parse("2049-03-01"), ToDateParser.toDate("1-MAR-49", "DD-MON-RRRR"));
assertEquals(ValueTimestamp.parse("1950-03-01"), ToDateParser.toDate("1-MAR-50", "DD-MON-RRRR"));
assertEquals(ValueTimestamp.parse("1999-03-01"), ToDateParser.toDate("1-MAR-99", "DD-MON-RRRR"));
assertEquals(date, ToDateParser.toDate(session, "31-DEC-9999 23:59:59", "DD-MON-YYYY HH24:MI:SS"));
assertEquals(date, ToDateParser.toDate(session, "31-DEC-9999 23:59:59", "DD-MON-RRRR HH24:MI:SS"));
assertEquals(ValueTimestamp.parse("0001-03-01"),
ToDateParser.toDate(session, "1-MAR-0001", "DD-MON-RRRR"));
assertEquals(ValueTimestamp.parse("9999-03-01"),
ToDateParser.toDate(session, "1-MAR-9999", "DD-MON-RRRR"));
assertEquals(ValueTimestamp.parse("2000-03-01"), ToDateParser.toDate(session, "1-MAR-000", "DD-MON-RRRR"));
assertEquals(ValueTimestamp.parse("1999-03-01"), ToDateParser.toDate(session, "1-MAR-099", "DD-MON-RRRR"));
assertEquals(ValueTimestamp.parse("0100-03-01"), ToDateParser.toDate(session, "1-MAR-100", "DD-MON-RRRR"));
assertEquals(ValueTimestamp.parse("2000-03-01"), ToDateParser.toDate(session, "1-MAR-00", "DD-MON-RRRR"));
assertEquals(ValueTimestamp.parse("2049-03-01"), ToDateParser.toDate(session, "1-MAR-49", "DD-MON-RRRR"));
assertEquals(ValueTimestamp.parse("1950-03-01"), ToDateParser.toDate(session, "1-MAR-50", "DD-MON-RRRR"));
assertEquals(ValueTimestamp.parse("1999-03-01"), ToDateParser.toDate(session, "1-MAR-99", "DD-MON-RRRR"));
}
assertEquals(ValueTimestampTimeZone.parse("2000-05-10 10:11:12-08:15"),
ToDateParser.toTimestampTz("2000-05-10 10:11:12 -8:15", "YYYY-MM-DD HH24:MI:SS TZH:TZM"));
ToDateParser.toTimestampTz(session, "2000-05-10 10:11:12 -8:15", "YYYY-MM-DD HH24:MI:SS TZH:TZM"));
assertEquals(ValueTimestampTimeZone.parse("2000-05-10 10:11:12-08:15"),
ToDateParser.toTimestampTz("2000-05-10 10:11:12 GMT-08:15", "YYYY-MM-DD HH24:MI:SS TZR"));
ToDateParser.toTimestampTz(session, "2000-05-10 10:11:12 GMT-08:15", "YYYY-MM-DD HH24:MI:SS TZR"));
assertEquals(ValueTimestampTimeZone.parse("2000-02-10 10:11:12-08"),
ToDateParser.toTimestampTz("2000-02-10 10:11:12 US/Pacific", "YYYY-MM-DD HH24:MI:SS TZR"));
ToDateParser.toTimestampTz(session, "2000-02-10 10:11:12 US/Pacific", "YYYY-MM-DD HH24:MI:SS TZR"));
assertEquals(ValueTimestampTimeZone.parse("2000-02-10 10:11:12-08"),
ToDateParser.toTimestampTz("2000-02-10 10:11:12 PST", "YYYY-MM-DD HH24:MI:SS TZD"));
ToDateParser.toTimestampTz(session, "2000-02-10 10:11:12 PST", "YYYY-MM-DD HH24:MI:SS TZD"));
}
private void testToCharFromDateTime() throws SQLException {
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论