S-JIS[2025-12-13]

pyo3 datetime型

Rustpyo3の日付型のメモ。


概要

Pythonのdatetimeモジュールの日付型は、PyO3 0.27ではpyo3::typesのPyDateTime等で扱う。


PyDateの例

日付(年月日)は、PyO3ではpyo3::types::PyDateで扱う。
関数の引数や戻り値の型としては、Py<PyDate>を指定する。

example-pyo3/src/lib.rs:

use pyo3::prelude::*;

#[pymodule]
mod example_pyo3 {
    use pyo3::{prelude::*, types::*};
〜

    #[pyfunction]
    fn inc_date(py: Python, date: &Bound<PyDate>) -> PyResult<Py<PyDate>> {
        let year = date.get_year();
        let month = date.get_month();
        let day = date.get_day();

        let next_date = PyDate::new(py, year, month, day + 1)?;
        Ok(next_date.into())
    }
}

pyが必要な場合、第1引数に「py: Python」を定義しておく。

Py<PyDate>はポインターのようなものらしく、into_pyobject(py)でオブジェクトとして扱えるようになる。


呼び出す例

Pythonプロジェクト側で、datetimeモジュールを依存ライブラリーに追加しておく。

cd call-pyo3
uv add datetime

call-pyo3/main.py:

import datetime
import example_pyo3

def main():
    print("Hello from call-pyo3!")
    print(example_pyo3.inc_date(datetime.date(2025, 12, 13)))

if __name__ == "__main__":
    main()

実行例

> cd call-pyo3
> uv run main.py
Hello from call-pyo3!
2025-12-14

chronoの例

Rustで日付を扱うchronoクレートをPyO3 0.27で使う例。


まず、chronoクレートを依存ライブラリーに追加する。

cd example-pyo3
cargo add chrono

次に、pyo3にchronoフィーチャーを追加する。

example-pyo3/Cargo.toml:

〜
[dependencies]
chrono = "0.4.42"
pyo3 = { version = "0.27.2", features = ["chrono"] }

PyDateとchrono::NaiveDateを変換する例。

example-pyo3/src/lib.rs:

use pyo3::prelude::*;

#[pymodule]
mod example_pyo3 {
    use pyo3::{prelude::*, types::*};
〜

    #[pyfunction]
    fn inc_date(py: Python, date: &Bound<PyDate>) -> PyResult<Py<PyDate>> {
        let date: chrono::NaiveDate = date.extract()?; // PyDateをchronoのNaiveDateに変換

        let next_date = date + chrono::Duration::days(1);
        let next_date = next_date.into_pyobject(py)?;   // chronoのNativeDateをPyDateに変換
        Ok(next_date.into())
    }
}

Pythonから呼び出す例


chronoを直接使用する例

pyfunctionの関数の引数や戻り値として直接chronoの日付を指定することも出来る。

use pyo3::prelude::*;

#[pymodule]
mod example_pyo3 {
    use pyo3::{prelude::*, types::*};
〜

    #[pyfunction]
    fn inc_date(date: chrono::NaiveDate) -> PyResult<chrono::NaiveDate> {
        let next_date = date + chrono::Duration::days(1);

        Ok(next_date)
    }
}

pyo3へ戻る / Rustへ戻る / 技術メモへ戻る
メールの送信先:ひしだま