Period#

class pandas::Period#

Scalar type representing a single value.

Example#

#include <pandas/pandas.h>
using namespace pandas;

// Use Period
Period obj;
// ... operations ...

Constructors#

Signature

Location

Example

Period(int64_t ordinal, const std::string& freq)

pd_period.h:74

Period(const std::string& value, const std::string& freq)

pd_period.h:92

Statistics#

Signature

Return Type

Location

Example

int minute() const

int

pd_period.h:227

View

Arithmetic#

Signature

Return Type

Location

Example

Period add_ordinals(int64_t n) const

Period

pd_period.h:480

Time Series#

Signature

Return Type

Location

Example

Period asfreq(const std::string& freq, const std::string& how = "E") const

Period

pd_period.h:317

View

pandas::Timestamp to_timestamp(const std::string& freq = "", const std::string& how = "start") const

pandas::Timestamp

pd_period.h:381

View

Iteration#

Signature

Return Type

Location

Example

pandas::Timestamp end_time() const

pandas::Timestamp

pd_period.h:407

View

Type Checking#

Signature

Return Type

Location

Example

bool is_leap_year() const

bool

pd_period.h:302

View

Other Methods#

Signature

Return Type

Location

Example

static Period NaT(const std::string& freq = "D")

static Period

pd_period.h:160

View

int day() const

int

pd_period.h:211

View

