Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ name = "chrono"
# Don't forget to adjust `ALL_NON_EXCLUSIVE_FEATURES` in CI scripts when adding a feature or an optional dependency.
default = ["clock", "std", "oldtime", "wasmbind"]
alloc = []
defmt = ["dep:defmt"]
libc = []
winapi = ["windows-targets"]
std = ["alloc"]
Expand All @@ -43,6 +44,7 @@ serde = { version = "1.0.99", default-features = false, optional = true }
pure-rust-locales = { version = "0.8", optional = true }
rkyv = { version = "0.7.43", optional = true, default-features = false }
arbitrary = { version = "1.0.0", features = ["derive"], optional = true }
defmt = { version = "0.3", optional = true }

[target.'cfg(all(target_arch = "wasm32", not(any(target_os = "emscripten", target_os = "wasi"))))'.dependencies]
wasm-bindgen = { version = "0.2", optional = true }
Expand Down
10 changes: 10 additions & 0 deletions src/date.rs
Original file line number Diff line number Diff line change
Expand Up @@ -551,6 +551,16 @@ where
}
}

#[cfg(feature = "defmt")]
impl<Tz: TimeZone> defmt::Format for Date<Tz>
where
Tz::Offset: defmt::Format,
{
fn format(&self, fmt: defmt::Formatter) {
defmt::write!(fmt, "{}{}", self.naive_local(), self.offset);
}
}

// Note that implementation of Arbitrary cannot be automatically derived for Date<Tz>, due to
// the nontrivial bound <Tz as TimeZone>::Offset: Arbitrary.
#[cfg(all(feature = "arbitrary", feature = "std"))]
Expand Down
10 changes: 10 additions & 0 deletions src/datetime/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1761,6 +1761,16 @@ impl<Tz: TimeZone> fmt::Debug for DateTime<Tz> {
}
}

#[cfg(feature = "defmt")]
impl<Tz: TimeZone> defmt::Format for DateTime<Tz>
where
Tz::Offset: defmt::Format,
{
fn format(&self, fmt: defmt::Formatter) {
defmt::write!(fmt, "{}{}", self.overflowing_naive_local(), self.offset);
}
}

// `fmt::Debug` is hand implemented for the `rkyv::Archive` variant of `DateTime` because
// deriving a trait recursively does not propagate trait defined associated types with their own
// constraints:
Expand Down
7 changes: 7 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -684,6 +684,13 @@ impl fmt::Debug for OutOfRange {
}
}

#[cfg(feature = "defmt")]
impl defmt::Format for OutOfRange {
fn format(&self, fmt: defmt::Formatter) {
defmt::write!(fmt, "out of range");
}
}

#[cfg(feature = "std")]
impl std::error::Error for OutOfRange {}

Expand Down
7 changes: 7 additions & 0 deletions src/month.rs
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,13 @@ impl fmt::Debug for ParseMonthError {
}
}

#[cfg(feature = "defmt")]
impl defmt::Format for ParseMonthError {
fn format(&self, fmt: defmt::Formatter) {
defmt::write!(fmt, "ParseMonthError {{ .. }}")
}
}

#[cfg(feature = "serde")]
mod month_serde {
use super::Month;
Expand Down
19 changes: 19 additions & 0 deletions src/naive/date/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2128,6 +2128,7 @@ impl From<NaiveDateTime> for NaiveDate {

/// Iterator over `NaiveDate` with a step size of one day.
#[derive(Debug, Copy, Clone, Hash, PartialEq, PartialOrd, Eq, Ord)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct NaiveDateDaysIterator {
value: NaiveDate,
}
Expand Down Expand Up @@ -2164,6 +2165,7 @@ impl FusedIterator for NaiveDateDaysIterator {}

/// Iterator over `NaiveDate` with a step size of one week.
#[derive(Debug, Copy, Clone, Hash, PartialEq, PartialOrd, Eq, Ord)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct NaiveDateWeeksIterator {
value: NaiveDate,
}
Expand Down Expand Up @@ -2238,6 +2240,23 @@ impl fmt::Debug for NaiveDate {
}
}

#[cfg(feature = "defmt")]
impl defmt::Format for NaiveDate {
fn format(&self, fmt: defmt::Formatter) {
let year = self.year();
let mdf = self.mdf();
if (0..=9999).contains(&year) {
defmt::write!(fmt, "{:02}{:02}", year / 100, year % 100);
} else {
// ISO 8601 requires the explicit sign for out-of-range years
let sign = ['+', '-'][(year < 0) as usize];
defmt::write!(fmt, "{}{:05}", sign, year.abs());
}

defmt::write!(fmt, "-{:02}-{:02}", mdf.month(), mdf.day());
}
}

/// The `Display` output of the naive date `d` is the same as
/// [`d.format("%Y-%m-%d")`](crate::format::strftime).
///
Expand Down
7 changes: 7 additions & 0 deletions src/naive/datetime/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2053,6 +2053,13 @@ impl fmt::Debug for NaiveDateTime {
}
}

