提交 39e74015 authored 作者: Noel Grandin's avatar Noel Grandin

Merge branch 'master' of https://github.com/plus33/h2database into plus33-master

...@@ -95,7 +95,7 @@ public class Function extends Expression implements FunctionCall { ...@@ -95,7 +95,7 @@ public class Function extends Expression implements FunctionCall {
XMLATTR = 83, XMLNODE = 84, XMLCOMMENT = 85, XMLCDATA = 86, XMLATTR = 83, XMLNODE = 84, XMLCOMMENT = 85, XMLCDATA = 86,
XMLSTARTDOC = 87, XMLTEXT = 88, REGEXP_REPLACE = 89, RPAD = 90, XMLSTARTDOC = 87, XMLTEXT = 88, REGEXP_REPLACE = 89, RPAD = 90,
LPAD = 91, CONCAT_WS = 92, TO_CHAR = 93, TRANSLATE = 94, ORA_HASH = 95, LPAD = 91, CONCAT_WS = 92, TO_CHAR = 93, TRANSLATE = 94, ORA_HASH = 95,
TO_DATE = 96, TO_TIMESTAMP = 97; TO_DATE = 96, TO_TIMESTAMP = 97, ADD_MONTHS = 98;
public static final int CURDATE = 100, CURTIME = 101, DATE_ADD = 102, public static final int CURDATE = 100, CURTIME = 101, DATE_ADD = 102,
DATE_DIFF = 103, DAY_NAME = 104, DAY_OF_MONTH = 105, DATE_DIFF = 103, DAY_NAME = 104, DAY_OF_MONTH = 105,
...@@ -310,6 +310,7 @@ public class Function extends Expression implements FunctionCall { ...@@ -310,6 +310,7 @@ public class Function extends Expression implements FunctionCall {
0, Value.DATE); 0, Value.DATE);
addFunction("TO_DATE", TO_DATE, VAR_ARGS, Value.STRING); addFunction("TO_DATE", TO_DATE, VAR_ARGS, Value.STRING);
addFunction("TO_TIMESTAMP", TO_TIMESTAMP, VAR_ARGS, Value.STRING); addFunction("TO_TIMESTAMP", TO_TIMESTAMP, VAR_ARGS, Value.STRING);
addFunction("ADD_MONTHS", ADD_MONTHS, 2, Value.TIMESTAMP);
// alias for MSSQLServer // alias for MSSQLServer
addFunctionNotDeterministic("GETDATE", CURDATE, addFunctionNotDeterministic("GETDATE", CURDATE,
0, Value.DATE); 0, Value.DATE);
...@@ -1441,6 +1442,9 @@ public class Function extends Expression implements FunctionCall { ...@@ -1441,6 +1442,9 @@ public class Function extends Expression implements FunctionCall {
result = ValueTimestamp.get(ToDateParser.toTimestamp(v0.getString(), result = ValueTimestamp.get(ToDateParser.toTimestamp(v0.getString(),
v1 == null ? null : v1.getString())); v1 == null ? null : v1.getString()));
break; break;
case ADD_MONTHS:
result = ValueTimestamp.get(DateTimeUtils.addMonths(v0.getTimestamp(), v1.getInt()));
break;
case TRANSLATE: { case TRANSLATE: {
String matching = v1.getString(); String matching = v1.getString();
String replacement = v2.getString(); String replacement = v2.getString();
......
...@@ -905,4 +905,20 @@ public class DateTimeUtils { ...@@ -905,4 +905,20 @@ public class DateTimeUtils {
return dateValue(y, m + 3, (int) d); return dateValue(y, m + 3, (int) d);
} }
/**
* Adds the number of months to the date. If the resulting month's number of days is less than the original's day-of-month, the resulting
* day-of-months gets adjusted accordingly:
*
* 30.04.2007 - 2 months = 28.02.2007
*/
public static Timestamp addMonths(final Timestamp refDate, final int nrOfMonthsToAdd) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(refDate);
calendar.add(Calendar.MONTH, nrOfMonthsToAdd);
Timestamp resultDate = new Timestamp(calendar.getTimeInMillis());
resultDate.setNanos(refDate.getNanos());
return resultDate;
}
} }
...@@ -11,7 +11,6 @@ import java.sql.ResultSet; ...@@ -11,7 +11,6 @@ import java.sql.ResultSet;
import java.sql.Statement; import java.sql.Statement;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Date; import java.util.Date;
import org.h2.tools.DeleteDbFiles; import org.h2.tools.DeleteDbFiles;
/** /**
...@@ -36,6 +35,9 @@ public class ToDate { ...@@ -36,6 +35,9 @@ public class ToDate {
stat.execute("create table ToDateTest(id int primary key, " + stat.execute("create table ToDateTest(id int primary key, " +
"start_date datetime, end_date datetime)"); "start_date datetime, end_date datetime)");
stat.execute("insert into ToDateTest values(1, "
+ "ADD_MONTHS(TO_DATE('2015-11-13', 'yyyy-MM-DD'), 1), "
+ "TO_DATE('2015-12-15', 'YYYY-MM-DD'))");
stat.execute("insert into ToDateTest values(1, " + stat.execute("insert into ToDateTest values(1, " +
"TO_DATE('2015-11-13', 'yyyy-MM-DD'), " + "TO_DATE('2015-11-13', 'yyyy-MM-DD'), " +
"TO_DATE('2015-12-15', 'YYYY-MM-DD'))"); "TO_DATE('2015-12-15', 'YYYY-MM-DD'))");
......
...@@ -38,7 +38,6 @@ import java.util.Locale; ...@@ -38,7 +38,6 @@ import java.util.Locale;
import java.util.Properties; import java.util.Properties;
import java.util.TimeZone; import java.util.TimeZone;
import java.util.UUID; import java.util.UUID;
import org.h2.api.Aggregate; import org.h2.api.Aggregate;
import org.h2.api.AggregateFunction; import org.h2.api.AggregateFunction;
import org.h2.api.ErrorCode; import org.h2.api.ErrorCode;
...@@ -49,6 +48,7 @@ import org.h2.store.fs.FileUtils; ...@@ -49,6 +48,7 @@ import org.h2.store.fs.FileUtils;
import org.h2.test.TestBase; import org.h2.test.TestBase;
import org.h2.test.ap.TestAnnotationProcessor; import org.h2.test.ap.TestAnnotationProcessor;
import org.h2.tools.SimpleResultSet; import org.h2.tools.SimpleResultSet;
import org.h2.util.DateTimeUtils;
import org.h2.util.IOUtils; import org.h2.util.IOUtils;
import org.h2.util.New; import org.h2.util.New;
import org.h2.util.StringUtils; import org.h2.util.StringUtils;
...@@ -78,6 +78,7 @@ public class TestFunctions extends TestBase implements AggregateFunction { ...@@ -78,6 +78,7 @@ public class TestFunctions extends TestBase implements AggregateFunction {
deleteDb("functions"); deleteDb("functions");
testToDate(); testToDate();
testToDateException(); testToDateException();
testAddMonths();
testDataType(); testDataType();
testVersion(); testVersion();
testFunctionTable(); testFunctionTable();
...@@ -1408,6 +1409,31 @@ public class TestFunctions extends TestBase implements AggregateFunction { ...@@ -1408,6 +1409,31 @@ public class TestFunctions extends TestBase implements AggregateFunction {
date.setTime(c.getTimeInMillis()); date.setTime(c.getTimeInMillis());
} }
private void testAddMonths() throws ParseException {
Timestamp date;
Timestamp expected;
// 01-Aug-03 + 3 months = 01-Nov-03
date = new Timestamp(new SimpleDateFormat("yyyy-MM-dd").parse("2003-08-01").getTime());
expected = new Timestamp(new SimpleDateFormat("yyyy-MM-dd").parse("2003-11-01").getTime());
assertEquals(expected, DateTimeUtils.addMonths(new Timestamp(date.getTime()), 3));
// 31-Jan-03 + 1 month = 28-Feb-2003
date = new Timestamp(new SimpleDateFormat("yyyy-MM-dd").parse("2003-01-31").getTime());
expected = new Timestamp(new SimpleDateFormat("yyyy-MM-dd").parse("2003-02-28").getTime());
assertEquals(expected, DateTimeUtils.addMonths(new Timestamp(date.getTime()), 1));
// 21-Aug-2003 - 3 months = 21-May-2003
date = new Timestamp(new SimpleDateFormat("yyyy-MM-dd").parse("2003-08-21").getTime());
expected = new Timestamp(new SimpleDateFormat("yyyy-MM-dd").parse("2003-05-21").getTime());
assertEquals(expected, DateTimeUtils.addMonths(new Timestamp(date.getTime()), -3));
// 21-Aug-2003 00:00:00:333 - 3 months = 21-May-2003 00:00:00:333
date = new Timestamp(new SimpleDateFormat("yyyy-MM-dd SSS").parse("2003-08-21 333").getTime());
expected = new Timestamp(new SimpleDateFormat("yyyy-MM-dd SSS").parse("2003-05-21 333").getTime());
assertEquals(expected, DateTimeUtils.addMonths(new Timestamp(date.getTime()), -3));
}
private void testToCharFromDateTime() throws SQLException { private void testToCharFromDateTime() throws SQLException {
deleteDb("functions"); deleteDb("functions");
Connection conn = getConnection("functions"); Connection conn = getConnection("functions");
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论