mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-25 00:52:02 +00:00
Add new function toLastDayOfMonth
This commit is contained in:
parent
15bcbb97e5
commit
57ff05b6e6
@ -393,6 +393,13 @@ This is a generalization of other functions named `toStartOf*`. For example,
|
||||
`toStartOfInterval(t, INTERVAL 1 day)` returns the same as `toStartOfDay(t)`,
|
||||
`toStartOfInterval(t, INTERVAL 15 minute)` returns the same as `toStartOfFifteenMinutes(t)` etc.
|
||||
|
||||
## toLastDayOfMonth {#toLastDayOfMonth}
|
||||
|
||||
Rounds up a date or date with time to the last day of the month.
|
||||
Returns the date.
|
||||
|
||||
Alias: `LAST_DAY`.
|
||||
|
||||
## toTime {#totime}
|
||||
|
||||
Converts a date with time to a certain fixed date, while preserving the time.
|
||||
|
@ -360,6 +360,27 @@ public:
|
||||
return toDayNum(LUTIndex(i - (lut[i].day_of_month - 1)));
|
||||
}
|
||||
|
||||
/// Round up to last day of month.
|
||||
template <typename DateOrTime>
|
||||
inline Time toLastDayOfMonth(DateOrTime v) const
|
||||
{
|
||||
const LUTIndex i = toLUTIndex(v);
|
||||
if constexpr (std::is_unsigned_v<DateOrTime> || std::is_same_v<DateOrTime, DayNum>)
|
||||
return lut_saturated[i - lut[i].day_of_month + lut[i].days_in_month].date;
|
||||
else
|
||||
return lut[i - lut[i].day_of_month + lut[i].days_in_month].date;
|
||||
}
|
||||
|
||||
template <typename DateOrTime>
|
||||
inline auto toLastDayNumOfMonth(DateOrTime v) const
|
||||
{
|
||||
const LUTIndex i = toLUTIndex(v);
|
||||
if constexpr (std::is_unsigned_v<DateOrTime> || std::is_same_v<DateOrTime, DayNum>)
|
||||
return toDayNum(LUTIndexWithSaturation(i - lut[i].day_of_month + lut[i].days_in_month));
|
||||
else
|
||||
return toDayNum(LUTIndex(i - lut[i].day_of_month + lut[i].days_in_month));
|
||||
}
|
||||
|
||||
/// Round down to start of quarter.
|
||||
template <typename DateOrTime>
|
||||
inline auto toFirstDayNumOfQuarter(DateOrTime v) const
|
||||
|
@ -142,6 +142,8 @@ TEST(DateLUTTest, TimeValuesInMiddleOfRange)
|
||||
EXPECT_EQ(lut.addYears(time, 10), 1884270011 /*time_t*/);
|
||||
EXPECT_EQ(lut.timeToString(time), "2019-09-16 19:20:11" /*std::string*/);
|
||||
EXPECT_EQ(lut.dateToString(time), "2019-09-16" /*std::string*/);
|
||||
EXPECT_EQ(lut.toLastDayOfMonth(time), 1569790800 /*time_t*/);
|
||||
EXPECT_EQ(lut.toLastDayNumOfMonth(time), DayNum(18169) /*DayNum*/);
|
||||
}
|
||||
|
||||
|
||||
@ -202,6 +204,8 @@ TEST(DateLUTTest, TimeValuesAtLeftBoderOfRange)
|
||||
EXPECT_EQ(lut.addYears(time, 10), 315532800 /*time_t*/);
|
||||
EXPECT_EQ(lut.timeToString(time), "1970-01-01 00:00:00" /*std::string*/);
|
||||
EXPECT_EQ(lut.dateToString(time), "1970-01-01" /*std::string*/);
|
||||
EXPECT_EQ(lut.toLastDayOfMonth(time), 2592000 /*time_t*/);
|
||||
EXPECT_EQ(lut.toLastDayNumOfMonth(time), DayNum(30) /*DayNum*/);
|
||||
}
|
||||
|
||||
TEST(DateLUTTest, TimeValuesAtRightBoderOfRangeOfOldLUT)
|
||||
@ -264,6 +268,8 @@ TEST(DateLUTTest, TimeValuesAtRightBoderOfRangeOfOldLUT)
|
||||
|
||||
EXPECT_EQ(lut.timeToString(time), "2106-01-31 01:17:53" /*std::string*/);
|
||||
EXPECT_EQ(lut.dateToString(time), "2106-01-31" /*std::string*/);
|
||||
EXPECT_EQ(lut.toLastDayOfMonth(time), 4294339200 /*time_t*/); // 2016-01-01
|
||||
EXPECT_EQ(lut.toLastDayNumOfMonth(time), DayNum(49703));
|
||||
}
|
||||
|
||||
|
||||
|
@ -174,6 +174,30 @@ struct ToStartOfMonthImpl
|
||||
using FactorTransform = ZeroTransform;
|
||||
};
|
||||
|
||||
struct ToLastDayOfMonthImpl
|
||||
{
|
||||
static constexpr auto name = "toLastDayOfMonth";
|
||||
|
||||
static inline UInt16 execute(Int64 t, const DateLUTImpl & time_zone)
|
||||
{
|
||||
return time_zone.toLastDayNumOfMonth(time_zone.toDayNum(t));
|
||||
}
|
||||
static inline UInt16 execute(UInt32 t, const DateLUTImpl & time_zone)
|
||||
{
|
||||
return time_zone.toLastDayNumOfMonth(time_zone.toDayNum(t));
|
||||
}
|
||||
static inline UInt16 execute(Int32 d, const DateLUTImpl & time_zone)
|
||||
{
|
||||
return time_zone.toLastDayNumOfMonth(ExtendedDayNum(d));
|
||||
}
|
||||
static inline UInt16 execute(UInt16 d, const DateLUTImpl & time_zone)
|
||||
{
|
||||
return time_zone.toLastDayNumOfMonth(DayNum(d));
|
||||
}
|
||||
|
||||
using FactorTransform = ZeroTransform;
|
||||
};
|
||||
|
||||
struct ToStartOfQuarterImpl
|
||||
{
|
||||
static constexpr auto name = "toStartOfQuarter";
|
||||
|
@ -20,6 +20,7 @@ void registerFunctionToISOYear(FunctionFactory &);
|
||||
void registerFunctionToCustomWeek(FunctionFactory &);
|
||||
void registerFunctionToModifiedJulianDay(FunctionFactory &);
|
||||
void registerFunctionToStartOfMonth(FunctionFactory &);
|
||||
void registerFunctionToLastDayOfMonth(FunctionFactory &);
|
||||
void registerFunctionToStartOfQuarter(FunctionFactory &);
|
||||
void registerFunctionToStartOfYear(FunctionFactory &);
|
||||
void registerFunctionToStartOfMinute(FunctionFactory &);
|
||||
@ -91,6 +92,7 @@ void registerFunctionsDateTime(FunctionFactory & factory)
|
||||
registerFunctionToCustomWeek(factory);
|
||||
registerFunctionToModifiedJulianDay(factory);
|
||||
registerFunctionToStartOfMonth(factory);
|
||||
registerFunctionToLastDayOfMonth(factory);
|
||||
registerFunctionToStartOfQuarter(factory);
|
||||
registerFunctionToStartOfYear(factory);
|
||||
registerFunctionToStartOfSecond(factory);
|
||||
|
21
src/Functions/toLastDayOfMonth.cpp
Normal file
21
src/Functions/toLastDayOfMonth.cpp
Normal file
@ -0,0 +1,21 @@
|
||||
#include <Functions/FunctionFactory.h>
|
||||
#include <Functions/DateTimeTransforms.h>
|
||||
#include <Functions/FunctionDateOrDateTimeToSomething.h>
|
||||
|
||||
|
||||
namespace DB
|
||||
{
|
||||
|
||||
using FunctionToLastDayOfMonth = FunctionDateOrDateTimeToSomething<DataTypeDate, ToLastDayOfMonthImpl>;
|
||||
|
||||
void registerFunctionToLastDayOfMonth(FunctionFactory & factory)
|
||||
{
|
||||
factory.registerFunction<FunctionToLastDayOfMonth>();
|
||||
|
||||
/// MysQL compatibility alias.
|
||||
factory.registerFunction<FunctionToLastDayOfMonth>("LAST_DAY", FunctionFactory::CaseInsensitive);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -229,7 +229,7 @@ std::map<std::string, FuncRet> func_to_return_type = {
|
||||
{"torelativeweeknum", FuncRet(Type::i, "")}, {"torelativedaynum", FuncRet(Type::i, "")}, {"torelativehournum", FuncRet(Type::i, "")},
|
||||
{"torelativeminutenum", FuncRet(Type::i, "")}, {"torelativesecondsnum", FuncRet(Type::i, "")}, {"datediff", FuncRet(Type::d | Type::dt, "")},
|
||||
{"formatdatetime", FuncRet(Type::s, "")}, {"now", FuncRet(Type::dt | Type::d, "now()")}, {"today", FuncRet(Type::d | Type::dt, "today()")},
|
||||
{"yesterday", FuncRet(Type::d | Type::dt, "yesterday()")}
|
||||
{"yesterday", FuncRet(Type::d | Type::dt, "yesterday()")}, {"tolastdayofmonth", FuncRet(Type::dt | Type::d, "")}
|
||||
};
|
||||
|
||||
std::set<std::string> func_args_same_types = {
|
||||
@ -253,7 +253,7 @@ std::map<std::string, ColumnType> func_to_param_type = {
|
||||
{"tostartofinterval", Type::d | Type::dt}, {"totime", Type::d | Type::dt}, {"torelativehonthnum", Type::d | Type::dt},
|
||||
{"torelativeweeknum", Type::d | Type::dt}, {"torelativedaynum", Type::d | Type::dt}, {"torelativehournum", Type::d | Type::dt},
|
||||
{"torelativeminutenum", Type::d | Type::dt}, {"torelativesecondnum", Type::d | Type::dt}, {"datediff", Type::d | Type::dt},
|
||||
{"formatdatetime", Type::dt}
|
||||
{"formatdatetime", Type::dt}, {"tolastdayofmonth", Type::d | Type::dt}
|
||||
};
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user