diff --git a/cpp/src/arrow/compute/kernels/scalar_temporal_benchmark.cc b/cpp/src/arrow/compute/kernels/scalar_temporal_benchmark.cc index 032b1aab7db44..2686a1b6a0be2 100644 --- a/cpp/src/arrow/compute/kernels/scalar_temporal_benchmark.cc +++ b/cpp/src/arrow/compute/kernels/scalar_temporal_benchmark.cc @@ -231,6 +231,7 @@ DECLARE_TEMPORAL_BENCHMARKS_ZONED(IsDaylightSavings); DECLARE_TEMPORAL_BENCHMARKS(PGYear); DECLARE_TEMPORAL_BENCHMARKS(PGMonth); DECLARE_TEMPORAL_BENCHMARKS(PGDay); +DECLARE_TEMPORAL_BENCHMARKS(PGWeek); DECLARE_TEMPORAL_BENCHMARKS(USYear); DECLARE_TEMPORAL_BENCHMARKS(ISOYear); DECLARE_TEMPORAL_BENCHMARKS(ISOWeek); diff --git a/cpp/src/arrow/compute/kernels/scalar_temporal_unary.cc b/cpp/src/arrow/compute/kernels/scalar_temporal_unary.cc index 9a72252593c9d..a8966fed82d9a 100644 --- a/cpp/src/arrow/compute/kernels/scalar_temporal_unary.cc +++ b/cpp/src/arrow/compute/kernels/scalar_temporal_unary.cc @@ -55,7 +55,6 @@ using arrow_vendored::date::weekday; using arrow_vendored::date::weeks; using arrow_vendored::date::year; using arrow_vendored::date::year_month_day; -using arrow_vendored::date::year_month_day_pg; using arrow_vendored::date::year_month_weekday; using arrow_vendored::date::years; using arrow_vendored::date::zoned_time; @@ -467,7 +466,7 @@ struct USYear { // ---------------------------------------------------------------------- // Extract PostgreSQL year from temporal types // -// This class is the same as Year except using year_month_day_pg. +// This class is the same as Year except using pg_epoch. template struct PGYear { @@ -477,8 +476,8 @@ struct PGYear { template T Call(KernelContext*, Arg0 arg, Status*) const { return static_cast(static_cast( - year_month_day_pg( - floor(localizer_.template ConvertTimePoint(arg))) + year_month_day( + floor(localizer_.template ConvertTimePoint(arg)), epoch_type::pg_epoch) .year())); } @@ -496,7 +495,9 @@ struct PGMonth { template T Call(KernelContext*, Arg0 arg, Status*) const { return static_cast(static_cast( - year_month_day_pg(floor(localizer_.template ConvertTimePoint(arg))) + year_month_day( + floor(localizer_.template ConvertTimePoint(arg)), + epoch_type::pg_epoch) .month())); } @@ -514,7 +515,9 @@ struct PGDay { template T Call(KernelContext*, Arg0 arg, Status*) const { return static_cast(static_cast( - year_month_day_pg(floor(localizer_.template ConvertTimePoint(arg))) + year_month_day( + floor(localizer_.template ConvertTimePoint(arg)), + epoch_type::pg_epoch) .day())); } @@ -556,7 +559,7 @@ struct PGWeek { template T Call(KernelContext*, Arg0 arg, Status*) const { const auto t = floor(localizer_.template ConvertTimePoint(arg)); - auto y = year_month_day_pg{t + days_offset_}.year(); + auto y = year_month_day{t + days_offset_, epoch_type::pg_epoch}.year(); if (first_week_is_fully_in_year_) { auto start = localizer_.ConvertDays(y / jan / wd_[1]); diff --git a/cpp/src/arrow/vendored/datetime/date.h b/cpp/src/arrow/vendored/datetime/date.h index 6c79efc743538..09f6cd642aab0 100644 --- a/cpp/src/arrow/vendored/datetime/date.h +++ b/cpp/src/arrow/vendored/datetime/date.h @@ -89,11 +89,6 @@ namespace arrow_vendored namespace date { -// 10957 = julian days of '2000-01-01' - julian days of '1970-01-01' -// This is used to align the number of days based on the PostgreSQL epoch to -// the number based on the unix epoch, or vice versa. -#define DIFFDAYS_BETWEEN_UNIXEPOCH_AND_PGEPOCH 10957 - //---------------+ // Configuration | //---------------+ @@ -692,6 +687,17 @@ template std::basic_ostream& operator<<(std::basic_ostream& os, const month_weekday_last& mwdl); +// epoch_type represents the difference days between the specific epoch and unix epoch. +enum epoch_type { + // '1970-01-01' + unix_epoch = 0, + + // 10957 = julian days of '2000-01-01' - julian days of '1970-01-01' + // This is used to align the number of days based on the PostgreSQL epoch to + // the number based on the unix epoch, or vice versa. + pg_epoch = 10957 +}; + // class year_month_day class year_month_day @@ -699,15 +705,18 @@ class year_month_day date::year y_; date::month m_; date::day d_; + epoch_type et_; public: year_month_day() = default; CONSTCD11 year_month_day(const date::year& y, const date::month& m, - const date::day& d) NOEXCEPT; - CONSTCD14 year_month_day(const year_month_day_last& ymdl) NOEXCEPT; + const date::day& d, epoch_type et = epoch_type::unix_epoch) NOEXCEPT; + CONSTCD14 year_month_day(const year_month_day_last& ymdl, + epoch_type et = epoch_type::unix_epoch) NOEXCEPT; - CONSTCD14 year_month_day(sys_days dp) NOEXCEPT; - CONSTCD14 explicit year_month_day(local_days dp) NOEXCEPT; + CONSTCD14 year_month_day(sys_days dp, epoch_type et = epoch_type::unix_epoch) NOEXCEPT; + CONSTCD14 explicit year_month_day(local_days dp, + epoch_type et = epoch_type::unix_epoch) NOEXCEPT; template CONSTCD14 year_month_day& operator+=(const months& m) NOEXCEPT; @@ -719,14 +728,15 @@ class year_month_day CONSTCD11 date::year year() const NOEXCEPT; CONSTCD11 date::month month() const NOEXCEPT; CONSTCD11 date::day day() const NOEXCEPT; + CONSTCD11 epoch_type epoch() const NOEXCEPT; CONSTCD14 operator sys_days() const NOEXCEPT; CONSTCD14 explicit operator local_days() const NOEXCEPT; CONSTCD14 bool ok() const NOEXCEPT; private: - static CONSTCD14 year_month_day from_days(days dp) NOEXCEPT; - CONSTCD14 days to_days() const NOEXCEPT; + static CONSTCD14 year_month_day from_days(days dp, epoch_type et) NOEXCEPT; + CONSTCD14 days to_days() const NOEXCEPT; }; CONSTCD11 bool operator==(const year_month_day& x, const year_month_day& y) NOEXCEPT; @@ -750,65 +760,6 @@ template std::basic_ostream& operator<<(std::basic_ostream& os, const year_month_day& ymd); -// class year_month_day_pg - -class year_month_day_pg { - date::year y_; - date::month m_; - date::day d_; - - public: - year_month_day_pg() = default; - CONSTCD11 year_month_day_pg(const date::year& y, const date::month& m, - const date::day& d) NOEXCEPT; - CONSTCD14 year_month_day_pg(const year_month_day& ymd) NOEXCEPT; - CONSTCD14 year_month_day_pg(const year_month_day_last& ymdl) NOEXCEPT; - - CONSTCD14 year_month_day_pg(sys_days dp) NOEXCEPT; - CONSTCD14 explicit year_month_day_pg(local_days dp) NOEXCEPT; - - template - CONSTCD14 year_month_day_pg& operator+=(const months& m) NOEXCEPT; - template - CONSTCD14 year_month_day_pg& operator-=(const months& m) NOEXCEPT; - CONSTCD14 year_month_day_pg& operator+=(const years& y) NOEXCEPT; - CONSTCD14 year_month_day_pg& operator-=(const years& y) NOEXCEPT; - - CONSTCD11 date::year year() const NOEXCEPT; - CONSTCD11 date::month month() const NOEXCEPT; - CONSTCD11 date::day day() const NOEXCEPT; - - CONSTCD14 operator sys_days() const NOEXCEPT; - CONSTCD14 explicit operator local_days() const NOEXCEPT; - CONSTCD14 bool ok() const NOEXCEPT; - - private: - static CONSTCD14 year_month_day_pg from_days(days dp) NOEXCEPT; - CONSTCD14 days to_days() const NOEXCEPT; -}; - -CONSTCD11 bool operator==(const year_month_day_pg& x, const year_month_day_pg& y) NOEXCEPT; -CONSTCD11 bool operator!=(const year_month_day_pg& x, const year_month_day_pg& y) NOEXCEPT; -CONSTCD11 bool operator<(const year_month_day_pg& x, const year_month_day_pg& y) NOEXCEPT; -CONSTCD11 bool operator>(const year_month_day_pg& x, const year_month_day_pg& y) NOEXCEPT; -CONSTCD11 bool operator<=(const year_month_day_pg& x, const year_month_day_pg& y) NOEXCEPT; -CONSTCD11 bool operator>=(const year_month_day_pg& x, const year_month_day_pg& y) NOEXCEPT; - -template -CONSTCD14 year_month_day_pg operator+(const year_month_day_pg& ymd, const months& dm) NOEXCEPT; -template -CONSTCD14 year_month_day_pg operator+(const months& dm, const year_month_day_pg& ymd) NOEXCEPT; -template -CONSTCD14 year_month_day_pg operator-(const year_month_day_pg& ymd, const months& dm) NOEXCEPT; -CONSTCD11 year_month_day_pg operator+(const year_month_day_pg& ymd, const years& dy) NOEXCEPT; -CONSTCD11 year_month_day_pg operator+(const years& dy, - const year_month_day_pg& ymd) NOEXCEPT; -CONSTCD11 year_month_day_pg operator-(const year_month_day_pg& ymd, const years& dy) NOEXCEPT; - -template -std::basic_ostream& operator<<(std::basic_ostream& os, - const year_month_day_pg& ymd); - // year_month_day_last class year_month_day_last @@ -2963,37 +2914,36 @@ operator-(const year_month_day_last& ymdl, const years& dy) NOEXCEPT // year_month_day CONSTCD11 -inline -year_month_day::year_month_day(const date::year& y, const date::month& m, - const date::day& d) NOEXCEPT - : y_(y) - , m_(m) - , d_(d) - {} +inline year_month_day::year_month_day(const date::year& y, const date::month& m, + const date::day& d, + epoch_type et) NOEXCEPT + : y_(y), + m_(m), + d_(d), + et_(et) {} CONSTCD14 -inline -year_month_day::year_month_day(const year_month_day_last& ymdl) NOEXCEPT - : y_(ymdl.year()) - , m_(ymdl.month()) - , d_(ymdl.day()) - {} +inline year_month_day::year_month_day(const year_month_day_last& ymdl, + epoch_type et) NOEXCEPT + : y_(ymdl.year()), + m_(ymdl.month()), + d_(ymdl.day()), + et_(et) {} CONSTCD14 -inline -year_month_day::year_month_day(sys_days dp) NOEXCEPT - : year_month_day(from_days(dp.time_since_epoch())) - {} +inline year_month_day::year_month_day(sys_days dp, + epoch_type et) NOEXCEPT + : year_month_day(from_days(dp.time_since_epoch(), et)) {} CONSTCD14 -inline -year_month_day::year_month_day(local_days dp) NOEXCEPT - : year_month_day(from_days(dp.time_since_epoch())) - {} +inline year_month_day::year_month_day(local_days dp, + epoch_type et) NOEXCEPT + : year_month_day(from_days(dp.time_since_epoch(), et)) {} CONSTCD11 inline year year_month_day::year() const NOEXCEPT {return y_;} CONSTCD11 inline month year_month_day::month() const NOEXCEPT {return m_;} CONSTCD11 inline day year_month_day::day() const NOEXCEPT {return d_;} +CONSTCD11 inline epoch_type year_month_day::epoch() const NOEXCEPT {return et_;} template CONSTCD14 @@ -3049,7 +2999,7 @@ year_month_day::to_days() const NOEXCEPT auto const yoe = static_cast(y - era * 400); // [0, 399] auto const doy = (153*(m > 2 ? m-3 : m+9) + 2)/5 + d-1; // [0, 365] auto const doe = yoe * 365 + yoe/4 - yoe/100 + doy; // [0, 146096] - return days{era * 146097 + static_cast(doe) - 719468}; + return days{era * 146097 + static_cast(doe) - 719468 - et_}; } CONSTCD14 @@ -3150,13 +3100,13 @@ operator<<(std::basic_ostream& os, const year_month_day& ymd) CONSTCD14 inline year_month_day -year_month_day::from_days(days dp) NOEXCEPT +year_month_day::from_days(days dp, epoch_type et) NOEXCEPT { static_assert(std::numeric_limits::digits >= 18, "This algorithm has not been ported to a 16 bit unsigned integer"); static_assert(std::numeric_limits::digits >= 20, "This algorithm has not been ported to a 16 bit signed integer"); - auto const z = dp.count() + 719468; + auto const z = dp.count() + 719468 + et; auto const era = (z >= 0 ? z : z - 146096) / 146097; auto const doe = static_cast(z - era * 146097); // [0, 146096] auto const yoe = (doe - doe/1460 + doe/36524 - doe/146096) / 365; // [0, 399] @@ -3165,7 +3115,7 @@ year_month_day::from_days(days dp) NOEXCEPT auto const mp = (5*doy + 2)/153; // [0, 11] auto const d = doy - (153*mp+2)/5 + 1; // [1, 31] auto const m = mp < 10 ? mp+3 : mp-9; // [1, 12] - return year_month_day{date::year{y + (m <= 2)}, date::month(m), date::day(d)}; + return year_month_day{date::year{y + (m <= 2)}, date::month(m), date::day(d), et}; } template @@ -3219,210 +3169,6 @@ operator-(const year_month_day& ymd, const years& dy) NOEXCEPT return ymd + (-dy); } -// year_month_day_pg - -CONSTCD11 -inline year_month_day_pg::year_month_day_pg(const date::year& y, const date::month& m, - const date::day& d) NOEXCEPT : y_(y), - m_(m), - d_(d) {} - -CONSTCD14 -inline year_month_day_pg::year_month_day_pg(const year_month_day& ymd) NOEXCEPT - : y_(ymd.year()), - m_(ymd.month()), - d_(ymd.day()) {} - -CONSTCD14 -inline year_month_day_pg::year_month_day_pg(const year_month_day_last& ymdl) NOEXCEPT - : y_(ymdl.year()), - m_(ymdl.month()), - d_(ymdl.day()) {} - -CONSTCD14 -inline year_month_day_pg::year_month_day_pg(sys_days dp) NOEXCEPT - : year_month_day_pg(from_days(dp.time_since_epoch())) {} - -CONSTCD14 -inline year_month_day_pg::year_month_day_pg(local_days dp) NOEXCEPT - : year_month_day_pg(from_days(dp.time_since_epoch())) {} - -CONSTCD11 inline year year_month_day_pg::year() const NOEXCEPT { return y_; } -CONSTCD11 inline month year_month_day_pg::month() const NOEXCEPT { return m_; } -CONSTCD11 inline day year_month_day_pg::day() const NOEXCEPT { return d_; } - -template -CONSTCD14 inline year_month_day_pg& year_month_day_pg::operator+=( - const months& m) NOEXCEPT { - *this = *this + m; - return *this; -} - -template -CONSTCD14 inline year_month_day_pg& year_month_day_pg::operator-=( - const months& m) NOEXCEPT { - *this = *this - m; - return *this; -} - -CONSTCD14 -inline year_month_day_pg& year_month_day_pg::operator+=(const years& y) NOEXCEPT { - *this = *this + y; - return *this; -} - -CONSTCD14 -inline year_month_day_pg& year_month_day_pg::operator-=(const years& y) NOEXCEPT { - *this = *this - y; - return *this; -} - -CONSTCD14 -inline days year_month_day_pg::to_days() const NOEXCEPT { - static_assert(std::numeric_limits::digits >= 18, - "This algorithm has not been ported to a 16 bit unsigned integer"); - static_assert(std::numeric_limits::digits >= 20, - "This algorithm has not been ported to a 16 bit signed integer"); - auto const y = static_cast(y_) - (m_ <= February); - auto const m = static_cast(m_); - auto const d = static_cast(d_); - auto const era = (y >= 0 ? y : y - 399) / 400; - auto const yoe = static_cast(y - era * 400); // [0, 399] - auto const doy = (153 * (m > 2 ? m - 3 : m + 9) + 2) / 5 + d - 1; // [0, 365] - auto const doe = yoe * 365 + yoe / 4 - yoe / 100 + doy; // [0, 146096] - return days{era * 146097 + static_cast(doe) - 719468 - - DIFFDAYS_BETWEEN_UNIXEPOCH_AND_PGEPOCH}; -} - -CONSTCD14 -inline year_month_day_pg::operator sys_days() const NOEXCEPT { return sys_days{to_days()}; } - -CONSTCD14 -inline year_month_day_pg::operator local_days() const NOEXCEPT { - return local_days{to_days()}; -} - -CONSTCD14 -inline bool year_month_day_pg::ok() const NOEXCEPT { - if (!(y_.ok() && m_.ok())) return false; - return date::day{1} <= d_ && d_ <= (y_ / m_ / last).day(); -} - -CONSTCD11 -inline bool operator==(const year_month_day_pg& x, const year_month_day_pg& y) NOEXCEPT { - return x.year() == y.year() && x.month() == y.month() && x.day() == y.day(); -} - -CONSTCD11 -inline bool operator!=(const year_month_day_pg& x, const year_month_day_pg& y) NOEXCEPT { - return !(x == y); -} - -CONSTCD11 -inline bool operator<(const year_month_day_pg& x, const year_month_day_pg& y) NOEXCEPT { - return x.year() < y.year() - ? true - : (x.year() > y.year() - ? false - : (x.month() < y.month() - ? true - : (x.month() > y.month() ? false : (x.day() < y.day())))); -} - -CONSTCD11 -inline bool operator>(const year_month_day_pg& x, const year_month_day_pg& y) NOEXCEPT { - return y < x; -} - -CONSTCD11 -inline bool operator<=(const year_month_day_pg& x, const year_month_day_pg& y) NOEXCEPT { - return !(y < x); -} - -CONSTCD11 -inline bool operator>=(const year_month_day_pg& x, const year_month_day_pg& y) NOEXCEPT { - return !(x < y); -} - -template -inline std::basic_ostream& operator<<( - std::basic_ostream& os, const year_month_day_pg& ymd) { - detail::save_ostream _(os); - os.fill('0'); - os.flags(std::ios::dec | std::ios::right); - os.imbue(std::locale::classic()); - os << static_cast(ymd.year()) << '-'; - os.width(2); - os << static_cast(ymd.month()) << '-'; - os.width(2); - os << static_cast(ymd.day()); - if (!ymd.ok()) os << " is not a valid year_month_day"; - return os; -} - -CONSTCD14 -inline year_month_day_pg year_month_day_pg::from_days(days dp) NOEXCEPT { - static_assert(std::numeric_limits::digits >= 18, - "This algorithm has not been ported to a 16 bit unsigned integer"); - static_assert(std::numeric_limits::digits >= 20, - "This algorithm has not been ported to a 16 bit signed integer"); - auto const z = dp.count() + 719468 + DIFFDAYS_BETWEEN_UNIXEPOCH_AND_PGEPOCH; - auto const era = (z >= 0 ? z : z - 146096) / 146097; - auto const doe = static_cast(z - era * 146097); // [0, 146096] - auto const yoe = (doe - doe / 1460 + doe / 36524 - doe / 146096) / 365; // [0, 399] - auto const y = static_cast(yoe) + era * 400; - auto const doy = doe - (365 * yoe + yoe / 4 - yoe / 100); // [0, 365] - auto const mp = (5 * doy + 2) / 153; // [0, 11] - auto const d = doy - (153 * mp + 2) / 5 + 1; // [1, 31] - auto const m = mp < 10 ? mp + 3 : mp - 9; // [1, 12] - return year_month_day_pg{date::year{y + (m <= 2)}, date::month(m), date::day(d)}; -} - -template -CONSTCD14 -inline -year_month_day_pg -operator+(const year_month_day_pg& ymd, const months& dm) NOEXCEPT { - return (ymd.year() / ymd.month() + dm) / ymd.day(); -} - -template -CONSTCD14 -inline -year_month_day_pg -operator+(const months& dm, const year_month_day_pg& ymd) NOEXCEPT { - return ymd + dm; -} - -template -CONSTCD14 -inline -year_month_day_pg -operator-(const year_month_day_pg& ymd, const months& dm) NOEXCEPT { - return ymd + (-dm); -} - -CONSTCD11 -inline -year_month_day_pg -operator+(const year_month_day_pg& ymd, const years& dy) NOEXCEPT { - return (ymd.year() + dy) / ymd.month() / ymd.day(); -} - -CONSTCD11 -inline -year_month_day_pg -operator+(const years& dy, const year_month_day_pg& ymd) NOEXCEPT { - return ymd + dy; -} - -CONSTCD11 -inline -year_month_day_pg -operator-(const year_month_day_pg& ymd, const years& dy) NOEXCEPT { - return ymd + (-dy); -} - // year_month_weekday CONSTCD11