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

Merge pull request #937 from ScaY/scay-issue#935

Add "date_trunc" function (only with 'day')
...@@ -107,7 +107,7 @@ public class Function extends Expression implements FunctionCall { ...@@ -107,7 +107,7 @@ public class Function extends Expression implements FunctionCall {
SECOND = 114, WEEK = 115, YEAR = 116, CURRENT_DATE = 117, SECOND = 114, WEEK = 115, YEAR = 116, CURRENT_DATE = 117,
CURRENT_TIME = 118, CURRENT_TIMESTAMP = 119, EXTRACT = 120, CURRENT_TIME = 118, CURRENT_TIMESTAMP = 119, EXTRACT = 120,
FORMATDATETIME = 121, PARSEDATETIME = 122, ISO_YEAR = 123, FORMATDATETIME = 121, PARSEDATETIME = 122, ISO_YEAR = 123,
ISO_WEEK = 124, ISO_DAY_OF_WEEK = 125; ISO_WEEK = 124, ISO_DAY_OF_WEEK = 125, DATE_TRUNC = 132;
/** /**
* Pseudo functions for DATEADD, DATEDIFF, and EXTRACT. * Pseudo functions for DATEADD, DATEDIFF, and EXTRACT.
...@@ -419,6 +419,7 @@ public class Function extends Expression implements FunctionCall { ...@@ -419,6 +419,7 @@ public class Function extends Expression implements FunctionCall {
1, Value.INT); 1, Value.INT);
addFunction("ISO_DAY_OF_WEEK", ISO_DAY_OF_WEEK, addFunction("ISO_DAY_OF_WEEK", ISO_DAY_OF_WEEK,
1, Value.INT); 1, Value.INT);
addFunction("DATE_TRUNC", DATE_TRUNC, 2, Value.NULL);
// system // system
addFunctionNotDeterministic("DATABASE", DATABASE, addFunctionNotDeterministic("DATABASE", DATABASE,
0, Value.STRING); 0, Value.STRING);
...@@ -1493,6 +1494,13 @@ public class Function extends Expression implements FunctionCall { ...@@ -1493,6 +1494,13 @@ public class Function extends Expression implements FunctionCall {
break; break;
case DATE_DIFF: case DATE_DIFF:
result = ValueLong.get(datediff(v0.getString(), v1, v2)); result = ValueLong.get(datediff(v0.getString(), v1, v2));
break;
case DATE_TRUNC:
// Retrieve the time unit (e.g. 'day', 'microseconds', etc.)
String timeUnit = StringUtils.toUpperEnglish(v0.getString());
result = DateTimeUtils.truncateDate(timeUnit, v1);
break; break;
case EXTRACT: { case EXTRACT: {
int field = getDatePart(v0.getString()); int field = getDatePart(v0.getString());
...@@ -2371,6 +2379,10 @@ public class Function extends Expression implements FunctionCall { ...@@ -2371,6 +2379,10 @@ public class Function extends Expression implements FunctionCall {
min = 1; min = 1;
max = 2; max = 2;
break; break;
case DATE_TRUNC:
min = 2;
max = 2;
break;
case TO_CHAR: case TO_CHAR:
case TO_DATE: case TO_DATE:
min = 1; min = 1;
......
...@@ -1471,4 +1471,48 @@ public class DateTimeUtils { ...@@ -1471,4 +1471,48 @@ public class DateTimeUtils {
return nanosOfDay - mod; return nanosOfDay - mod;
} }
/**
* Truncate the given date to 'day'
*
* @param timeUnit the time unit (e.g. 'DAY', 'HOUR', etc.)
* @param value the date
* @return date truncated to 'day'
*/
public static Value truncateDate(String timeUnit, Value value) {
Value result = null;
// Retrieve the dateValue.
long[] fieldDateAndTime = DateTimeUtils.dateAndTimeFromValue(value);
long dateValue = fieldDateAndTime[0];
// Case where the date has to be truncated to the day.
if (timeUnit.equals("DAY")) {
if (value instanceof ValueTimestampTimeZone) {
// Create a new ValueTimestampTimeZone by only setting the
// date. The time in nanoseconds since midnight will be set
// to 0.
ValueTimestampTimeZone vTmp = (ValueTimestampTimeZone) value;
result = ValueTimestampTimeZone.fromDateValueAndNanos(vTmp.getDateValue(), 0,
vTmp.getTimeZoneOffsetMins());
} else {
// By default, we create a timestamp by setting the
// datevalue to the datevalue retrieved and the time in
// nanoseconds since midnight to 0.
result = ValueTimestamp.fromDateValueAndNanos(dateValue, 0);
}
} else {
// Return an exception for the other possible value (not yet
// supported).
throw DbException.getUnsupportedException(timeUnit);
}
return result;
}
} }
...@@ -147,9 +147,10 @@ public class TestScript extends TestBase { ...@@ -147,9 +147,10 @@ public class TestScript extends TestBase {
"current-time", "dateadd", "datediff", "dayname", "current-time", "dateadd", "datediff", "dayname",
"day-of-month", "day-of-week", "day-of-year", "extract", "day-of-month", "day-of-week", "day-of-year", "extract",
"formatdatetime", "hour", "minute", "month", "monthname", "formatdatetime", "hour", "minute", "month", "monthname",
"parsedatetime", "quarter", "second", "truncate", "week", "year" }) { "parsedatetime", "quarter", "second", "truncate", "week", "year", "date_trunc" }) {
testScript("functions/timeanddate/" + s + ".sql"); testScript("functions/timeanddate/" + s + ".sql");
} }
deleteDb("script"); deleteDb("script");
System.out.flush(); System.out.flush();
} }
......
select DATE_TRUNC('day', time '00:00:00');
>> 1970-01-01 00:00:00
select DATE_TRUNC('DAY', time '00:00:00');
>> 1970-01-01 00:00:00
select DATE_TRUNC('day', time '15:14:13');
>> 1970-01-01 00:00:00
select DATE_TRUNC('DAY', time '15:14:13');
>> 1970-01-01 00:00:00
select DATE_TRUNC('day', date '2015-05-29');
>> 2015-05-29 00:00:00
select DATE_TRUNC('DAY', date '2015-05-29');
>> 2015-05-29 00:00:00
select DATE_TRUNC('day', timestamp '2015-05-29 15:14:13');
>> 2015-05-29 00:00:00
select DATE_TRUNC('DAY', timestamp '2015-05-29 15:14:13');
>> 2015-05-29 00:00:00
select DATE_TRUNC('day', timestamp with time zone '2015-05-29 15:14:13');
>> 2015-05-29 00:00:00+00
select DATE_TRUNC('DAY', timestamp with time zone '2015-05-29 15:14:13');
>> 2015-05-29 00:00:00+00
select DATE_TRUNC('day', timestamp with time zone '2015-05-29 05:14:13-06');
>> 2015-05-29 00:00:00-06
select DATE_TRUNC('DAY', timestamp with time zone '2015-05-29 05:14:13-06');
>> 2015-05-29 00:00:00-06
select DATE_TRUNC('day', timestamp with time zone '2015-05-29 15:14:13+10');
>> 2015-05-29 00:00:00+10
select DATE_TRUNC('DAY', timestamp with time zone '2015-05-29 15:14:13+10');
>> 2015-05-29 00:00:00+10
select DATE_TRUNC('day', '2015-05-29 15:14:13');
>> 2015-05-29 00:00:00
select DATE_TRUNC('DAY', '2015-05-29 15:14:13');
>> 2015-05-29 00:00:00
SELECT DATE_TRUNC('---', '2015-05-29 15:14:13');
> exception
SELECT DATE_TRUNC('microseconds', '2015-05-29 15:14:13');
> exception
SELECT DATE_TRUNC('MICROSECONDS', '2015-05-29 15:14:13');
> exception
SELECT DATE_TRUNC('milliseconds', '2015-05-29 15:14:13');
> exception
SELECT DATE_TRUNC('MILLISECONDS', '2015-05-29 15:14:13');
> exception
SELECT DATE_TRUNC('second', '2015-05-29 15:14:13');
> exception
SELECT DATE_TRUNC('SECOND', '2015-05-29 15:14:13');
> exception
SELECT DATE_TRUNC('minute', '2015-05-29 15:14:13');
> exception
SELECT DATE_TRUNC('MINUTE', '2015-05-29 15:14:13');
> exception
SELECT DATE_TRUNC('hour', '2015-05-29 15:14:13');
> exception
SELECT DATE_TRUNC('HOUR', '2015-05-29 15:14:13');
> exception
SELECT DATE_TRUNC('week', '2015-05-29 15:14:13');
> exception
SELECT DATE_TRUNC('WEEK', '2015-05-29 15:14:13');
> exception
SELECT DATE_TRUNC('month', '2015-05-29 15:14:13');
> exception
SELECT DATE_TRUNC('MONTH', '2015-05-29 15:14:13');
> exception
SELECT DATE_TRUNC('quarter', '2015-05-29 15:14:13');
> exception
SELECT DATE_TRUNC('QUARTER', '2015-05-29 15:14:13');
> exception
SELECT DATE_TRUNC('year', '2015-05-29 15:14:13');
> exception
SELECT DATE_TRUNC('YEAR', '2015-05-29 15:14:13');
> exception
SELECT DATE_TRUNC('decade', '2015-05-29 15:14:13');
> exception
SELECT DATE_TRUNC('DECADE', '2015-05-29 15:14:13');
> exception
SELECT DATE_TRUNC('century', '2015-05-29 15:14:13');
> exception
SELECT DATE_TRUNC('CENTURY', '2015-05-29 15:14:13');
> exception
SELECT DATE_TRUNC('millennium', '2015-05-29 15:14:13');
> exception
SELECT DATE_TRUNC('MILLENNIUM', '2015-05-29 15:14:13');
> exception
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论