/// A *temporary* object which can be used as an argument to `format!` or others. /// This is normally constructed via `format` methods of each date and time type. #[cfg(feature = "alloc")] #[derive(Debug)] pubstruct DelayedFormat<I> { /// The date view, if any.
date: Option<NaiveDate>, /// The time view, if any.
time: Option<NaiveTime>, /// The name and local-to-UTC difference for the offset (timezone), if any.
off: Option<(String, FixedOffset)>, /// An iterator returning formatting items.
items: I, /// Locale used for text. /// ZST if the `unstable-locales` feature is not enabled.
locale: Locale,
}
#[cfg(feature = "alloc")] impl<'a, I: Iterator<Item = B> + Clone, B: Borrow<Item<'a>>> DelayedFormat<I> { /// Makes a new `DelayedFormat` value out of local date and time. #[must_use] pubfn new(date: Option<NaiveDate>, time: Option<NaiveTime>, items: I) -> DelayedFormat<I> {
DelayedFormat { date, time, off: None, items, locale: default_locale() }
}
/// Makes a new `DelayedFormat` value out of local date and time and UTC offset. #[must_use] pubfn new_with_offset<Off>(
date: Option<NaiveDate>,
time: Option<NaiveTime>,
offset: &Off,
items: I,
) -> DelayedFormat<I> where
Off: Offset + Display,
{ let name_and_diff = (offset.to_string(), offset.fix());
DelayedFormat { date, time, off: Some(name_and_diff), items, locale: default_locale() }
}
/// Makes a new `DelayedFormat` value out of local date and time and locale. #[cfg(feature = "unstable-locales")] #[must_use] pubfn new_with_locale(
date: Option<NaiveDate>,
time: Option<NaiveTime>,
items: I,
locale: Locale,
) -> DelayedFormat<I> {
DelayedFormat { date, time, off: None, items, locale }
}
/// Makes a new `DelayedFormat` value out of local date and time, UTC offset and locale. #[cfg(feature = "unstable-locales")] #[must_use] pubfn new_with_offset_and_locale<Off>(
date: Option<NaiveDate>,
time: Option<NaiveTime>,
offset: &Off,
items: I,
locale: Locale,
) -> DelayedFormat<I> where
Off: Offset + Display,
{ let name_and_diff = (offset.to_string(), offset.fix());
DelayedFormat { date, time, off: Some(name_and_diff), items, locale }
}
/// Formats `DelayedFormat` into a `core::fmt::Write` instance. /// # Errors /// This function returns a `core::fmt::Error` if formatting into the `core::fmt::Write` instance fails. /// /// # Example /// ### Writing to a String /// ``` /// let dt = chrono::DateTime::from_timestamp(1643723400, 123456789).unwrap(); /// let df = dt.format("%Y-%m-%d %H:%M:%S%.9f"); /// let mut buffer = String::new(); /// let _ = df.write_to(&mut buffer); /// ``` pubfn write_to(&self, w: &mut (impl Write + ?Sized)) -> fmt::Result { for item inself.items.clone() { match *item.borrow() {
Item::Literal(s) | Item::Space(s) => w.write_str(s), #[cfg(feature = "alloc")]
Item::OwnedLiteral(ref s) | Item::OwnedSpace(ref s) => w.write_str(s),
Item::Numeric(ref spec, pad) => self.format_numeric(w, spec, pad),
Item::Fixed(ref spec) => self.format_fixed(w, spec),
Item::Error => Err(fmt::Error),
}?;
}
Ok(())
}
#[cfg(any(feature = "alloc", feature = "serde"))] impl OffsetFormat { /// Writes an offset from UTC with the format defined by `self`. fn format(&self, w: &mut (impl Write + ?Sized), off: FixedOffset) -> fmt::Result { let off = off.local_minus_utc(); ifself.allow_zulu && off == 0 {
w.write_char('Z')?; return Ok(());
} let (sign, off) = if off < 0 { ('-', -off) } else { ('+', off) };
let hours; letmut mins = 0; letmut secs = 0; let precision = matchself.precision {
OffsetPrecision::Hours => { // Minutes and seconds are simply truncated
hours = (off / 3600) as u8;
OffsetPrecision::Hours
}
OffsetPrecision::Minutes | OffsetPrecision::OptionalMinutes => { // Round seconds to the nearest minute. let minutes = (off + 30) / 60;
mins = (minutes % 60) as u8;
hours = (minutes / 60) as u8; ifself.precision == OffsetPrecision::OptionalMinutes && mins == 0 {
OffsetPrecision::Hours
} else {
OffsetPrecision::Minutes
}
}
OffsetPrecision::Seconds
| OffsetPrecision::OptionalSeconds
| OffsetPrecision::OptionalMinutesAndSeconds => { let minutes = off / 60;
secs = (off % 60) as u8;
mins = (minutes % 60) as u8;
hours = (minutes / 60) as u8; ifself.precision != OffsetPrecision::Seconds && secs == 0 { ifself.precision == OffsetPrecision::OptionalMinutesAndSeconds && mins == 0 {
OffsetPrecision::Hours
} else {
OffsetPrecision::Minutes
}
} else {
OffsetPrecision::Seconds
}
}
}; let colons = self.colons == Colons::Colon;
/// Specific formatting options for seconds. This may be extended in the /// future, so exhaustive matching in external code is not recommended. /// /// See the `TimeZone::to_rfc3339_opts` function for usage. #[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)] #[allow(clippy::manual_non_exhaustive)] pubenum SecondsFormat { /// Format whole seconds only, with no decimal point nor subseconds.
Secs,
/// Use fixed 3 subsecond digits. This corresponds to [Fixed::Nanosecond3].
Millis,
/// Use fixed 6 subsecond digits. This corresponds to [Fixed::Nanosecond6].
Micros,
/// Use fixed 9 subsecond digits. This corresponds to [Fixed::Nanosecond9].
Nanos,
/// Automatically select one of `Secs`, `Millis`, `Micros`, or `Nanos` to display all available /// non-zero sub-second digits. This corresponds to [Fixed::Nanosecond].
AutoSi,
// Do not match against this. #[doc(hidden)]
__NonExhaustive,
}
/// Writes the date, time and offset to the string. same as `%Y-%m-%dT%H:%M:%S%.f%:z` #[inline] #[cfg(any(feature = "alloc", feature = "serde"))] pub(crate) fn write_rfc3339(
w: &mut (impl Write + ?Sized),
dt: NaiveDateTime,
off: FixedOffset,
secform: SecondsFormat,
use_z: bool,
) -> fmt::Result { let year = dt.date().year(); if (0..=9999).contains(&year) {
write_hundreds(w, (year / 100) as u8)?;
write_hundreds(w, (year % 100) as u8)?;
} else { // ISO 8601 requires the explicit sign for out-of-range years
write!(w, "{year:+05}")?;
}
w.write_char('-')?;
write_hundreds(w, dt.date().month() as u8)?;
w.write_char('-')?;
write_hundreds(w, dt.date().day() as u8)?;
w.write_char('T')?;
let (hour, min, mut sec) = dt.time().hms(); letmut nano = dt.nanosecond(); if nano >= 1_000_000_000 {
sec += 1;
nano -= 1_000_000_000;
}
write_hundreds(w, hour as u8)?;
w.write_char(':')?;
write_hundreds(w, min as u8)?;
w.write_char(':')?; let sec = sec;
write_hundreds(w, sec as u8)?;
#[cfg(feature = "alloc")] /// write datetimes like `Tue, 1 Jul 2003 10:52:37 +0200`, same as `%a, %d %b %Y %H:%M:%S %z` pub(crate) fn write_rfc2822(
w: &mut (impl Write + ?Sized),
dt: NaiveDateTime,
off: FixedOffset,
) -> fmt::Result { let year = dt.year(); // RFC2822 is only defined on years 0 through 9999 if !(0..=9999).contains(&year) { return Err(fmt::Error);
}
let english = default_locale();
w.write_str(short_weekdays(english)[dt.weekday().num_days_from_sunday() as usize])?;
w.write_str(", ")?; let day = dt.day(); if day < 10 {
w.write_char((b'0' + day as u8) as char)?;
} else {
write_hundreds(w, day as u8)?;
}
w.write_char(' ')?;
w.write_str(short_months(english)[dt.month0() as usize])?;
w.write_char(' ')?;
write_hundreds(w, (year / 100) as u8)?;
write_hundreds(w, (year % 100) as u8)?;
w.write_char(' ')?;
let (hour, min, sec) = dt.time().hms();
write_hundreds(w, hour as u8)?;
w.write_char(':')?;
write_hundreds(w, min as u8)?;
w.write_char(':')?; let sec = sec + dt.nanosecond() / 1_000_000_000;
write_hundreds(w, sec as u8)?;
w.write_char(' ')?;
OffsetFormat {
precision: OffsetPrecision::Minutes,
colons: Colons::None,
allow_zulu: false,
padding: Pad::Zero,
}
.format(w, off)
}
/// Equivalent to `{:02}` formatting for n < 100. pub(crate) fn write_hundreds(w: &mut (impl Write + ?Sized), n: u8) -> fmt::Result { if n >= 100 { return Err(fmt::Error);
}
let tens = b'0' + n / 10; let ones = b'0' + n % 10;
w.write_char(tens as char)?;
w.write_char(ones as char)
}
let t = NaiveTime::from_hms_micro_opt(3, 5, 7, 432100).unwrap();
assert_eq!(t.format("%S,%f,%.f").to_string(), "07,432100000,.432100");
assert_eq!(t.format("%.3f,%.6f,%.9f").to_string(), ".432,.432100,.432100000");
let t = NaiveTime::from_hms_milli_opt(3, 5, 7, 210).unwrap();
assert_eq!(t.format("%S,%f,%.f").to_string(), "07,210000000,.210");
assert_eq!(t.format("%.3f,%.6f,%.9f").to_string(), ".210,.210000,.210000000");
let t = NaiveTime::from_hms_opt(3, 5, 7).unwrap();
assert_eq!(t.format("%S,%f,%.f").to_string(), "07,000000000,");
assert_eq!(t.format("%.3f,%.6f,%.9f").to_string(), ".000,.000000,.000000000");
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.