pitrou commented on code in PR #48601:
URL: https://github.com/apache/arrow/pull/48601#discussion_r2660768172
##########
cpp/src/arrow/compute/kernels/scalar_temporal_test.cc:
##########
@@ -38,6 +39,10 @@ using internal::StringFormatter;
namespace compute {
+TEST(ChronoConfig, LogChronoBackend) {
Review Comment:
Do we want to keep this?
##########
cpp/src/arrow/util/chrono_internal.h:
##########
@@ -0,0 +1,269 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+#pragma once
+
+/// \file chrono_internal.h
+/// \brief Abstraction layer for C++20 chrono calendar/timezone APIs
+///
+/// This header provides a unified interface for chrono calendar and timezone
+/// functionality. On compilers with full C++20 chrono support, it uses
+/// std::chrono. On other compilers, it falls back to the vendored Howard
Hinnant
+/// date library.
+///
+/// The main benefit is on Windows where std::chrono uses the system timezone
+/// database, eliminating the need for users to install IANA tzdata separately.
+
+#include <chrono>
+#include <string>
+#include <string_view>
+
+// Feature detection for C++20 chrono timezone support
+// We only enable for compilers with FULL support (not partial)
+//
https://en.cppreference.com/w/cpp/compiler_support/20.html#cpp_lib_chrono_201907L
+//
+// MSVC 19.29+ (VS16.10+): Full C++20 chrono support, uses Windows internal TZ
database.
+// GCC libstdc++ has a bug where DST state is incorrectly reset when a timezone
+// transitions between rule sets in tzdata.zi (e.g., Australia/Broken_Hill
around
+// 2000-02-29 23:23:24).
+// Until this is fixed, we use the vendored date.h library for GCC.
+
+#if defined(_MSC_VER) && defined(__cpp_lib_chrono) && __cpp_lib_chrono >=
201907L
+# define ARROW_USE_STD_CHRONO 1
+#else
+# define ARROW_USE_STD_CHRONO 0
+#endif
+
+#if ARROW_USE_STD_CHRONO
+// Use C++20 standard library chrono
+# include <format>
+# include <iterator>
+# include <ostream>
+#else
+// Use vendored Howard Hinnant date library
+# include "arrow/vendored/datetime.h"
+#endif
+
+namespace arrow::internal::chrono {
+
+#if ARROW_USE_STD_CHRONO
+
+// ============================================================================
+// C++20 std::chrono backend
+// ============================================================================
+
+// Duration types
+using days = std::chrono::days;
+using weeks = std::chrono::weeks;
+using months = std::chrono::months;
+using years = std::chrono::years;
+
+// Time point types
+template <typename Duration>
+using sys_time = std::chrono::sys_time<Duration>;
+using sys_days = std::chrono::sys_days;
+using sys_seconds = std::chrono::sys_seconds;
+
+template <typename Duration>
+using local_time = std::chrono::local_time<Duration>;
+using local_days = std::chrono::local_days;
+using local_seconds = std::chrono::local_seconds;
+
+// Calendar types
+using year = std::chrono::year;
+using month = std::chrono::month;
+using day = std::chrono::day;
+using weekday = std::chrono::weekday;
+using year_month_day = std::chrono::year_month_day;
+using year_month_weekday = std::chrono::year_month_weekday;
+
+template <typename Duration>
+using hh_mm_ss = std::chrono::hh_mm_ss<Duration>;
+
+// Timezone types
+using time_zone = std::chrono::time_zone;
+using sys_info = std::chrono::sys_info;
+using local_info = std::chrono::local_info;
+using choose = std::chrono::choose;
+
+template <typename Duration, typename TimeZonePtr = const time_zone*>
+using zoned_time = std::chrono::zoned_time<Duration, TimeZonePtr>;
+
+template <typename TimeZonePtr>
+using zoned_traits = std::chrono::zoned_traits<TimeZonePtr>;
+
+// Exceptions
+using nonexistent_local_time = std::chrono::nonexistent_local_time;
+using ambiguous_local_time = std::chrono::ambiguous_local_time;
+
+// Weekday constants
+using std::chrono::Monday;
+using std::chrono::Sunday;
+
+// Rounding functions
+using std::chrono::ceil;
+using std::chrono::floor;
+using std::chrono::round;
+
+// trunc (truncation toward zero) is not in std::chrono, only floor/ceil/round
+template <typename ToDuration, typename Rep, typename Period>
+constexpr ToDuration trunc(const std::chrono::duration<Rep, Period>& d) {
+ auto floored = std::chrono::floor<ToDuration>(d);
+ // floor rounds toward -infinity; for negative values with remainder, add 1
to get
+ // toward zero
+ if (d.count() < 0 && (d - floored).count() != 0) {
+ return floored + ToDuration{1};
+ }
+ return floored;
+}
+
+// Timezone lookup
+inline const time_zone* locate_zone(std::string_view tz_name) {
+ return std::chrono::locate_zone(tz_name);
+}
+
+inline const time_zone* current_zone() { return std::chrono::current_zone(); }
+
+// Formatting support - streams directly using C++20 std::vformat_to
+// Provides: direct streaming, stream state preservation, chaining, rich
format specifiers
+template <typename CharT, typename Traits, typename Duration, typename
TimeZonePtr>
+std::basic_ostream<CharT, Traits>& to_stream(
+ std::basic_ostream<CharT, Traits>& os, const CharT* fmt,
+ const std::chrono::zoned_time<Duration, TimeZonePtr>& zt) {
+ std::vformat_to(std::ostreambuf_iterator<CharT>(os), std::string("{:") + fmt
+ "}",
+ std::make_format_args(zt));
+ return os;
+}
+
+// Format a duration using strftime-like format specifiers
+// Converts "%H%M" style to C++20's "{:%H%M}" style and uses std::vformat
+template <typename Duration>
+std::string format(const char* fmt, const Duration& d) {
+ return std::vformat(std::string("{:") + fmt + "}", std::make_format_args(d));
+}
+
+// Literals namespace
+namespace literals {
Review Comment:
Is there any particular reason to expose this in a `literals` nested
namespace rather than in `chrono` itself?
##########
cpp/src/arrow/util/chrono_internal.h:
##########
@@ -0,0 +1,269 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+#pragma once
+
+/// \file chrono_internal.h
+/// \brief Abstraction layer for C++20 chrono calendar/timezone APIs
+///
+/// This header provides a unified interface for chrono calendar and timezone
+/// functionality. On compilers with full C++20 chrono support, it uses
+/// std::chrono. On other compilers, it falls back to the vendored Howard
Hinnant
+/// date library.
+///
+/// The main benefit is on Windows where std::chrono uses the system timezone
+/// database, eliminating the need for users to install IANA tzdata separately.
+
+#include <chrono>
+#include <string>
+#include <string_view>
+
+// Feature detection for C++20 chrono timezone support
+// We only enable for compilers with FULL support (not partial)
+//
https://en.cppreference.com/w/cpp/compiler_support/20.html#cpp_lib_chrono_201907L
+//
+// MSVC 19.29+ (VS16.10+): Full C++20 chrono support, uses Windows internal TZ
database.
+// GCC libstdc++ has a bug where DST state is incorrectly reset when a timezone
+// transitions between rule sets in tzdata.zi (e.g., Australia/Broken_Hill
around
+// 2000-02-29 23:23:24).
+// Until this is fixed, we use the vendored date.h library for GCC.
+
+#if defined(_MSC_VER) && defined(__cpp_lib_chrono) && __cpp_lib_chrono >=
201907L
+# define ARROW_USE_STD_CHRONO 1
+#else
+# define ARROW_USE_STD_CHRONO 0
+#endif
+
+#if ARROW_USE_STD_CHRONO
+// Use C++20 standard library chrono
+# include <format>
+# include <iterator>
+# include <ostream>
+#else
+// Use vendored Howard Hinnant date library
+# include "arrow/vendored/datetime.h"
+#endif
+
+namespace arrow::internal::chrono {
+
+#if ARROW_USE_STD_CHRONO
+
+// ============================================================================
+// C++20 std::chrono backend
+// ============================================================================
+
+// Duration types
+using days = std::chrono::days;
+using weeks = std::chrono::weeks;
+using months = std::chrono::months;
+using years = std::chrono::years;
+
+// Time point types
+template <typename Duration>
+using sys_time = std::chrono::sys_time<Duration>;
+using sys_days = std::chrono::sys_days;
+using sys_seconds = std::chrono::sys_seconds;
+
+template <typename Duration>
+using local_time = std::chrono::local_time<Duration>;
+using local_days = std::chrono::local_days;
+using local_seconds = std::chrono::local_seconds;
+
+// Calendar types
+using year = std::chrono::year;
+using month = std::chrono::month;
+using day = std::chrono::day;
+using weekday = std::chrono::weekday;
+using year_month_day = std::chrono::year_month_day;
+using year_month_weekday = std::chrono::year_month_weekday;
+
+template <typename Duration>
+using hh_mm_ss = std::chrono::hh_mm_ss<Duration>;
+
+// Timezone types
+using time_zone = std::chrono::time_zone;
+using sys_info = std::chrono::sys_info;
+using local_info = std::chrono::local_info;
+using choose = std::chrono::choose;
+
+template <typename Duration, typename TimeZonePtr = const time_zone*>
+using zoned_time = std::chrono::zoned_time<Duration, TimeZonePtr>;
+
+template <typename TimeZonePtr>
+using zoned_traits = std::chrono::zoned_traits<TimeZonePtr>;
+
+// Exceptions
+using nonexistent_local_time = std::chrono::nonexistent_local_time;
+using ambiguous_local_time = std::chrono::ambiguous_local_time;
+
+// Weekday constants
+using std::chrono::Monday;
+using std::chrono::Sunday;
+
+// Rounding functions
+using std::chrono::ceil;
+using std::chrono::floor;
+using std::chrono::round;
+
+// trunc (truncation toward zero) is not in std::chrono, only floor/ceil/round
+template <typename ToDuration, typename Rep, typename Period>
+constexpr ToDuration trunc(const std::chrono::duration<Rep, Period>& d) {
+ auto floored = std::chrono::floor<ToDuration>(d);
+ // floor rounds toward -infinity; for negative values with remainder, add 1
to get
+ // toward zero
+ if (d.count() < 0 && (d - floored).count() != 0) {
+ return floored + ToDuration{1};
+ }
+ return floored;
+}
+
+// Timezone lookup
+inline const time_zone* locate_zone(std::string_view tz_name) {
+ return std::chrono::locate_zone(tz_name);
+}
+
+inline const time_zone* current_zone() { return std::chrono::current_zone(); }
+
+// Formatting support - streams directly using C++20 std::vformat_to
+// Provides: direct streaming, stream state preservation, chaining, rich
format specifiers
+template <typename CharT, typename Traits, typename Duration, typename
TimeZonePtr>
+std::basic_ostream<CharT, Traits>& to_stream(
+ std::basic_ostream<CharT, Traits>& os, const CharT* fmt,
+ const std::chrono::zoned_time<Duration, TimeZonePtr>& zt) {
+ std::vformat_to(std::ostreambuf_iterator<CharT>(os), std::string("{:") + fmt
+ "}",
+ std::make_format_args(zt));
+ return os;
+}
+
+// Format a duration using strftime-like format specifiers
+// Converts "%H%M" style to C++20's "{:%H%M}" style and uses std::vformat
+template <typename Duration>
+std::string format(const char* fmt, const Duration& d) {
+ return std::vformat(std::string("{:") + fmt + "}", std::make_format_args(d));
+}
+
+// Literals namespace
+namespace literals {
+// Month literals
+inline constexpr std::chrono::month jan = std::chrono::January;
+inline constexpr std::chrono::month dec = std::chrono::December;
+
+// Weekday literals
+inline constexpr std::chrono::weekday sun = std::chrono::Sunday;
+inline constexpr std::chrono::weekday mon = std::chrono::Monday;
+inline constexpr std::chrono::weekday wed = std::chrono::Wednesday;
+inline constexpr std::chrono::weekday thu = std::chrono::Thursday;
Review Comment:
I'm curious, why expose only a subset of them?
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]