Convert an optional timezone-aware Python datetime to a UTC timestamp.
(value: Option<&Bound<'_, PyAny>>)
| 44 | |
| 45 | /// Convert an optional timezone-aware Python datetime to a UTC timestamp. |
| 46 | pub fn opt_py_to_timestamp(value: Option<&Bound<'_, PyAny>>) -> PyResult<Option<DateTime<Utc>>> { |
| 47 | let Some(timestamp) = value.filter(|timestamp| !timestamp.is_none()) else { |
| 48 | return Ok(None); |
| 49 | }; |
| 50 | |
| 51 | let py = timestamp.py(); |
| 52 | let datetime_type = py.import("datetime")?.getattr("datetime")?; |
| 53 | if !timestamp.is_instance(&datetime_type)? { |
| 54 | return Err(pyo3::exceptions::PyTypeError::new_err( |
| 55 | "timestamp must be a datetime.datetime object", |
| 56 | )); |
| 57 | } |
| 58 | if timestamp.getattr("tzinfo")?.is_none() || timestamp.call_method0("utcoffset")?.is_none() { |
| 59 | return Err(pyo3::exceptions::PyValueError::new_err( |
| 60 | "timestamp datetime must be timezone-aware", |
| 61 | )); |
| 62 | } |
| 63 | |
| 64 | let iso_timestamp: String = timestamp.call_method0("isoformat")?.extract()?; |
| 65 | DateTime::parse_from_rfc3339(&iso_timestamp) |
| 66 | .map(|timestamp| Some(timestamp.with_timezone(&Utc))) |
| 67 | .map_err(|e| pyo3::exceptions::PyValueError::new_err(format!("invalid timestamp: {e}"))) |
| 68 | } |
| 69 | |
| 70 | #[cfg(test)] |
| 71 | #[path = "../tests/unit/convert_tests.rs"] |
no outgoing calls
no test coverage detected