#[cfg(feature = "defmt")]
impl defmt::Format for NaiveDateTime {
fn format(&self, fmt: defmt::Formatter) {
defmt::write!(fmt, "{}T{}", self.date, self.time);
}
}

/// The `Display` output of the naive date and time `dt` is the same as
/// [`dt.format("%Y-%m-%d %H:%M:%S%.f")`](crate::format::strftime).
///
Expand Down
15 changes: 15 additions & 0 deletions src/naive/isoweek.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,21 @@ impl fmt::Debug for IsoWeek {
}
}

#[cfg(feature = "defmt")]
impl defmt::Format for IsoWeek {
fn format(&self, fmt: defmt::Formatter) {
let year = self.year();
let week = self.week();
if (0..=9999).contains(&year) {
defmt::write!(fmt, "{:04}-W{:02}", year, week)
} else {
// ISO 8601 requires the explicit sign for out-of-range years
let sign = ['+', '-'][(year < 0) as usize];
defmt::write!(fmt, "{}{:05}-W{:02}", sign, year.abs(), week)
}
}
}

#[cfg(test)]
mod tests {
#[cfg(feature = "rkyv-validation")]
Expand Down
25 changes: 25 additions & 0 deletions src/naive/time/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1529,6 +1529,31 @@ impl fmt::Debug for NaiveTime {
}
}

#[cfg(feature = "defmt")]
impl defmt::Format for NaiveTime {
fn format(&self, fmt: defmt::Formatter) {
let (hour, min, sec) = self.hms();
let (sec, nano) = if self.frac >= 1_000_000_000 {
(sec + 1, self.frac - 1_000_000_000)
} else {
(sec, self.frac)
};

let (hour, min, sec) = (hour as u8, min as u8, sec as u8);
defmt::write!(fmt, "{:02}:{:02}:{:02}", hour, min, sec);

if nano == 0 {
return;
} else if nano % 1_000_000 == 0 {
defmt::write!(fmt, ".{:03}", nano / 1_000_000);
} else if nano % 1_000 == 0 {
defmt::write!(fmt, ".{:06}", nano / 1_000);
} else {
defmt::write!(fmt, ".{:09}", nano);
}
}
}

/// The `Display` output of the naive time `t` is the same as
/// [`t.format("%H:%M:%S%.f")`](crate::format::strftime).
///
Expand Down
1 change: 1 addition & 0 deletions src/offset/fixed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ use crate::naive::{NaiveDate, NaiveDateTime};
archive_attr(derive(Clone, Copy, PartialEq, Eq, Hash, Debug))
)]
#[cfg_attr(feature = "rkyv-validation", archive(check_bytes))]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct FixedOffset {
local_minus_utc: i32,
}
Expand Down
1 change: 1 addition & 0 deletions src/offset/local/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ mod tz_info;
)]
#[cfg_attr(feature = "rkyv-validation", archive(check_bytes))]
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct Local;

impl Local {
Expand Down
1 change: 1 addition & 0 deletions src/round.rs
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,7 @@ where
///
/// See: [`DurationRound`]
#[derive(Debug, Clone, PartialEq, Eq, Copy)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum RoundingError {
/// Error when the TimeDelta exceeds the TimeDelta from or until the Unix epoch.
///
Expand Down
2 changes: 2 additions & 0 deletions src/time_delta.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ const SECS_PER_WEEK: i64 = 604_800;
archive_attr(derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Hash))
)]
#[cfg_attr(feature = "rkyv-validation", archive(check_bytes))]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct TimeDelta {
secs: i64,
nanos: i32, // Always 0 <= nanos < NANOS_PER_SEC
Expand Down Expand Up @@ -600,6 +601,7 @@ impl fmt::Display for TimeDelta {
/// *seconds*, while this module supports signed range of up to
/// `i64::MAX` of *milliseconds*.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct OutOfRangeError(());

impl fmt::Display for OutOfRangeError {
Expand Down
8 changes: 8 additions & 0 deletions src/weekday.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ use crate::OutOfRange;
)]
#[cfg_attr(feature = "rkyv-validation", archive(check_bytes))]
#[cfg_attr(all(feature = "arbitrary", feature = "std"), derive(arbitrary::Arbitrary))]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum Weekday {
/// Monday.
Mon = 0,
Expand Down Expand Up @@ -257,6 +258,13 @@ impl fmt::Debug for ParseWeekdayError {
}
}

#[cfg(feature = "defmt")]
impl defmt::Format for ParseWeekdayError {
fn format(&self, fmt: defmt::Formatter) {
defmt::write!(fmt, "ParseWeekdayError {{ .. }}")
}
}

// the actual `FromStr` implementation is in the `format` module to leverage the existing code

#[cfg(feature = "serde")]
Expand Down
Loading