Skip to main content

HeaderDateTime

Struct HeaderDateTime 

Source
#[non_exhaustive]
pub struct HeaderDateTime { pub year: u16, pub month: u8, pub day: u8, pub hour: u8, pub minute: u8, pub second: u8, pub tz_sign: TzSign, pub tz_hour: u8, pub tz_minute: u8, }
Expand description

An RFC 5322 §3.3 date-time value parsed from a header.

Public fields permit serde transparency and direct field access from JMAP-shaped code. The fields mirror mail_parser::DateTime 1-to-1 except for tz_sign, which is an explicit enum rather than a bool. This is a deliberate API choice — see TzSign — and means HeaderDateTime and mail_parser::DateTime are not bit-identical even though they round-trip via HeaderDateTime::from_mail_parser / HeaderDateTime::to_mail_parser.

§Wire-format dependency on mail-parser

Self::to_rfc3339 and Self::to_timestamp delegate to mail_parser::DateTime’s formatters. The exact strings produced by to_rfc3339, and the exact value produced by to_timestamp for edge-case input, are therefore defined by the pinned mail-parser version. mime-tree’s Cargo.toml uses a caret range (mail-parser = "0.11") so 0.11.x patch updates can in principle change the output without a mime-tree version bump. Downstream callers that persist these strings (database keys, JMAP wire responses, indexed columns) SHOULD pin mail-parser tightly if they require byte-stable output across mime-tree patch bumps.

§Field invariants

parse_header_typed only constructs HeaderDateTime values that passed mail-parser’s validation: year >= 1900, month ∈ 1..=12, day ∈ 1..=31 (calendar-validated), hour ∈ 0..=23, minute ∈ 0..=59, second ∈ 0..=60 (RFC 5322 §4.3 leap second), tz_hour ∈ 0..=23, tz_minute ∈ 0..=59.

Direct construction with public fields can produce out-of-range values. The behaviour of to_rfc3339 and to_timestamp on such values is unspecified — output may be syntactically malformed RFC 3339 or a meaningless i64. Callers that build HeaderDateTime from external sources should validate ranges themselves.

§Equality semantics

The derived PartialEq/Eq/Hash is field-wise, not instant-wise. Two HeaderDateTime values representing the same moment in time at different offsets compare as not-equal and hash differently. For example:

  2024-01-01T12:00:00+00:00   (12:00 UTC)
  2024-01-01T13:00:00+01:00   (12:00 UTC, expressed +01:00)

are the same instant but compare !=. Callers needing instant-equality (deduping timestamps across clients in different time zones, time-series bucketing) MUST compare Self::to_timestamp values rather than relying on the derived PartialEq.

Fields (Non-exhaustive)§

This struct is marked as non-exhaustive
Non-exhaustive structs could have additional fields added in future. Therefore, non-exhaustive structs cannot be constructed in external crates using the traditional Struct { .. } syntax; cannot be matched against without a wildcard ..; and struct update syntax will not work.
§year: u16

Four-digit calendar year. Parser-produced values: 1900..=3000.

§month: u8

Month of the year, 1..=12 for parser-produced values.

§day: u8

Day of the month, 1..=31 (calendar-validated against year/month) for parser-produced values.

§hour: u8

Hour of the day, 0..=23 for parser-produced values.

§minute: u8

Minute, 0..=59 for parser-produced values.

§second: u8

Second, 0..=60 for parser-produced values (RFC 5322 §4.3 allows 60 to represent a leap second).

§tz_sign: TzSign

Sign of the timezone offset from GMT.

§tz_hour: u8

Hours component of the timezone offset, 0..=23 for parser-produced values.

§tz_minute: u8

Minutes component of the timezone offset, 0..=59 for parser-produced values.

Implementations§

Source§

impl HeaderDateTime

Source

pub fn to_rfc3339(&self) -> String

Render as an RFC 3339 / ISO 8601 §5.6 date-time string.

§Output format
  • Non-UTC offset (any of tz_hour, tz_minute non-zero): YYYY-MM-DDTHH:MM:SS±HH:MM. Each component is zero-padded; ± is - for west-of-GMT, + otherwise.
  • UTC (tz_hour == 0 && tz_minute == 0): YYYY-MM-DDTHH:MM:SSZ. Zulu form, not +00:00.

No subsecond fraction is emitted (the seconds-fraction extension of RFC 3339 is not represented in HeaderDateTime).

§Examples
  • 1997-11-21T09:55:06-06:00 for 21 Nov 1997 09:55:06 -0600.
  • 2024-01-15T12:34:56Z for 15 Jan 2024 12:34:56 +0000.
§Behaviour on out-of-range input

The exact string for out-of-range field values (e.g. month = 13) is unspecified — it depends on the pinned mail-parser version and may not be syntactically valid RFC 3339. See the type-level docs.

Source

pub fn to_timestamp(&self) -> i64

Render as a Unix timestamp (seconds since 1970-01-01T00:00:00Z).

Pre-epoch dates return negative values. The result is computed linearly from the field values without validation; on out-of-range or otherwise invalid input (e.g. month = 0, day = 99, year overflowing the calendar arithmetic) the returned i64 is unspecified and SHOULD NOT be relied upon. See the type-level docs.

Trait Implementations§

Source§

impl Clone for HeaderDateTime

Source§

fn clone(&self) -> HeaderDateTime

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for HeaderDateTime

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<'de> Deserialize<'de> for HeaderDateTime

Source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
where __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl Display for HeaderDateTime

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Render as an RFC 3339 / ISO 8601 §5.6 date-time string by delegating to HeaderDateTime::to_rfc3339. See that method for the exact output format and behaviour on out-of-range input.

Source§

impl Eq for HeaderDateTime

Source§

impl Hash for HeaderDateTime

Source§

fn hash<__H: Hasher>(&self, state: &mut __H)

Feeds this value into the given Hasher. Read more
1.3.0 · Source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where H: Hasher, Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
Source§

impl PartialEq for HeaderDateTime

Source§

fn eq(&self, other: &HeaderDateTime) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl Serialize for HeaderDateTime

Source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
where __S: Serializer,

Serialize this value into the given Serde serializer. Read more
Source§

impl StructuralPartialEq for HeaderDateTime

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T> ToString for T
where T: Display + ?Sized,

Source§

fn to_string(&self) -> String

Converts the given value to a String. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.