int day_of_week() const { return dayofweek()

int

pd_period.h:256

View

int day_of_year() const { return dayofyear()

int

pd_period.h:266

View

int dayofweek() const

int

pd_period.h:251

View

int dayofyear() const

int

pd_period.h:261

View

int days_in_month() const

int

pd_period.h:290

View

days_since_epoch_to_date(days, y, m, d)

pd_period.h:352

PeriodFrequency freq() const

PeriodFrequency

pd_period.h:181

View

int64_t freq_multiplier() const

int64_t

pd_period.h:489

static int64_t freq_to_nanos(PeriodFrequency freq)

static int64_t

pd_period.h:466

std::string freqstr() const

std::string

pd_period.h:176

View

int hour() const

int

pd_period.h:219

View

bool isNaT() const

bool

pd_period.h:186

View

int month() const

int

pd_period.h:203

View

static Period now(const std::string& freq = "D", const std::string& tz = "")

static Period

pd_period.h:129

View

int64_t ordinal() const

int64_t

pd_period.h:171

View

int quarter() const

int

pd_period.h:243

View

int qyear() const

int

pd_period.h:281

View

std::string repr() const

std::string

pd_period.h:450

View

int second() const

int

pd_period.h:235

View

pandas::Timestamp start_time() const

pandas::Timestamp

pd_period.h:400

View

std::string strftime(const std::string& date_format) const

std::string

pd_period.h:428

View

std::string toString() const

std::string

pd_period.h:418

View

int week() const

int

pd_period.h:271

View

int weekofyear() const { return week()

int

pd_period.h:276

int year() const

int

pd_period.h:195

View

Code Examples#

The following examples are extracted from the test suite.

minute (pd_test_1_all.cpp:7505)
7495    std::cout << "========= minute property =============================";
7496
7497    std::vector<std::optional<numpy::datetime64>> values = {
7498        make_dt(0),                    // Minute 0
7499        make_dt(30 * NS_PER_MIN),      // Minute 30
7500        make_dt(59 * NS_PER_MIN)       // Minute 59
7501    };
7502    pandas::DatetimeArray arr(values);
7503    pandas::DatetimeIndex idx(arr);
7504
7505    auto minutes = idx.minute();
7506
7507    bool passed = (minutes.size() == 3);
7508    auto m0 = minutes[0];
7509    auto m1 = minutes[1];
7510    auto m2 = minutes[2];
7511    passed = passed && m0.has_value() && *m0 == 0;
7512    passed = passed && m1.has_value() && *m1 == 30;
7513    passed = passed && m2.has_value() && *m2 == 59;
7514
7515    if (!passed) {
asfreq (pd_test_1_all.cpp:2869)
2859        std::cout << "========= PeriodArray: asfreq ======================= ";
2860
2861        // Monthly to quarterly
2862        pandas::PeriodArray arr_m(std::vector<std::string>{
2863            "2024-01",
2864            "2024-04",
2865            "2024-07",
2866            "NaT"
2867        }, "M");
2868
2869        auto arr_q = arr_m.asfreq("Q");
2870        if (arr_q.size() != 4) {
2871            std::cout << "  [FAIL] : asfreq size should be 4" << std::endl;
2872            throw std::runtime_error("pd_test_period_array_asfreq failed: size");
2873        }
2874        if (arr_q.freqstr() != "Q") {
2875            std::cout << "  [FAIL] : asfreq freqstr should be 'Q'" << std::endl;
2876            throw std::runtime_error("pd_test_period_array_asfreq failed: freqstr");
2877        }
2878
2879        // Check NaT is preserved
to_timestamp (pd_test_1_all.cpp:2830)
2820    void pd_test_period_array_to_timestamp() {
2821        std::cout << "========= PeriodArray: to_timestamp ======================= ";
2822
2823        pandas::PeriodArray arr(std::vector<std::string>{
2824            "2024-01",
2825            "2024-06",
2826            "NaT"
2827        }, "M");
2828
2829        // to_timestamp with start
2830        auto ts_start = arr.to_timestamp("start");
2831        if (ts_start.size() != 3) {
2832            std::cout << "  [FAIL] : to_timestamp size should be 3" << std::endl;
2833            throw std::runtime_error("pd_test_period_array_to_timestamp failed: size");
2834        }
2835
2836        auto ts0 = ts_start[0];
2837        if (!ts0.has_value()) {
2838            std::cout << "  [FAIL] : ts_start[0] should have value" << std::endl;
2839            throw std::runtime_error("pd_test_period_array_to_timestamp failed: ts_start[0]");
2840        }
end_time (pd_test_1_all.cpp:17146)
17136    std::cout << " -> tests passed" << std::endl;
17137}
17138
17139void pd_test_period_index_end_time() {
17140    std::cout << "========= end_time property ===========================";
17141
17142    std::vector<int64_t> ordinals = {0};  // 1970-01-01 daily period
17143    pandas::PeriodIndex idx = pandas::PeriodIndex::from_ordinals(ordinals, "D");
17144
17145    pandas::DatetimeArray end_times = idx.end_time();
17146
17147    bool passed = (end_times.size() == 1 && !end_times.is_na(0));
17148    if (!passed) {
17149        std::cout << "  [FAIL] : in pd_test_period_index_end_time()" << std::endl;
17150        throw std::runtime_error("pd_test_period_index_end_time failed");
17151    }
17152
17153    std::cout << " -> tests passed" << std::endl;
17154}
is_leap_year (pd_test_1_all.cpp:1280)
1270        }
1271
1272        // is_month_end
1273        auto me = arr.is_month_end();
1274        if (!me[1].has_value() || !me[1].value()) {
1275            std::cout << "  [FAIL] : 2023-03-31 should be month end" << std::endl;
1276            throw std::runtime_error("pd_test_datetime_array_boolean_props failed: month end");
1277        }
1278
1279        // is_leap_year
1280        auto ly = arr.is_leap_year();
1281        if (!ly[2].has_value() || !ly[2].value()) {
1282            std::cout << "  [FAIL] : 2024 should be leap year" << std::endl;
1283            throw std::runtime_error("pd_test_datetime_array_boolean_props failed: leap year");
1284        }
1285        if (!ly[0].has_value() || ly[0].value()) {
1286            std::cout << "  [FAIL] : 2023 should not be leap year" << std::endl;
1287            throw std::runtime_error("pd_test_datetime_array_boolean_props failed: not leap year");
1288        }
1289
1290        std::cout << " -> tests passed" << std::endl;
NaT (pd_test_1_all.cpp:1305)
1295        pandas::DatetimeArray arr(std::vector<std::string>{
1296            "2023-06-15",
1297            "NaT",
1298            "2023-01-01",
1299            "2023-12-31"
1300        });
1301
1302        // argsort ascending
1303        auto indices = arr.argsort(true, "last");
1304        // Expected order: 2023-01-01(2), 2023-06-15(0), 2023-12-31(3), NaT(1)
1305        if (indices.getElementAt({0}) != 2) {
1306            std::cout << "  [FAIL] : argsort: first should be index 2 (2023-01-01)" << std::endl;
1307            throw std::runtime_error("pd_test_datetime_array_sorting failed: argsort first");
1308        }
1309        if (indices.getElementAt({3}) != 1) {
1310            std::cout << "  [FAIL] : argsort: last should be index 1 (NaT)" << std::endl;
1311            throw std::runtime_error("pd_test_datetime_array_sorting failed: NaT position");
1312        }
1313
1314        // argmin
day (pd_test_1_all.cpp:1193)
1183            std::cout << "  [FAIL] : month[0] should be 3" << std::endl;
1184            throw std::runtime_error("pd_test_datetime_array_component_month_day failed: month[0]");
1185        }
1186        auto m1 = months[1];
1187        if (!m1.has_value() || m1.value() != 12) {
1188            std::cout << "  [FAIL] : month[1] should be 12" << std::endl;
1189            throw std::runtime_error("pd_test_datetime_array_component_month_day failed: month[1]");
1190        }
1191
1192        // Day
1193        auto days = arr.day();
1194        auto d0 = days[0];
1195        if (!d0.has_value() || d0.value() != 15) {
1196            std::cout << "  [FAIL] : day[0] should be 15" << std::endl;
1197            throw std::runtime_error("pd_test_datetime_array_component_month_day failed: day[0]");
1198        }
1199        auto d1 = days[1];
1200        if (!d1.has_value() || d1.value() != 25) {
1201            std::cout << "  [FAIL] : day[1] should be 25" << std::endl;
1202            throw std::runtime_error("pd_test_datetime_array_component_month_day failed: day[1]");
1203        }
day_of_week (pd_test_3_all.cpp:22018)
22008void test_dt_aliases() {
22009    std::cout << "========= dt accessor aliases ====================";
22010
22011    std::vector<numpy::datetime64> dates = {
22012        numpy::datetime64("2023-01-15"),
22013        numpy::datetime64("2023-06-20")
22014    };
22015    pandas::Series<numpy::datetime64> s(dates);
22016
22017    auto dow1 = s.dt().dayofweek();
22018    auto dow2 = s.dt().day_of_week();
22019    auto dow3 = s.dt().weekday();
22020
22021    if (dow1[0] != dow2[0] || dow1[0] != dow3[0]) {
22022        throw std::runtime_error("dt aliases: dayofweek/day_of_week/weekday mismatch");
22023    }
22024
22025    auto doy1 = s.dt().dayofyear();
22026    auto doy2 = s.dt().day_of_year();
22027
22028    if (doy1[0] != doy2[0]) {
day_of_year (pd_test_3_all.cpp:22026)
22016    auto dow1 = s.dt().dayofweek();
22017    auto dow2 = s.dt().day_of_week();
22018    auto dow3 = s.dt().weekday();
22019
22020    if (dow1[0] != dow2[0] || dow1[0] != dow3[0]) {
22021        throw std::runtime_error("dt aliases: dayofweek/day_of_week/weekday mismatch");
22022    }
22023
22024    auto doy1 = s.dt().dayofyear();
22025    auto doy2 = s.dt().day_of_year();
22026
22027    if (doy1[0] != doy2[0]) {
22028        throw std::runtime_error("dt aliases: dayofyear/day_of_year mismatch");
22029    }
22030
22031    std::cout << " -> tests passed" << std::endl;
22032}
22033
22034void test_dt_days_in_month() {
22035    std::cout << "========= dt.days_in_month ======================";
dayofweek (pd_test_1_all.cpp:7565)
7555    // 1970-01-01 was a Thursday (day 3)
7556    std::vector<std::optional<numpy::datetime64>> values = {
7557        make_dt(0),                // Thursday (3)
7558        make_dt(NS_PER_DAY),       // Friday (4)
7559        make_dt(2 * NS_PER_DAY),   // Saturday (5)
7560        make_dt(3 * NS_PER_DAY)    // Sunday (6)
7561    };
7562    pandas::DatetimeArray arr(values);
7563    pandas::DatetimeIndex idx(arr);
7564
7565    auto dow = idx.dayofweek();
7566
7567    bool passed = (dow.size() == 4);
7568    if (!passed) {
7569        std::cout << "  [FAIL] : in pd_test_datetime_index_dayofweek()" << std::endl;
7570        throw std::runtime_error("pd_test_datetime_index_dayofweek failed");
7571    }
7572
7573    std::cout << " -> tests passed" << std::endl;
7574}
dayofyear (pd_test_3_all.cpp:18582)
18572    auto seconds = s.dt().second();
18573    if (seconds[0] != 45 || seconds[1] != 30 || seconds[2] != 59) {
18574        std::cout << "  [FAIL] : second() failed" << std::endl;
18575        throw std::runtime_error("pd_test_dt_time_components: second() failed");
18576    }
18577
18578    std::cout << " -> tests passed" << std::endl;
18579}
18580
18581// ============================================================================
18582// Test dt().dayofweek(), dt().dayofyear(), dt().quarter()
18583// ============================================================================
18584
18585void pd_test_dt_derived_properties() {
18586    std::cout << "========= Series.dt().dayofweek/dayofyear/quarter() ======";
18587
18588    // 2020-01-01 is a Wednesday (dayofweek=2), dayofyear=1, Q1
18589    // 2020-07-04 is a Saturday (dayofweek=5), dayofyear=186, Q3
18590    pandas::Series<std::string> s({"2020-01-01", "2020-07-04"});
18591
18592    auto dow = s.dt().dayofweek();
days_in_month (pd_test_1_all.cpp:2766)
2756            std::cout << "  [FAIL] : day[0] should be 15" << std::endl;
2757            throw std::runtime_error("pd_test_period_array_day_components failed: day[0]");
2758        }
2759        auto d1 = days[1];
2760        if (!d1.has_value() || d1.value() != 25) {
2761            std::cout << "  [FAIL] : day[1] should be 25" << std::endl;
2762            throw std::runtime_error("pd_test_period_array_day_components failed: day[1]");
2763        }
2764
2765        // Days in month
2766        auto dim = arr.days_in_month();
2767        auto dim0 = dim[0];
2768        if (!dim0.has_value() || dim0.value() != 31) {
2769            std::cout << "  [FAIL] : days_in_month[0] should be 31 (March)" << std::endl;
2770            throw std::runtime_error("pd_test_period_array_day_components failed: days_in_month[0]");
2771        }
2772        auto dim1 = dim[1];
2773        if (!dim1.has_value() || dim1.value() != 31) {
2774            std::cout << "  [FAIL] : days_in_month[1] should be 31 (December)" << std::endl;
2775            throw std::runtime_error("pd_test_period_array_day_components failed: days_in_month[1]");
2776        }
freq (pd_test_1_all.cpp:8233)
8223    std::cout << "========= freq property ===============================";
8224
8225    std::vector<std::optional<numpy::datetime64>> values = {
8226        numpy::datetime64(0LL, numpy::DateTimeUnit::Nanosecond),
8227        numpy::datetime64(86400000000000LL, numpy::DateTimeUnit::Nanosecond)  // 1 day
8228    };
8229    pandas::DatetimeArray arr(values);
8230    pandas::DatetimeMixinIndex idx(arr);
8231
8232    // Default freq is nullopt or inferred
8233    auto f = idx.freq();
8234    std::string fs = idx.freqstr();
8235
8236    bool passed = true;  // freq may or may not be set
8237    if (!passed) {
8238        std::cout << "  [FAIL] : in pd_test_datetime_mixin_freq()" << std::endl;
8239        throw std::runtime_error("pd_test_datetime_mixin_freq failed");
8240    }
8241
8242    std::cout << " -> tests passed" << std::endl;
8243}
freqstr (pd_test_1_all.cpp:2671)
2661        }
2662
2663        pandas::PeriodDtype dtype_y("Y");
2664        if (dtype_y.name() != "period[Y]") {
2665            std::cout << "  [FAIL] : dtype_y.name() should be 'period[Y]'" << std::endl;
2666            throw std::runtime_error("pd_test_period_array_freq_validation failed: dtype name Y");
2667        }
2668
2669        // Test frequency string
2670        pandas::PeriodArray arr(std::vector<std::string>{"2024-01-15"}, "D");
2671        if (arr.freqstr() != "D") {
2672            std::cout << "  [FAIL] : arr.freqstr() should be 'D'" << std::endl;
2673            throw std::runtime_error("pd_test_period_array_freq_validation failed: freqstr");
2674        }
2675
2676        std::cout << " -> tests passed" << std::endl;
2677    }
2678
2679    void pd_test_period_array_year_month_quarter() {
2680        std::cout << "========= PeriodArray: year/month/quarter components ======================= ";
hour (pd_test_1_all.cpp:7476)
7466    std::cout << "========= hour property ===============================";
7467
7468    std::vector<std::optional<numpy::datetime64>> values = {
7469        make_dt(0),                    // Hour 0
7470        make_dt(6 * NS_PER_HOUR),      // Hour 6
7471        make_dt(23 * NS_PER_HOUR)      // Hour 23
7472    };
7473    pandas::DatetimeArray arr(values);
7474    pandas::DatetimeIndex idx(arr);
7475
7476    auto hours = idx.hour();
7477
7478    bool passed = (hours.size() == 3);
7479    auto h0 = hours[0];
7480    auto h1 = hours[1];
7481    auto h2 = hours[2];
7482    passed = passed && h0.has_value() && *h0 == 0;
7483    passed = passed && h1.has_value() && *h1 == 6;
7484    passed = passed && h2.has_value() && *h2 == 23;
7485
7486    if (!passed) {
isNaT (pd_test_3_all.cpp:1523)
1513    }
1514
1515    // Case B: pandas::Timedelta == pandas::Timedelta
1516    {
1517        static_assert(std::is_same_v<pandas::Timedelta, pandas::Timedelta>,
1518                      "pandas::Timedelta must alias pandas::Timedelta");
1519    }
1520
1521    // Case C: pandas::NaT is a NaT-valued Timestamp
1522    {
1523        if (!pandas::NaT.isNaT()) {
1524            throw std::runtime_error("pandas::NaT is not a NaT value");
1525        }
1526        pandas::Timestamp default_ts;
1527        if (default_ts.isNaT() != pandas::NaT.isNaT()) {
1528            throw std::runtime_error(
1529                "pandas::NaT and default Timestamp NaT-state mismatch");
1530        }
1531    }
1532
1533    // Case D: round-trip - reproduces the failing test pattern
month (pd_test_1_all.cpp:1180)
1170    void pd_test_datetime_array_component_month_day() {
1171        std::cout << "========= DatetimeArray: month/day components ======================= ";
1172
1173        pandas::DatetimeArray arr(std::vector<std::string>{
1174            "2023-03-15",
1175            "2023-12-25",
1176            "NaT"
1177        });
1178
1179        // Month
1180        auto months = arr.month();
1181        auto m0 = months[0];
1182        if (!m0.has_value() || m0.value() != 3) {
1183            std::cout << "  [FAIL] : month[0] should be 3" << std::endl;
1184            throw std::runtime_error("pd_test_datetime_array_component_month_day failed: month[0]");
1185        }
1186        auto m1 = months[1];
1187        if (!m1.has_value() || m1.value() != 12) {
1188            std::cout << "  [FAIL] : month[1] should be 12" << std::endl;
1189            throw std::runtime_error("pd_test_datetime_array_component_month_day failed: month[1]");
1190        }
now (pd_test_3_all.cpp:20077)
20067    bool passed = months_default[0] == "June" && days_default[0] == "Monday";
20068    if (!passed) {
20069        std::cout << "  [FAIL] : in pd_test_name_locale_params()" << std::endl;
20070        throw std::runtime_error("pd_test_name_locale_params failed");
20071    }
20072
20073    std::cout << " -> tests passed" << std::endl;
20074}
20075
20076// ============================================================================
20077// Test Period.now() with tz parameter
20078// ============================================================================
20079
20080void pd_test_period_now_tz() {
20081    std::cout << "========= Period.now(tz) ================================";
20082
20083    // Test now() with default (local time)
20084    auto p_local = pandas::Period::now("D");
20085
20086    // Test now() with UTC timezone
20087    auto p_utc = pandas::Period::now("D", "UTC");
ordinal (pd_test_5_all.cpp:41796)
41786    std::cout << "----- case_11_period_nat_sentinel_api_self_check -----\n";
41787    pandas::Period nat1 = pandas::Period::NaT("D");
41788    pandas::Period nat2;  // default ctor = NaT
41789    pandas::Period real(123, std::string("D"));
41790
41791    pandas_tests::check(nat1.isNaT(), "case11.NaT_factory_isNaT", local_fail);
41792    pandas_tests::check(nat2.isNaT(),
41793                        "case11.default_ctor_isNaT", local_fail);
41794    pandas_tests::check(!real.isNaT(),
41795                        "case11.real_period_is_NOT_NaT", local_fail);
41796    pandas_tests::check(nat1.ordinal() == pandas::PERIOD_NAT,
41797                        "case11.NaT_ordinal_equals_PERIOD_NAT_sentinel", local_fail);
41798    pandas_tests::check(real.ordinal() == 123,
41799                        "case11.real_period_ordinal_value", local_fail);
41800
41801    std::cout << "  NaT.ordinal=" << nat1.ordinal()
41802              << " PERIOD_NAT=" << pandas::PERIOD_NAT
41803              << " real.ordinal=" << real.ordinal() << "\n";
41804}
41805
41806void case_12_period_oracle_parity_subset(int& local_fail) {
quarter (pd_test_1_all.cpp:1218)
1208    void pd_test_datetime_array_quarter() {
1209        std::cout << "========= DatetimeArray: quarter ======================= ";
1210
1211        pandas::DatetimeArray arr(std::vector<std::string>{
1212            "2023-01-15",  // Q1
1213            "2023-05-20",  // Q2
1214            "2023-09-10",  // Q3
1215            "2023-11-25"   // Q4
1216        });
1217
1218        auto quarters = arr.quarter();
1219
1220        auto q0 = quarters[0];
1221        if (!q0.has_value() || q0.value() != 1) {
1222            std::cout << "  [FAIL] : quarter[0] should be 1" << std::endl;
1223            throw std::runtime_error("pd_test_datetime_array_quarter failed: quarter[0]");
1224        }
1225        auto q1 = quarters[1];
1226        if (!q1.has_value() || q1.value() != 2) {
1227            std::cout << "  [FAIL] : quarter[1] should be 2" << std::endl;
1228            throw std::runtime_error("pd_test_datetime_array_quarter failed: quarter[1]");
qyear (pd_test_1_all.cpp:17092)
17082// ============================================================================
17083
17084void pd_test_period_index_qyear() {
17085    std::cout << "========= qyear property ==============================";
17086
17087    // Monthly periods in Q1 2020
17088    std::vector<int> years = {2020, 2020, 2020};
17089    std::vector<int> months = {1, 2, 3};
17090    pandas::PeriodIndex idx = pandas::PeriodIndex::from_fields(years, months, {}, {}, {}, {}, "M");
17091
17092    pandas::IntegerArray<numpy::int32> qyears = idx.qyear();
17093
17094    bool passed = (qyears.size() == 3 &&
17095                   qyears[0].has_value() && *qyears[0] == 2020 &&
17096                   qyears[1].has_value() && *qyears[1] == 2020 &&
17097                   qyears[2].has_value() && *qyears[2] == 2020);
17098    if (!passed) {
17099        std::cout << "  [FAIL] : in pd_test_period_index_qyear()" << std::endl;
17100        throw std::runtime_error("pd_test_period_index_qyear failed");
17101    }
repr (pd_test_1_all.cpp:10906)
10896    std::cout << " -> tests passed" << std::endl;
10897}
10898
10899void pd_test_extension_index_repr() {
10900    std::cout << "========= repr =========================";
10901
10902    pandas::CategoricalArray arr({"a", "b", "c"});
10903    // Use ExtensionIndex<CategoricalArray> directly to test base class repr
10904    pandas::ExtensionIndex<pandas::CategoricalArray> idx(arr, "test");
10905
10906    std::string repr_str = idx.repr();
10907
10908    bool passed = (!repr_str.empty() && repr_str.find("ExtensionIndex") != std::string::npos);
10909    if (!passed) {
10910        std::cout << "  [FAIL] : in pd_test_extension_index_repr() : repr check failed" << std::endl;
10911        throw std::runtime_error("pd_test_extension_index_repr failed");
10912    }
10913
10914    std::cout << " -> tests passed" << std::endl;
10915}
second (pd_test_1_all.cpp:7534)
7524    std::cout << "========= second property =============================";
7525
7526    std::vector<std::optional<numpy::datetime64>> values = {
7527        make_dt(0),                    // Second 0
7528        make_dt(30 * NS_PER_SEC),      // Second 30
7529        make_dt(59 * NS_PER_SEC)       // Second 59
7530    };
7531    pandas::DatetimeArray arr(values);
7532    pandas::DatetimeIndex idx(arr);
7533
7534    auto seconds = idx.second();
7535
7536    bool passed = (seconds.size() == 3);
7537    auto s0 = seconds[0];
7538    auto s1 = seconds[1];
7539    auto s2 = seconds[2];
7540    passed = passed && s0.has_value() && *s0 == 0;
7541    passed = passed && s1.has_value() && *s1 == 30;
7542    passed = passed && s2.has_value() && *s2 == 59;
7543
7544    if (!passed) {
start_time (pd_test_1_all.cpp:2848)
2838            std::cout << "  [FAIL] : ts_start[0] should have value" << std::endl;
2839            throw std::runtime_error("pd_test_period_array_to_timestamp failed: ts_start[0]");
2840        }
2841
2842        auto ts2 = ts_start[2];
2843        if (ts2.has_value()) {
2844            std::cout << "  [FAIL] : ts_start[2] should be NaT" << std::endl;
2845            throw std::runtime_error("pd_test_period_array_to_timestamp failed: ts_start[2]");
2846        }
2847
2848        // start_time() alias
2849        auto start_times = arr.start_time();
2850        if (start_times.size() != 3) {
2851            std::cout << "  [FAIL] : start_time size should be 3" << std::endl;
2852            throw std::runtime_error("pd_test_period_array_to_timestamp failed: start_time size");
2853        }
2854
2855        std::cout << " -> tests passed" << std::endl;
2856    }
2857
2858    void pd_test_period_array_asfreq() {
strftime (pd_test_1_all.cpp:8434)
8424void pd_test_datetime_mixin_strftime() {
8425    std::cout << "========= strftime ====================================";
8426
8427    std::vector<std::optional<numpy::datetime64>> values = {
8428        numpy::datetime64(0LL, numpy::DateTimeUnit::Nanosecond),  // 1970-01-01
8429        numpy::datetime64(86400000000000LL, numpy::DateTimeUnit::Nanosecond)  // 1970-01-02
8430    };
8431    pandas::DatetimeArray arr(values);
8432    pandas::DatetimeMixinIndex idx(arr);
8433
8434    std::vector<std::string> formatted = idx.strftime("%Y-%m-%d");
8435
8436    bool passed = (formatted.size() == 2 && !formatted[0].empty() && !formatted[1].empty());
8437    if (!passed) {
8438        std::cout << "  [FAIL] : in pd_test_datetime_mixin_strftime()" << std::endl;
8439        throw std::runtime_error("pd_test_datetime_mixin_strftime failed");
8440    }
8441
8442    std::cout << " -> tests passed" << std::endl;
8443}
toString (pd_test_1_all.cpp:9539)
9529void pd_test_timedelta_rounding_params() {
9530    std::cout << "========= Timedelta rounding with DST params =====";
9531
9532    // Create a Timedelta: 1h 30m 45s
9533    // Constructor is: (days, hours, minutes, seconds, ...)
9534    pandas::Timedelta td(0, 1, 30, 45);  // 0 days, 1h, 30m, 45s
9535
9536    // Test floor with ambiguous/nonexistent params
9537    pandas::Timedelta floored = td.floor("h", "raise", "raise");
9538    std::cout << std::endl << "  floor('h'): " << floored.toString();
9539
9540    // Test ceil with ambiguous/nonexistent params
9541    pandas::Timedelta ceiled = td.ceil("h", "raise", "raise");
9542    std::cout << std::endl << "  ceil('h'): " << ceiled.toString();
9543
9544    // Test round with ambiguous/nonexistent params
9545    pandas::Timedelta rounded = td.round("h", "raise", "raise");
9546    std::cout << std::endl << "  round('h'): " << rounded.toString();
9547
9548    // Verify results:
week (pd_test_timestamp_scalar.cpp:406)
396      // 2024-06-15 is a Saturday
397      pandas::Timestamp ts(2024, 6, 15);
398
399      if (ts.dayofweek() != 5) { pass = false; fail_msg = "2024-06-15 should be Saturday (5)"; }
400      if (ts.day_of_week() != 5) { pass = false; fail_msg = "day_of_week alias"; }
401      if (ts.dayofyear() != 167) { pass = false; fail_msg = "2024-06-15 should be day 167"; }
402      if (ts.day_of_year() != 167) { pass = false; fail_msg = "day_of_year alias"; }
403      if (ts.quarter() != 2) { pass = false; fail_msg = "June is Q2"; }
404      if (ts.days_in_month() != 30) { pass = false; fail_msg = "June has 30 days"; }
405
406      int week = ts.week();
407      if (week < 1 || week > 53) { pass = false; fail_msg = "week should be 1-53"; }
408
409      if (!pass) {
410        std::cout << "  [FAIL] : in np_test_timestamp_derived() : " << fail_msg;
411        throw std::runtime_error("np_test_timestamp_derived failed: " + fail_msg);
412      }
413
414      std::cout << " -> tests passed" << std::endl;
415    }
year (pd_test_1_all.cpp:1147)
1137    void pd_test_datetime_array_component_year() {
1138        std::cout << "========= DatetimeArray: year component ======================= ";
1139
1140        pandas::DatetimeArray arr(std::vector<std::string>{
1141            "2020-01-15",
1142            "NaT",
1143            "2025-06-20"
1144        });
1145
1146        auto years = arr.year();
1147
1148        auto y0 = years[0];
1149        if (!y0.has_value() || y0.value() != 2020) {
1150            std::cout << "  [FAIL] : year[0] should be 2020" << std::endl;
1151            throw std::runtime_error("pd_test_datetime_array_component_year failed: year[0]");
1152        }
1153
1154        auto y1 = years[1];
1155        if (y1.has_value()) {
1156            std::cout << "  [FAIL] : year[1] should be NA (NaT)" << std::endl;