DatetimeIndexOpsMixin ===================== .. cpp:class:: numpy::DatetimeIndexOpsMixin numpy C++ class. Example ------- .. code-block:: cpp #include using namespace numpy; // Use DatetimeIndexOpsMixin DatetimeIndexOpsMixin obj; // ... operations ... Constructors ------------ .. list-table:: :widths: 55 25 20 :header-rows: 1 * - Signature - Location - Example * - ``explicit DatetimeIndexOpsMixin(const ArrayType& array, const std::optional& name = std::nullopt, bool copy = false)`` - df_datetime_index_ops_mixin.h:138 - * - ``explicit DatetimeIndexOpsMixin(ArrayType&& array, const std::optional& name = std::nullopt)`` - df_datetime_index_ops_mixin.h:148 - * - ``DatetimeIndexOpsMixin(const DatetimeIndexOpsMixin& other)`` - df_datetime_index_ops_mixin.h:157 - * - ``DatetimeIndexOpsMixin(DatetimeIndexOpsMixin&& other) noexcept`` - df_datetime_index_ops_mixin.h:165 - Statistics ---------- .. list-table:: :widths: 40 20 15 25 :header-rows: 1 * - Signature - Return Type - Location - Example * - ``std::optional mean() const`` - std::optional - df_datetime_index_ops_mixin.h:1299 - :ref:`View ` * - ``IntegerArray minute() const`` - IntegerArray - df_datetime_index_ops_mixin.h:666 - :ref:`View ` * - ``IntegerArray nanosecond() const`` - IntegerArray - df_datetime_index_ops_mixin.h:727 - :ref:`View ` Math Operations --------------- .. list-table:: :widths: 40 20 15 25 :header-rows: 1 * - Signature - Return Type - Location - Example * - ``DatetimeIndexOpsMixin ceil(const std::string& freq) const`` - DatetimeIndexOpsMixin - df_datetime_index_ops_mixin.h:353 - :ref:`View ` * - ``ArrayType ceiled(result)`` - ArrayType - df_datetime_index_ops_mixin.h:382 - * - ``DatetimeIndexOpsMixin floor(const std::string& freq) const`` - DatetimeIndexOpsMixin - df_datetime_index_ops_mixin.h:309 - :ref:`View ` * - ``ArrayType floored(result)`` - ArrayType - df_datetime_index_ops_mixin.h:338 - * - ``DatetimeIndexOpsMixin round(const std::string& freq) const`` - DatetimeIndexOpsMixin - df_datetime_index_ops_mixin.h:267 - :ref:`View ` * - ``ArrayType rounded(result)`` - ArrayType - df_datetime_index_ops_mixin.h:294 - Linear Algebra -------------- .. list-table:: :widths: 40 20 15 25 :header-rows: 1 * - Signature - Return Type - Location - Example * - ``DatetimeIndexOpsMixin normalize() const`` - DatetimeIndexOpsMixin - df_datetime_index_ops_mixin.h:1151 - :ref:`View ` I/O --- .. list-table:: :widths: 40 20 15 25 :header-rows: 1 * - Signature - Return Type - Location - Example * - ``PeriodArray to_period(const std::string& freq) const`` - PeriodArray - df_datetime_index_ops_mixin.h:1259 - * - ``std::string to_string() const override`` - std::string - df_datetime_index_ops_mixin.h:1347 - :ref:`View ` * - ``DatetimeArray to_timestamp(const std::string& how = "start") const`` - DatetimeArray - df_datetime_index_ops_mixin.h:1245 - Type Handling ------------- .. list-table:: :widths: 40 20 15 25 :header-rows: 1 * - Signature - Return Type - Location - Example * - ``DatetimeIndexOpsMixin copy() const`` - DatetimeIndexOpsMixin - df_datetime_index_ops_mixin.h:1401 - :ref:`View ` Type Checking ------------- .. list-table:: :widths: 40 20 15 25 :header-rows: 1 * - Signature - Return Type - Location - Example * - ``BooleanArray is_leap_year() const`` - BooleanArray - df_datetime_index_ops_mixin.h:1090 - :ref:`View ` * - ``BooleanArray is_month_end() const`` - BooleanArray - df_datetime_index_ops_mixin.h:936 - :ref:`View ` * - ``BooleanArray is_month_start() const`` - BooleanArray - df_datetime_index_ops_mixin.h:908 - :ref:`View ` * - ``BooleanArray is_negative() const`` - BooleanArray - df_datetime_index_ops_mixin.h:1120 - * - ``BooleanArray is_positive() const`` - BooleanArray - df_datetime_index_ops_mixin.h:1108 - * - ``BooleanArray is_quarter_end() const`` - BooleanArray - df_datetime_index_ops_mixin.h:998 - :ref:`View ` * - ``BooleanArray is_quarter_start() const`` - BooleanArray - df_datetime_index_ops_mixin.h:966 - :ref:`View ` * - ``BooleanArray is_year_end() const`` - BooleanArray - df_datetime_index_ops_mixin.h:1061 - :ref:`View ` * - ``BooleanArray is_year_start() const`` - BooleanArray - df_datetime_index_ops_mixin.h:1032 - :ref:`View ` * - ``BooleanArray is_zero() const`` - BooleanArray - df_datetime_index_ops_mixin.h:1132 - :ref:`View ` Other Methods ------------- .. list-table:: :widths: 40 20 15 25 :header-rows: 1 * - Signature - Return Type - Location - Example * - ``DatetimeIndexOpsMixin asfreq(const std::string& freq, const std::string& how = "start") const`` - DatetimeIndexOpsMixin - df_datetime_index_ops_mixin.h:1226 - * - ``std::unique_ptr clone() const override`` - std::unique_ptr - df_datetime_index_ops_mixin.h:1340 - :ref:`View ` * - ``static int64_t datetime_to_period_ordinal(int64_t ns, const std::string& freq)`` - static int64_t - df_datetime_index_ops_mixin.h:1522 - * - ``IntegerArray day() const`` - IntegerArray - df_datetime_index_ops_mixin.h:640 - :ref:`View ` * - ``std::vector day_name() const`` - std::vector - df_datetime_index_ops_mixin.h:579 - :ref:`View ` * - ``IntegerArray dayofweek() const`` - IntegerArray - df_datetime_index_ops_mixin.h:758 - :ref:`View ` * - ``IntegerArray dayofyear() const`` - IntegerArray - df_datetime_index_ops_mixin.h:777 - :ref:`View ` * - ``static std::string format_datetime_strftime(const numpy::datetime64& val, const std::string& format)`` - static std::string - df_datetime_index_ops_mixin.h:1452 - * - ``static std::string format_period_strftime(numpy::int64 ordinal, const std::string& format, PeriodFrequency freq)`` - static std::string - df_datetime_index_ops_mixin.h:1478 - * - ``std::optional freq() const`` - std::optional - df_datetime_index_ops_mixin.h:203 - * - ``std::string freqstr() const`` - std::string - df_datetime_index_ops_mixin.h:219 - * - ``gmtime_r(&secs, &tm_time)`` - - df_datetime_index_ops_mixin.h:1467 - * - ``gmtime_s(&tm_time, &secs)`` - - df_datetime_index_ops_mixin.h:1465 - * - ``IntegerArray hour() const`` - IntegerArray - df_datetime_index_ops_mixin.h:652 - :ref:`View ` * - ``std::optional inferred_freq() const`` - std::optional - df_datetime_index_ops_mixin.h:232 - * - ``IntegerArray microsecond() const`` - IntegerArray - df_datetime_index_ops_mixin.h:694 - :ref:`View ` * - ``\* Floors all datetime values to midnight (00:00:00).`` - \* Floors all datetime values to - df_datetime_index_ops_mixin.h:1147 - * - ``IntegerArray month() const`` - IntegerArray - df_datetime_index_ops_mixin.h:628 - :ref:`View ` * - ``std::vector month_name() const`` - std::vector - df_datetime_index_ops_mixin.h:541 - :ref:`View ` * - ``\* Returns the full month names (e.g., "January", "February", ...).`` - \* Returns the full month - df_datetime_index_ops_mixin.h:536 - :ref:`View ` * - ``\* Returns the full day names (e.g., "Monday", "Tuesday", ...).`` - \* Returns the full day - df_datetime_index_ops_mixin.h:574 - :ref:`View ` * - ``static int64_t parse_freq_to_nanoseconds(const std::string& freq)`` - static int64_t - df_datetime_index_ops_mixin.h:1427 - * - ``static int64_t period_ordinal_to_nanoseconds(numpy::int64 ordinal, PeriodFrequency freq)`` - static int64_t - df_datetime_index_ops_mixin.h:1493 - * - ``IntegerArray quarter() const`` - IntegerArray - df_datetime_index_ops_mixin.h:789 - :ref:`View ` * - ``DatetimeIndexOpsMixin rename(const std::optional& new_name) const`` - DatetimeIndexOpsMixin - df_datetime_index_ops_mixin.h:1408 - * - ``DatetimeIndexOpsMixin result(\*this)`` - DatetimeIndexOpsMixin - df_datetime_index_ops_mixin.h:1409 - :ref:`View ` * - ``IntegerArray second() const`` - IntegerArray - df_datetime_index_ops_mixin.h:680 - :ref:`View ` * - ``void set_freq(const std::optional& freq)`` - void - df_datetime_index_ops_mixin.h:251 - * - ``DatetimeIndexOpsMixin shift(int64_t periods, const std::optional& freq = std::nullopt) const`` - DatetimeIndexOpsMixin - df_datetime_index_ops_mixin.h:415 - :ref:`View ` * - ``ArrayType shifted(result)`` - ArrayType - df_datetime_index_ops_mixin.h:447 - * - ``ArrayType shifted(result)`` - ArrayType - df_datetime_index_ops_mixin.h:469 - * - ``DatetimeIndexOpsMixin snap(const std::string& freq = "S") const`` - DatetimeIndexOpsMixin - df_datetime_index_ops_mixin.h:397 - * - ``std::vector strftime(const std::string& date_format) const`` - std::vector - df_datetime_index_ops_mixin.h:493 - :ref:`View ` * - ``IntegerArray td_days() const`` - IntegerArray - df_datetime_index_ops_mixin.h:844 - * - ``IntegerArray td_microseconds() const`` - IntegerArray - df_datetime_index_ops_mixin.h:868 - * - ``IntegerArray td_nanoseconds() const`` - IntegerArray - df_datetime_index_ops_mixin.h:880 - * - ``IntegerArray td_seconds() const`` - IntegerArray - df_datetime_index_ops_mixin.h:856 - * - ``FloatingArray total_seconds() const`` - FloatingArray - df_datetime_index_ops_mixin.h:892 - :ref:`View ` * - ``std::string tz() const`` - std::string - df_datetime_index_ops_mixin.h:1194 - :ref:`View ` * - ``bool tz_aware() const`` - bool - df_datetime_index_ops_mixin.h:1207 - * - ``DatetimeIndexOpsMixin tz_convert(const std::string& tz) const`` - DatetimeIndexOpsMixin - df_datetime_index_ops_mixin.h:1181 - :ref:`View ` * - ``DatetimeIndexOpsMixin tz_localize(const std::string& tz) const`` - DatetimeIndexOpsMixin - df_datetime_index_ops_mixin.h:1166 - :ref:`View ` * - ``IntegerArray week() const`` - IntegerArray - df_datetime_index_ops_mixin.h:801 - :ref:`View ` * - ``IntegerArray weekday() const`` - IntegerArray - df_datetime_index_ops_mixin.h:769 - :ref:`View ` * - ``IntegerArray weekofyear() const`` - IntegerArray - df_datetime_index_ops_mixin.h:832 - * - ``IntegerArray year() const`` - IntegerArray - df_datetime_index_ops_mixin.h:616 - :ref:`View ` Code Examples ------------- The following examples are extracted from the test suite. .. _example-datetimeindexopsmixin-mean-0: .. dropdown:: mean (np_test_1_all.cpp:11714) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 11704 :emphasize-lines: 11 // Create test array auto array = createInt32Array({ 2, 3 }, 0); array.setElementAt({ 0, 0 }, 1); array.setElementAt({ 0, 1 }, 2); array.setElementAt({ 0, 2 }, 3); array.setElementAt({ 1, 0 }, 4); array.setElementAt({ 1, 1 }, 5); array.setElementAt({ 1, 2 }, 6); // Test mean without axis auto mean_all = mean(array); if (!(approx_equal(mean_all.getElementAt({ 0 }), 3.5, 1e-10))) { std::string description = std::string("testBasicStatistics():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !(approx_equal(mean_all.getElementAt({ 0 }), 3.5, 1e-10))"; std::cout << std::string("[FAIL] ") + description << std::endl; throw std::runtime_error(description); } // std::cout << "[OK] mean (all elements) works correctly\n"; // Test mean along axis 0 auto mean_axis0 = mean(array, 0); if (!(mean_axis0.getShape()[0] == 3)) { .. _example-datetimeindexopsmixin-minute-1: .. dropdown:: minute (np_test_5_all.cpp:22186) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 22176 :emphasize-lines: 11 errors++; } numpy::Timedelta td3("45s"); if (std::abs(td3.total_seconds() - 45.0) > 0.0001) { std::cout << "[FAIL] np_test_timedelta_edge_cases: '45s' expected 45 sec" << std::endl; errors++; } numpy::Timedelta td4("NaT"); if (!td4.isNaT()) { std::cout << "[FAIL] np_test_timedelta_edge_cases: 'NaT' should parse to NaT" << std::endl; errors++; } } // Stream operator { numpy::Timedelta td(1, 2, 30); .. _example-datetimeindexopsmixin-nanosecond-2: .. dropdown:: nanosecond (np_test_5_all.cpp:22193) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 22183 :emphasize-lines: 11 errors++; } numpy::Timedelta td4("NaT"); if (!td4.isNaT()) { std::cout << "[FAIL] np_test_timedelta_edge_cases: 'NaT' should parse to NaT" << std::endl; errors++; } } // Stream operator { numpy::Timedelta td(1, 2, 30); std::ostringstream oss; oss << td; std::string str = oss.str(); if (str.empty() || str.find("days") == std::string::npos) { std::cout << "[FAIL] np_test_timedelta_edge_cases: stream operator failed" << std::endl; errors++; .. _example-datetimeindexopsmixin-ceil-3: .. dropdown:: ceil (np_test_2_all.cpp:5735) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 5725 :emphasize-lines: 11 throw std::runtime_error(description); } if (!(approx_equal(floor_result.getElementAt({ 5 }), std::floor(2.7)))) { std::string description = std::string("testRoundingFunctions():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !(approx_equal(floor_result.getElementAt({ 5 }), std::floor(2.7)))"; std::cout << std::string("[FAIL] ") + description << std::endl; throw std::runtime_error(description); } // std::cout << "[OK] floor function works correctly\n"; // Test ceil auto ceil_result = ceil(values); if (!(approx_equal(ceil_result.getElementAt({ 0 }), std::ceil(-2.7)))) { std::string description = std::string("testRoundingFunctions():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !(approx_equal(ceil_result.getElementAt({ 0 }), std::ceil(-2.7)))"; std::cout << std::string("[FAIL] ") + description << std::endl; throw std::runtime_error(description); } if (!(approx_equal(ceil_result.getElementAt({ 5 }), std::ceil(2.7)))) { std::string description = std::string("testRoundingFunctions():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !(approx_equal(ceil_result.getElementAt({ 5 }), std::ceil(2.7)))"; std::cout << std::string("[FAIL] ") + description << std::endl; throw std::runtime_error(description); } .. _example-datetimeindexopsmixin-floor-4: .. dropdown:: floor (np_test_2_all.cpp:5721) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 5711 :emphasize-lines: 11 throw std::runtime_error(description); } if (!(approx_equal(round_result.getElementAt({ 5 }), std::round(2.7)))) { std::string description = std::string("testRoundingFunctions():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !(approx_equal(round_result.getElementAt({ 5 }), std::round(2.7)))"; std::cout << std::string("[FAIL] ") + description << std::endl; throw std::runtime_error(description); } // std::cout << "[OK] round function works correctly\n"; // Test floor auto floor_result = floor(values); if (!(approx_equal(floor_result.getElementAt({ 0 }), std::floor(-2.7)))) { std::string description = std::string("testRoundingFunctions():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !(approx_equal(floor_result.getElementAt({ 0 }), std::floor(-2.7)))"; std::cout << std::string("[FAIL] ") + description << std::endl; throw std::runtime_error(description); } if (!(approx_equal(floor_result.getElementAt({ 5 }), std::floor(2.7)))) { std::string description = std::string("testRoundingFunctions():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !(approx_equal(floor_result.getElementAt({ 5 }), std::floor(2.7)))"; std::cout << std::string("[FAIL] ") + description << std::endl; throw std::runtime_error(description); } .. _example-datetimeindexopsmixin-round-5: .. dropdown:: round (np_test_1_all.cpp:23769) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 23759 :emphasize-lines: 11 throw std::runtime_error(description); } if (!(power_scalar_result.getShape() == array.getShape())) { std::string description = std::string("testMathFunctionSignatures():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !(power_scalar_result.getShape() == array.getShape())"; std::cout << std::string("[FAIL] ") + description << std::endl; throw std::runtime_error(description); } // std::cout << "[OK] Power functions have correct signatures\n"; // Test rounding functions with new decimals parameter auto round_result = round(array); // Default decimals=0 auto round_decimals_result = round(array, 2); // With decimals if (!(round_result.getShape() == array.getShape())) { std::string description = std::string("testMathFunctionSignatures():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !(round_result.getShape() == array.getShape())"; std::cout << std::string("[FAIL] ") + description << std::endl; throw std::runtime_error(description); } if (!(round_decimals_result.getShape() == array.getShape())) { std::string description = std::string("testMathFunctionSignatures():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !(round_decimals_result.getShape() == array.getShape())"; std::cout << std::string("[FAIL] ") + description << std::endl; throw std::runtime_error(description); .. _example-datetimeindexopsmixin-normalize-6: .. dropdown:: normalize (np_test_5_all.cpp:22817) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 22807 :emphasize-lines: 11 if (str.find("2024") == std::string::npos) { pass = false; fail_msg = "toString should contain year"; } // isoformat std::string iso = ts.isoformat(); if (iso.find("2024-06-15") == std::string::npos) { pass = false; fail_msg = "isoformat should contain date"; } // isoformat with space separator std::string iso_space = ts.isoformat(' '); if (iso_space.find(" ") == std::string::npos) { pass = false; fail_msg = "isoformat with space separator"; } // strftime std::string fmt = ts.strftime("%Y/%m/%d"); if (fmt != "2024/06/15") { pass = false; fail_msg = "strftime format"; } // ctime std::string ct = ts.ctime(); if (ct.find("2024") == std::string::npos) { pass = false; fail_msg = "ctime should contain year"; } // day_name std::string dayname = ts.day_name(); if (dayname != "Saturday") { pass = false; fail_msg = "2024-06-15 is Saturday"; } .. _example-datetimeindexopsmixin-to_string-7: .. dropdown:: to_string (np_test_1_all.cpp:454) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 444 :emphasize-lines: 11 // Modify through different views view1.setElementAt({0, 0}, 100); view2.setElementAt({2, 1}, 200); // This is (1, 2) in original view3.setElementAt({0, 0}, 300); // This is (1, 1) in original // std::cout << "After modifications through multiple views:" << std::endl; //original.printArray(); // Verify all changes are reflected if (!(original.getElementAt({0, 0}) == 100)) { std::string description = std::string("testAdvancedViewLifecycle():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !(original.getElementAt({0, 0}) == 100)"; std::cout << std::string("[FAIL] ") + description << std::endl; throw std::runtime_error(description); } if (!(original.getElementAt({1, 2}) == 200)) { std::string description = std::string("testAdvancedViewLifecycle():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !(original.getElementAt({1, 2}) == 200)"; std::cout << std::string("[FAIL] ") + description << std::endl; throw std::runtime_error(description); } if (!(original.getElementAt({1, 1}) == 300)) { std::string description = std::string("testAdvancedViewLifecycle():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !(original.getElementAt({1, 1}) == 300)"; .. _example-datetimeindexopsmixin-copy-8: .. dropdown:: copy (np_test_1_all.cpp:9812) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 9802 :emphasize-lines: 11 //original.printArray(); // The modification should be at position (1,1) in original if (!(original.getElementAt({1, 1}) == 9999)) { std::string description = std::string("testSliceCopyVsViewMemoryOwnership():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !(original.getElementAt({1, 1}) == 9999)"; std::cout << std::string("[FAIL] ") + description << std::endl; throw std::runtime_error(description); } // std::cout << "[OK] Slice view shares memory with original"; // Test slice copy (should be independent) auto slice_copy = original.sliceArray({{2, 4}, {2, 4}}); // std::cout << "Slice copy [2:4, 2:4]:"; //slice_copy.printArray(); slice_copy.setElementAt({0, 0}, 7777); // std::cout << "After modifying slice copy at (0,0):" << std::endl; // std::cout << "Original array:" << std::endl; //original.printArray(); // std::cout << "Slice copy:" << std::endl; .. _example-datetimeindexopsmixin-is_leap_year-9: .. dropdown:: is_leap_year (np_test_5_all.cpp:22577) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 22567 :emphasize-lines: 11 numpy::Timestamp::strptime("", "%Y-%m-%d"); } catch (const std::invalid_argument&) { threw = true; } if (!threw) { throw std::runtime_error("strptime failed: should throw for empty string"); } // Test 9: Empty format should throw threw = false; try { numpy::Timestamp::strptime("2024-03-15", ""); } catch (const std::invalid_argument&) { threw = true; } if (!threw) { throw std::runtime_error("strptime failed: should throw for empty format"); } // Test 10: Literal percent numpy::Timestamp ts10 = numpy::Timestamp::strptime("100%2024-03-15", "100%%%Y-%m-%d"); .. _example-datetimeindexopsmixin-is_month_end-10: .. dropdown:: is_month_end (np_test_5_all.cpp:22590) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 22580 :emphasize-lines: 11 threw = true; } if (!threw) { throw std::runtime_error("strptime failed: should throw for empty format"); } // Test 10: Literal percent numpy::Timestamp ts10 = numpy::Timestamp::strptime("100%2024-03-15", "100%%%Y-%m-%d"); if (ts10.year() != 2024) { throw std::runtime_error("strptime failed: literal percent parsing"); } std::cout << " -> tests passed" << std::endl; } // ============================================================================ // COMPONENT PROPERTIES TESTS // ============================================================================ void np_test_timestamp_properties() { std::cout << "========= timestamp: component properties ========================"; .. _example-datetimeindexopsmixin-is_month_start-11: .. dropdown:: is_month_start (np_test_5_all.cpp:22585) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 22575 :emphasize-lines: 11 // Test 9: Empty format should throw threw = false; try { numpy::Timestamp::strptime("2024-03-15", ""); } catch (const std::invalid_argument&) { threw = true; } if (!threw) { throw std::runtime_error("strptime failed: should throw for empty format"); } // Test 10: Literal percent numpy::Timestamp ts10 = numpy::Timestamp::strptime("100%2024-03-15", "100%%%Y-%m-%d"); if (ts10.year() != 2024) { throw std::runtime_error("strptime failed: literal percent parsing"); } std::cout << " -> tests passed" << std::endl; } // ============================================================================ .. _example-datetimeindexopsmixin-is_quarter_end-12: .. dropdown:: is_quarter_end (np_test_5_all.cpp:22591) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 22581 :emphasize-lines: 11 } if (!threw) { throw std::runtime_error("strptime failed: should throw for empty format"); } // Test 10: Literal percent numpy::Timestamp ts10 = numpy::Timestamp::strptime("100%2024-03-15", "100%%%Y-%m-%d"); if (ts10.year() != 2024) { throw std::runtime_error("strptime failed: literal percent parsing"); } std::cout << " -> tests passed" << std::endl; } // ============================================================================ // COMPONENT PROPERTIES TESTS // ============================================================================ void np_test_timestamp_properties() { std::cout << "========= timestamp: component properties ========================"; .. _example-datetimeindexopsmixin-is_quarter_start-13: .. dropdown:: is_quarter_start (np_test_5_all.cpp:22586) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 22576 :emphasize-lines: 11 threw = false; try { numpy::Timestamp::strptime("2024-03-15", ""); } catch (const std::invalid_argument&) { threw = true; } if (!threw) { throw std::runtime_error("strptime failed: should throw for empty format"); } // Test 10: Literal percent numpy::Timestamp ts10 = numpy::Timestamp::strptime("100%2024-03-15", "100%%%Y-%m-%d"); if (ts10.year() != 2024) { throw std::runtime_error("strptime failed: literal percent parsing"); } std::cout << " -> tests passed" << std::endl; } // ============================================================================ // COMPONENT PROPERTIES TESTS .. _example-datetimeindexopsmixin-is_year_end-14: .. dropdown:: is_year_end (np_test_5_all.cpp:22589) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 22579 :emphasize-lines: 11 } catch (const std::invalid_argument&) { threw = true; } if (!threw) { throw std::runtime_error("strptime failed: should throw for empty format"); } // Test 10: Literal percent numpy::Timestamp ts10 = numpy::Timestamp::strptime("100%2024-03-15", "100%%%Y-%m-%d"); if (ts10.year() != 2024) { throw std::runtime_error("strptime failed: literal percent parsing"); } std::cout << " -> tests passed" << std::endl; } // ============================================================================ // COMPONENT PROPERTIES TESTS // ============================================================================ void np_test_timestamp_properties() { .. _example-datetimeindexopsmixin-is_year_start-15: .. dropdown:: is_year_start (np_test_5_all.cpp:22584) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 22574 :emphasize-lines: 11 // Test 9: Empty format should throw threw = false; try { numpy::Timestamp::strptime("2024-03-15", ""); } catch (const std::invalid_argument&) { threw = true; } if (!threw) { throw std::runtime_error("strptime failed: should throw for empty format"); } // Test 10: Literal percent numpy::Timestamp ts10 = numpy::Timestamp::strptime("100%2024-03-15", "100%%%Y-%m-%d"); if (ts10.year() != 2024) { throw std::runtime_error("strptime failed: literal percent parsing"); } std::cout << " -> tests passed" << std::endl; } .. _example-datetimeindexopsmixin-is_zero-16: .. dropdown:: is_zero (np_test_2_all.cpp:7329) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 7319 :emphasize-lines: 11 // Test machine epsilon auto eps_double = machine_epsilon(); if (!(eps_double > 0)) { std::string description = std::string("test_basic_utilities():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !(eps_double > 0)"; std::cout << std::string("[FAIL] ") + description << std::endl; throw std::runtime_error(description); } // std::cout << "Machine epsilon (double): " << eps_double << std::endl; // Test zero check bool is_zero_result = is_zero(1e-16); if (!(is_zero_result == true)) { std::string description = std::string("test_basic_utilities():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !(is_zero_result == true)"; std::cout << std::string("[FAIL] ") + description << std::endl; throw std::runtime_error(description); } // std::cout << "Is 1e-16 zero? " << (is_zero_result ? "Yes" : "No") << std::endl; // Test safe divide double safe_result = safe_divide(1.0, 2.0); if (!(safe_result == 0.5)) { .. _example-datetimeindexopsmixin-clone-17: .. dropdown:: clone (np_test_1_all.cpp:24942) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 24932 :emphasize-lines: 11 } // Test reproducibility numpy::random::PCG64DXSM rng2(11111); if (rng2.next_uint64() != val) { std::cout << " [FAIL] : in np_test_bitgen_pcg64dxsm() : not reproducible"; throw std::runtime_error("np_test_bitgen_pcg64dxsm failed"); } // Test clone auto cloned = rng.clone(); if (cloned->name() != "PCG64DXSM") { std::cout << " [FAIL] : in np_test_bitgen_pcg64dxsm() : clone name incorrect"; throw std::runtime_error("np_test_bitgen_pcg64dxsm failed"); } std::cout << " -> tests passed" << std::endl; } // ============================================================================ // PHILOX TESTS .. _example-datetimeindexopsmixin-day-18: .. dropdown:: day (np_test_5_all.cpp:22185) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 22175 :emphasize-lines: 11 << std::endl; errors++; } numpy::Timedelta td3("45s"); if (std::abs(td3.total_seconds() - 45.0) > 0.0001) { std::cout << "[FAIL] np_test_timedelta_edge_cases: '45s' expected 45 sec" << std::endl; errors++; } numpy::Timedelta td4("NaT"); if (!td4.isNaT()) { std::cout << "[FAIL] np_test_timedelta_edge_cases: 'NaT' should parse to NaT" << std::endl; errors++; } } // Stream operator { .. _example-datetimeindexopsmixin-day_name-19: .. dropdown:: day_name (np_test_5_all.cpp:22735) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 22725 :emphasize-lines: 11 if (!pass) { std::cout << " [FAIL] : in np_test_timestamp_timezone() : " << fail_msg; throw std::runtime_error("np_test_timestamp_timezone failed: " + fail_msg); } std::cout << " -> tests passed" << std::endl; } // ============================================================================ // CONVERSION TESTS // ============================================================================ void np_test_timestamp_conversions() { std::cout << "========= timestamp: conversion methods =========================="; auto pass = true; std::string fail_msg; numpy::Timestamp ts(2024, 6, 15, 12, 30, 45, 123456, 789); // to_datetime64 .. _example-datetimeindexopsmixin-dayofweek-20: .. dropdown:: dayofweek (np_test_5_all.cpp:22547) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 22537 :emphasize-lines: 11 throw std::runtime_error("strptime failed: American format parsing"); } // Test 4: 2-digit year numpy::Timestamp ts4 = numpy::Timestamp::strptime("03/15/24", "%m/%d/%y"); if (ts4.year() != 2024) { throw std::runtime_error("strptime failed: 2-digit year parsing"); } // Test 5: With microseconds numpy::Timestamp ts5 = numpy::Timestamp::strptime("2024-03-15 14:30:45.123456", "%Y-%m-%d %H:%M:%S.%f"); if (ts5.microsecond() != 123456) { throw std::runtime_error("strptime failed: microseconds parsing"); } // Test 6: 12-hour format with AM/PM numpy::Timestamp ts6 = numpy::Timestamp::strptime("03/15/2024 02:30:00 PM", "%m/%d/%Y %I:%M:%S %p"); if (ts6.hour() != 14) { throw std::runtime_error("strptime failed: 12-hour format parsing"); } .. _example-datetimeindexopsmixin-dayofyear-21: .. dropdown:: dayofyear (np_test_5_all.cpp:22549) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 22539 :emphasize-lines: 11 // Test 4: 2-digit year numpy::Timestamp ts4 = numpy::Timestamp::strptime("03/15/24", "%m/%d/%y"); if (ts4.year() != 2024) { throw std::runtime_error("strptime failed: 2-digit year parsing"); } // Test 5: With microseconds numpy::Timestamp ts5 = numpy::Timestamp::strptime("2024-03-15 14:30:45.123456", "%Y-%m-%d %H:%M:%S.%f"); if (ts5.microsecond() != 123456) { throw std::runtime_error("strptime failed: microseconds parsing"); } // Test 6: 12-hour format with AM/PM numpy::Timestamp ts6 = numpy::Timestamp::strptime("03/15/2024 02:30:00 PM", "%m/%d/%Y %I:%M:%S %p"); if (ts6.hour() != 14) { throw std::runtime_error("strptime failed: 12-hour format parsing"); } // Test 7: Day of year format numpy::Timestamp ts7 = numpy::Timestamp::strptime("2024-075", "%Y-%j"); .. _example-datetimeindexopsmixin-hour-22: .. dropdown:: hour (np_test_5_all.cpp:22186) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 22176 :emphasize-lines: 11 errors++; } numpy::Timedelta td3("45s"); if (std::abs(td3.total_seconds() - 45.0) > 0.0001) { std::cout << "[FAIL] np_test_timedelta_edge_cases: '45s' expected 45 sec" << std::endl; errors++; } numpy::Timedelta td4("NaT"); if (!td4.isNaT()) { std::cout << "[FAIL] np_test_timedelta_edge_cases: 'NaT' should parse to NaT" << std::endl; errors++; } } // Stream operator { numpy::Timedelta td(1, 2, 30); .. _example-datetimeindexopsmixin-microsecond-23: .. dropdown:: microsecond (np_test_5_all.cpp:22193) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 22183 :emphasize-lines: 11 errors++; } numpy::Timedelta td4("NaT"); if (!td4.isNaT()) { std::cout << "[FAIL] np_test_timedelta_edge_cases: 'NaT' should parse to NaT" << std::endl; errors++; } } // Stream operator { numpy::Timedelta td(1, 2, 30); std::ostringstream oss; oss << td; std::string str = oss.str(); if (str.empty() || str.find("days") == std::string::npos) { std::cout << "[FAIL] np_test_timedelta_edge_cases: stream operator failed" << std::endl; errors++; .. _example-datetimeindexopsmixin-month-24: .. dropdown:: month (np_test_5_all.cpp:22185) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 22175 :emphasize-lines: 11 << std::endl; errors++; } numpy::Timedelta td3("45s"); if (std::abs(td3.total_seconds() - 45.0) > 0.0001) { std::cout << "[FAIL] np_test_timedelta_edge_cases: '45s' expected 45 sec" << std::endl; errors++; } numpy::Timedelta td4("NaT"); if (!td4.isNaT()) { std::cout << "[FAIL] np_test_timedelta_edge_cases: 'NaT' should parse to NaT" << std::endl; errors++; } } // Stream operator { .. _example-datetimeindexopsmixin-month_name-25: .. dropdown:: month_name (np_test_5_all.cpp:22739) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 22729 :emphasize-lines: 11 std::cout << " -> tests passed" << std::endl; } // ============================================================================ // CONVERSION TESTS // ============================================================================ void np_test_timestamp_conversions() { std::cout << "========= timestamp: conversion methods =========================="; auto pass = true; std::string fail_msg; numpy::Timestamp ts(2024, 6, 15, 12, 30, 45, 123456, 789); // to_datetime64 numpy::datetime64 dt = ts.to_datetime64(); if (dt.isNaT()) { pass = false; fail_msg = "to_datetime64 should not return NaT"; } // asm8 alias .. _example-datetimeindexopsmixin-names-26: .. dropdown:: names (np_test_2_all.cpp:18817) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 18807 :emphasize-lines: 11 create_txt_file("test_auto_names.txt"); // Don't provide names - should generate f0, f1, f2, f3 auto data = numpy::io::recfromtxt(csv_test_dir + "test_auto_names.txt"); auto dtype = data.getDType(); // Verify auto-generated names if (!dtype.hasField("f0") || !dtype.hasField("f1") || !dtype.hasField("f2") || !dtype.hasField("f3")) { std::cout << " [FAIL] : Missing auto-generated field names (f0, f1, f2, f3)"; throw std::runtime_error("np_test_io_extensions_recfromtxt_auto_names failed: missing auto names"); } std::cout << " -> tests passed" << std::endl; } // ============================================================================ // ERROR HANDLING TESTS // ============================================================================ .. _example-datetimeindexopsmixin-names-27: .. dropdown:: names (np_test_2_all.cpp:18817) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 18807 :emphasize-lines: 11 create_txt_file("test_auto_names.txt"); // Don't provide names - should generate f0, f1, f2, f3 auto data = numpy::io::recfromtxt(csv_test_dir + "test_auto_names.txt"); auto dtype = data.getDType(); // Verify auto-generated names if (!dtype.hasField("f0") || !dtype.hasField("f1") || !dtype.hasField("f2") || !dtype.hasField("f3")) { std::cout << " [FAIL] : Missing auto-generated field names (f0, f1, f2, f3)"; throw std::runtime_error("np_test_io_extensions_recfromtxt_auto_names failed: missing auto names"); } std::cout << " -> tests passed" << std::endl; } // ============================================================================ // ERROR HANDLING TESTS // ============================================================================ .. _example-datetimeindexopsmixin-quarter-28: .. dropdown:: quarter (np_test_5_all.cpp:22551) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 22541 :emphasize-lines: 11 numpy::Timestamp ts4 = numpy::Timestamp::strptime("03/15/24", "%m/%d/%y"); if (ts4.year() != 2024) { throw std::runtime_error("strptime failed: 2-digit year parsing"); } // Test 5: With microseconds numpy::Timestamp ts5 = numpy::Timestamp::strptime("2024-03-15 14:30:45.123456", "%Y-%m-%d %H:%M:%S.%f"); if (ts5.microsecond() != 123456) { throw std::runtime_error("strptime failed: microseconds parsing"); } // Test 6: 12-hour format with AM/PM numpy::Timestamp ts6 = numpy::Timestamp::strptime("03/15/2024 02:30:00 PM", "%m/%d/%Y %I:%M:%S %p"); if (ts6.hour() != 14) { throw std::runtime_error("strptime failed: 12-hour format parsing"); } // Test 7: Day of year format numpy::Timestamp ts7 = numpy::Timestamp::strptime("2024-075", "%Y-%j"); if (ts7.month() != 3 || ts7.day() != 15) { // Day 75 of 2024 is March 15 throw std::runtime_error("strptime failed: day of year parsing"); .. _example-datetimeindexopsmixin-result-29: .. dropdown:: result (np_test_1_all.cpp:6090) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 6080 :emphasize-lines: 11 throw std::runtime_error(description); } // std::cout << "Timer restart test passed. Second: " << second_elapsed << " ms" << std::endl; std::cout << " -> tests passed" << std::endl; } void test_benchmark_result_storageBenchmarkSorting() { std::cout << "========= test_benchmark_result_storage ======================="; BenchmarkResult result("TestAlgorithm", 1000, 15.5, true, 4096); if (!(result.algorithm_name == "TestAlgorithm")) { std::string description = std::string("test_benchmark_result_storageBenchmarkSorting():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !(result.algorithm_name == \"TestAlgorithm\")"; std::cout << std::string("[FAIL] ") + description << std::endl; throw std::runtime_error(description); } if (!(result.array_size == 1000)) { std::string description = std::string("test_benchmark_result_storageBenchmarkSorting():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !(result.array_size == 1000)"; std::cout << std::string("[FAIL] ") + description << std::endl; throw std::runtime_error(description); .. _example-datetimeindexopsmixin-second-30: .. dropdown:: second (np_test_5_all.cpp:22186) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 22176 :emphasize-lines: 11 errors++; } numpy::Timedelta td3("45s"); if (std::abs(td3.total_seconds() - 45.0) > 0.0001) { std::cout << "[FAIL] np_test_timedelta_edge_cases: '45s' expected 45 sec" << std::endl; errors++; } numpy::Timedelta td4("NaT"); if (!td4.isNaT()) { std::cout << "[FAIL] np_test_timedelta_edge_cases: 'NaT' should parse to NaT" << std::endl; errors++; } } // Stream operator { numpy::Timedelta td(1, 2, 30); .. _example-datetimeindexopsmixin-shift-31: .. dropdown:: shift (np_test_1_all.cpp:2761) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 2751 :emphasize-lines: 11 throw std::runtime_error(description); } if (!(left_array.getElementAt({3}) == 16384)) { std::string description = std::string("testBitShifts():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !(left_array.getElementAt({3}) == 16384)"; std::cout << std::string("[FAIL] ") + description << std::endl; throw std::runtime_error(description); } // std::cout << "[OK] Left shift by array\n"; // Test excessive shift (should result in 0) auto excessive_left = left_shift(arr, 20); // More than 16 bits if (!(excessive_left.getElementAt({0}) == 0)) { std::string description = std::string("testBitShifts():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !(excessive_left.getElementAt({0}) == 0)"; std::cout << std::string("[FAIL] ") + description << std::endl; throw std::runtime_error(description); } if (!(excessive_left.getElementAt({1}) == 0)) { std::string description = std::string("testBitShifts():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !(excessive_left.getElementAt({1}) == 0)"; std::cout << std::string("[FAIL] ") + description << std::endl; throw std::runtime_error(description); .. _example-datetimeindexopsmixin-strftime-32: .. dropdown:: strftime (np_test_5_all.cpp:22727) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 22717 :emphasize-lines: 11 if (utc.fold() != 0) { pass = false; fail_msg = "fold should be 0"; } // Named timezone numpy::Timestamp ny(2024, 6, 15, 12, 0, 0, 0, 0, "America/New_York"); if (ny.tz() != "America/New_York") { pass = false; fail_msg = "Should have NY timezone"; } std::string tzname = ny.tzname(); if (tzname != "EDT" && tzname != "EST") { pass = false; fail_msg = "Summer should be EDT or EST"; } if (!pass) { std::cout << " [FAIL] : in np_test_timestamp_timezone() : " << fail_msg; throw std::runtime_error("np_test_timestamp_timezone failed: " + fail_msg); } std::cout << " -> tests passed" << std::endl; } // ============================================================================ // CONVERSION TESTS // ============================================================================ void np_test_timestamp_conversions() { .. _example-datetimeindexopsmixin-total_seconds-33: .. dropdown:: total_seconds (np_test_5_all.cpp:21288) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 21278 :emphasize-lines: 11 } } // max() { numpy::Timedelta max_td = numpy::Timedelta::max(); if (max_td.value() != INT64_MAX) { std::cout << "[FAIL] np_test_timedelta_static_factories: max() expected INT64_MAX" << std::endl; errors++; } } // resolution() { numpy::Timedelta res = numpy::Timedelta::resolution(); if (res.value() != 1) { std::cout << "[FAIL] np_test_timedelta_static_factories: resolution() expected 1 ns" << std::endl; errors++; } .. _example-datetimeindexopsmixin-tz-34: .. dropdown:: tz (np_test_5_all.cpp:22214) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 22204 :emphasize-lines: 11 } } if (errors == 0) { std::cout << "np_test_timedelta_edge_cases -> tests passed" << std::endl; } return errors; } } // namespace numpy_tests_timedelta // ============================================================================= // Main Test Runner // ============================================================================= int np_test_timedelta_main() { int errors = 0; errors += numpy_tests_timedelta::np_test_timedelta_constructors(); errors += numpy_tests_timedelta::np_test_timedelta_static_factories(); errors += numpy_tests_timedelta::np_test_timedelta_components(); errors += numpy_tests_timedelta::np_test_timedelta_total_conversions(); .. _example-datetimeindexopsmixin-tz_convert-35: .. dropdown:: tz_convert (np_test_5_all.cpp:22899) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 22889 :emphasize-lines: 11 if (floored_h.hour() != 14 || floored_h.minute() != 0 || floored_h.second() != 0) { pass = false; fail_msg = "floor to hour failed"; } // ceil to hour numpy::Timestamp ceiled_h = ts.ceil("h"); if (ceiled_h.hour() != 15 || ceiled_h.minute() != 0) { pass = false; fail_msg = "ceil to hour failed"; } // round to hour (37 minutes -> round up) numpy::Timestamp rounded_h = ts.round("h"); if (rounded_h.hour() != 15) { pass = false; fail_msg = "round to hour should be 15 (37 > 30)"; } // normalize (floor to day) numpy::Timestamp normalized = ts.normalize(); .. _example-datetimeindexopsmixin-tz_localize-36: .. dropdown:: tz_localize (np_test_5_all.cpp:22892) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 22882 :emphasize-lines: 11 auto pass = true; std::string fail_msg; numpy::Timestamp ts(2024, 6, 15, 14, 37, 45, 123456); // floor to hour numpy::Timestamp floored_h = ts.floor("h"); if (floored_h.hour() != 14 || floored_h.minute() != 0 || floored_h.second() != 0) { pass = false; fail_msg = "floor to hour failed"; } // ceil to hour numpy::Timestamp ceiled_h = ts.ceil("h"); if (ceiled_h.hour() != 15 || ceiled_h.minute() != 0) { pass = false; fail_msg = "ceil to hour failed"; } // round to hour (37 minutes -> round up) numpy::Timestamp rounded_h = ts.round("h"); .. _example-datetimeindexopsmixin-week-37: .. dropdown:: week (np_test_1_all.cpp:27347) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 27337 :emphasize-lines: 11 std::cout << "========= busday_offset: forward offset ======================="; // Start on Monday, offset by 5 business days -> should be next Monday NDArray dates({ 1 }); NDArray offsets({ 1 }); dates.setElementAt({ 0 }, datetime64(19723, DateTimeUnit::Day)); // 2024-01-01 (Monday) offsets.setElementAt({ 0 }, int64_t(5)); auto result = busday_offset(dates, offsets); // Expected: Monday + 5 business days = Monday next week (skipping weekend) datetime64 expected(19730, DateTimeUnit::Day); // 2024-01-08 (Monday) if (result.getElementAt({ 0 }) != expected) { std::cout << " [FAIL] : in test_busday_offset_forward() : incorrect offset result"; throw std::runtime_error("busday_offset forward test failed"); } std::cout << " -> tests passed" << std::endl; } .. _example-datetimeindexopsmixin-weekday-38: .. dropdown:: weekday (np_test_5_all.cpp:22772) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 22762 :emphasize-lines: 11 // timestamp double posix = ts.timestamp(); if (posix <= 0) { pass = false; fail_msg = "POSIX timestamp should be positive"; } // timetuple auto [y, mo, d, h, mi, s] = ts.timetuple(); if (y != 2024 || mo != 6) { pass = false; fail_msg = "timetuple values incorrect"; } // date/time tuples auto [dy, dm, dd] = ts.date(); if (dy != 2024) { pass = false; fail_msg = "date tuple year"; } auto [th, tmi, ts2, tus] = ts.time(); if (th != 12) { pass = false; fail_msg = "time tuple hour"; } // Julian date double jd = ts.to_julian_date(); if (jd < 2400000) { pass = false; fail_msg = "Julian date should be reasonable"; } // Ordinal int ord = ts.toordinal(); .. _example-datetimeindexopsmixin-year-39: .. dropdown:: year (np_test_5_all.cpp:22185) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 22175 :emphasize-lines: 11 << std::endl; errors++; } numpy::Timedelta td3("45s"); if (std::abs(td3.total_seconds() - 45.0) > 0.0001) { std::cout << "[FAIL] np_test_timedelta_edge_cases: '45s' expected 45 sec" << std::endl; errors++; } numpy::Timedelta td4("NaT"); if (!td4.isNaT()) { std::cout << "[FAIL] np_test_timedelta_edge_cases: 'NaT' should parse to NaT" << std::endl; errors++; } } // Stream operator {