Skip to content

Commit

Permalink
Fix fixed offset timezone conversion bug.
Browse files Browse the repository at this point in the history
  • Loading branch information
grantslatton committed Jun 24, 2023
1 parent edf47b5 commit 7c86007
Showing 1 changed file with 30 additions and 5 deletions.
35 changes: 30 additions & 5 deletions src/conversions/chrono.rs
Original file line number Diff line number Diff line change
Expand Up @@ -216,8 +216,8 @@ impl FromPyObject<'_> for NaiveDateTime {

impl<Tz: TimeZone> ToPyObject for DateTime<Tz> {
fn to_object(&self, py: Python<'_>) -> PyObject {
let date = self.naive_utc().date();
let time = self.naive_utc().time();
let date = self.naive_local().date();
let time = self.naive_local().time();
let yy = date.year();
let mm = date.month() as u8;
let dd = date.day() as u8;
Expand Down Expand Up @@ -261,7 +261,7 @@ impl FromPyObject<'_> for DateTime<FixedOffset> {
NaiveTime::from_hms_micro_opt(h, m, s, ms)
.ok_or_else(|| PyValueError::new_err("invalid or out-of-range time"))?,
);
Ok(DateTime::from_utc(dt, tz))
Ok(DateTime::from_local(dt, tz))
}
}

Expand Down Expand Up @@ -372,6 +372,7 @@ impl FromPyObject<'_> for Utc {
#[cfg(test)]
mod tests {
use std::{cmp::Ordering, panic};
use crate::types::PyDict;

use super::*;

Expand Down Expand Up @@ -607,7 +608,7 @@ mod tests {
.and_hms_micro_opt(hour, minute, ssecond, ms)
.unwrap();
let datetime =
DateTime::<FixedOffset>::from_utc(datetime, offset).to_object(py);
DateTime::<FixedOffset>::from_local(datetime, offset).to_object(py);
let datetime: &PyDateTime = datetime.extract(py).unwrap();
let py_tz = offset.to_object(py);
let py_tz = py_tz.downcast(py).unwrap();
Expand Down Expand Up @@ -700,7 +701,7 @@ mod tests {
.unwrap()
.and_hms_micro_opt(hour, minute, second, ms)
.unwrap();
let datetime = DateTime::<FixedOffset>::from_utc(datetime, offset);
let datetime = DateTime::<FixedOffset>::from_local(datetime, offset);
assert_eq!(
py_datetime, datetime,
"{}: {} != {}",
Expand Down Expand Up @@ -729,6 +730,30 @@ mod tests {
})
}

#[test]
fn test_pyo3_offset_fixed_frompyobject_created_in_python() {
Python::with_gil(|py| {
let code = r#"
import datetime
t = datetime.datetime.fromtimestamp(12345).replace(tzinfo=datetime.timezone(datetime.timedelta(hours=-8)))
"#.trim();

let globals = PyDict::new(py);
py.run(code, Some(globals), None).unwrap();

// Get ISO 8601 string from python
let t = globals.get_item("t").unwrap();
let py_iso_str = t.call_method0("isoformat").unwrap();

// Get ISO 8601 string from rust
let t = t.extract::<DateTime<FixedOffset>>().unwrap();
let rust_iso_str = t.to_rfc3339();

// They should be equal
assert_eq!(py_iso_str.to_string(), rust_iso_str);
})
}

#[test]
fn test_pyo3_offset_fixed_topyobject() {
Python::with_gil(|py| {
Expand Down

0 comments on commit 7c86007

Please sign in to comment.