Add uniform naming for temporal type properties (#246)
This commit is contained in:
parent
18b801a722
commit
7e82cc6550
@ -1080,9 +1080,9 @@ TypedValue Date(const TypedValue *args, int64_t nargs, const FunctionContext &ct
|
||||
utils::DateParameters date_parameters;
|
||||
|
||||
using namespace std::literals;
|
||||
std::unordered_map parameter_mappings = {std::pair{"year"sv, &date_parameters.years},
|
||||
std::pair{"month"sv, &date_parameters.months},
|
||||
std::pair{"day"sv, &date_parameters.days}};
|
||||
std::unordered_map parameter_mappings = {std::pair{"year"sv, &date_parameters.year},
|
||||
std::pair{"month"sv, &date_parameters.month},
|
||||
std::pair{"day"sv, &date_parameters.day}};
|
||||
|
||||
MapNumericParameters<Integer>(parameter_mappings, args[0].ValueMap());
|
||||
return TypedValue(utils::Date(date_parameters), ctx.memory);
|
||||
@ -1104,11 +1104,11 @@ TypedValue LocalTime(const TypedValue *args, int64_t nargs, const FunctionContex
|
||||
|
||||
using namespace std::literals;
|
||||
std::unordered_map parameter_mappings{
|
||||
std::pair{"hour"sv, &local_time_parameters.hours},
|
||||
std::pair{"minute"sv, &local_time_parameters.minutes},
|
||||
std::pair{"second"sv, &local_time_parameters.seconds},
|
||||
std::pair{"millisecond"sv, &local_time_parameters.milliseconds},
|
||||
std::pair{"microsecond"sv, &local_time_parameters.microseconds},
|
||||
std::pair{"hour"sv, &local_time_parameters.hour},
|
||||
std::pair{"minute"sv, &local_time_parameters.minute},
|
||||
std::pair{"second"sv, &local_time_parameters.second},
|
||||
std::pair{"millisecond"sv, &local_time_parameters.millisecond},
|
||||
std::pair{"microsecond"sv, &local_time_parameters.microsecond},
|
||||
};
|
||||
|
||||
MapNumericParameters<Integer>(parameter_mappings, args[0].ValueMap());
|
||||
@ -1131,14 +1131,14 @@ TypedValue LocalDateTime(const TypedValue *args, int64_t nargs, const FunctionCo
|
||||
utils::LocalTimeParameters local_time_parameters;
|
||||
using namespace std::literals;
|
||||
std::unordered_map parameter_mappings{
|
||||
std::pair{"year"sv, &date_parameters.years},
|
||||
std::pair{"month"sv, &date_parameters.months},
|
||||
std::pair{"day"sv, &date_parameters.days},
|
||||
std::pair{"hour"sv, &local_time_parameters.hours},
|
||||
std::pair{"minute"sv, &local_time_parameters.minutes},
|
||||
std::pair{"second"sv, &local_time_parameters.seconds},
|
||||
std::pair{"millisecond"sv, &local_time_parameters.milliseconds},
|
||||
std::pair{"microsecond"sv, &local_time_parameters.microseconds},
|
||||
std::pair{"year"sv, &date_parameters.year},
|
||||
std::pair{"month"sv, &date_parameters.month},
|
||||
std::pair{"day"sv, &date_parameters.day},
|
||||
std::pair{"hour"sv, &local_time_parameters.hour},
|
||||
std::pair{"minute"sv, &local_time_parameters.minute},
|
||||
std::pair{"second"sv, &local_time_parameters.second},
|
||||
std::pair{"millisecond"sv, &local_time_parameters.millisecond},
|
||||
std::pair{"microsecond"sv, &local_time_parameters.microsecond},
|
||||
};
|
||||
|
||||
MapNumericParameters<Integer>(parameter_mappings, args[0].ValueMap());
|
||||
@ -1154,12 +1154,12 @@ TypedValue Duration(const TypedValue *args, int64_t nargs, const FunctionContext
|
||||
|
||||
utils::DurationParameters duration_parameters;
|
||||
using namespace std::literals;
|
||||
std::unordered_map parameter_mappings{std::pair{"day"sv, &duration_parameters.days},
|
||||
std::pair{"hour"sv, &duration_parameters.hours},
|
||||
std::pair{"minute"sv, &duration_parameters.minutes},
|
||||
std::pair{"second"sv, &duration_parameters.seconds},
|
||||
std::pair{"millisecond"sv, &duration_parameters.milliseconds},
|
||||
std::pair{"microsecond"sv, &duration_parameters.microseconds}};
|
||||
std::unordered_map parameter_mappings{std::pair{"day"sv, &duration_parameters.day},
|
||||
std::pair{"hour"sv, &duration_parameters.hour},
|
||||
std::pair{"minute"sv, &duration_parameters.minute},
|
||||
std::pair{"second"sv, &duration_parameters.second},
|
||||
std::pair{"millisecond"sv, &duration_parameters.millisecond},
|
||||
std::pair{"microsecond"sv, &duration_parameters.microsecond}};
|
||||
MapNumericParameters<Number>(parameter_mappings, args[0].ValueMap());
|
||||
return TypedValue(utils::Duration(duration_parameters), ctx.memory);
|
||||
}
|
||||
|
@ -250,54 +250,54 @@ class ExpressionEvaluator : public ExpressionVisitor<TypedValue> {
|
||||
auto expression_result = property_lookup.expression_->Accept(*this);
|
||||
auto maybe_date = [this](const auto &date, const auto &prop_name) -> std::optional<TypedValue> {
|
||||
if (prop_name == "year") {
|
||||
return TypedValue(date.years, ctx_->memory);
|
||||
return TypedValue(date.year, ctx_->memory);
|
||||
}
|
||||
if (prop_name == "month") {
|
||||
return TypedValue(date.months, ctx_->memory);
|
||||
return TypedValue(date.month, ctx_->memory);
|
||||
}
|
||||
if (prop_name == "day") {
|
||||
return TypedValue(date.days, ctx_->memory);
|
||||
return TypedValue(date.day, ctx_->memory);
|
||||
}
|
||||
return std::nullopt;
|
||||
};
|
||||
auto maybe_local_time = [this](const auto <, const auto &prop_name) -> std::optional<TypedValue> {
|
||||
if (prop_name == "hour") {
|
||||
return TypedValue(lt.hours, ctx_->memory);
|
||||
return TypedValue(lt.hour, ctx_->memory);
|
||||
}
|
||||
if (prop_name == "minute") {
|
||||
return TypedValue(lt.minutes, ctx_->memory);
|
||||
return TypedValue(lt.minute, ctx_->memory);
|
||||
}
|
||||
if (prop_name == "seconds") {
|
||||
return TypedValue(lt.seconds, ctx_->memory);
|
||||
if (prop_name == "second") {
|
||||
return TypedValue(lt.second, ctx_->memory);
|
||||
}
|
||||
if (prop_name == "milliseconds") {
|
||||
return TypedValue(lt.milliseconds, ctx_->memory);
|
||||
if (prop_name == "millisecond") {
|
||||
return TypedValue(lt.millisecond, ctx_->memory);
|
||||
}
|
||||
if (prop_name == "microseconds") {
|
||||
return TypedValue(lt.microseconds, ctx_->memory);
|
||||
if (prop_name == "microsecond") {
|
||||
return TypedValue(lt.microsecond, ctx_->memory);
|
||||
}
|
||||
return std::nullopt;
|
||||
};
|
||||
auto maybe_duration = [this](const auto &dur, const auto &prop_name) -> std::optional<TypedValue> {
|
||||
if (prop_name == "days") {
|
||||
if (prop_name == "day") {
|
||||
return TypedValue(dur.Days(), ctx_->memory);
|
||||
}
|
||||
if (prop_name == "hours") {
|
||||
if (prop_name == "hour") {
|
||||
return TypedValue(dur.SubDaysAsHours(), ctx_->memory);
|
||||
}
|
||||
if (prop_name == "minutes") {
|
||||
if (prop_name == "minute") {
|
||||
return TypedValue(dur.SubDaysAsMinutes(), ctx_->memory);
|
||||
}
|
||||
if (prop_name == "seconds") {
|
||||
if (prop_name == "second") {
|
||||
return TypedValue(dur.SubDaysAsSeconds(), ctx_->memory);
|
||||
}
|
||||
if (prop_name == "milliseconds") {
|
||||
if (prop_name == "millisecond") {
|
||||
return TypedValue(dur.SubDaysAsMilliseconds(), ctx_->memory);
|
||||
}
|
||||
if (prop_name == "microseconds") {
|
||||
if (prop_name == "microsecond") {
|
||||
return TypedValue(dur.SubDaysAsMicroseconds(), ctx_->memory);
|
||||
}
|
||||
if (prop_name == "nanoseconds") {
|
||||
if (prop_name == "nanosecond") {
|
||||
return TypedValue(dur.SubDaysAsNanoseconds(), ctx_->memory);
|
||||
}
|
||||
return std::nullopt;
|
||||
|
@ -1163,15 +1163,15 @@ mgp_error mgp_date_equal(mgp_date *first, mgp_date *second, int *result) {
|
||||
}
|
||||
|
||||
mgp_error mgp_date_get_year(mgp_date *date, int *year) {
|
||||
return WrapExceptions([date] { return date->date.years; }, year);
|
||||
return WrapExceptions([date] { return date->date.year; }, year);
|
||||
}
|
||||
|
||||
mgp_error mgp_date_get_month(mgp_date *date, int *month) {
|
||||
return WrapExceptions([date] { return date->date.months; }, month);
|
||||
return WrapExceptions([date] { return date->date.month; }, month);
|
||||
}
|
||||
|
||||
mgp_error mgp_date_get_day(mgp_date *date, int *day) {
|
||||
return WrapExceptions([date] { return date->date.days; }, day);
|
||||
return WrapExceptions([date] { return date->date.day; }, day);
|
||||
}
|
||||
|
||||
mgp_error mgp_date_timestamp(mgp_date *date, int64_t *timestamp) {
|
||||
@ -1218,23 +1218,23 @@ mgp_error mgp_local_time_equal(mgp_local_time *first, mgp_local_time *second, in
|
||||
}
|
||||
|
||||
mgp_error mgp_local_time_get_hour(mgp_local_time *local_time, int *hour) {
|
||||
return WrapExceptions([local_time] { return local_time->local_time.hours; }, hour);
|
||||
return WrapExceptions([local_time] { return local_time->local_time.hour; }, hour);
|
||||
}
|
||||
|
||||
mgp_error mgp_local_time_get_minue(mgp_local_time *local_time, int *minute) {
|
||||
return WrapExceptions([local_time] { return local_time->local_time.minutes; }, minute);
|
||||
return WrapExceptions([local_time] { return local_time->local_time.minute; }, minute);
|
||||
}
|
||||
|
||||
mgp_error mgp_local_time_get_second(mgp_local_time *local_time, int *second) {
|
||||
return WrapExceptions([local_time] { return local_time->local_time.seconds; }, second);
|
||||
return WrapExceptions([local_time] { return local_time->local_time.second; }, second);
|
||||
}
|
||||
|
||||
mgp_error mgp_local_time_get_millisecond(mgp_local_time *local_time, int *millisecond) {
|
||||
return WrapExceptions([local_time] { return local_time->local_time.milliseconds; }, millisecond);
|
||||
return WrapExceptions([local_time] { return local_time->local_time.millisecond; }, millisecond);
|
||||
}
|
||||
|
||||
mgp_error mgp_local_time_get_microsecond(mgp_local_time *local_time, int *microsecond) {
|
||||
return WrapExceptions([local_time] { return local_time->local_time.microseconds; }, microsecond);
|
||||
return WrapExceptions([local_time] { return local_time->local_time.microsecond; }, microsecond);
|
||||
}
|
||||
|
||||
mgp_error mgp_local_time_timestamp(mgp_local_time *local_time, int64_t *timestamp) {
|
||||
@ -1297,36 +1297,36 @@ mgp_error mgp_local_date_time_equal(mgp_local_date_time *first, mgp_local_date_t
|
||||
}
|
||||
|
||||
mgp_error mgp_local_date_time_get_year(mgp_local_date_time *local_date_time, int *year) {
|
||||
return WrapExceptions([local_date_time] { return local_date_time->local_date_time.date.years; }, year);
|
||||
return WrapExceptions([local_date_time] { return local_date_time->local_date_time.date.year; }, year);
|
||||
}
|
||||
|
||||
mgp_error mgp_local_date_time_get_month(mgp_local_date_time *local_date_time, int *month) {
|
||||
return WrapExceptions([local_date_time] { return local_date_time->local_date_time.date.months; }, month);
|
||||
return WrapExceptions([local_date_time] { return local_date_time->local_date_time.date.month }, month);
|
||||
}
|
||||
|
||||
mgp_error mgp_local_date_time_get_day(mgp_local_date_time *local_date_time, int *day) {
|
||||
return WrapExceptions([local_date_time] { return local_date_time->local_date_time.date.days; }, day);
|
||||
return WrapExceptions([local_date_time] { return local_date_time->local_date_time.date.day; }, day);
|
||||
}
|
||||
|
||||
mgp_error mgp_local_date_time_get_hour(mgp_local_date_time *local_date_time, int *hour) {
|
||||
return WrapExceptions([local_date_time] { return local_date_time->local_date_time.local_time.hours; }, hour);
|
||||
return WrapExceptions([local_date_time] { return local_date_time->local_date_time.local_time.hour; }, hour);
|
||||
}
|
||||
|
||||
mgp_error mgp_local_date_time_get_minute(mgp_local_date_time *local_date_time, int *minute) {
|
||||
return WrapExceptions([local_date_time] { return local_date_time->local_date_time.local_time.minutes; }, minute);
|
||||
return WrapExceptions([local_date_time] { return local_date_time->local_date_time.local_time.minute; }, minute);
|
||||
}
|
||||
|
||||
mgp_error mgp_local_date_time_get_second(mgp_local_date_time *local_date_time, int *second) {
|
||||
return WrapExceptions([local_date_time] { return local_date_time->local_date_time.local_time.seconds; }, second);
|
||||
return WrapExceptions([local_date_time] { return local_date_time->local_date_time.local_time.second; }, second);
|
||||
}
|
||||
|
||||
mgp_error mgp_local_date_time_get_millisecond(mgp_local_date_time *local_date_time, int *millisecond) {
|
||||
return WrapExceptions([local_date_time] { return local_date_time->local_date_time.local_time.milliseconds; },
|
||||
return WrapExceptions([local_date_time] { return local_date_time->local_date_time.local_time.millisecond; },
|
||||
millisecond);
|
||||
}
|
||||
|
||||
mgp_error mgp_local_date_time_get_microsecond(mgp_local_date_time *local_date_time, int *microsecond) {
|
||||
return WrapExceptions([local_date_time] { return local_date_time->local_date_time.local_time.microseconds; },
|
||||
return WrapExceptions([local_date_time] { return local_date_time->local_date_time.local_time.microsecond; },
|
||||
microsecond);
|
||||
}
|
||||
|
||||
|
@ -116,7 +116,7 @@ struct mgp_value {
|
||||
};
|
||||
|
||||
inline utils::DateParameters MapDateParameters(const mgp_date_parameters *parameters) {
|
||||
return {.years = parameters->year, .months = parameters->month, .days = parameters->day};
|
||||
return {.year = parameters->year, .month = parameters->month, .day = parameters->day};
|
||||
}
|
||||
|
||||
struct mgp_date {
|
||||
@ -160,11 +160,11 @@ struct mgp_date {
|
||||
};
|
||||
|
||||
inline utils::LocalTimeParameters MapLocalTimeParameters(const mgp_local_time_parameters *parameters) {
|
||||
return {.hours = parameters->hour,
|
||||
.minutes = parameters->minute,
|
||||
.seconds = parameters->second,
|
||||
.milliseconds = parameters->millisecond,
|
||||
.microseconds = parameters->microsecond};
|
||||
return {.hour = parameters->hour,
|
||||
.minute = parameters->minute,
|
||||
.second = parameters->second,
|
||||
.millisecond = parameters->millisecond,
|
||||
.microsecond = parameters->microsecond};
|
||||
}
|
||||
|
||||
struct mgp_local_time {
|
||||
@ -264,12 +264,12 @@ struct mgp_local_date_time {
|
||||
};
|
||||
|
||||
inline utils::DurationParameters MapDurationParameters(const mgp_duration_parameters *parameters) {
|
||||
return {.days = parameters->day,
|
||||
.hours = parameters->hour,
|
||||
.minutes = parameters->minute,
|
||||
.seconds = parameters->second,
|
||||
.milliseconds = parameters->millisecond,
|
||||
.microseconds = parameters->microsecond};
|
||||
return {.day = parameters->day,
|
||||
.hour = parameters->hour,
|
||||
.minute = parameters->minute,
|
||||
.second = parameters->second,
|
||||
.millisecond = parameters->millisecond,
|
||||
.microsecond = parameters->microsecond};
|
||||
}
|
||||
|
||||
struct mgp_duration {
|
||||
|
@ -2071,21 +2071,21 @@ py::Object MgpValueToPyObject(const mgp_value &value, PyGraph *py_graph) {
|
||||
}
|
||||
case MGP_VALUE_TYPE_DATE: {
|
||||
const auto &date = value.date_v->date;
|
||||
py::Object py_date(PyDate_FromDate(date.years, date.months, date.days));
|
||||
py::Object py_date(PyDate_FromDate(date.year, date.month, date.day));
|
||||
return py_date;
|
||||
}
|
||||
case MGP_VALUE_TYPE_LOCAL_TIME: {
|
||||
const auto &local_time = value.local_time_v->local_time;
|
||||
py::Object py_local_time(PyTime_FromTime(local_time.hours, local_time.minutes, local_time.seconds,
|
||||
local_time.milliseconds * 1000 + local_time.microseconds));
|
||||
py::Object py_local_time(PyTime_FromTime(local_time.hour, local_time.minute, local_time.second,
|
||||
local_time.millisecond * 1000 + local_time.microsecond));
|
||||
return py_local_time;
|
||||
}
|
||||
case MGP_VALUE_TYPE_LOCAL_DATE_TIME: {
|
||||
const auto &local_time = value.local_date_time_v->local_date_time.local_time;
|
||||
const auto &date = value.local_date_time_v->local_date_time.date;
|
||||
py::Object py_local_date_time(
|
||||
PyDateTime_FromDateAndTime(date.years, date.months, date.days, local_time.hours, local_time.minutes,
|
||||
local_time.seconds, local_time.milliseconds * 1000 + local_time.microseconds));
|
||||
PyDateTime_FromDateAndTime(date.year, date.month, date.day, local_time.hour, local_time.minute,
|
||||
local_time.second, local_time.millisecond * 1000 + local_time.microsecond));
|
||||
return py_local_date_time;
|
||||
}
|
||||
case MGP_VALUE_TYPE_DURATION: {
|
||||
|
@ -40,32 +40,32 @@ Date::Date(const int64_t microseconds) {
|
||||
const auto chrono_micros = chrono::microseconds(microseconds);
|
||||
const auto s_days = chrono::sys_days(chrono::duration_cast<chrono::days>(chrono_micros));
|
||||
const auto date = chrono::year_month_day(s_days);
|
||||
years = static_cast<int>(date.year());
|
||||
months = static_cast<unsigned>(date.month());
|
||||
days = static_cast<unsigned>(date.day());
|
||||
year = static_cast<int>(date.year());
|
||||
month = static_cast<unsigned>(date.month());
|
||||
day = static_cast<unsigned>(date.day());
|
||||
}
|
||||
|
||||
Date::Date(const DateParameters &date_parameters) {
|
||||
if (!IsInBounds(0, 9999, date_parameters.years)) {
|
||||
if (!IsInBounds(0, 9999, date_parameters.year)) {
|
||||
throw temporal::InvalidArgumentException(
|
||||
"Creating a Date with invalid year parameter. The value should be an integer between 0 and 9999.");
|
||||
}
|
||||
|
||||
if (!IsInBounds(1, 12, date_parameters.months)) {
|
||||
if (!IsInBounds(1, 12, date_parameters.month)) {
|
||||
throw temporal::InvalidArgumentException(
|
||||
"Creating a Date with invalid month parameter. The value should be an integer between 1 and 12.");
|
||||
}
|
||||
|
||||
if (!IsInBounds(1, 31, date_parameters.days) ||
|
||||
!IsValidDay(date_parameters.days, date_parameters.months, date_parameters.years)) {
|
||||
if (!IsInBounds(1, 31, date_parameters.day) ||
|
||||
!IsValidDay(date_parameters.day, date_parameters.month, date_parameters.year)) {
|
||||
throw temporal::InvalidArgumentException(
|
||||
"Creating a Date with invalid day parameter. The value should be an integer between 1 and 31, depending on the "
|
||||
"month and year.");
|
||||
}
|
||||
|
||||
years = date_parameters.years;
|
||||
months = date_parameters.months;
|
||||
days = date_parameters.days;
|
||||
year = date_parameters.year;
|
||||
month = date_parameters.month;
|
||||
day = date_parameters.day;
|
||||
}
|
||||
|
||||
namespace {
|
||||
@ -140,7 +140,7 @@ std::pair<DateParameters, bool> ParseDateParameters(std::string_view date_string
|
||||
if (!maybe_year) {
|
||||
throw temporal::InvalidArgumentException("Invalid year in the string. {}", kSupportedDateFormatsHelpMessage);
|
||||
}
|
||||
date_parameters.years = *maybe_year;
|
||||
date_parameters.year = *maybe_year;
|
||||
date_string.remove_prefix(4);
|
||||
|
||||
bool is_extended_format = false;
|
||||
@ -153,7 +153,7 @@ std::pair<DateParameters, bool> ParseDateParameters(std::string_view date_string
|
||||
if (!maybe_month) {
|
||||
throw temporal::InvalidArgumentException("Invalid month in the string. {}", kSupportedDateFormatsHelpMessage);
|
||||
}
|
||||
date_parameters.months = *maybe_month;
|
||||
date_parameters.month = *maybe_month;
|
||||
date_string.remove_prefix(2);
|
||||
|
||||
if (!date_string.empty()) {
|
||||
@ -168,7 +168,7 @@ std::pair<DateParameters, bool> ParseDateParameters(std::string_view date_string
|
||||
if (!maybe_day) {
|
||||
throw temporal::InvalidArgumentException("Invalid month in the string. {}", kSupportedDateFormatsHelpMessage);
|
||||
}
|
||||
date_parameters.days = *maybe_day;
|
||||
date_parameters.day = *maybe_day;
|
||||
date_string.remove_prefix(2);
|
||||
}
|
||||
|
||||
@ -181,16 +181,16 @@ std::pair<DateParameters, bool> ParseDateParameters(std::string_view date_string
|
||||
|
||||
int64_t Date::MicrosecondsSinceEpoch() const {
|
||||
namespace chrono = std::chrono;
|
||||
return chrono::duration_cast<chrono::microseconds>(utils::DaysSinceEpoch(years, months, days)).count();
|
||||
return chrono::duration_cast<chrono::microseconds>(utils::DaysSinceEpoch(year, month, day)).count();
|
||||
}
|
||||
|
||||
int64_t Date::DaysSinceEpoch() const { return utils::DaysSinceEpoch(years, months, days).count(); }
|
||||
int64_t Date::DaysSinceEpoch() const { return utils::DaysSinceEpoch(year, month, day).count(); }
|
||||
|
||||
size_t DateHash::operator()(const Date &date) const {
|
||||
utils::HashCombine<uint64_t, uint64_t> hasher;
|
||||
size_t result = hasher(0, date.years);
|
||||
result = hasher(result, date.months);
|
||||
result = hasher(result, date.days);
|
||||
size_t result = hasher(0, date.year);
|
||||
result = hasher(result, date.month);
|
||||
result = hasher(result, date.day);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -263,7 +263,7 @@ std::pair<LocalTimeParameters, bool> ParseLocalTimeParameters(std::string_view l
|
||||
if (!maybe_hour) {
|
||||
throw temporal::InvalidArgumentException("Invalid hour in the string. {}", kSupportedTimeFormatsHelpMessage);
|
||||
}
|
||||
local_time_parameters.hours = *maybe_hour;
|
||||
local_time_parameters.hour = *maybe_hour;
|
||||
local_time_string.remove_prefix(2);
|
||||
|
||||
if (local_time_string.empty()) {
|
||||
@ -276,7 +276,7 @@ std::pair<LocalTimeParameters, bool> ParseLocalTimeParameters(std::string_view l
|
||||
if (!maybe_minute) {
|
||||
throw temporal::InvalidArgumentException("Invalid minutes in the string. {}", kSupportedTimeFormatsHelpMessage);
|
||||
}
|
||||
local_time_parameters.minutes = *maybe_minute;
|
||||
local_time_parameters.minute = *maybe_minute;
|
||||
local_time_string.remove_prefix(2);
|
||||
|
||||
if (local_time_string.empty()) {
|
||||
@ -289,7 +289,7 @@ std::pair<LocalTimeParameters, bool> ParseLocalTimeParameters(std::string_view l
|
||||
if (!maybe_seconds) {
|
||||
throw temporal::InvalidArgumentException("Invalid seconds in the string. {}", kSupportedTimeFormatsHelpMessage);
|
||||
}
|
||||
local_time_parameters.seconds = *maybe_seconds;
|
||||
local_time_parameters.second = *maybe_seconds;
|
||||
local_time_string.remove_prefix(2);
|
||||
|
||||
if (local_time_string.empty()) {
|
||||
@ -306,7 +306,7 @@ std::pair<LocalTimeParameters, bool> ParseLocalTimeParameters(std::string_view l
|
||||
throw temporal::InvalidArgumentException("Invalid milliseconds in the string. {}",
|
||||
kSupportedTimeFormatsHelpMessage);
|
||||
}
|
||||
local_time_parameters.milliseconds = *maybe_milliseconds;
|
||||
local_time_parameters.millisecond = *maybe_milliseconds;
|
||||
local_time_string.remove_prefix(3);
|
||||
|
||||
if (local_time_string.empty()) {
|
||||
@ -318,7 +318,7 @@ std::pair<LocalTimeParameters, bool> ParseLocalTimeParameters(std::string_view l
|
||||
throw temporal::InvalidArgumentException("Invalid microseconds in the string. {}",
|
||||
kSupportedTimeFormatsHelpMessage);
|
||||
}
|
||||
local_time_parameters.microseconds = *maybe_microseconds;
|
||||
local_time_parameters.microsecond = *maybe_microseconds;
|
||||
local_time_string.remove_prefix(3);
|
||||
|
||||
if (!local_time_string.empty()) {
|
||||
@ -339,46 +339,46 @@ LocalTime::LocalTime(const int64_t microseconds) {
|
||||
throw temporal::InvalidArgumentException("Invalid LocalTime specified in microseconds");
|
||||
}
|
||||
|
||||
hours = parsed_hours;
|
||||
minutes = GetAndSubtractDuration<std::chrono::minutes>(chrono_microseconds);
|
||||
seconds = GetAndSubtractDuration<std::chrono::seconds>(chrono_microseconds);
|
||||
milliseconds = GetAndSubtractDuration<std::chrono::milliseconds>(chrono_microseconds);
|
||||
this->microseconds = chrono_microseconds.count();
|
||||
hour = parsed_hours;
|
||||
minute = GetAndSubtractDuration<std::chrono::minutes>(chrono_microseconds);
|
||||
second = GetAndSubtractDuration<std::chrono::seconds>(chrono_microseconds);
|
||||
millisecond = GetAndSubtractDuration<std::chrono::milliseconds>(chrono_microseconds);
|
||||
microsecond = chrono_microseconds.count();
|
||||
}
|
||||
|
||||
LocalTime::LocalTime(const LocalTimeParameters &local_time_parameters) {
|
||||
if (!IsInBounds(0, 23, local_time_parameters.hours)) {
|
||||
if (!IsInBounds(0, 23, local_time_parameters.hour)) {
|
||||
throw temporal::InvalidArgumentException("Creating a LocalTime with invalid hour parameter.");
|
||||
}
|
||||
|
||||
if (!IsInBounds(0, 59, local_time_parameters.minutes)) {
|
||||
if (!IsInBounds(0, 59, local_time_parameters.minute)) {
|
||||
throw temporal::InvalidArgumentException("Creating a LocalTime with invalid minutes parameter.");
|
||||
}
|
||||
|
||||
// ISO 8601 supports leap seconds, but we ignore it for now to simplify the implementation
|
||||
if (!IsInBounds(0, 59, local_time_parameters.seconds)) {
|
||||
if (!IsInBounds(0, 59, local_time_parameters.second)) {
|
||||
throw temporal::InvalidArgumentException("Creating a LocalTime with invalid seconds parameter.");
|
||||
}
|
||||
|
||||
if (!IsInBounds(0, 999, local_time_parameters.milliseconds)) {
|
||||
if (!IsInBounds(0, 999, local_time_parameters.millisecond)) {
|
||||
throw temporal::InvalidArgumentException("Creating a LocalTime with invalid milliseconds parameter.");
|
||||
}
|
||||
|
||||
if (!IsInBounds(0, 999, local_time_parameters.microseconds)) {
|
||||
if (!IsInBounds(0, 999, local_time_parameters.microsecond)) {
|
||||
throw temporal::InvalidArgumentException("Creating a LocalTime with invalid microseconds parameter.");
|
||||
}
|
||||
|
||||
hours = local_time_parameters.hours;
|
||||
minutes = local_time_parameters.minutes;
|
||||
seconds = local_time_parameters.seconds;
|
||||
milliseconds = local_time_parameters.milliseconds;
|
||||
microseconds = local_time_parameters.microseconds;
|
||||
hour = local_time_parameters.hour;
|
||||
minute = local_time_parameters.minute;
|
||||
second = local_time_parameters.second;
|
||||
millisecond = local_time_parameters.millisecond;
|
||||
microsecond = local_time_parameters.microsecond;
|
||||
}
|
||||
|
||||
std::chrono::microseconds LocalTime::SumLocalTimeParts() const {
|
||||
namespace chrono = std::chrono;
|
||||
return chrono::hours{hours} + chrono::minutes{minutes} + chrono::seconds{seconds} +
|
||||
chrono::milliseconds{milliseconds} + chrono::microseconds{microseconds};
|
||||
return chrono::hours{hour} + chrono::minutes{minute} + chrono::seconds{second} + chrono::milliseconds{millisecond} +
|
||||
chrono::microseconds{microsecond};
|
||||
}
|
||||
|
||||
int64_t LocalTime::MicrosecondsSinceEpoch() const { return SumLocalTimeParts().count(); }
|
||||
@ -390,11 +390,11 @@ int64_t LocalTime::NanosecondsSinceEpoch() const {
|
||||
|
||||
size_t LocalTimeHash::operator()(const LocalTime &local_time) const {
|
||||
utils::HashCombine<uint64_t, uint64_t> hasher;
|
||||
size_t result = hasher(0, local_time.hours);
|
||||
result = hasher(result, local_time.minutes);
|
||||
result = hasher(result, local_time.seconds);
|
||||
result = hasher(result, local_time.milliseconds);
|
||||
result = hasher(result, local_time.microseconds);
|
||||
size_t result = hasher(0, local_time.hour);
|
||||
result = hasher(result, local_time.minute);
|
||||
result = hasher(result, local_time.second);
|
||||
result = hasher(result, local_time.millisecond);
|
||||
result = hasher(result, local_time.microsecond);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -486,17 +486,16 @@ int64_t LocalDateTime::MicrosecondsSinceEpoch() const {
|
||||
|
||||
int64_t LocalDateTime::SecondsSinceEpoch() const {
|
||||
namespace chrono = std::chrono;
|
||||
const auto to_sec = chrono::duration_cast<chrono::seconds>(DaysSinceEpoch(date.years, date.months, date.days));
|
||||
const auto to_sec = chrono::duration_cast<chrono::seconds>(DaysSinceEpoch(date.year, date.month, date.day));
|
||||
const auto local_time_seconds =
|
||||
chrono::hours(local_time.hours) + chrono::minutes(local_time.minutes) + chrono::seconds(local_time.seconds);
|
||||
chrono::hours(local_time.hour) + chrono::minutes(local_time.minute) + chrono::seconds(local_time.second);
|
||||
return (to_sec + local_time_seconds).count();
|
||||
}
|
||||
|
||||
int64_t LocalDateTime::SubSecondsAsNanoseconds() const {
|
||||
namespace chrono = std::chrono;
|
||||
const auto milli_as_nanos = chrono::duration_cast<chrono::nanoseconds>(chrono::milliseconds(local_time.milliseconds));
|
||||
const auto micros_as_nanos =
|
||||
chrono::duration_cast<chrono::nanoseconds>(chrono::microseconds(local_time.microseconds));
|
||||
const auto milli_as_nanos = chrono::duration_cast<chrono::nanoseconds>(chrono::milliseconds(local_time.millisecond));
|
||||
const auto micros_as_nanos = chrono::duration_cast<chrono::nanoseconds>(chrono::microseconds(local_time.microsecond));
|
||||
|
||||
return (milli_as_nanos + micros_as_nanos).count();
|
||||
}
|
||||
@ -566,7 +565,7 @@ std::optional<DurationParameters> TryParseDurationString(std::string_view string
|
||||
};
|
||||
|
||||
const auto parse_duration_days_part = [&](auto date_string) {
|
||||
if (!parse_and_assign(date_string, 'D', duration_parameters.days)) {
|
||||
if (!parse_and_assign(date_string, 'D', duration_parameters.day)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -574,21 +573,21 @@ std::optional<DurationParameters> TryParseDurationString(std::string_view string
|
||||
};
|
||||
|
||||
const auto parse_duration_time_part = [&](auto time_string) {
|
||||
if (!parse_and_assign(time_string, 'H', duration_parameters.hours)) {
|
||||
if (!parse_and_assign(time_string, 'H', duration_parameters.hour)) {
|
||||
return false;
|
||||
}
|
||||
if (time_string.empty()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!parse_and_assign(time_string, 'M', duration_parameters.minutes)) {
|
||||
if (!parse_and_assign(time_string, 'M', duration_parameters.minute)) {
|
||||
return false;
|
||||
}
|
||||
if (time_string.empty()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!parse_and_assign(time_string, 'S', duration_parameters.seconds)) {
|
||||
if (!parse_and_assign(time_string, 'S', duration_parameters.second)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -661,12 +660,12 @@ constexpr To CastChronoDouble(const double value) {
|
||||
Duration::Duration(int64_t microseconds) { this->microseconds = microseconds; }
|
||||
|
||||
Duration::Duration(const DurationParameters ¶meters) {
|
||||
microseconds = (CastChronoDouble<std::chrono::days, std::chrono::microseconds>(parameters.days) +
|
||||
CastChronoDouble<std::chrono::hours, std::chrono::microseconds>(parameters.hours) +
|
||||
CastChronoDouble<std::chrono::minutes, std::chrono::microseconds>(parameters.minutes) +
|
||||
CastChronoDouble<std::chrono::seconds, std::chrono::microseconds>(parameters.seconds) +
|
||||
CastChronoDouble<std::chrono::milliseconds, std::chrono::microseconds>(parameters.milliseconds) +
|
||||
CastChronoDouble<std::chrono::microseconds, std::chrono::microseconds>(parameters.microseconds))
|
||||
microseconds = (CastChronoDouble<std::chrono::days, std::chrono::microseconds>(parameters.day) +
|
||||
CastChronoDouble<std::chrono::hours, std::chrono::microseconds>(parameters.hour) +
|
||||
CastChronoDouble<std::chrono::minutes, std::chrono::microseconds>(parameters.minute) +
|
||||
CastChronoDouble<std::chrono::seconds, std::chrono::microseconds>(parameters.second) +
|
||||
CastChronoDouble<std::chrono::milliseconds, std::chrono::microseconds>(parameters.millisecond) +
|
||||
CastChronoDouble<std::chrono::microseconds, std::chrono::microseconds>(parameters.microsecond))
|
||||
.count();
|
||||
}
|
||||
|
||||
|
@ -47,12 +47,12 @@ struct InvalidArgumentException : public utils::BasicException {
|
||||
} // namespace temporal
|
||||
|
||||
struct DurationParameters {
|
||||
double days{0};
|
||||
double hours{0};
|
||||
double minutes{0};
|
||||
double seconds{0};
|
||||
double milliseconds{0};
|
||||
double microseconds{0};
|
||||
double day{0};
|
||||
double hour{0};
|
||||
double minute{0};
|
||||
double second{0};
|
||||
double millisecond{0};
|
||||
double microsecond{0};
|
||||
};
|
||||
|
||||
DurationParameters ParseDurationParameters(std::string_view string);
|
||||
@ -115,9 +115,9 @@ struct DurationHash {
|
||||
};
|
||||
|
||||
struct DateParameters {
|
||||
int64_t years{0};
|
||||
int64_t months{1};
|
||||
int64_t days{1};
|
||||
int64_t year{0};
|
||||
int64_t month{1};
|
||||
int64_t day{1};
|
||||
|
||||
bool operator==(const DateParameters &) const = default;
|
||||
};
|
||||
@ -125,28 +125,28 @@ struct DateParameters {
|
||||
// boolean indicates whether the parsed string was in extended format
|
||||
std::pair<DateParameters, bool> ParseDateParameters(std::string_view date_string);
|
||||
|
||||
constexpr std::chrono::year_month_day ToChronoYMD(uint16_t years, uint8_t months, uint8_t days) {
|
||||
constexpr std::chrono::year_month_day ToChronoYMD(uint16_t year, uint8_t month, uint8_t day) {
|
||||
namespace chrono = std::chrono;
|
||||
return chrono::year_month_day(chrono::year(years), chrono::month(months), chrono::day(days));
|
||||
return chrono::year_month_day(chrono::year(year), chrono::month(month), chrono::day(day));
|
||||
}
|
||||
|
||||
constexpr std::chrono::sys_days ToChronoSysDaysYMD(uint16_t years, uint8_t months, uint8_t days) {
|
||||
return std::chrono::sys_days(ToChronoYMD(years, months, days));
|
||||
constexpr std::chrono::sys_days ToChronoSysDaysYMD(uint16_t year, uint8_t month, uint8_t day) {
|
||||
return std::chrono::sys_days(ToChronoYMD(year, month, day));
|
||||
}
|
||||
|
||||
constexpr std::chrono::days DaysSinceEpoch(uint16_t years, uint8_t months, uint8_t days) {
|
||||
return ToChronoSysDaysYMD(years, months, days).time_since_epoch();
|
||||
constexpr std::chrono::days DaysSinceEpoch(uint16_t year, uint8_t month, uint8_t day) {
|
||||
return ToChronoSysDaysYMD(year, month, day).time_since_epoch();
|
||||
}
|
||||
|
||||
struct Date {
|
||||
explicit Date() : Date{DateParameters{}} {}
|
||||
// we assume we accepted date in microseconds which was normilized using the epoch time point
|
||||
// we assume we accepted date in microseconds which was normalized using the epoch time point
|
||||
explicit Date(int64_t microseconds);
|
||||
explicit Date(const DateParameters &date_parameters);
|
||||
|
||||
friend std::ostream &operator<<(std::ostream &os, const Date &date) {
|
||||
return os << fmt::format("{:0>2}-{:0>2}-{:0>2}", date.years, static_cast<int>(date.months),
|
||||
static_cast<int>(date.days));
|
||||
return os << fmt::format("{:0>2}-{:0>2}-{:0>2}", date.year, static_cast<int>(date.month),
|
||||
static_cast<int>(date.day));
|
||||
}
|
||||
|
||||
int64_t MicrosecondsSinceEpoch() const;
|
||||
@ -166,17 +166,17 @@ struct Date {
|
||||
|
||||
friend Duration operator-(const Date &lhs, const Date &rhs) {
|
||||
namespace chrono = std::chrono;
|
||||
const auto lhs_days = utils::DaysSinceEpoch(lhs.years, lhs.months, lhs.days);
|
||||
const auto rhs_days = utils::DaysSinceEpoch(rhs.years, rhs.months, rhs.days);
|
||||
const auto lhs_days = utils::DaysSinceEpoch(lhs.year, lhs.month, lhs.day);
|
||||
const auto rhs_days = utils::DaysSinceEpoch(rhs.year, rhs.month, rhs.day);
|
||||
const auto days_elapsed = lhs_days - rhs_days;
|
||||
return Duration(chrono::duration_cast<chrono::microseconds>(days_elapsed).count());
|
||||
}
|
||||
|
||||
auto operator<=>(const Date &) const = default;
|
||||
|
||||
uint16_t years;
|
||||
uint8_t months;
|
||||
uint8_t days;
|
||||
uint16_t year;
|
||||
uint8_t month;
|
||||
uint8_t day;
|
||||
};
|
||||
|
||||
struct DateHash {
|
||||
@ -184,11 +184,11 @@ struct DateHash {
|
||||
};
|
||||
|
||||
struct LocalTimeParameters {
|
||||
int64_t hours{0};
|
||||
int64_t minutes{0};
|
||||
int64_t seconds{0};
|
||||
int64_t milliseconds{0};
|
||||
int64_t microseconds{0};
|
||||
int64_t hour{0};
|
||||
int64_t minute{0};
|
||||
int64_t second{0};
|
||||
int64_t millisecond{0};
|
||||
int64_t microsecond{0};
|
||||
|
||||
bool operator==(const LocalTimeParameters &) const = default;
|
||||
};
|
||||
@ -213,9 +213,9 @@ struct LocalTime {
|
||||
namespace chrono = std::chrono;
|
||||
using milli = chrono::milliseconds;
|
||||
using micro = chrono::microseconds;
|
||||
const auto subseconds = milli(lt.milliseconds) + micro(lt.microseconds);
|
||||
return os << fmt::format("{:0>2}:{:0>2}:{:0>2}.{:0>6}", static_cast<int>(lt.hours), static_cast<int>(lt.minutes),
|
||||
static_cast<int>(lt.seconds), subseconds.count());
|
||||
const auto subseconds = milli(lt.millisecond) + micro(lt.microsecond);
|
||||
return os << fmt::format("{:0>2}:{:0>2}:{:0>2}.{:0>6}", static_cast<int>(lt.hour), static_cast<int>(lt.minute),
|
||||
static_cast<int>(lt.second), subseconds.count());
|
||||
}
|
||||
|
||||
friend LocalTime operator+(const LocalTime &local_time, const Duration &dur) {
|
||||
@ -246,11 +246,11 @@ struct LocalTime {
|
||||
return lhs_dur - rhs_dur;
|
||||
}
|
||||
|
||||
uint8_t hours;
|
||||
uint8_t minutes;
|
||||
uint8_t seconds;
|
||||
uint16_t milliseconds;
|
||||
uint16_t microseconds;
|
||||
uint8_t hour;
|
||||
uint8_t minute;
|
||||
uint8_t second;
|
||||
uint16_t millisecond;
|
||||
uint16_t microsecond;
|
||||
};
|
||||
|
||||
struct LocalTimeHash {
|
||||
|
@ -444,9 +444,9 @@ constexpr uint8_t Cast(T marker) {
|
||||
}
|
||||
|
||||
void AssertThatDatesAreEqual(const utils::Date &d1, const utils::Date &d2) {
|
||||
ASSERT_EQ(d1.days, d2.days);
|
||||
ASSERT_EQ(d1.months, d2.months);
|
||||
ASSERT_EQ(d1.years, d2.years);
|
||||
ASSERT_EQ(d1.day, d2.day);
|
||||
ASSERT_EQ(d1.month, d2.month);
|
||||
ASSERT_EQ(d1.year, d2.year);
|
||||
}
|
||||
|
||||
TEST_F(BoltDecoder, DateOld) {
|
||||
@ -594,11 +594,11 @@ TEST_F(BoltDecoder, ArbitraryDuration) {
|
||||
}
|
||||
|
||||
void AssertThatLocalTimeIsEqual(utils::LocalTime t1, utils::LocalTime t2) {
|
||||
ASSERT_EQ(t1.hours, t2.hours);
|
||||
ASSERT_EQ(t1.minutes, t2.minutes);
|
||||
ASSERT_EQ(t1.seconds, t2.seconds);
|
||||
ASSERT_EQ(t1.microseconds, t2.microseconds);
|
||||
ASSERT_EQ(t1.milliseconds, t2.milliseconds);
|
||||
ASSERT_EQ(t1.hour, t2.hour);
|
||||
ASSERT_EQ(t1.minute, t2.minute);
|
||||
ASSERT_EQ(t1.second, t2.second);
|
||||
ASSERT_EQ(t1.microsecond, t2.microsecond);
|
||||
ASSERT_EQ(t1.millisecond, t2.millisecond);
|
||||
}
|
||||
|
||||
TEST_F(BoltDecoder, LocalTimeOneMicro) {
|
||||
|
@ -985,41 +985,41 @@ TEST_F(ExpressionEvaluatorPropertyLookup, Duration) {
|
||||
const utils::Duration dur({10, 1, 30, 2, 22, 45});
|
||||
frame[symbol] = TypedValue(dur);
|
||||
|
||||
const std::pair days = std::make_pair("days", dba.NameToProperty("days"));
|
||||
const auto total_days = Value(days);
|
||||
const std::pair day = std::make_pair("day", dba.NameToProperty("day"));
|
||||
const auto total_days = Value(day);
|
||||
EXPECT_TRUE(total_days.IsInt());
|
||||
EXPECT_EQ(total_days.ValueInt(), 10);
|
||||
|
||||
const std::pair hours = std::make_pair("hours", dba.NameToProperty("hours"));
|
||||
const auto total_hours = Value(hours);
|
||||
const std::pair hour = std::make_pair("hour", dba.NameToProperty("hour"));
|
||||
const auto total_hours = Value(hour);
|
||||
EXPECT_TRUE(total_hours.IsInt());
|
||||
EXPECT_EQ(total_hours.ValueInt(), 1);
|
||||
|
||||
const std::pair mins = std::make_pair("minutes", dba.NameToProperty("minutes"));
|
||||
const auto total_mins = Value(mins);
|
||||
const std::pair minute = std::make_pair("minute", dba.NameToProperty("minute"));
|
||||
const auto total_mins = Value(minute);
|
||||
EXPECT_TRUE(total_mins.IsInt());
|
||||
|
||||
EXPECT_EQ(total_mins.ValueInt(), 1 * 60 + 30);
|
||||
|
||||
const std::pair secs = std::make_pair("seconds", dba.NameToProperty("seconds"));
|
||||
const auto total_secs = Value(secs);
|
||||
const std::pair sec = std::make_pair("second", dba.NameToProperty("second"));
|
||||
const auto total_secs = Value(sec);
|
||||
EXPECT_TRUE(total_secs.IsInt());
|
||||
const auto expected_secs = total_mins.ValueInt() * 60 + 2;
|
||||
EXPECT_EQ(total_secs.ValueInt(), expected_secs);
|
||||
|
||||
const std::pair milli = std::make_pair("milliseconds", dba.NameToProperty("milliseconds"));
|
||||
const std::pair milli = std::make_pair("millisecond", dba.NameToProperty("millisecond"));
|
||||
const auto total_milli = Value(milli);
|
||||
EXPECT_TRUE(total_milli.IsInt());
|
||||
const auto expected_milli = total_secs.ValueInt() * 1000 + 22;
|
||||
EXPECT_EQ(total_milli.ValueInt(), expected_milli);
|
||||
|
||||
const std::pair micro = std::make_pair("microseconds", dba.NameToProperty("microseconds"));
|
||||
const std::pair micro = std::make_pair("microsecond", dba.NameToProperty("microsecond"));
|
||||
const auto total_micros = Value(micro);
|
||||
EXPECT_TRUE(total_micros.IsInt());
|
||||
const auto expected_micros = expected_milli * 1000 + 45;
|
||||
EXPECT_EQ(total_micros.ValueInt(), expected_micros);
|
||||
|
||||
const std::pair nano = std::make_pair("nanoseconds", dba.NameToProperty("nanoseconds"));
|
||||
const std::pair nano = std::make_pair("nanosecond", dba.NameToProperty("nanosecond"));
|
||||
const auto total_nano = Value(nano);
|
||||
EXPECT_TRUE(total_nano.IsInt());
|
||||
const auto expected_nano = expected_micros * 1000;
|
||||
@ -1030,18 +1030,18 @@ TEST_F(ExpressionEvaluatorPropertyLookup, Date) {
|
||||
const utils::Date date({1996, 11, 22});
|
||||
frame[symbol] = TypedValue(date);
|
||||
|
||||
const std::pair years = std::make_pair("year", dba.NameToProperty("year"));
|
||||
const auto y = Value(years);
|
||||
const std::pair year = std::make_pair("year", dba.NameToProperty("year"));
|
||||
const auto y = Value(year);
|
||||
EXPECT_TRUE(y.IsInt());
|
||||
EXPECT_EQ(y.ValueInt(), 1996);
|
||||
|
||||
const std::pair months = std::make_pair("month", dba.NameToProperty("month"));
|
||||
const auto m = Value(months);
|
||||
const std::pair month = std::make_pair("month", dba.NameToProperty("month"));
|
||||
const auto m = Value(month);
|
||||
EXPECT_TRUE(m.IsInt());
|
||||
EXPECT_EQ(m.ValueInt(), 11);
|
||||
|
||||
const std::pair days = std::make_pair("day", dba.NameToProperty("day"));
|
||||
const auto d = Value(days);
|
||||
const std::pair day = std::make_pair("day", dba.NameToProperty("day"));
|
||||
const auto d = Value(day);
|
||||
EXPECT_TRUE(d.IsInt());
|
||||
EXPECT_EQ(d.ValueInt(), 22);
|
||||
}
|
||||
@ -1060,17 +1060,17 @@ TEST_F(ExpressionEvaluatorPropertyLookup, LocalTime) {
|
||||
EXPECT_TRUE(min.IsInt());
|
||||
EXPECT_EQ(min.ValueInt(), 2);
|
||||
|
||||
const std::pair second = std::make_pair("seconds", dba.NameToProperty("seconds"));
|
||||
const std::pair second = std::make_pair("second", dba.NameToProperty("second"));
|
||||
const auto sec = Value(second);
|
||||
EXPECT_TRUE(sec.IsInt());
|
||||
EXPECT_EQ(sec.ValueInt(), 3);
|
||||
|
||||
const std::pair millis = std::make_pair("milliseconds", dba.NameToProperty("milliseconds"));
|
||||
const std::pair millis = std::make_pair("millisecond", dba.NameToProperty("millisecond"));
|
||||
const auto mil = Value(millis);
|
||||
EXPECT_TRUE(mil.IsInt());
|
||||
EXPECT_EQ(mil.ValueInt(), 11);
|
||||
|
||||
const std::pair micros = std::make_pair("microseconds", dba.NameToProperty("microseconds"));
|
||||
const std::pair micros = std::make_pair("microsecond", dba.NameToProperty("microsecond"));
|
||||
const auto mic = Value(micros);
|
||||
EXPECT_TRUE(mic.IsInt());
|
||||
EXPECT_EQ(mic.ValueInt(), 22);
|
||||
@ -1080,18 +1080,18 @@ TEST_F(ExpressionEvaluatorPropertyLookup, LocalDateTime) {
|
||||
const utils::LocalDateTime ldt({1993, 8, 6}, {2, 3, 4, 55, 40});
|
||||
frame[symbol] = TypedValue(ldt);
|
||||
|
||||
const std::pair years = std::make_pair("year", dba.NameToProperty("year"));
|
||||
const auto y = Value(years);
|
||||
const std::pair year = std::make_pair("year", dba.NameToProperty("year"));
|
||||
const auto y = Value(year);
|
||||
EXPECT_TRUE(y.IsInt());
|
||||
EXPECT_EQ(y.ValueInt(), 1993);
|
||||
|
||||
const std::pair months = std::make_pair("month", dba.NameToProperty("month"));
|
||||
const auto m = Value(months);
|
||||
const std::pair month = std::make_pair("month", dba.NameToProperty("month"));
|
||||
const auto m = Value(month);
|
||||
EXPECT_TRUE(m.IsInt());
|
||||
EXPECT_EQ(m.ValueInt(), 8);
|
||||
|
||||
const std::pair days = std::make_pair("day", dba.NameToProperty("day"));
|
||||
const auto d = Value(days);
|
||||
const std::pair day = std::make_pair("day", dba.NameToProperty("day"));
|
||||
const auto d = Value(day);
|
||||
EXPECT_TRUE(d.IsInt());
|
||||
EXPECT_EQ(d.ValueInt(), 6);
|
||||
|
||||
@ -1105,17 +1105,17 @@ TEST_F(ExpressionEvaluatorPropertyLookup, LocalDateTime) {
|
||||
EXPECT_TRUE(min.IsInt());
|
||||
EXPECT_EQ(min.ValueInt(), 3);
|
||||
|
||||
const std::pair second = std::make_pair("seconds", dba.NameToProperty("seconds"));
|
||||
const std::pair second = std::make_pair("second", dba.NameToProperty("second"));
|
||||
const auto sec = Value(second);
|
||||
EXPECT_TRUE(sec.IsInt());
|
||||
EXPECT_EQ(sec.ValueInt(), 4);
|
||||
|
||||
const std::pair millis = std::make_pair("milliseconds", dba.NameToProperty("milliseconds"));
|
||||
const std::pair millis = std::make_pair("millisecond", dba.NameToProperty("millisecond"));
|
||||
const auto mil = Value(millis);
|
||||
EXPECT_TRUE(mil.IsInt());
|
||||
EXPECT_EQ(mil.ValueInt(), 55);
|
||||
|
||||
const std::pair micros = std::make_pair("microseconds", dba.NameToProperty("microseconds"));
|
||||
const std::pair micros = std::make_pair("microsecond", dba.NameToProperty("microsecond"));
|
||||
const auto mic = Value(micros);
|
||||
EXPECT_TRUE(mic.IsInt());
|
||||
EXPECT_EQ(mic.ValueInt(), 40);
|
||||
|
@ -13,12 +13,12 @@
|
||||
namespace {
|
||||
|
||||
std::string ToString(const utils::DateParameters &date_parameters) {
|
||||
return fmt::format("{:04d}-{:02d}-{:02d}", date_parameters.years, date_parameters.months, date_parameters.days);
|
||||
return fmt::format("{:04d}-{:02d}-{:02d}", date_parameters.year, date_parameters.month, date_parameters.day);
|
||||
}
|
||||
|
||||
std::string ToString(const utils::LocalTimeParameters &local_time_parameters) {
|
||||
return fmt::format("{:02}:{:02d}:{:02d}", local_time_parameters.hours, local_time_parameters.minutes,
|
||||
local_time_parameters.seconds);
|
||||
return fmt::format("{:02}:{:02d}:{:02d}", local_time_parameters.hour, local_time_parameters.minute,
|
||||
local_time_parameters.second);
|
||||
}
|
||||
|
||||
struct TestDateParameters {
|
||||
@ -37,13 +37,18 @@ struct TestLocalTimeParameters {
|
||||
bool should_throw;
|
||||
};
|
||||
|
||||
constexpr std::array test_local_times{
|
||||
TestLocalTimeParameters{{.hours = 24}, true}, TestLocalTimeParameters{{.hours = -1}, true},
|
||||
TestLocalTimeParameters{{.minutes = -1}, true}, TestLocalTimeParameters{{.minutes = 60}, true},
|
||||
TestLocalTimeParameters{{.seconds = -1}, true}, TestLocalTimeParameters{{.minutes = 60}, true},
|
||||
TestLocalTimeParameters{{.milliseconds = -1}, true}, TestLocalTimeParameters{{.milliseconds = 1000}, true},
|
||||
TestLocalTimeParameters{{.microseconds = -1}, true}, TestLocalTimeParameters{{.microseconds = 1000}, true},
|
||||
TestLocalTimeParameters{{23, 59, 59, 999, 999}, false}, TestLocalTimeParameters{{0, 0, 0, 0, 0}, false}};
|
||||
constexpr std::array test_local_times{TestLocalTimeParameters{{.hour = 24}, true},
|
||||
TestLocalTimeParameters{{.hour = -1}, true},
|
||||
TestLocalTimeParameters{{.minute = -1}, true},
|
||||
TestLocalTimeParameters{{.minute = 60}, true},
|
||||
TestLocalTimeParameters{{.second = -1}, true},
|
||||
TestLocalTimeParameters{{.minute = 60}, true},
|
||||
TestLocalTimeParameters{{.millisecond = -1}, true},
|
||||
TestLocalTimeParameters{{.millisecond = 1000}, true},
|
||||
TestLocalTimeParameters{{.microsecond = -1}, true},
|
||||
TestLocalTimeParameters{{.microsecond = 1000}, true},
|
||||
TestLocalTimeParameters{{23, 59, 59, 999, 999}, false},
|
||||
TestLocalTimeParameters{{0, 0, 0, 0, 0}, false}};
|
||||
} // namespace
|
||||
|
||||
TEST(TemporalTest, DateConstruction) {
|
||||
@ -160,15 +165,15 @@ TEST(TemporalTest, LocalDateTimeMicrosecondsSinceEpochConversion) {
|
||||
|
||||
TEST(TemporalTest, DurationConversion) {
|
||||
{
|
||||
utils::Duration duration{{.minutes = 123.25}};
|
||||
utils::Duration duration{{.minute = 123.25}};
|
||||
const auto microseconds = duration.microseconds;
|
||||
utils::LocalDateTime local_date_time{microseconds};
|
||||
ASSERT_EQ(local_date_time.date.years, 1970);
|
||||
ASSERT_EQ(local_date_time.date.months, 1);
|
||||
ASSERT_EQ(local_date_time.date.days, 1);
|
||||
ASSERT_EQ(local_date_time.local_time.hours, 2);
|
||||
ASSERT_EQ(local_date_time.local_time.minutes, 3);
|
||||
ASSERT_EQ(local_date_time.local_time.seconds, 15);
|
||||
ASSERT_EQ(local_date_time.date.year, 1970);
|
||||
ASSERT_EQ(local_date_time.date.month, 1);
|
||||
ASSERT_EQ(local_date_time.date.day, 1);
|
||||
ASSERT_EQ(local_date_time.local_time.hour, 2);
|
||||
ASSERT_EQ(local_date_time.local_time.minute, 3);
|
||||
ASSERT_EQ(local_date_time.local_time.second, 15);
|
||||
};
|
||||
}
|
||||
|
||||
@ -252,29 +257,29 @@ TEST(TemporalTest, LocalDateTimeParsing) {
|
||||
}
|
||||
|
||||
void CheckDurationParameters(const auto &values, const auto &expected) {
|
||||
ASSERT_EQ(values.days, expected.days);
|
||||
ASSERT_EQ(values.hours, expected.hours);
|
||||
ASSERT_EQ(values.minutes, expected.minutes);
|
||||
ASSERT_EQ(values.seconds, expected.seconds);
|
||||
ASSERT_EQ(values.milliseconds, expected.milliseconds);
|
||||
ASSERT_EQ(values.microseconds, expected.microseconds);
|
||||
ASSERT_EQ(values.day, expected.day);
|
||||
ASSERT_EQ(values.hour, expected.hour);
|
||||
ASSERT_EQ(values.minute, expected.minute);
|
||||
ASSERT_EQ(values.second, expected.second);
|
||||
ASSERT_EQ(values.millisecond, expected.millisecond);
|
||||
ASSERT_EQ(values.microsecond, expected.microsecond);
|
||||
}
|
||||
|
||||
TEST(TemporalTest, DurationParsing) {
|
||||
ASSERT_THROW(utils::ParseDurationParameters("P12Y"), utils::BasicException);
|
||||
ASSERT_THROW(utils::ParseDurationParameters("P12Y32DT2M"), utils::BasicException);
|
||||
|
||||
CheckDurationParameters(utils::ParseDurationParameters("PT26H"), utils::DurationParameters{.hours = 26});
|
||||
CheckDurationParameters(utils::ParseDurationParameters("PT2M"), utils::DurationParameters{.minutes = 2.0});
|
||||
CheckDurationParameters(utils::ParseDurationParameters("PT22S"), utils::DurationParameters{.seconds = 22});
|
||||
CheckDurationParameters(utils::ParseDurationParameters("PT26H"), utils::DurationParameters{.hour = 26});
|
||||
CheckDurationParameters(utils::ParseDurationParameters("PT2M"), utils::DurationParameters{.minute = 2.0});
|
||||
CheckDurationParameters(utils::ParseDurationParameters("PT22S"), utils::DurationParameters{.second = 22});
|
||||
|
||||
CheckDurationParameters(utils::ParseDurationParameters("PT.33S"), utils::DurationParameters{.seconds = 0.33});
|
||||
CheckDurationParameters(utils::ParseDurationParameters("PT.33S"), utils::DurationParameters{.second = 0.33});
|
||||
|
||||
CheckDurationParameters(utils::ParseDurationParameters("PT2M3S"),
|
||||
utils::DurationParameters{.minutes = 2.0, .seconds = 3.0});
|
||||
CheckDurationParameters(utils::ParseDurationParameters("PT2.5H"), utils::DurationParameters{.hours = 2.5});
|
||||
utils::DurationParameters{.minute = 2.0, .second = 3.0});
|
||||
CheckDurationParameters(utils::ParseDurationParameters("PT2.5H"), utils::DurationParameters{.hour = 2.5});
|
||||
CheckDurationParameters(utils::ParseDurationParameters("P2DT2.5H"),
|
||||
utils::DurationParameters{.days = 2.0, .hours = 2.5});
|
||||
utils::DurationParameters{.day = 2.0, .hour = 2.5});
|
||||
|
||||
ASSERT_THROW(utils::ParseDurationParameters("P2M3S"), utils::BasicException);
|
||||
ASSERT_THROW(utils::ParseDurationParameters("PTM3S"), utils::BasicException);
|
||||
@ -439,16 +444,16 @@ TEST(TemporalTest, LocalTimeAndDurationAddition) {
|
||||
const auto half_an_hour_before_midnight = utils::LocalTime({23, 30, 10});
|
||||
{
|
||||
const auto half_past_midnight = half_an_hour_before_midnight + utils::Duration({1, 1, 0, 0});
|
||||
ASSERT_EQ(half_past_midnight, utils::LocalTime({.minutes = 30, .seconds = 10}));
|
||||
ASSERT_EQ(half_past_midnight, utils::LocalTime({.minute = 30, .second = 10}));
|
||||
}
|
||||
const auto identity = half_an_hour_before_midnight + utils::Duration({.days = 1});
|
||||
const auto identity = half_an_hour_before_midnight + utils::Duration({.day = 1});
|
||||
ASSERT_EQ(identity, half_an_hour_before_midnight);
|
||||
ASSERT_EQ(identity, half_an_hour_before_midnight + utils::Duration({.days = 1, .hours = 24}));
|
||||
ASSERT_EQ(identity, half_an_hour_before_midnight + utils::Duration({.day = 1, .hour = 24}));
|
||||
const auto an_hour_and_a_half_before_midnight = utils::LocalTime({22, 30, 10});
|
||||
ASSERT_EQ(half_an_hour_before_midnight + utils::Duration({.hours = 23}), an_hour_and_a_half_before_midnight);
|
||||
ASSERT_EQ(half_an_hour_before_midnight + utils::Duration({.hour = 23}), an_hour_and_a_half_before_midnight);
|
||||
|
||||
const auto minus_one_hour = utils::Duration({-10, -1, 0, 0, -20, -20});
|
||||
const auto minus_one_hour_exact = utils::Duration({.days = -10, .hours = -1});
|
||||
const auto minus_one_hour_exact = utils::Duration({.day = -10, .hour = -1});
|
||||
{
|
||||
const auto half_past_midnight = half_past_one + minus_one_hour;
|
||||
ASSERT_EQ(half_past_midnight, utils::LocalTime({0, 30, 9, 979, 980}));
|
||||
@ -484,41 +489,41 @@ TEST(TemporalTest, LocalTimeDeltaDuration) {
|
||||
const auto half_past_one = utils::LocalTime({1, 30, 10});
|
||||
const auto half_past_two = utils::LocalTime({2, 30, 10});
|
||||
const auto an_hour_negative = half_past_one - half_past_two;
|
||||
ASSERT_EQ(an_hour_negative, utils::Duration({.hours = -1}));
|
||||
ASSERT_EQ(an_hour_negative, utils::Duration({.hour = -1}));
|
||||
const auto an_hour = half_past_two - half_past_one;
|
||||
ASSERT_EQ(an_hour, utils::Duration({.hours = 1}));
|
||||
ASSERT_EQ(an_hour, utils::Duration({.hour = 1}));
|
||||
}
|
||||
|
||||
TEST(TemporalTest, DateAddition) {
|
||||
const auto unix_epoch = utils::Date({1970, 1, 1});
|
||||
const auto one_day_after_unix_epoch = unix_epoch + utils::Duration({.days = 1});
|
||||
const auto one_day_after_unix_epoch_symmetrical = utils::Duration({.days = 1}) + unix_epoch;
|
||||
const auto one_day_after_unix_epoch = unix_epoch + utils::Duration({.day = 1});
|
||||
const auto one_day_after_unix_epoch_symmetrical = utils::Duration({.day = 1}) + unix_epoch;
|
||||
ASSERT_EQ(one_day_after_unix_epoch, utils::Date({1970, 1, 2}));
|
||||
ASSERT_EQ(one_day_after_unix_epoch_symmetrical, one_day_after_unix_epoch);
|
||||
|
||||
const auto one_month_after_unix_epoch = unix_epoch + utils::Duration({.days = 31});
|
||||
const auto one_month_after_unix_epoch = unix_epoch + utils::Duration({.day = 31});
|
||||
ASSERT_EQ(one_month_after_unix_epoch, utils::Date({1970, 2, 1}));
|
||||
|
||||
const auto one_year_after_unix_epoch = unix_epoch + utils::Duration({.days = 365});
|
||||
const auto one_year_after_unix_epoch = unix_epoch + utils::Duration({.day = 365});
|
||||
ASSERT_EQ(one_year_after_unix_epoch, utils::Date({1971, 1, 1}));
|
||||
|
||||
const auto last_day_of_unix_epoch = one_year_after_unix_epoch + utils::Duration({.days = -1});
|
||||
const auto last_day_of_unix_epoch = one_year_after_unix_epoch + utils::Duration({.day = -1});
|
||||
ASSERT_EQ(last_day_of_unix_epoch, utils::Date({1970, 12, 31}));
|
||||
|
||||
const auto one_day_before_unix_epoch = unix_epoch + utils::Duration({.days = -1});
|
||||
const auto one_day_before_unix_epoch = unix_epoch + utils::Duration({.day = -1});
|
||||
ASSERT_EQ(one_day_before_unix_epoch, utils::Date({1969, 12, 31}));
|
||||
|
||||
ASSERT_EQ(last_day_of_unix_epoch + utils::Duration({.days = -31}), utils::Date({1970, 11, 30}));
|
||||
ASSERT_EQ(last_day_of_unix_epoch + utils::Duration({.day = -31}), utils::Date({1970, 11, 30}));
|
||||
ASSERT_THROW(unix_epoch + utils::Duration(std::numeric_limits<int64_t>::max()), utils::BasicException);
|
||||
ASSERT_THROW(unix_epoch + utils::Duration(std::numeric_limits<int64_t>::min()), utils::BasicException);
|
||||
}
|
||||
|
||||
TEST(TemporalTest, DateSubstraction) {
|
||||
const auto day_after_unix_epoch = utils::Date({1970, 1, 2});
|
||||
const auto unix_epoch = day_after_unix_epoch - utils::Duration({.days = 1});
|
||||
const auto unix_epoch = day_after_unix_epoch - utils::Duration({.day = 1});
|
||||
ASSERT_EQ(unix_epoch, utils::Date({1970, 1, 1}));
|
||||
ASSERT_EQ(utils::Date({1971, 1, 1}) - utils::Duration({.days = 1}), utils::Date({1970, 12, 31}));
|
||||
ASSERT_EQ(utils::Date({1971, 1, 1}) - utils::Duration({.days = -1}), utils::Date({1971, 1, 2}));
|
||||
ASSERT_EQ(utils::Date({1971, 1, 1}) - utils::Duration({.day = 1}), utils::Date({1970, 12, 31}));
|
||||
ASSERT_EQ(utils::Date({1971, 1, 1}) - utils::Duration({.day = -1}), utils::Date({1971, 1, 2}));
|
||||
ASSERT_THROW(unix_epoch - utils::Duration(std::numeric_limits<int64_t>::max()), utils::BasicException);
|
||||
ASSERT_THROW(unix_epoch - utils::Duration(std::numeric_limits<int64_t>::min()), utils::BasicException);
|
||||
}
|
||||
@ -526,25 +531,25 @@ TEST(TemporalTest, DateSubstraction) {
|
||||
TEST(TemporalTest, DateDelta) {
|
||||
const auto unix_epoch = utils::Date({1970, 1, 1});
|
||||
const auto one_year_after_unix_epoch = utils::Date({1971, 1, 1});
|
||||
ASSERT_EQ(one_year_after_unix_epoch - unix_epoch, utils::Duration({.days = 365}));
|
||||
ASSERT_EQ(unix_epoch - one_year_after_unix_epoch, utils::Duration({.days = -365}));
|
||||
ASSERT_EQ(one_year_after_unix_epoch - unix_epoch, utils::Duration({.day = 365}));
|
||||
ASSERT_EQ(unix_epoch - one_year_after_unix_epoch, utils::Duration({.day = -365}));
|
||||
}
|
||||
|
||||
TEST(TemporalTest, LocalDateTimeAdditionSubtraction) {
|
||||
const auto unix_epoch = utils::LocalDateTime({1970, 1, 1}, {.hours = 12});
|
||||
auto one_day_after_unix_epoch = unix_epoch + utils::Duration({.hours = 24});
|
||||
auto one_day_after_unix_epoch_symmetrical = utils::Duration({.hours = 24}) + unix_epoch;
|
||||
ASSERT_EQ(one_day_after_unix_epoch, utils::LocalDateTime({1970, 1, 2}, {.hours = 12}));
|
||||
const auto unix_epoch = utils::LocalDateTime({1970, 1, 1}, {.hour = 12});
|
||||
auto one_day_after_unix_epoch = unix_epoch + utils::Duration({.hour = 24});
|
||||
auto one_day_after_unix_epoch_symmetrical = utils::Duration({.hour = 24}) + unix_epoch;
|
||||
ASSERT_EQ(one_day_after_unix_epoch, utils::LocalDateTime({1970, 1, 2}, {.hour = 12}));
|
||||
ASSERT_EQ(one_day_after_unix_epoch_symmetrical, one_day_after_unix_epoch);
|
||||
|
||||
const auto one_day_before_unix_epoch = utils::LocalDateTime({1969, 12, 31}, {23, 59, 59});
|
||||
ASSERT_EQ(one_day_before_unix_epoch + utils::Duration({.seconds = 1}), utils::LocalDateTime({1970, 1, 1}, {}));
|
||||
ASSERT_EQ(one_day_before_unix_epoch + utils::Duration({.second = 1}), utils::LocalDateTime({1970, 1, 1}, {}));
|
||||
|
||||
one_day_after_unix_epoch = unix_epoch + utils::Duration({.days = 1});
|
||||
ASSERT_EQ(one_day_after_unix_epoch, utils::LocalDateTime({1970, 1, 2}, {.hours = 12}));
|
||||
one_day_after_unix_epoch = unix_epoch + utils::Duration({.day = 1});
|
||||
ASSERT_EQ(one_day_after_unix_epoch, utils::LocalDateTime({1970, 1, 2}, {.hour = 12}));
|
||||
|
||||
ASSERT_EQ(one_day_after_unix_epoch + utils::Duration({.days = -1}), unix_epoch);
|
||||
ASSERT_EQ(one_day_after_unix_epoch - utils::Duration({.days = 1}), unix_epoch);
|
||||
ASSERT_EQ(one_day_after_unix_epoch + utils::Duration({.day = -1}), unix_epoch);
|
||||
ASSERT_EQ(one_day_after_unix_epoch - utils::Duration({.day = 1}), unix_epoch);
|
||||
ASSERT_THROW(one_day_after_unix_epoch + utils::Duration(std::numeric_limits<int64_t>::max()), utils::BasicException);
|
||||
ASSERT_THROW(one_day_after_unix_epoch + utils::Duration(std::numeric_limits<int64_t>::min()), utils::BasicException);
|
||||
ASSERT_THROW(one_day_after_unix_epoch - utils::Duration(std::numeric_limits<int64_t>::max()), utils::BasicException);
|
||||
@ -555,8 +560,8 @@ TEST(TemporalTest, LocalDateTimeDelta) {
|
||||
const auto unix_epoch = utils::LocalDateTime({1970, 1, 1}, {1, 1, 1});
|
||||
const auto one_year_after_unix_epoch = utils::LocalDateTime({1971, 2, 1}, {12, 1, 1});
|
||||
const auto two_years_after_unix_epoch = utils::LocalDateTime({1972, 2, 1}, {1, 1, 1, 20, 34});
|
||||
ASSERT_EQ(one_year_after_unix_epoch - unix_epoch, utils::Duration({.days = 396, .hours = 11}));
|
||||
ASSERT_EQ(unix_epoch - one_year_after_unix_epoch, utils::Duration({.days = -396, .hours = -11}));
|
||||
ASSERT_EQ(one_year_after_unix_epoch - unix_epoch, utils::Duration({.day = 396, .hour = 11}));
|
||||
ASSERT_EQ(unix_epoch - one_year_after_unix_epoch, utils::Duration({.day = -396, .hour = -11}));
|
||||
ASSERT_EQ(two_years_after_unix_epoch - unix_epoch,
|
||||
utils::Duration({.days = 761, .milliseconds = 20, .microseconds = 34}));
|
||||
utils::Duration({.day = 761, .millisecond = 20, .microsecond = 34}));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user