-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for "week of month" in date parsing pattern #10511
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -56,6 +56,13 @@ DateTimeFormatterBuilder& DateTimeFormatterBuilder::appendWeekOfWeekYear( | |
return *this; | ||
} | ||
|
||
DateTimeFormatterBuilder& DateTimeFormatterBuilder::appendWeekOfMonth( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should this function be called in buildJodaDateTimeFormatter or buildMysqlDateTimeFormatter? Like https://github.com/facebookincubator/velox/blob/main/velox/functions/lib/DateTimeFormatter.cpp#L1463. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
size_t minDigits) { | ||
tokens_.emplace_back( | ||
FormatPattern{DateTimeFormatSpecifier::WEEK_OF_MONTH, minDigits}); | ||
return *this; | ||
} | ||
|
||
DateTimeFormatterBuilder& DateTimeFormatterBuilder::appendDayOfWeek0Based( | ||
size_t minDigits) { | ||
tokens_.emplace_back( | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -144,6 +144,26 @@ bool isValidWeekDate(int32_t weekYear, int32_t weekOfYear, int32_t dayOfWeek) { | |
return true; | ||
} | ||
|
||
bool isValidWeekOfMonthDate( | ||
int32_t year, | ||
int32_t month, | ||
int32_t weekOfMonth, | ||
int32_t dayOfWeek) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please add some unit tests for this function. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've added tests in e6d51ae |
||
if (dayOfWeek < 1 || dayOfWeek > 7) { | ||
return false; | ||
} | ||
if (weekOfMonth < 1 || weekOfMonth > 5) { | ||
return false; | ||
} | ||
if (month < 1 || month > 12) { | ||
return false; | ||
} | ||
if (year < kMinYear || year > kMaxYear) { | ||
return false; | ||
} | ||
return true; | ||
} | ||
|
||
inline bool validDate(int64_t daysSinceEpoch) { | ||
return daysSinceEpoch >= std::numeric_limits<int32_t>::min() && | ||
daysSinceEpoch <= std::numeric_limits<int32_t>::max(); | ||
|
@@ -593,6 +613,26 @@ Status daysSinceEpochFromWeekDate( | |
return Status::OK(); | ||
} | ||
|
||
Status daysSinceEpochFromWeekOfMonthDate( | ||
int32_t year, | ||
int32_t month, | ||
int32_t weekOfMonth, | ||
int32_t dayOfWeek, | ||
int64_t& out) { | ||
if (!isValidWeekOfMonthDate(year, month, weekOfMonth, dayOfWeek)) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. isValidWeekOfMonthDate doesn't perform full validation. For example, it allows weekOfMonth = 5 and dayOfWeek = 6, but these may not exist for all months. Where / how do we handle these cases of invalid inputs? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I have tested SimpleDateFormat and I see it can parse the "invalid" weekOfMonth and dayOfWeek etc. Perhaps we should remove the validation to align with
|
||
return Status::UserError( | ||
"Date out of range: {}-{}-{}-{}", year, month, weekOfMonth, dayOfWeek); | ||
} | ||
int64_t daysSinceEpochOfFirstDayOfMonth; | ||
VELOX_RETURN_NOT_OK( | ||
daysSinceEpochFromDate(year, month, 1, daysSinceEpochOfFirstDayOfMonth)); | ||
int32_t firstDayOfWeek = | ||
extractISODayOfTheWeek(daysSinceEpochOfFirstDayOfMonth); | ||
out = daysSinceEpochOfFirstDayOfMonth - (firstDayOfWeek - 1) + | ||
7 * (weekOfMonth - 1) + dayOfWeek - 1; | ||
return Status::OK(); | ||
} | ||
|
||
Status | ||
daysSinceEpochFromDayOfYear(int32_t year, int32_t dayOfYear, int64_t& out) { | ||
if (!isValidDayOfYear(year, dayOfYear)) { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -107,6 +107,15 @@ Status daysSinceEpochFromWeekDate( | |
int32_t dayOfWeek, | ||
int64_t& out); | ||
|
||
/// Computes the (signed) number of days since unix epoch (1970-01-01). | ||
/// Returns UserError status if the date is invalid. | ||
Status daysSinceEpochFromWeekOfMonthDate( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Perhaps, extract this function into a separate PR and add a unit test. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The DateTimeFormatter.parse function depends on this function. Do you mean to submit all changes to the DateTimeFormatter.parse function and this function as a separate PR? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I assume this comment suggest us opening another PR which contains the implementation and tests for There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I opened a PR for this. #10604 |
||
int32_t year, | ||
int32_t month, | ||
int32_t weekOfMonth, | ||
int32_t dayOfWeek, | ||
int64_t& out); | ||
|
||
/// Computes the (signed) number of days since unix epoch (1970-01-01). | ||
/// Returns UserError status if the date is invalid. | ||
Status | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder why we need this change, and could you clarify what is covered by
weekDateFormat
which seems to be a larger scope thanweekOfMonthDateFormat
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
weekDateFormat
has different format withweekOfMonthDateFormat
.weekDateFormat
is composed of year, weekOfYear and dayOfWeek andweekOfMonthDateFormat
is composed of year, month, weekOfMonth and dayOfWeek. dayOfWeek is used by bothweekDateFormat
andweekOfMonthDateFormat
, so dayOfWeek can't indicate the format isweekDateFormat