Skip to content

Commit c48e81e

Browse files
authored
GH-48593: [C++] C++20: use standard calendar / timezone APIs (#48601)
### Rationale for this change Switch to std::chrono for MSVC to be able to use the system-provided timezone automatically on Windows. ### What changes are included in this PR? This adds `chrono_internal.h` that uses C++20 std::chrono timezone/calendar APIs on compilers with support (MSVC only for now) and falls back to vendored `date.h` otherwise. ### Are these changes tested? Partially tested locally and partially to be tested on CI. ### Are there any user-facing changes? Yes, Windows users will no longer need to install the IANA tzdb (see [instructions here](https://arrow.apache.org/docs/cpp/build_system.html#runtime-dependencies) and [here](https://arrow.apache.org/docs/python/install.html#tzdata-on-windows)). We possibly have tzdb download set up in CI too and should update it appropriately. * GitHub Issue: #48593 Authored-by: Rok Mihevc <rok@mihevc.org> Signed-off-by: Raúl Cumplido <raulcumplido@gmail.com>
1 parent 3ff230c commit c48e81e

38 files changed

Lines changed: 598 additions & 270 deletions

.github/workflows/cpp.yml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -367,8 +367,13 @@ jobs:
367367
export CMAKE_BUILD_PARALLEL_LEVEL=$NUMBER_OF_PROCESSORS
368368
ci/scripts/cpp_build.sh "$(pwd)" "$(pwd)/build"
369369
- name: Download Timezone Database
370+
if: matrix.msystem_upper == 'CLANG64'
370371
shell: bash
371-
run: ci/scripts/download_tz_database.sh
372+
run: |
373+
# TODO(GH-48593): msys2 clang64 uses libc++ and vendored date.h library
374+
# which needs tzdata database to build Arrow with time zone support.
375+
# https://github.com/apache/arrow/issues/48593
376+
ci/scripts/download_tz_database.sh
372377
- name: Download MinIO
373378
shell: msys2 {0}
374379
run: |

.github/workflows/cpp_windows.yml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,9 +86,6 @@ jobs:
8686
with:
8787
fetch-depth: 0
8888
submodules: recursive
89-
- name: Download Timezone Database
90-
shell: bash
91-
run: ci/scripts/download_tz_database.sh
9289
- name: Install msys2 (for tzdata for ORC tests)
9390
uses: msys2/setup-msys2@v2
9491
id: setup-msys2

.github/workflows/matlab.yml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -147,9 +147,6 @@ jobs:
147147
uses: matlab-actions/setup-matlab@v2
148148
with:
149149
release: R2025b
150-
- name: Download Timezone Database
151-
shell: bash
152-
run: ci/scripts/download_tz_database.sh
153150
- name: Install ccache
154151
shell: bash
155152
run: ci/scripts/install_ccache.sh 4.6.3 /usr

.github/workflows/r.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,12 @@ jobs:
277277
mkdir -p "$HOME/.local/bin"
278278
ci/scripts/install_minio.sh latest "$HOME/.local"
279279
echo "$HOME/.local/bin" >> $GITHUB_PATH
280+
- name: Download Timezone Database
281+
shell: bash
282+
run: |
283+
# RTools 40 uses GCC 8.x which does not support C++20 chrono timezones,
284+
# so Arrow uses the vendored date library which requires tzdata
285+
ci/scripts/download_tz_database.sh
280286
- run: mkdir r/windows
281287
- name: Download artifacts
282288
uses: actions/download-artifact@v8

ci/conda_env_gandiva_win.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,6 @@
1515
# specific language governing permissions and limitations
1616
# under the License.
1717

18-
# ARROW-17830 Temporarily pin LLVM version on Appveyor due to a bug in Conda's packaging of LLVM 15.
18+
# ARROW-17830 Temporarily pin LLVM version on Windows due to a bug in Conda's packaging of LLVM 15.
1919
clangdev<15
2020
llvmdev<15

ci/scripts/PKGBUILD

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,6 @@ source_dir="$ARROW_HOME"
5050
# Append `#commit=54b1b2f688e5e84b4c664b1e12a95f93b94ab2f3` to the URL to select a revision
5151
# source=("${source_dir}"::"git+https://github.com/apache/arrow")
5252
# sha256sums=("SKIP")
53-
# source_dir="${APPVEYOR_BUILD_FOLDER}/${source_dir}"
5453

5554
cpp_build_dir=build-${CARCH}-cpp
5655

ci/scripts/download_tz_database.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
set -ex
2121

2222
# Download database
23-
curl https://data.iana.org/time-zones/releases/tzdata2024b.tar.gz --output ~/Downloads/tzdata.tar.gz
23+
curl https://data.iana.org/time-zones/tzdata-latest.tar.gz --output ~/Downloads/tzdata.tar.gz
2424

2525
# Extract
2626
mkdir -p ~/Downloads/tzdata

cpp/src/arrow/compute/function_test.cc

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,11 +95,9 @@ TEST(FunctionOptions, Equality) {
9595
options.emplace_back(new StrptimeOptions("%Y", TimeUnit::type::MILLI, true));
9696
options.emplace_back(new StrptimeOptions("%Y", TimeUnit::type::NANO));
9797
options.emplace_back(new StrftimeOptions("%Y-%m-%dT%H:%M:%SZ", "C"));
98-
#ifndef _WIN32
9998
options.emplace_back(new AssumeTimezoneOptions(
10099
"Europe/Amsterdam", AssumeTimezoneOptions::Ambiguous::AMBIGUOUS_RAISE,
101100
AssumeTimezoneOptions::Nonexistent::NONEXISTENT_RAISE));
102-
#endif
103101
options.emplace_back(new PadOptions(5, " "));
104102
options.emplace_back(new PadOptions(10, "A"));
105103
options.emplace_back(new PadOptions(10, "A", false));

cpp/src/arrow/compute/kernels/scalar_cast_test.cc

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2358,15 +2358,7 @@ constexpr char kTimestampSecondsJson[] =
23582358
constexpr char kTimestampExtremeJson[] =
23592359
R"(["1677-09-20T00:00:59.123456", "2262-04-13T23:23:23.999999"])";
23602360

2361-
class CastTimezone : public ::testing::Test {
2362-
protected:
2363-
void SetUp() override {
2364-
#ifdef _WIN32
2365-
// Initialize timezone database on Windows
2366-
ASSERT_OK(InitTestTimezoneDatabase());
2367-
#endif
2368-
}
2369-
};
2361+
class CastTimezone : public ::testing::Test {};
23702362

23712363
TEST(Cast, TimestampToDate) {
23722364
// See scalar_temporal_test.cc
@@ -2595,6 +2587,11 @@ TEST(Cast, TimestampToTime) {
25952587
}
25962588

25972589
TEST_F(CastTimezone, ZonedTimestampToTime) {
2590+
// TODO(GH-48743): GCC libstdc++ has a bug with DST transitions
2591+
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116110
2592+
#if defined(_WIN32) && defined(__GNUC__) && !defined(__clang__)
2593+
GTEST_SKIP() << "Test triggers GCC libstdc++ bug (GH-48743).";
2594+
#endif
25982595
CheckCast(ArrayFromJSON(timestamp(TimeUnit::NANO, "Pacific/Marquesas"), kTimestampJson),
25992596
ArrayFromJSON(time64(TimeUnit::NANO), R"([
26002597
52259123456789, 50003999999999, 56480001001001, 65000000000000,

cpp/src/arrow/compute/kernels/scalar_temporal_binary.cc

Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
#include "arrow/util/checked_cast.h"
2828
#include "arrow/util/logging_internal.h"
2929
#include "arrow/util/time.h"
30-
#include "arrow/vendored/datetime.h"
3130

3231
namespace arrow {
3332

@@ -37,28 +36,30 @@ using internal::checked_pointer_cast;
3736
namespace compute {
3837
namespace internal {
3938

39+
namespace chrono = arrow::internal::chrono;
40+
4041
namespace {
4142

42-
using arrow_vendored::date::days;
43-
using arrow_vendored::date::floor;
44-
using arrow_vendored::date::hh_mm_ss;
45-
using arrow_vendored::date::local_days;
46-
using arrow_vendored::date::local_time;
47-
using arrow_vendored::date::sys_days;
48-
using arrow_vendored::date::sys_time;
49-
using arrow_vendored::date::trunc;
50-
using arrow_vendored::date::weekday;
51-
using arrow_vendored::date::weeks;
52-
using arrow_vendored::date::year_month_day;
53-
using arrow_vendored::date::year_month_weekday;
54-
using arrow_vendored::date::years;
55-
using arrow_vendored::date::literals::dec;
56-
using arrow_vendored::date::literals::jan;
57-
using arrow_vendored::date::literals::last;
58-
using arrow_vendored::date::literals::mon;
59-
using arrow_vendored::date::literals::sun;
60-
using arrow_vendored::date::literals::thu;
61-
using arrow_vendored::date::literals::wed;
43+
using chrono::days;
44+
using chrono::dec;
45+
using chrono::floor;
46+
using chrono::hh_mm_ss;
47+
using chrono::jan;
48+
using chrono::last;
49+
using chrono::local_days;
50+
using chrono::local_time;
51+
using chrono::mon;
52+
using chrono::sun;
53+
using chrono::sys_days;
54+
using chrono::sys_time;
55+
using chrono::thu;
56+
using chrono::trunc;
57+
using chrono::wed;
58+
using chrono::weekday;
59+
using chrono::weeks;
60+
using chrono::year_month_day;
61+
using chrono::year_month_weekday;
62+
using chrono::years;
6263
using internal::applicator::ScalarBinaryNotNullStatefulEqualTypes;
6364

6465
using DayOfWeekState = OptionsWrapper<DayOfWeekOptions>;

0 commit comments

Comments
 (0)