toCustomWeek, toCustomYear, toStartOfCustomYear functions

This commit is contained in:
Andy Yang 2019-05-05 15:54:51 +08:00
parent 8dd7d4d46b
commit eb4d85e964
6 changed files with 161 additions and 1 deletions

View File

@ -432,6 +432,22 @@ struct ToStartOfISOYearImpl
using FactorTransform = ZeroTransform;
};
struct ToStartOfCustomYearImpl
{
static constexpr auto name = "toStartOfCustomYear";
static inline UInt16 execute(UInt32 t, const DateLUTImpl & time_zone)
{
return time_zone.toFirstDayNumOfCustomYear(time_zone.toDayNum(t));
}
static inline UInt16 execute(UInt16 d, const DateLUTImpl & time_zone)
{
return time_zone.toFirstDayNumOfCustomYear(DayNum(d));
}
using FactorTransform = ZeroTransform;
};
struct ToISOWeekImpl
{
static constexpr auto name = "toISOWeek";
@ -448,6 +464,38 @@ struct ToISOWeekImpl
using FactorTransform = ToISOYearImpl;
};
struct ToCustomYearImpl
{
static constexpr auto name = "toCustomYear";
static inline UInt16 execute(UInt32 t, const DateLUTImpl & time_zone)
{
return time_zone.toCustomYear(time_zone.toDayNum(t));
}
static inline UInt16 execute(UInt16 d, const DateLUTImpl & time_zone)
{
return time_zone.toCustomYear(DayNum(d));
}
using FactorTransform = ZeroTransform;
};
struct ToCustomWeekImpl
{
static constexpr auto name = "toCustomWeek";
static inline UInt8 execute(UInt32 t, const DateLUTImpl & time_zone)
{
return time_zone.toCustomWeek(time_zone.toDayNum(t));
}
static inline UInt8 execute(UInt16 d, const DateLUTImpl & time_zone)
{
return time_zone.toCustomWeek(DayNum(d));
}
using FactorTransform = ToCustomYearImpl;
};
struct ToRelativeYearNumImpl
{
static constexpr auto name = "toRelativeYearNum";

View File

@ -16,6 +16,8 @@ void registerFunctionToStartOfDay(FunctionFactory &);
void registerFunctionToMonday(FunctionFactory &);
void registerFunctionToISOWeek(FunctionFactory &);
void registerFunctionToISOYear(FunctionFactory &);
void registerFunctionToCustomWeek(FunctionFactory &);
void registerFunctionToCustomYear(FunctionFactory &);
void registerFunctionToStartOfMonth(FunctionFactory &);
void registerFunctionToStartOfQuarter(FunctionFactory &);
void registerFunctionToStartOfYear(FunctionFactory &);
@ -26,6 +28,7 @@ void registerFunctionToStartOfFifteenMinutes(FunctionFactory &);
void registerFunctionToStartOfHour(FunctionFactory &);
void registerFunctionToStartOfInterval(FunctionFactory &);
void registerFunctionToStartOfISOYear(FunctionFactory &);
void registerFunctionToStartOfCustomYear(FunctionFactory &);
void registerFunctionToRelativeYearNum(FunctionFactory &);
void registerFunctionToRelativeQuarterNum(FunctionFactory &);
void registerFunctionToRelativeMonthNum(FunctionFactory &);
@ -79,6 +82,8 @@ void registerFunctionsDateTime(FunctionFactory & factory)
registerFunctionToMonday(factory);
registerFunctionToISOWeek(factory);
registerFunctionToISOYear(factory);
registerFunctionToCustomWeek(factory);
registerFunctionToCustomYear(factory);
registerFunctionToStartOfMonth(factory);
registerFunctionToStartOfQuarter(factory);
registerFunctionToStartOfYear(factory);
@ -89,6 +94,7 @@ void registerFunctionsDateTime(FunctionFactory & factory)
registerFunctionToStartOfHour(factory);
registerFunctionToStartOfInterval(factory);
registerFunctionToStartOfISOYear(factory);
registerFunctionToStartOfCustomYear(factory);
registerFunctionToRelativeYearNum(factory);
registerFunctionToRelativeQuarterNum(factory);
registerFunctionToRelativeMonthNum(factory);

View File

@ -0,0 +1,20 @@
#include <Functions/IFunction.h>
#include <Functions/FunctionFactory.h>
#include <Functions/DateTimeTransforms.h>
#include <Functions/FunctionDateOrDateTimeToSomething.h>
#include <DataTypes/DataTypesNumber.h>
namespace DB
{
using FunctionToCustomWeek = FunctionDateOrDateTimeToSomething<DataTypeUInt8, ToCustomWeekImpl>;
void registerFunctionToCustomWeek(FunctionFactory & factory)
{
factory.registerFunction<FunctionToCustomWeek>();
}
}

View File

@ -0,0 +1,20 @@
#include <Functions/IFunction.h>
#include <Functions/FunctionFactory.h>
#include <Functions/DateTimeTransforms.h>
#include <Functions/FunctionDateOrDateTimeToSomething.h>
#include <DataTypes/DataTypesNumber.h>
namespace DB
{
using FunctionToCustomYear = FunctionDateOrDateTimeToSomething<DataTypeUInt16, ToCustomYearImpl>;
void registerFunctionToCustomYear(FunctionFactory & factory)
{
factory.registerFunction<FunctionToCustomYear>();
}
}

View File

@ -0,0 +1,20 @@
#include <Functions/IFunction.h>
#include <Functions/FunctionFactory.h>
#include <Functions/DateTimeTransforms.h>
#include <Functions/FunctionDateOrDateTimeToSomething.h>
#include <DataTypes/DataTypesNumber.h>
namespace DB
{
using FunctionToStartOfCustomYear = FunctionDateOrDateTimeToSomething<DataTypeDate, ToStartOfCustomYearImpl>;
void registerFunctionToStartOfCustomYear(FunctionFactory & factory)
{
factory.registerFunction<FunctionToStartOfCustomYear>();
}
}

View File

@ -74,7 +74,6 @@ private:
/// Time zone name.
std::string time_zone;
/// We can correctly process only timestamps that less DATE_LUT_MAX (i.e. up to 2105 year inclusively)
/// We don't care about overflow.
inline DayNum findIndex(time_t t) const
@ -379,6 +378,53 @@ public:
return toISOWeek(toDayNum(t));
}
/// Get year that contains the custom week.
inline unsigned toCustomYear(DayNum d) const
{
// Checking the week across the year
auto year = toYear(DayNum(d + 7 - toDayOfWeek(d)));
auto day_of_year = makeDayNum(year, 1, 1);
// Checking greater than or equal to Monday, If true take current year, else take last year.
return toFirstDayNumOfWeek(day_of_year) <= d ? year : year - 1;
}
inline unsigned toCustomYear(time_t t) const
{
return toCustomYear(toDayNum(t));
}
/// Custom year begins with a monday of the week that is contained January 1,
/// which day can be modified through config of first_week_of_day.
/// Example: Custom year 2019 begins at 2018-12-31. And Custom year 2017 begins at 2016-12-26.
inline DayNum toFirstDayNumOfCustomYear(DayNum d) const
{
auto custom_year = toCustomYear(d);
return toFirstDayNumOfWeek(makeDayNum(custom_year, 1, 1));
}
inline DayNum toFirstDayNumOfCustomYear(time_t t) const
{
return toFirstDayNumOfCustomYear(toDayNum(t));
}
inline time_t toFirstDayOfCustomYear(time_t t) const
{
return fromDayNum(toFirstDayNumOfCustomYear(t));
}
/// Custom week number. Week begins at monday.
/// The week number 1 is the first week in year that contains January 1,
/// which day can be modified through config of first_week_of_day.
inline unsigned toCustomWeek(DayNum d) const
{
return 1 + (toFirstDayNumOfWeek(d) - toFirstDayNumOfCustomYear(d)) / 7;
}
inline unsigned toCustomWeek(time_t t) const
{
return toCustomWeek(toDayNum(t));
}
/// Number of month from some fixed moment in the past (year * 12 + month)
inline unsigned toRelativeMonthNum(DayNum d) const
{