Timedelta ========= .. cpp:class:: pandas::Timedelta pandas C++ class. Example ------- .. code-block:: cpp #include using namespace pandas; // Use Timedelta Timedelta obj; // ... operations ... Constructors ------------ .. list-table:: :widths: 55 25 20 :header-rows: 1 * - Signature - Location - Example * - ``explicit Timedelta(int64_t nanoseconds)`` - pd_timedelta.h:340 - :ref:`View ` * - ``explicit Timedelta(const std::string& duration_string)`` - pd_timedelta.h:360 - :ref:`View ` * - ``Timedelta(int64_t value, const std::string& unit)`` - pd_timedelta.h:371 - :ref:`View ` * - ``explicit Timedelta(const numpy::timedelta64& td)`` - pd_timedelta.h:383 - :ref:`View ` * - ``explicit Timedelta(const std::chrono::duration& dur)`` - pd_timedelta.h:419 - :ref:`View ` Construction ------------ .. list-table:: :widths: 40 20 15 25 :header-rows: 1 * - Signature - Return Type - Location - Example * - ``static Timedelta from_string(const std::string& s) { return Timedelta(s)`` - static Timedelta - pd_timedelta.h:366 - :ref:`View ` * - ``static Timedelta from_value(double value, const std::string& unit)`` - static Timedelta - pd_timedelta.h:378 - :ref:`View ` Statistics ---------- .. list-table:: :widths: 40 20 15 25 :header-rows: 1 * - Signature - Return Type - Location - Example * - ``static Timedelta max()`` - static Timedelta - pd_timedelta.h:438 - :ref:`View ` * - ``static Timedelta min()`` - static Timedelta - pd_timedelta.h:434 - :ref:`View ` * - ``int32_t minutes() const`` - int32_t - pd_timedelta.h:481 - :ref:`View ` Arithmetic ---------- .. list-table:: :widths: 40 20 15 25 :header-rows: 1 * - Signature - Return Type - Location - Example * - ``std::pair divmod(const Timedelta& other) const`` - std::pair - pd_timedelta.h:996 - :ref:`View ` Combining --------- .. list-table:: :widths: 40 20 15 25 :header-rows: 1 * - Signature - Return Type - Location - Example * - ``static void appendFractionalNanos(std::ostringstream& oss, int64_t frac)`` - static void - pd_timedelta.h:611 - * - ``appendFractionalNanos(oss, frac)`` - - pd_timedelta.h:647 - * - ``appendFractionalNanos(oss, frac)`` - - pd_timedelta.h:679 - I/O --- .. list-table:: :widths: 40 20 15 25 :header-rows: 1 * - Signature - Return Type - Location - Example * - ``std::chrono::nanoseconds to_chrono() const`` - std::chrono::nanoseconds - pd_timedelta.h:586 - :ref:`View ` * - ``Duration to_chrono_duration() const`` - Duration - pd_timedelta.h:595 - :ref:`View ` * - ``int64_t to_numpy(const std::string& dtype = "numpy::timedelta64[ns]", bool copy = false) const`` - int64_t - pd_timedelta.h:579 - :ref:`View ` * - ``numpy::timedelta64 to_timedelta64(numpy::DateTimeUnit unit = numpy::DateTimeUnit::Nanosecond) const`` - numpy::timedelta64 - pd_timedelta.h:548 - :ref:`View ` Other Methods ------------- .. list-table:: :widths: 40 20 15 25 :header-rows: 1 * - Signature - Return Type - Location - Example * - ``static Timedelta NaT()`` - static Timedelta - pd_timedelta.h:428 - :ref:`View ` * - ``Timedelta abs() const`` - Timedelta - pd_timedelta.h:1006 - :ref:`View ` * - ``Timedelta as_unit(const std::string& unit, bool round_ok = true) const`` - Timedelta - pd_timedelta.h:828 - :ref:`View ` * - ``Timedelta ceil(const std::string& freq, const std::string& ambiguous = "raise", const std::string& nonexistent = "raise") const`` - Timedelta - pd_timedelta.h:775 - :ref:`View ` * - ``int64_t components_days() const { return days()`` - int64_t - pd_timedelta.h:512 - :ref:`View ` * - ``std::string components_str() const`` - std::string - pd_timedelta.h:738 - :ref:`View ` * - ``void computeComponents() const`` - void - pd_timedelta.h:69 - * - ``int64_t days() const`` - int64_t - pd_timedelta.h:469 - :ref:`View ` * - ``int64_t delta() const`` - int64_t - pd_timedelta.h:464 - :ref:`View ` * - ``Timedelta floor(const std::string& freq, const std::string& ambiguous = "raise", const std::string& nonexistent = "raise") const`` - Timedelta - pd_timedelta.h:757 - :ref:`View ` * - ``int64_t floor_divide(const Timedelta& other) const`` - int64_t - pd_timedelta.h:980 - * - ``Timedelta floor_divide(int64_t scalar) const`` - Timedelta - pd_timedelta.h:988 - * - ``std::string frac_str(buf)`` - std::string - pd_timedelta.h:615 - * - ``int32_t hours() const`` - int32_t - pd_timedelta.h:475 - :ref:`View ` * - ``void invalidateCache()`` - void - pd_timedelta.h:65 - * - ``bool isNaT() const`` - bool - pd_timedelta.h:450 - :ref:`View ` * - ``std::string isoformat() const`` - std::string - pd_timedelta.h:687 - :ref:`View ` * - ``int32_t microseconds() const`` - int32_t - pd_timedelta.h:499 - :ref:`View ` * - ``int32_t milliseconds() const`` - int32_t - pd_timedelta.h:493 - :ref:`View ` * - ``int32_t nanoseconds() const`` - int32_t - pd_timedelta.h:505 - :ref:`View ` * - ``static int64_t parseDurationString(const std::string& s)`` - static int64_t - pd_timedelta.h:165 - * - ``static int64_t parseFrequencyToNanos(const std::string& freq)`` - static int64_t - pd_timedelta.h:103 - * - ``static int64_t parseISO8601Duration(const std::string& input)`` - static int64_t - pd_timedelta.h:116 - * - ``static Timedelta resolution()`` - static Timedelta - pd_timedelta.h:442 - :ref:`View ` * - ``Timedelta round(const std::string& freq, const std::string& ambiguous = "raise", const std::string& nonexistent = "raise") const`` - Timedelta - pd_timedelta.h:796 - :ref:`View ` * - ``std::string s_str(buf)`` - std::string - pd_timedelta.h:717 - :ref:`View ` * - ``int32_t seconds() const`` - int32_t - pd_timedelta.h:487 - :ref:`View ` * - ``std::istringstream ss(input)`` - std::istringstream - pd_timedelta.h:237 - :ref:`View ` * - ``std::string toString() const`` - std::string - pd_timedelta.h:626 - :ref:`View ` * - ``double total_days() const`` - double - pd_timedelta.h:533 - :ref:`View ` * - ``double total_hours() const`` - double - pd_timedelta.h:528 - :ref:`View ` * - ``double total_minutes() const`` - double - pd_timedelta.h:523 - :ref:`View ` * - ``double total_nanoseconds() const`` - double - pd_timedelta.h:538 - * - ``double total_seconds() const`` - double - pd_timedelta.h:518 - :ref:`View ` * - ``int64_t value() const`` - int64_t - pd_timedelta.h:459 - :ref:`View ` Code Examples ------------- The following examples are extracted from the test suite. .. _example-timedelta-timedelta-0: .. dropdown:: Timedelta (pd_test_5_all.cpp:25576) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 25566 :emphasize-lines: 11 apply_default_display(df); check_str("case_38.datetime_with_nat_site4", EXPECTED_case_38_datetime_with_nat_site4, df.to_string(), local_fail); } void f_set_index_col_multiindex_display_10_507319_case_39_timedelta_site3(int& local_fail) { std::cout << "----- case_39_timedelta_site3 -----\n"; pandas::DataFrame df; std::vector tds = { pandas::Timedelta("1 days"), pandas::Timedelta("2 days"), pandas::Timedelta("-1 days"), pandas::Timedelta("3 days"), }; df.add_column("td", tds); df.set_columns_levels({{"G"}, {"td"}}, {"top", "leaf"}); df.set_multiindex(make_mi_ab_short()); apply_default_display(df); check_str("case_39.timedelta_site3", EXPECTED_case_39_timedelta_site3, .. _example-timedelta-timedelta-1: .. dropdown:: Timedelta (pd_test_5_all.cpp:25576) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 25566 :emphasize-lines: 11 apply_default_display(df); check_str("case_38.datetime_with_nat_site4", EXPECTED_case_38_datetime_with_nat_site4, df.to_string(), local_fail); } void f_set_index_col_multiindex_display_10_507319_case_39_timedelta_site3(int& local_fail) { std::cout << "----- case_39_timedelta_site3 -----\n"; pandas::DataFrame df; std::vector tds = { pandas::Timedelta("1 days"), pandas::Timedelta("2 days"), pandas::Timedelta("-1 days"), pandas::Timedelta("3 days"), }; df.add_column("td", tds); df.set_columns_levels({{"G"}, {"td"}}, {"top", "leaf"}); df.set_multiindex(make_mi_ab_short()); apply_default_display(df); check_str("case_39.timedelta_site3", EXPECTED_case_39_timedelta_site3, .. _example-timedelta-timedelta-2: .. dropdown:: Timedelta (pd_test_5_all.cpp:25576) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 25566 :emphasize-lines: 11 apply_default_display(df); check_str("case_38.datetime_with_nat_site4", EXPECTED_case_38_datetime_with_nat_site4, df.to_string(), local_fail); } void f_set_index_col_multiindex_display_10_507319_case_39_timedelta_site3(int& local_fail) { std::cout << "----- case_39_timedelta_site3 -----\n"; pandas::DataFrame df; std::vector tds = { pandas::Timedelta("1 days"), pandas::Timedelta("2 days"), pandas::Timedelta("-1 days"), pandas::Timedelta("3 days"), }; df.add_column("td", tds); df.set_columns_levels({{"G"}, {"td"}}, {"top", "leaf"}); df.set_multiindex(make_mi_ab_short()); apply_default_display(df); check_str("case_39.timedelta_site3", EXPECTED_case_39_timedelta_site3, .. _example-timedelta-timedelta-3: .. dropdown:: Timedelta (pd_test_5_all.cpp:25576) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 25566 :emphasize-lines: 11 apply_default_display(df); check_str("case_38.datetime_with_nat_site4", EXPECTED_case_38_datetime_with_nat_site4, df.to_string(), local_fail); } void f_set_index_col_multiindex_display_10_507319_case_39_timedelta_site3(int& local_fail) { std::cout << "----- case_39_timedelta_site3 -----\n"; pandas::DataFrame df; std::vector tds = { pandas::Timedelta("1 days"), pandas::Timedelta("2 days"), pandas::Timedelta("-1 days"), pandas::Timedelta("3 days"), }; df.add_column("td", tds); df.set_columns_levels({{"G"}, {"td"}}, {"top", "leaf"}); df.set_multiindex(make_mi_ab_short()); apply_default_display(df); check_str("case_39.timedelta_site3", EXPECTED_case_39_timedelta_site3, .. _example-timedelta-timedelta-4: .. dropdown:: Timedelta (pd_test_5_all.cpp:25576) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 25566 :emphasize-lines: 11 apply_default_display(df); check_str("case_38.datetime_with_nat_site4", EXPECTED_case_38_datetime_with_nat_site4, df.to_string(), local_fail); } void f_set_index_col_multiindex_display_10_507319_case_39_timedelta_site3(int& local_fail) { std::cout << "----- case_39_timedelta_site3 -----\n"; pandas::DataFrame df; std::vector tds = { pandas::Timedelta("1 days"), pandas::Timedelta("2 days"), pandas::Timedelta("-1 days"), pandas::Timedelta("3 days"), }; df.add_column("td", tds); df.set_columns_levels({{"G"}, {"td"}}, {"top", "leaf"}); df.set_multiindex(make_mi_ab_short()); apply_default_display(df); check_str("case_39.timedelta_site3", EXPECTED_case_39_timedelta_site3, .. _example-timedelta-from_string-5: .. dropdown:: from_string (pd_test_3_all.cpp:10837) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 10827 :emphasize-lines: 11 const auto& s1 = df.column("A"); const auto& s2 = df.col("A"); if (s1.size() != s2.size() || s1[0] != s2[0]) { std::cout << " [FAIL] : in pd_test_3_all_column_alias() : mismatch" << std::endl; throw std::runtime_error("pd_test_3_all_column_alias failed"); } std::cout << " -> tests passed" << std::endl; } void pd_test_3_all_timedelta_from_string() { std::cout << "========= Timedelta::from_string() ======================"; auto td1 = pandas::Timedelta::from_string("1 days"); pandas::Timedelta td2("1 days"); if (td1.value() != td2.value()) { std::cout << " [FAIL] : in pd_test_3_all_timedelta_from_string() : mismatch" << std::endl; throw std::runtime_error("pd_test_3_all_timedelta_from_string failed"); } std::cout << " -> tests passed" << std::endl; } void pd_test_3_all_replace_int() { .. _example-timedelta-from_value-6: .. dropdown:: from_value (pd_test_timedelta_scalar.cpp:158) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 148 :emphasize-lines: 11 std::cout << " Timedelta(2, 'W') = " << td_week.days() << " days" << std::endl; if (td_week.days() != 14) { std::cout << "[FAIL] np_test_timedelta_constructors: Timedelta(2, 'W') expected 14 days, got " << td_week.days() << std::endl; errors++; } } // From value and unit - static factory for fractional values { pandas::Timedelta td_frac = pandas::Timedelta::from_value(1.5, "h"); // 1.5 hours = 90 minutes std::cout << " Timedelta::from_value(1.5, 'h') = " << td_frac.total_minutes() << " minutes" << std::endl; if (std::abs(td_frac.total_minutes() - 90.0) > 0.0001) { std::cout << "[FAIL] np_test_timedelta_constructors: from_value(1.5, 'h') expected 90 minutes, got " << td_frac.total_minutes() << std::endl; errors++; } pandas::Timedelta td_frac2 = pandas::Timedelta::from_value(0.5, "D"); // 0.5 days = 12 hours std::cout << " Timedelta::from_value(0.5, 'D') = " << td_frac2.total_hours() << " hours" << std::endl; if (std::abs(td_frac2.total_hours() - 12.0) > 0.0001) { .. _example-timedelta-max-7: .. dropdown:: max (pd_test_1_all.cpp:771) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 761 :emphasize-lines: 11 pandas::CategoricalArray arr = pandas::CategoricalArray::from_codes(codes, cats, true); // ordered // Test min std::optional min_val = arr.min(); if (!min_val.has_value() || *min_val != "low") { std::cout << " [FAIL] : in pd_test_categorical_array_ordered_operations() : min != 'low'" << std::endl; throw std::runtime_error("pd_test_categorical_array_ordered_operations failed: min != 'low'"); } // Test max std::optional max_val = arr.max(); if (!max_val.has_value() || *max_val != "high") { std::cout << " [FAIL] : in pd_test_categorical_array_ordered_operations() : max != 'high'" << std::endl; throw std::runtime_error("pd_test_categorical_array_ordered_operations failed: max != 'high'"); } // Test unordered throws for min/max pandas::CategoricalArray unordered = arr.as_unordered(); bool threw = false; try { unordered.min(); .. _example-timedelta-min-8: .. dropdown:: min (pd_test_1_all.cpp:764) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 754 :emphasize-lines: 11 } void pd_test_categorical_array_ordered_operations() { std::cout << "========= CategoricalArray: ordered operations (min/max) ======================= "; std::vector cats = {"low", "medium", "high"}; std::vector codes = {0, 2, 1, 0, -1}; // low, high, medium, low, NA pandas::CategoricalArray arr = pandas::CategoricalArray::from_codes(codes, cats, true); // ordered // Test min std::optional min_val = arr.min(); if (!min_val.has_value() || *min_val != "low") { std::cout << " [FAIL] : in pd_test_categorical_array_ordered_operations() : min != 'low'" << std::endl; throw std::runtime_error("pd_test_categorical_array_ordered_operations failed: min != 'low'"); } // Test max std::optional max_val = arr.max(); if (!max_val.has_value() || *max_val != "high") { std::cout << " [FAIL] : in pd_test_categorical_array_ordered_operations() : max != 'high'" << std::endl; throw std::runtime_error("pd_test_categorical_array_ordered_operations failed: max != 'high'"); .. _example-timedelta-minutes-9: .. dropdown:: minutes (pd_test_3_all.cpp:21614) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 21604 :emphasize-lines: 11 } if (d.months() != 2) { throw std::runtime_error("DateOffset: months mismatch"); } if (d.days() != 5) { throw std::runtime_error("DateOffset: days mismatch"); } if (d.hours() != 3) { throw std::runtime_error("DateOffset: hours mismatch"); } if (d.minutes() != 30) { throw std::runtime_error("DateOffset: minutes mismatch"); } if (d.seconds() != 10) { throw std::runtime_error("DateOffset: seconds mismatch"); } std::cout << " -> tests passed" << std::endl; } void test_yearend_freqstr() { .. _example-timedelta-divmod-10: .. dropdown:: divmod (pd_test_3_all.cpp:12077) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 12067 :emphasize-lines: 11 auto cov_val = s1.cov(s2); if (!cov_val.has_value()) { std::cout << " [FAIL] : covariance should have a value" << std::endl; throw std::runtime_error("pd_test_series_corr_cov failed"); } std::cout << " -> tests passed" << std::endl; } // ============================================================================ // Test 9: divmod() // ============================================================================ void pd_test_series_divmod() { std::cout << "========= Series.divmod() =========================="; std::vector vals = {10.0, 20.0, 30.0}; pandas::Series s(vals, "test"); auto [quot, rem] = s.divmod(7.0); // 10/7 = 1 remainder 3 .. _example-timedelta-to_chrono-11: .. dropdown:: to_chrono (pd_test_timedelta_scalar.cpp:400) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 390 :emphasize-lines: 11 int64_t nanos = td.to_numpy(); if (nanos != pandas::Timedelta::NANOS_PER_DAY) { std::cout << "[FAIL] np_test_timedelta_conversions: to_numpy expected " << pandas::Timedelta::NANOS_PER_DAY << ", got " << nanos << std::endl; errors++; } } // to_chrono { std::chrono::nanoseconds dur = td.to_chrono(); if (dur.count() != pandas::Timedelta::NANOS_PER_DAY) { std::cout << "[FAIL] np_test_timedelta_conversions: to_chrono expected " << pandas::Timedelta::NANOS_PER_DAY << ", got " << dur.count() << std::endl; errors++; } } // to_chrono_duration { auto hrs = td.to_chrono_duration(); .. _example-timedelta-to_chrono_duration-12: .. dropdown:: to_chrono_duration (pd_test_timedelta_scalar.cpp:410) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 400 :emphasize-lines: 11 std::chrono::nanoseconds dur = td.to_chrono(); if (dur.count() != pandas::Timedelta::NANOS_PER_DAY) { std::cout << "[FAIL] np_test_timedelta_conversions: to_chrono expected " << pandas::Timedelta::NANOS_PER_DAY << ", got " << dur.count() << std::endl; errors++; } } // to_chrono_duration { auto hrs = td.to_chrono_duration(); if (hrs.count() != 24) { std::cout << "[FAIL] np_test_timedelta_conversions: to_chrono_duration expected 24, got " << hrs.count() << std::endl; errors++; } } if (errors == 0) { std::cout << "np_test_timedelta_conversions -> tests passed" << std::endl; } .. _example-timedelta-to_numpy-13: .. dropdown:: to_numpy (pd_test_1_all.cpp:16764) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 16754 :emphasize-lines: 11 // ===================================================================== // to_numpy Tests // ===================================================================== void pd_test_ndframe_to_numpy() { std::cout << "========= to_numpy =============================================" << std::endl; pandas::Series s({10, 20, 30}); auto arr = s.to_numpy(); bool passed = arr.getSize() == 3; if (!passed) { std::cout << " [FAIL] : in pd_test_ndframe_to_numpy() : size" << std::endl; throw std::runtime_error("pd_test_ndframe_to_numpy failed: size"); } passed = arr.getElementAt({0}) == 10 && arr.getElementAt({1}) == 20 && arr.getElementAt({2}) == 30; if (!passed) { std::cout << " [FAIL] : in pd_test_ndframe_to_numpy() : values" << std::endl; .. _example-timedelta-to_timedelta64-14: .. dropdown:: to_timedelta64 (pd_test_timedelta_scalar.cpp:370) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 360 :emphasize-lines: 11 // ============================================================================= // Test 5: Conversion Methods // ============================================================================= int np_test_timedelta_conversions() { int errors = 0; pandas::Timedelta td(1, 0, 0); // 1 day // to_timedelta64 with Day unit { numpy::timedelta64 td64 = td.to_timedelta64(numpy::DateTimeUnit::Day); if (td64.getValue() != 1) { std::cout << "[FAIL] np_test_timedelta_conversions: to_timedelta64(Day) expected 1, got " << td64.getValue() << std::endl; errors++; } } // to_timedelta64 with Hour unit { numpy::timedelta64 td64 = td.to_timedelta64(numpy::DateTimeUnit::Hour); .. _example-timedelta-nat-15: .. dropdown:: NaT (pd_test_1_all.cpp:1305) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 1295 :emphasize-lines: 11 pandas::DatetimeArray arr(std::vector{ "2023-06-15", "NaT", "2023-01-01", "2023-12-31" }); // argsort ascending auto indices = arr.argsort(true, "last"); // Expected order: 2023-01-01(2), 2023-06-15(0), 2023-12-31(3), NaT(1) if (indices.getElementAt({0}) != 2) { std::cout << " [FAIL] : argsort: first should be index 2 (2023-01-01)" << std::endl; throw std::runtime_error("pd_test_datetime_array_sorting failed: argsort first"); } if (indices.getElementAt({3}) != 1) { std::cout << " [FAIL] : argsort: last should be index 1 (NaT)" << std::endl; throw std::runtime_error("pd_test_datetime_array_sorting failed: NaT position"); } // argmin .. _example-timedelta-abs-16: .. dropdown:: abs (pd_test_1_all.cpp:283) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 273 :emphasize-lines: 11 std::optional(true) }); auto s = arr.sum(); if (!s.has_value() || s.value() != 3) { std::cout << " [FAIL] : in pd_test_boolean_array_reductions() : sum should be 3" << std::endl; throw std::runtime_error("pd_test_boolean_array_reductions failed: sum"); } auto m = arr.mean(); if (!m.has_value() || std::abs(m.value() - 0.75) > 0.001) { std::cout << " [FAIL] : in pd_test_boolean_array_reductions() : mean should be 0.75" << std::endl; throw std::runtime_error("pd_test_boolean_array_reductions failed: mean"); } std::cout << " -> tests passed" << std::endl; } void pd_test_boolean_array_dtype() { std::cout << "========= BooleanArray: dtype ======================= "; .. _example-timedelta-as_unit-17: .. dropdown:: as_unit (pd_test_1_all.cpp:9361) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 9351 :emphasize-lines: 11 data.setElementAt({1}, numpy::datetime64(2000000000LL, numpy::DateTimeUnit::Nanosecond)); // 2 seconds in ns numpy::NDArray mask(std::vector{2}); mask.setElementAt({0}, numpy::bool_(false)); mask.setElementAt({1}, numpy::bool_(false)); pandas::DatetimeArray arr(data, mask); pandas::DatetimeTDMixin idx(arr, "test"); // Convert to microseconds pandas::DatetimeTDMixin us_idx = idx.as_unit("us"); // Convert to same unit (should return identical) pandas::DatetimeTDMixin same_idx = idx.as_unit("ns"); bool passed = (us_idx.size() == 2 && same_idx.size() == 2 && us_idx.name().has_value() && *us_idx.name() == "test"); if (!passed) { std::cout << " [FAIL] : in pd_test_datetime_as_unit() : as_unit check failed" << std::endl; throw std::runtime_error("pd_test_datetime_as_unit failed"); } .. _example-timedelta-ceil-18: .. dropdown:: ceil (pd_test_1_all.cpp:4949) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 4939 :emphasize-lines: 11 throw std::runtime_error("pd_test_arithmetic_series_round failed: round failed"); } auto f = a.floor(); passed = std::abs(f[0] - 1.0) < 0.001 && std::abs(f[2] - 3.0) < 0.001 && std::abs(f[3] - (-2.0)) < 0.001; if (!passed) { std::cout << " [FAIL] : in pd_test_arithmetic_series_round() : floor failed" << std::endl; throw std::runtime_error("pd_test_arithmetic_series_round failed: floor failed"); } auto c = a.ceil(); passed = std::abs(c[0] - 2.0) < 0.001 && std::abs(c[2] - 4.0) < 0.001 && std::abs(c[3] - (-1.0)) < 0.001; if (!passed) { std::cout << " [FAIL] : in pd_test_arithmetic_series_round() : ceil failed" << std::endl; throw std::runtime_error("pd_test_arithmetic_series_round failed: ceil failed"); } // Round with decimals pandas::Series b({1.234, 2.567, 3.891}); auto r2 = b.round(2); passed = std::abs(r2[0] - 1.23) < 0.001 && std::abs(r2[1] - 2.57) < 0.001; .. _example-timedelta-components_days-19: .. dropdown:: components_days (pd_test_timedelta_scalar.cpp:282) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 272 :emphasize-lines: 11 if (td.nanoseconds() != 300) { std::cout << "[FAIL] np_test_timedelta_components: nanoseconds() expected 300, got " << td.nanoseconds() << std::endl; errors++; } } // Components alias { pandas::Timedelta td(5, 0, 0); if (td.components_days() != 5) { std::cout << "[FAIL] np_test_timedelta_components: components_days() expected 5, got " << td.components_days() << std::endl; errors++; } } if (errors == 0) { std::cout << "np_test_timedelta_components -> tests passed" << std::endl; } return errors; .. _example-timedelta-components_str-20: .. dropdown:: components_str (pd_test_timedelta_scalar.cpp:476) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 466 :emphasize-lines: 11 if (iso.find("P1D") == std::string::npos) { std::cout << "[FAIL] np_test_timedelta_strings: isoformat expected 'P1D...', got '" << iso << "'" << std::endl; errors++; } } // components_str { pandas::Timedelta td(1, 2, 30, 45, 100, 200, 300); std::string comp = td.components_str(); if (comp.find("days=1") == std::string::npos) { std::cout << "[FAIL] np_test_timedelta_strings: components_str missing days=1, got '" << comp << "'" << std::endl; errors++; } } if (errors == 0) { std::cout << "np_test_timedelta_strings -> tests passed" << std::endl; } .. _example-timedelta-days-21: .. dropdown:: days (pd_test_1_all.cpp:4160) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 4150 :emphasize-lines: 11 void pd_test_timedelta_array_component_days() { std::cout << "========= TimedeltaArray: days component ======================= "; pandas::TimedeltaArray arr({ std::optional(numpy::timedelta64(3, numpy::DateTimeUnit::Day)), std::nullopt, std::optional(numpy::timedelta64(36, numpy::DateTimeUnit::Hour)) // 1.5 days }); auto days_arr = arr.days(); auto d0 = days_arr[0]; if (!d0.has_value() || d0.value() != 3) { std::cout << " [FAIL] : days[0] should be 3" << std::endl; throw std::runtime_error("pd_test_timedelta_array_component_days failed: days[0]"); } auto d1 = days_arr[1]; if (d1.has_value()) { std::cout << " [FAIL] : days[1] should be NA (NaT)" << std::endl; .. _example-timedelta-delta-22: .. dropdown:: delta (pd_test_timedelta_scalar.cpp:345) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 335 :emphasize-lines: 11 // total_days { double days = td.total_days(); if (std::abs(days - 1.5) > 0.0001) { std::cout << "[FAIL] np_test_timedelta_total_conversions: total_days expected 1.5, got " << days << std::endl; errors++; } } // value() and delta() { if (td.value() != td.delta()) { std::cout << "[FAIL] np_test_timedelta_total_conversions: value() != delta()" << std::endl; errors++; } } if (errors == 0) { std::cout << "np_test_timedelta_total_conversions -> tests passed" << std::endl; .. _example-timedelta-floor-23: .. dropdown:: floor (pd_test_1_all.cpp:4942) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 4932 :emphasize-lines: 11 pandas::Series a({1.4, 2.5, 3.6, -1.4, -2.5}); auto r = a.round(); bool passed = std::abs(r[0] - 1.0) < 0.001 && std::abs(r[2] - 4.0) < 0.001; if (!passed) { std::cout << " [FAIL] : in pd_test_arithmetic_series_round() : round failed" << std::endl; throw std::runtime_error("pd_test_arithmetic_series_round failed: round failed"); } auto f = a.floor(); passed = std::abs(f[0] - 1.0) < 0.001 && std::abs(f[2] - 3.0) < 0.001 && std::abs(f[3] - (-2.0)) < 0.001; if (!passed) { std::cout << " [FAIL] : in pd_test_arithmetic_series_round() : floor failed" << std::endl; throw std::runtime_error("pd_test_arithmetic_series_round failed: floor failed"); } auto c = a.ceil(); passed = std::abs(c[0] - 2.0) < 0.001 && std::abs(c[2] - 4.0) < 0.001 && std::abs(c[3] - (-1.0)) < 0.001; if (!passed) { std::cout << " [FAIL] : in pd_test_arithmetic_series_round() : ceil failed" << std::endl; .. _example-timedelta-hours-24: .. dropdown:: hours (pd_test_1_all.cpp:9567) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 9557 :emphasize-lines: 11 std::cout << std::endl << " [FAIL] : floor result incorrect"; passed = false; } // ceil should give 2 hours if (ceiled.total_seconds() != 7200.0) { std::cout << std::endl << " [FAIL] : ceil result incorrect"; passed = false; } // round should give 2 hours (30m45s > 30m) if (rounded.total_seconds() != 7200.0) { std::cout << std::endl << " [FAIL] : round result incorrect"; passed = false; } if (!passed) { throw std::runtime_error("pd_test_timedelta_rounding_params failed"); } std::cout << " -> tests passed" << std::endl; .. _example-timedelta-isnat-25: .. dropdown:: isNaT (pd_test_3_all.cpp:1523) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 1513 :emphasize-lines: 11 } // Case B: pandas::Timedelta == pandas::Timedelta { static_assert(std::is_same_v, "pandas::Timedelta must alias pandas::Timedelta"); } // Case C: pandas::NaT is a NaT-valued Timestamp { if (!pandas::NaT.isNaT()) { throw std::runtime_error("pandas::NaT is not a NaT value"); } pandas::Timestamp default_ts; if (default_ts.isNaT() != pandas::NaT.isNaT()) { throw std::runtime_error( "pandas::NaT and default Timestamp NaT-state mismatch"); } } // Case D: round-trip - reproduces the failing test pattern .. _example-timedelta-isoformat-26: .. dropdown:: isoformat (pd_test_timedelta_scalar.cpp:465) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 455 :emphasize-lines: 11 if (nat.toString() != "NaT") { std::cout << "[FAIL] np_test_timedelta_strings: toString(NaT) expected 'NaT', got '" << nat.toString() << "'" << std::endl; errors++; } } // isoformat { pandas::Timedelta td(1, 2, 30); std::string iso = td.isoformat(); if (iso.find("P1D") == std::string::npos) { std::cout << "[FAIL] np_test_timedelta_strings: isoformat expected 'P1D...', got '" << iso << "'" << std::endl; errors++; } } // components_str { pandas::Timedelta td(1, 2, 30, 45, 100, 200, 300); .. _example-timedelta-microseconds-27: .. dropdown:: microseconds (pd_test_1_all.cpp:19701) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 19691 :emphasize-lines: 11 constexpr int64_t NS_PER_US = 1000LL; std::vector> values = { make_td(0), // 0 us make_td(500 * NS_PER_US), // 500 us make_td(NS_PER_SEC + 100 * NS_PER_US) // 1 sec + 100 us }; pandas::TimedeltaArray arr(values); pandas::TimedeltaIndex idx(arr); auto microseconds = idx.microseconds(); bool passed = (microseconds.size() == 3); if (!passed) { std::cout << " [FAIL] : in pd_test_timedelta_index_microseconds()" << std::endl; throw std::runtime_error("pd_test_timedelta_index_microseconds failed"); } std::cout << " -> tests passed" << std::endl; } .. _example-timedelta-milliseconds-28: .. dropdown:: milliseconds (pd_test_2_all.cpp:10201) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 10191 :emphasize-lines: 11 #include #endif namespace dataframe_tests { namespace dataframe_tests_to_clipboard { // Helper function to get clipboard content (Windows only) #ifdef _WIN32 std::string get_clipboard_text() { // Add small delay to allow clipboard to stabilize std::this_thread::sleep_for(std::chrono::milliseconds(5)); if (!OpenClipboard(nullptr)) { return ""; } HANDLE hData = GetClipboardData(CF_TEXT); if (hData == nullptr) { CloseClipboard(); return ""; } .. _example-timedelta-nanoseconds-29: .. dropdown:: nanoseconds (pd_test_1_all.cpp:9379) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 9369 :emphasize-lines: 11 std::cout << " [FAIL] : in pd_test_datetime_as_unit() : as_unit check failed" << std::endl; throw std::runtime_error("pd_test_datetime_as_unit failed"); } std::cout << " -> tests passed" << std::endl; } void pd_test_timedelta_as_unit() { std::cout << "========= TimedeltaTDMixin as_unit ========================="; // Create index in nanoseconds (1 hour, 2 hours) numpy::NDArray data(std::vector{2}); data.setElementAt({0}, numpy::timedelta64(3600000000000LL, numpy::DateTimeUnit::Nanosecond)); // 1 hour data.setElementAt({1}, numpy::timedelta64(7200000000000LL, numpy::DateTimeUnit::Nanosecond)); // 2 hours numpy::NDArray mask(std::vector{2}); mask.setElementAt({0}, numpy::bool_(false)); mask.setElementAt({1}, numpy::bool_(false)); pandas::TimedeltaArray arr(data, mask); pandas::TimedeltaTDMixin idx(arr, "durations"); .. _example-timedelta-resolution-30: .. dropdown:: resolution (pd_test_1_all.cpp:15536) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 15526 :emphasize-lines: 11 } std::cout << " -> tests passed" << std::endl; } // ============================================================================ // Resolution Tests // ============================================================================ void pd_test_datetime_index_resolution() { std::cout << "========= DatetimeIndex resolution() ========================="; numpy::NDArray data(std::vector{1}); data.setElementAt({0}, numpy::datetime64(1000LL, numpy::DateTimeUnit::Nanosecond)); numpy::NDArray mask(std::vector{1}); mask.setElementAt({0}, numpy::bool_(false)); pandas::DatetimeArray arr(data, mask); pandas::DatetimeIndexBase idx(arr); .. _example-timedelta-round-31: .. dropdown:: round (pd_test_1_all.cpp:1688) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 1678 :emphasize-lines: 11 void pd_test_floating_array_rounding() { std::cout << "========= FloatingArray: rounding ======================= "; pandas::FloatingArray arr({ std::optional(1.234), std::optional(2.567), std::nullopt }); auto rounded = arr.round(2); if (std::abs(rounded[0].value() - 1.23) > 0.001 || std::abs(rounded[1].value() - 2.57) > 0.001) { std::cout << " [FAIL] : in pd_test_floating_array_rounding() : round(2)" << std::endl; throw std::runtime_error("pd_test_floating_array_rounding failed: round(2)"); } if (!rounded.is_na(2)) { std::cout << " [FAIL] : in pd_test_floating_array_rounding() : round should preserve NA" << std::endl; throw std::runtime_error("pd_test_floating_array_rounding failed: NA preservation"); } .. _example-timedelta-s_str-32: .. dropdown:: s_str (pd_test_5_all.cpp:83216) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 83206 :emphasize-lines: 11 } void case_7_type_mismatch_add(int& local_fail) { std::cout << "----- case_7_type_mismatch_add -----\n"; auto invoke = []() { // String -> "datetime64[ns, UTC]" routes through the // non-floating-point branch of astype's tz-datetime handling, // which throws pandas::TypeError via // error_messages::cannot_astype_convert (pd_series.h:7042). pandas::Series s_str({"a", "b", "c"}); (void)s_str.astype(std::string("datetime64[ns, UTC]")); }; bool caught_typed = false; bool caught_other = false; std::string other_what; try { invoke(); } catch (const pandas::TypeError&) { caught_typed = true; } catch (const std::exception& e) { caught_other = true; other_what = e.what(); } .. _example-timedelta-seconds-33: .. dropdown:: seconds (pd_test_1_all.cpp:4192) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 4182 :emphasize-lines: 11 void pd_test_timedelta_array_component_seconds() { std::cout << "========= TimedeltaArray: seconds component ======================= "; pandas::TimedeltaArray arr({ std::optional(numpy::timedelta64(90, numpy::DateTimeUnit::Second)), // 90 secs std::optional(numpy::timedelta64(3700, numpy::DateTimeUnit::Second)), // 1h + 100s std::nullopt }); auto secs = arr.seconds(); auto s0 = secs[0]; if (!s0.has_value() || s0.value() != 90) { std::cout << " [FAIL] : seconds[0] should be 90" << std::endl; throw std::runtime_error("pd_test_timedelta_array_component_seconds failed: seconds[0]"); } auto s1 = secs[1]; if (!s1.has_value() || s1.value() != 3700) { std::cout << " [FAIL] : seconds[1] should be 3700" << std::endl; .. _example-timedelta-ss-34: .. dropdown:: ss (pd_test_3_all.cpp:27670) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 27660 :emphasize-lines: 11 fail++; } else { auto cats = str_s->get_cat_categories(); if (cats.size() != 3) { std::cout << " FAIL: expected 3 categories, got " << cats.size() << std::endl; fail++; } } } pandas::Series ss({"a", "b", "a", "c"}, "strs"); auto result2 = ss.astype("category"); auto* str_s2 = dynamic_cast*>(result2.get()); if (!str_s2) { std::cout << " FAIL: expected Series for string->category" << std::endl; fail++; } else { if (str_s2->dtype_name() != "category") { std::cout << " FAIL: dtype should be category" << std::endl; fail++; } .. _example-timedelta-tostring-35: .. dropdown:: toString (pd_test_1_all.cpp:9539) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 9529 :emphasize-lines: 11 void pd_test_timedelta_rounding_params() { std::cout << "========= Timedelta rounding with DST params ====="; // Create a Timedelta: 1h 30m 45s // Constructor is: (days, hours, minutes, seconds, ...) pandas::Timedelta td(0, 1, 30, 45); // 0 days, 1h, 30m, 45s // Test floor with ambiguous/nonexistent params pandas::Timedelta floored = td.floor("h", "raise", "raise"); std::cout << std::endl << " floor('h'): " << floored.toString(); // Test ceil with ambiguous/nonexistent params pandas::Timedelta ceiled = td.ceil("h", "raise", "raise"); std::cout << std::endl << " ceil('h'): " << ceiled.toString(); // Test round with ambiguous/nonexistent params pandas::Timedelta rounded = td.round("h", "raise", "raise"); std::cout << std::endl << " round('h'): " << rounded.toString(); // Verify results: .. _example-timedelta-total_days-36: .. dropdown:: total_days (pd_test_timedelta_scalar.cpp:337) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 327 :emphasize-lines: 11 double hrs = td.total_hours(); if (std::abs(hrs - 36.0) > 0.0001) { std::cout << "[FAIL] np_test_timedelta_total_conversions: total_hours expected 36, got " << hrs << std::endl; errors++; } } // total_days { double days = td.total_days(); if (std::abs(days - 1.5) > 0.0001) { std::cout << "[FAIL] np_test_timedelta_total_conversions: total_days expected 1.5, got " << days << std::endl; errors++; } } // value() and delta() { if (td.value() != td.delta()) { .. _example-timedelta-total_hours-37: .. dropdown:: total_hours (pd_test_timedelta_scalar.cpp:69) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 59 :emphasize-lines: 11 << "got days=" << td.days() << " hours=" << td.hours() << " minutes=" << td.minutes() << std::endl; errors++; } } // From timedelta64 { numpy::timedelta64 td64(3600, numpy::DateTimeUnit::Second); // 1 hour pandas::Timedelta td(td64); if (std::abs(td.total_hours() - 1.0) > 0.0001) { std::cout << "[FAIL] np_test_timedelta_constructors: from timedelta64 expected 1 hour, got " << td.total_hours() << std::endl; errors++; } } // From std::chrono::duration { std::chrono::hours h(2); pandas::Timedelta td(h); .. _example-timedelta-total_minutes-38: .. dropdown:: total_minutes (pd_test_timedelta_scalar.cpp:106) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 96 :emphasize-lines: 11 pandas::Timedelta td_days(3, "D"); // 3 days std::cout << " Timedelta(3, 'D') = " << td_days.days() << " days" << std::endl; if (td_days.days() != 3) { std::cout << "[FAIL] np_test_timedelta_constructors: Timedelta(3, 'D') expected 3 days, got " << td_days.days() << std::endl; errors++; } pandas::Timedelta td_min(90, "min"); // 90 minutes = 1.5 hours std::cout << " Timedelta(90, 'min') = " << td_min.total_minutes() << " minutes" << std::endl; if (std::abs(td_min.total_minutes() - 90.0) > 0.0001) { std::cout << "[FAIL] np_test_timedelta_constructors: Timedelta(90, 'min') expected 90 minutes, got " << td_min.total_minutes() << std::endl; errors++; } pandas::Timedelta td_sec(30, "s"); // 30 seconds std::cout << " Timedelta(30, 's') = " << td_sec.total_seconds() << " seconds" << std::endl; if (std::abs(td_sec.total_seconds() - 30.0) > 0.0001) { std::cout << "[FAIL] np_test_timedelta_constructors: Timedelta(30, 's') expected 30 seconds, got " .. _example-timedelta-total_seconds-39: .. dropdown:: total_seconds (pd_test_1_all.cpp:4224) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 4214 :emphasize-lines: 11 void pd_test_timedelta_array_total_seconds() { std::cout << "========= TimedeltaArray: total_seconds ======================= "; pandas::TimedeltaArray arr({ std::optional(numpy::timedelta64(1, numpy::DateTimeUnit::Day)), std::optional(numpy::timedelta64(1, numpy::DateTimeUnit::Hour)), std::nullopt }); auto total = arr.total_seconds(); auto t0 = total[0]; if (!t0.has_value() || std::abs(t0.value() - 86400.0) > 0.001) { std::cout << " [FAIL] : total_seconds[0] should be 86400" << std::endl; throw std::runtime_error("pd_test_timedelta_array_total_seconds failed: total_seconds[0]"); } auto t1 = total[1]; if (!t1.has_value() || std::abs(t1.value() - 3600.0) > 0.001) { std::cout << " [FAIL] : total_seconds[1] should be 3600" << std::endl; .. _example-timedelta-value-40: .. dropdown:: value (pd_test_1_all.cpp:88) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 78 :emphasize-lines: 11 // T & T = T, T & F = F, T & NA = NA // F & T = F, F & F = F, F & NA = F (False dominates) // NA & T = NA, NA & F = F, NA & NA = NA pandas::BooleanArray t({std::optional(true)}); pandas::BooleanArray f({std::optional(false)}); pandas::BooleanArray na({std::nullopt}); // T & T = T auto tt = (t & t); if (!tt[0].has_value() || !tt[0].value()) { std::cout << " [FAIL] : in pd_test_boolean_array_kleene_and() : T & T should be T" << std::endl; throw std::runtime_error("pd_test_boolean_array_kleene_and failed: T & T"); } // T & F = F auto tf = (t & f); if (!tf[0].has_value() || tf[0].value()) { std::cout << " [FAIL] : in pd_test_boolean_array_kleene_and() : T & F should be F" << std::endl; throw std::runtime_error("pd_test_boolean_array_kleene_and failed: T & F"); }