chrono
chrono copied to clipboard
unexpected behavior of `duration_trunc` with `DateTime<FixedOffset>`
extern crate chrono; // 0.4.19
use chrono::{FixedOffset, Utc, Duration, DurationRound, Timelike};
fn main() {
let t = Utc::now();
let t = t.with_timezone(&FixedOffset::east(9 * 3600));
let t = t.duration_trunc(Duration::days(1)).unwrap();
assert_eq!(t.second(), 0);
assert_eq!(t.minute(), 0);
assert_eq!(t.hour(), 0); // I expect 0, but got 9.
}
Compiling playground v0.0.1 (/playground)
Finished dev [unoptimized + debuginfo] target(s) in 1.72s
Running `target/debug/playground`
thread 'main' panicked at 'assertion failed: `(left == right)`
left: `9`,
right: `0`', src/main.rs:11:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
I want to get the truncated time with timezone aware.
Copied the example from the docs https://docs.rs/chrono/0.4.13/chrono/trait.DurationRound.html#example-1 and changed to use Local vs Utc.
let dt = Local.ymd(2018, 1, 11).and_hms_milli(12, 0, 0, 154);
assert_eq!(
dt.duration_trunc(Duration::milliseconds(10)).unwrap().to_string(),
"2018-01-11 12:00:00.150 -08:00" // Seems like millisec truncation works just fine
);
assert_eq!(
dt.duration_trunc(Duration::days(1)).unwrap().to_string(),
"2018-01-11 00:00:00 -08:00" // got "2018-01-10 16:00:00 -08:00"
);
thread 'tests::duration_trunc' panicked at 'assertion failed: `(left == right)`
left: `"2018-01-10 16:00:00 -08:00"`,
right: `"2018-01-11 00:00:00 -08:00"`'
There's definitely an issue with timezone conversions and truncation duration_trunc seems to be converting to UTC then truncating and then converting back to TZ which is going to give unexpected results. Interestingly millisec seems to behave just fine.