提交 de2dbaa1 authored 作者: Igor Motov's avatar Igor Motov

Use Gregorian calendar regardless of the default locale

Date parsing logic assumes that the calendar type is Gregorian, so it should use the Gregorian calendar even if the default locale says otherwise.

Fixes #675
上级 326e5833
...@@ -21,6 +21,8 @@ Change Log ...@@ -21,6 +21,8 @@ Change Log
<h2>Next Version (unreleased)</h2> <h2>Next Version (unreleased)</h2>
<ul> <ul>
<li>Issue #675: Fix date operations on Locales with non-Gregorian calendars
</li>
<li>Fix removal of LOB when rolling back transaction on a table containing more than one LOB column. <li>Fix removal of LOB when rolling back transaction on a table containing more than one LOB column.
</li> </li>
<li>Issue #654: List ENUM type values in INFORMATION_SCHEMA.COLUMNS <li>Issue #654: List ENUM type values in INFORMATION_SCHEMA.COLUMNS
......
...@@ -1252,7 +1252,7 @@ public class Function extends Expression implements FunctionCall { ...@@ -1252,7 +1252,7 @@ public class Function extends Expression implements FunctionCall {
case TRUNCATE: { case TRUNCATE: {
if (v0.getType() == Value.TIMESTAMP) { if (v0.getType() == Value.TIMESTAMP) {
java.sql.Timestamp d = v0.getTimestamp(); java.sql.Timestamp d = v0.getTimestamp();
Calendar c = Calendar.getInstance(); Calendar c = DateTimeUtils.createCalendar();
c.setTime(d); c.setTime(d);
c.set(Calendar.HOUR_OF_DAY, 0); c.set(Calendar.HOUR_OF_DAY, 0);
c.set(Calendar.MINUTE, 0); c.set(Calendar.MINUTE, 0);
...@@ -1261,7 +1261,7 @@ public class Function extends Expression implements FunctionCall { ...@@ -1261,7 +1261,7 @@ public class Function extends Expression implements FunctionCall {
result = ValueTimestamp.fromMillis(c.getTimeInMillis()); result = ValueTimestamp.fromMillis(c.getTimeInMillis());
} else if (v0.getType() == Value.DATE) { } else if (v0.getType() == Value.DATE) {
ValueDate vd = (ValueDate) v0; ValueDate vd = (ValueDate) v0;
Calendar c = Calendar.getInstance(); Calendar c = DateTimeUtils.createCalendar();
c.setTime(vd.getDate()); c.setTime(vd.getDate());
c.set(Calendar.HOUR_OF_DAY, 0); c.set(Calendar.HOUR_OF_DAY, 0);
c.set(Calendar.MINUTE, 0); c.set(Calendar.MINUTE, 0);
...@@ -1270,7 +1270,7 @@ public class Function extends Expression implements FunctionCall { ...@@ -1270,7 +1270,7 @@ public class Function extends Expression implements FunctionCall {
result = ValueTimestamp.fromMillis(c.getTimeInMillis()); result = ValueTimestamp.fromMillis(c.getTimeInMillis());
} else if (v0.getType() == Value.STRING) { } else if (v0.getType() == Value.STRING) {
ValueString vd = (ValueString) v0; ValueString vd = (ValueString) v0;
Calendar c = Calendar.getInstance(); Calendar c = DateTimeUtils.createCalendar();
c.setTime(ValueTimestamp.parse(vd.getString(), session.getDatabase().getMode()).getDate()); c.setTime(ValueTimestamp.parse(vd.getString(), session.getDatabase().getMode()).getDate());
c.set(Calendar.HOUR_OF_DAY, 0); c.set(Calendar.HOUR_OF_DAY, 0);
c.set(Calendar.MINUTE, 0); c.set(Calendar.MINUTE, 0);
...@@ -1822,7 +1822,7 @@ public class Function extends Expression implements FunctionCall { ...@@ -1822,7 +1822,7 @@ public class Function extends Expression implements FunctionCall {
if (count > Integer.MAX_VALUE) { if (count > Integer.MAX_VALUE) {
throw DbException.getInvalidValueException("DATEADD count", count); throw DbException.getInvalidValueException("DATEADD count", count);
} }
Calendar calendar = Calendar.getInstance(); Calendar calendar = DateTimeUtils.createCalendar();
int nanos = d.getNanos() % 1000000; int nanos = d.getNanos() % 1000000;
calendar.setTime(d); calendar.setTime(d);
calendar.add(field, (int) count); calendar.add(field, (int) count);
...@@ -1846,7 +1846,7 @@ public class Function extends Expression implements FunctionCall { ...@@ -1846,7 +1846,7 @@ public class Function extends Expression implements FunctionCall {
*/ */
private static long datediff(String part, Timestamp d1, Timestamp d2) { private static long datediff(String part, Timestamp d1, Timestamp d2) {
int field = getDatePart(part); int field = getDatePart(part);
Calendar calendar = Calendar.getInstance(); Calendar calendar = DateTimeUtils.createCalendar();
long t1 = d1.getTime(), t2 = d2.getTime(); long t1 = d1.getTime(), t2 = d2.getTime();
// need to convert to UTC, otherwise we get inconsistent results with // need to convert to UTC, otherwise we get inconsistent results with
// certain time zones (those that are 30 minutes off) // certain time zones (those that are 30 minutes off)
...@@ -1896,7 +1896,7 @@ public class Function extends Expression implements FunctionCall { ...@@ -1896,7 +1896,7 @@ public class Function extends Expression implements FunctionCall {
default: default:
break; break;
} }
calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC")); calendar = DateTimeUtils.createCalendar(TimeZone.getTimeZone("UTC"));
calendar.setTimeInMillis(t1); calendar.setTimeInMillis(t1);
int year1 = calendar.get(Calendar.YEAR); int year1 = calendar.get(Calendar.YEAR);
int month1 = calendar.get(Calendar.MONTH); int month1 = calendar.get(Calendar.MONTH);
......
...@@ -3799,7 +3799,7 @@ public class JdbcResultSet extends TraceObject implements ResultSet, JdbcResultS ...@@ -3799,7 +3799,7 @@ public class JdbcResultSet extends TraceObject implements ResultSet, JdbcResultS
} else if (type == java.util.Date.class) { } else if (type == java.util.Date.class) {
return type.cast(new java.util.Date(value.getTimestamp().getTime())); return type.cast(new java.util.Date(value.getTimestamp().getTime()));
} else if (type == Calendar.class) { } else if (type == Calendar.class) {
Calendar calendar = Calendar.getInstance(); Calendar calendar = DateTimeUtils.createCalendar();
calendar.setTime(value.getTimestamp()); calendar.setTime(value.getTimestamp());
return type.cast(calendar); return type.cast(calendar);
} else if (type == UUID.class) { } else if (type == UUID.class) {
......
...@@ -73,7 +73,7 @@ public class DateTimeUtils { ...@@ -73,7 +73,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 = Calendar.getInstance() private static int zoneOffsetMillis = DateTimeUtils.createCalendar()
.get(Calendar.ZONE_OFFSET); .get(Calendar.ZONE_OFFSET);
private DateTimeUtils() { private DateTimeUtils() {
...@@ -86,7 +86,7 @@ public class DateTimeUtils { ...@@ -86,7 +86,7 @@ public class DateTimeUtils {
*/ */
public static void resetCalendar() { public static void resetCalendar() {
CACHED_CALENDAR.remove(); CACHED_CALENDAR.remove();
zoneOffsetMillis = Calendar.getInstance().get(Calendar.ZONE_OFFSET); zoneOffsetMillis = DateTimeUtils.createCalendar().get(Calendar.ZONE_OFFSET);
} }
/** /**
...@@ -97,7 +97,7 @@ public class DateTimeUtils { ...@@ -97,7 +97,7 @@ public class DateTimeUtils {
private static Calendar getCalendar() { private static Calendar getCalendar() {
Calendar c = CACHED_CALENDAR.get(); Calendar c = CACHED_CALENDAR.get();
if (c == null) { if (c == null) {
c = Calendar.getInstance(); c = DateTimeUtils.createCalendar();
CACHED_CALENDAR.set(c); CACHED_CALENDAR.set(c);
} }
c.clear(); c.clear();
...@@ -113,13 +113,32 @@ public class DateTimeUtils { ...@@ -113,13 +113,32 @@ public class DateTimeUtils {
private static Calendar getCalendar(TimeZone tz) { private static Calendar getCalendar(TimeZone tz) {
Calendar c = CACHED_CALENDAR_NON_DEFAULT_TIMEZONE.get(); Calendar c = CACHED_CALENDAR_NON_DEFAULT_TIMEZONE.get();
if (c == null || !c.getTimeZone().equals(tz)) { if (c == null || !c.getTimeZone().equals(tz)) {
c = Calendar.getInstance(tz); c = DateTimeUtils.createCalendar(tz);
CACHED_CALENDAR_NON_DEFAULT_TIMEZONE.set(c); CACHED_CALENDAR_NON_DEFAULT_TIMEZONE.set(c);
} }
c.clear(); c.clear();
return c; return c;
} }
/**
* Creates a calendar for the default timezone.
*
* @return a calendar instance. A cached instance is returned where possible
*/
public static Calendar createCalendar() {
return new GregorianCalendar();
}
/**
* Creates a calendar for the given timezone.
*
* @param tz timezone for the calendar, is never null
* @return a calendar instance. A cached instance is returned where possible
*/
public static Calendar createCalendar(TimeZone tz) {
return new GregorianCalendar(tz);
}
/** /**
* Convert the date to the specified time zone. * Convert the date to the specified time zone.
* *
...@@ -253,11 +272,9 @@ public class DateTimeUtils { ...@@ -253,11 +272,9 @@ public class DateTimeUtils {
throw DbException.getInvalidValueException("calendar", null); throw DbException.getInvalidValueException("calendar", null);
} }
target = (Calendar) target.clone(); target = (Calendar) target.clone();
Calendar local = Calendar.getInstance(); Calendar local = DateTimeUtils.createCalendar();
synchronized (local) { local.setTime(x);
local.setTime(x); convertTime(local, target);
convertTime(local, target);
}
return target.getTime().getTime(); return target.getTime().getTime();
} }
...@@ -531,7 +548,7 @@ public class DateTimeUtils { ...@@ -531,7 +548,7 @@ public class DateTimeUtils {
* @return the day of the week, Monday as 1 to Sunday as 7 * @return the day of the week, Monday as 1 to Sunday as 7
*/ */
public static int getIsoDayOfWeek(java.util.Date date) { public static int getIsoDayOfWeek(java.util.Date date) {
Calendar cal = Calendar.getInstance(); Calendar cal = DateTimeUtils.createCalendar();
cal.setTimeInMillis(date.getTime()); cal.setTimeInMillis(date.getTime());
int val = cal.get(Calendar.DAY_OF_WEEK) - 1; int val = cal.get(Calendar.DAY_OF_WEEK) - 1;
return val == 0 ? 7 : val; return val == 0 ? 7 : val;
...@@ -552,7 +569,7 @@ public class DateTimeUtils { ...@@ -552,7 +569,7 @@ public class DateTimeUtils {
* @return the week of the year * @return the week of the year
*/ */
public static int getIsoWeek(java.util.Date date) { public static int getIsoWeek(java.util.Date date) {
Calendar c = Calendar.getInstance(); Calendar c = DateTimeUtils.createCalendar();
c.setTimeInMillis(date.getTime()); c.setTimeInMillis(date.getTime());
c.setFirstDayOfWeek(Calendar.MONDAY); c.setFirstDayOfWeek(Calendar.MONDAY);
c.setMinimalDaysInFirstWeek(4); c.setMinimalDaysInFirstWeek(4);
...@@ -567,7 +584,7 @@ public class DateTimeUtils { ...@@ -567,7 +584,7 @@ public class DateTimeUtils {
* @return the year * @return the year
*/ */
public static int getIsoYear(java.util.Date date) { public static int getIsoYear(java.util.Date date) {
Calendar cal = Calendar.getInstance(); Calendar cal = DateTimeUtils.createCalendar();
cal.setTimeInMillis(date.getTime()); cal.setTimeInMillis(date.getTime());
cal.setFirstDayOfWeek(Calendar.MONDAY); cal.setFirstDayOfWeek(Calendar.MONDAY);
cal.setMinimalDaysInFirstWeek(4); cal.setMinimalDaysInFirstWeek(4);
...@@ -942,7 +959,7 @@ public class DateTimeUtils { ...@@ -942,7 +959,7 @@ public class DateTimeUtils {
* @return the new timestamp * @return the new timestamp
*/ */
public static Timestamp addMonths(Timestamp refDate, int nrOfMonthsToAdd) { public static Timestamp addMonths(Timestamp refDate, int nrOfMonthsToAdd) {
Calendar calendar = Calendar.getInstance(); Calendar calendar = DateTimeUtils.createCalendar();
calendar.setTime(refDate); calendar.setTime(refDate);
calendar.add(Calendar.MONTH, nrOfMonthsToAdd); calendar.add(Calendar.MONTH, nrOfMonthsToAdd);
......
...@@ -21,7 +21,7 @@ public class ToDateParser { ...@@ -21,7 +21,7 @@ public class ToDateParser {
private final ConfigParam functionName; private final ConfigParam functionName;
private String inputStr; private String inputStr;
private String formatStr; private String formatStr;
private final Calendar resultCalendar = (Calendar) Calendar.getInstance().clone(); private final Calendar resultCalendar = DateTimeUtils.createCalendar();
private Integer nanos; private Integer nanos;
/** /**
...@@ -33,7 +33,7 @@ public class ToDateParser { ...@@ -33,7 +33,7 @@ public class ToDateParser {
private ToDateParser(ConfigParam functionName, String input, String format) { private ToDateParser(ConfigParam functionName, String input, String format) {
// reset calendar - default oracle behaviour // reset calendar - default oracle behaviour
resultCalendar.set(Calendar.YEAR, 1970); resultCalendar.set(Calendar.YEAR, 1970);
resultCalendar.set(Calendar.MONTH, Calendar.getInstance().get(Calendar.MONTH)); resultCalendar.set(Calendar.MONTH, DateTimeUtils.createCalendar().get(Calendar.MONTH));
resultCalendar.clear(Calendar.DAY_OF_YEAR); resultCalendar.clear(Calendar.DAY_OF_YEAR);
resultCalendar.clear(Calendar.DAY_OF_WEEK); resultCalendar.clear(Calendar.DAY_OF_WEEK);
resultCalendar.clear(Calendar.DAY_OF_WEEK_IN_MONTH); resultCalendar.clear(Calendar.DAY_OF_WEEK_IN_MONTH);
......
...@@ -194,7 +194,7 @@ class ToDateTokenizer { ...@@ -194,7 +194,7 @@ class ToDateTokenizer {
result.set(Calendar.YEAR, dateNr); result.set(Calendar.YEAR, dateNr);
break; break;
case RR: case RR:
Calendar calendar = Calendar.getInstance(); Calendar calendar = DateTimeUtils.createCalendar();
int cc = calendar.get(Calendar.YEAR) / 100; int cc = calendar.get(Calendar.YEAR) / 100;
inputFragmentStr = matchStringOrThrow(PATTERN_TWO_DIGITS, inputFragmentStr = matchStringOrThrow(PATTERN_TWO_DIGITS,
params, formatTokenEnum); params, formatTokenEnum);
......
...@@ -217,7 +217,7 @@ public class ValueTimestamp extends Value { ...@@ -217,7 +217,7 @@ public class ValueTimestamp extends Value {
tz, year, month, day, hour, minute, (int) second, (int) ms); tz, year, month, day, hour, minute, (int) second, (int) ms);
ms = DateTimeUtils.convertToLocal( ms = DateTimeUtils.convertToLocal(
new Date(millis), new Date(millis),
Calendar.getInstance(TimeZone.getTimeZone("UTC"))); DateTimeUtils.createCalendar(TimeZone.getTimeZone("UTC")));
long md = DateTimeUtils.MILLIS_PER_DAY; long md = DateTimeUtils.MILLIS_PER_DAY;
long absoluteDay = (ms >= 0 ? ms : ms - md + 1) / md; long absoluteDay = (ms >= 0 ? ms : ms - md + 1) / md;
dateValue = DateTimeUtils.dateValueFromAbsoluteDay(absoluteDay); dateValue = DateTimeUtils.dateValueFromAbsoluteDay(absoluteDay);
......
...@@ -1199,7 +1199,7 @@ public class TestFunctions extends TestBase implements AggregateFunction { ...@@ -1199,7 +1199,7 @@ public class TestFunctions extends TestBase implements AggregateFunction {
"SELECT CURRENT_TIMESTAMP(), " + "SELECT CURRENT_TIMESTAMP(), " +
"TRUNCATE(CURRENT_TIMESTAMP()) FROM dual"); "TRUNCATE(CURRENT_TIMESTAMP()) FROM dual");
rs.next(); rs.next();
Calendar c = Calendar.getInstance(); Calendar c = DateTimeUtils.createCalendar();
c.setTime(rs.getTimestamp(1)); c.setTime(rs.getTimestamp(1));
c.set(Calendar.HOUR_OF_DAY, 0); c.set(Calendar.HOUR_OF_DAY, 0);
c.set(Calendar.MINUTE, 0); c.set(Calendar.MINUTE, 0);
...@@ -1305,7 +1305,7 @@ public class TestFunctions extends TestBase implements AggregateFunction { ...@@ -1305,7 +1305,7 @@ public class TestFunctions extends TestBase implements AggregateFunction {
} }
private void testToDate() throws ParseException { private void testToDate() throws ParseException {
final int month = Calendar.getInstance().get(Calendar.MONTH); final int month = DateTimeUtils.createCalendar().get(Calendar.MONTH);
Date date = null; Date date = null;
date = new SimpleDateFormat("yyyy-MM-dd").parse("1979-11-12"); date = new SimpleDateFormat("yyyy-MM-dd").parse("1979-11-12");
...@@ -1434,7 +1434,7 @@ public class TestFunctions extends TestBase implements AggregateFunction { ...@@ -1434,7 +1434,7 @@ public class TestFunctions extends TestBase implements AggregateFunction {
} }
private static void setMonth(Date date, int month) { private static void setMonth(Date date, int month) {
Calendar c = Calendar.getInstance(); Calendar c = DateTimeUtils.createCalendar();
c.setTime(date); c.setTime(date);
c.set(Calendar.MONTH, month); c.set(Calendar.MONTH, month);
date.setTime(c.getTimeInMillis()); date.setTime(c.getTimeInMillis());
......
...@@ -37,6 +37,7 @@ import java.util.TimeZone; ...@@ -37,6 +37,7 @@ import java.util.TimeZone;
import org.h2.api.ErrorCode; import org.h2.api.ErrorCode;
import org.h2.test.TestBase; import org.h2.test.TestBase;
import org.h2.util.DateTimeUtils;
import org.h2.util.IOUtils; import org.h2.util.IOUtils;
import org.h2.util.LocalDateTimeUtils; import org.h2.util.LocalDateTimeUtils;
...@@ -1408,7 +1409,7 @@ public class TestResultSet extends TestBase { ...@@ -1408,7 +1409,7 @@ public class TestResultSet extends TestBase {
"D DATE, T TIME, TS TIMESTAMP)"); "D DATE, T TIME, TS TIMESTAMP)");
PreparedStatement prep = conn.prepareStatement( PreparedStatement prep = conn.prepareStatement(
"INSERT INTO TEST VALUES(?, ?, ?, ?)"); "INSERT INTO TEST VALUES(?, ?, ?, ?)");
Calendar regular = Calendar.getInstance(); Calendar regular = DateTimeUtils.createCalendar();
Calendar other = null; Calendar other = null;
// search a locale that has a _different_ raw offset // search a locale that has a _different_ raw offset
long testTime = java.sql.Date.valueOf("2001-02-03").getTime(); long testTime = java.sql.Date.valueOf("2001-02-03").getTime();
...@@ -1421,7 +1422,7 @@ public class TestResultSet extends TestBase { ...@@ -1421,7 +1422,7 @@ public class TestResultSet extends TestBase {
if (rawOffsetDiff != 0 && rawOffsetDiff != 1000 * 60 * 60 * 24) { if (rawOffsetDiff != 0 && rawOffsetDiff != 1000 * 60 * 60 * 24) {
if (regular.getTimeZone().getOffset(testTime) != if (regular.getTimeZone().getOffset(testTime) !=
zone.getOffset(testTime)) { zone.getOffset(testTime)) {
other = Calendar.getInstance(zone); other = DateTimeUtils.createCalendar(zone);
break; break;
} }
} }
......
...@@ -42,6 +42,7 @@ import org.h2.test.synth.sql.RandomGen; ...@@ -42,6 +42,7 @@ import org.h2.test.synth.sql.RandomGen;
import org.h2.tools.Backup; import org.h2.tools.Backup;
import org.h2.tools.DeleteDbFiles; import org.h2.tools.DeleteDbFiles;
import org.h2.tools.Restore; import org.h2.tools.Restore;
import org.h2.util.DateTimeUtils;
import org.h2.util.MathUtils; import org.h2.util.MathUtils;
import org.h2.util.New; import org.h2.util.New;
...@@ -485,7 +486,7 @@ public class TestCrashAPI extends TestBase implements Runnable { ...@@ -485,7 +486,7 @@ public class TestCrashAPI extends TestBase implements Runnable {
// TODO should use generated savepoints // TODO should use generated savepoints
return null; return null;
} else if (type == Calendar.class) { } else if (type == Calendar.class) {
return Calendar.getInstance(); return DateTimeUtils.createCalendar();
} else if (type == java.net.URL.class) { } else if (type == java.net.URL.class) {
return null; return null;
} else if (type == java.math.BigDecimal.class) { } else if (type == java.math.BigDecimal.class) {
......
...@@ -352,7 +352,7 @@ public class TestDate extends TestBase { ...@@ -352,7 +352,7 @@ public class TestDate extends TestBase {
} }
private void testValidDate() { private void testValidDate() {
Calendar c = Calendar.getInstance(TimeZone.getTimeZone("UTC")); Calendar c = DateTimeUtils.createCalendar(TimeZone.getTimeZone("UTC"));
c.setLenient(false); c.setLenient(false);
for (int y = -2000; y < 3000; y++) { for (int y = -2000; y < 3000; y++) {
for (int m = -3; m <= 14; m++) { for (int m = -3; m <= 14; m++) {
...@@ -467,9 +467,9 @@ public class TestDate extends TestBase { ...@@ -467,9 +467,9 @@ public class TestDate extends TestBase {
assertEquals("19999-08-07", d2.getString()); assertEquals("19999-08-07", d2.getString());
assertEquals("13:14:15.16", t2.getString()); assertEquals("13:14:15.16", t2.getString());
ValueTimestamp ts1a = DateTimeUtils.convertTimestamp( ValueTimestamp ts1a = DateTimeUtils.convertTimestamp(
ts1.getTimestamp(), Calendar.getInstance()); ts1.getTimestamp(), DateTimeUtils.createCalendar());
ValueTimestamp ts2a = DateTimeUtils.convertTimestamp( ValueTimestamp ts2a = DateTimeUtils.convertTimestamp(
ts2.getTimestamp(), Calendar.getInstance()); ts2.getTimestamp(), DateTimeUtils.createCalendar());
assertEquals("-999-08-07 13:14:15.16", ts1a.getString()); assertEquals("-999-08-07 13:14:15.16", ts1a.getString());
assertEquals("19999-08-07 13:14:15.16", ts2a.getString()); assertEquals("19999-08-07 13:14:15.16", ts2a.getString());
......
...@@ -29,6 +29,7 @@ public class TestLocale extends TestBase { ...@@ -29,6 +29,7 @@ public class TestLocale extends TestBase {
@Override @Override
public void test() throws SQLException { public void test() throws SQLException {
testSpecialLocale(); testSpecialLocale();
testDatesInJapanLocale();
} }
private void testSpecialLocale() throws SQLException { private void testSpecialLocale() throws SQLException {
...@@ -55,4 +56,32 @@ public class TestLocale extends TestBase { ...@@ -55,4 +56,32 @@ public class TestLocale extends TestBase {
conn.close(); conn.close();
} }
private void testDatesInJapanLocale() throws SQLException {
deleteDb(getTestName());
Connection conn = getConnection(getTestName());
Statement stat = conn.createStatement();
Locale old = Locale.getDefault();
try {
// when using Japanese as the default locale, the default calendar is
// the imperial japanese calendar
Locale.setDefault(new Locale("ja", "JP", "JP"));
stat.execute("CREATE TABLE test(d TIMESTAMP, dz TIMESTAMP WITH TIME ZONE) " +
"as select '2017-12-03T00:00:00Z', '2017-12-03T00:00:00Z'");
ResultSet rs = stat.executeQuery("select YEAR(d) y, YEAR(dz) yz from test");
rs.next();
assertEquals(2017, rs.getInt("y"));
assertEquals(2017, rs.getInt("yz"));
stat.execute("drop table test");
rs = stat.executeQuery(
"CALL FORMATDATETIME(TIMESTAMP '2001-02-03 04:05:06', 'yyyy-MM-dd HH:mm:ss', 'en')");
rs.next();
assertEquals("2001-02-03 04:05:06", rs.getString(1));
} finally {
Locale.setDefault(old);
}
conn.close();
}
} }
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论