Jiff supports adding non-uniform units (like days) to time zone aware datetimes. It handles DST transitions (23-hour or 25-hour days) correctly so that adding a day preserves the expected civil time. It also allows consistent conversion between calendar units (days) and clock units (hours) using Span.
use jiff::{civil::date, ToSpan, Unit};
fn main() -> anyhow::Result<()> {
let zdt1 = date(2024, 3, 9).at(21, 0, 0, 0).in_tz("America/New_York")?;
let zdt2 = zdt1.checked_add(1.day())?;
// Even though 2 o'clock didn't occur on 2024-03-10, adding 1 day
// returns the same civil time the next day.
assert_eq!(zdt2.to_string(), "2024-03-10T21:00:00-04:00[America/New_York]");
// The span of time is 23 hours:
assert_eq!(&zdt2 - &zdt1, 23.hours().fieldwise());
// But if you ask for the span in units of days, you get exactly 1:
assert_eq!(zdt1.until((Unit::Day, &zdt2))?, 1.day().fieldwise());
Ok(())
}