Struct DateTimePrinter
struct DateTimePrinter { ... }
A printer for Temporal datetimes.
This printer converts an in memory representation of a datetime related
type to a machine (but also human) readable format. Using this printer, one
can convert Zoned, Timestamp, civil::DateTime, civil::Date
or civil::Time values to a string. Note that all of those types provide
Diplay implementations that utilize the default
configuration of this printer. However, this printer can be configured to
behave differently and can also print directly to anything that implements
the fmt::Write trait.
See the fmt::temporal module documentation for
more information on the specific format used. Note that the Temporal
datetime parser is strictly more flexible than what is supported by this
printer. For example, parsing 2024-06-15T07:00-04[America/New_York] will
work just fine, even though the seconds are omitted. However, this printer
provides no way to write a datetime without the second component.
Example
This example shows how to print a Zoned value with a space separating
the date and time instead of the more standard T separator.
use ;
// A printer can be created in a const context.
const PRINTER: DateTimePrinter = new.separator;
let zdt = date.at.in_tz?;
let mut buf = Stringnew;
// Printing to a `String` can never fail.
PRINTER.print_zoned.unwrap;
assert_eq!;
# Ok::
Example: using adapters with std::io::Write and std::fmt::Write
By using the StdIoWrite and
StdFmtWrite adapters, one can print datetimes
directly to implementations of std::io::Write and std::fmt::Write,
respectively. The example below demonstrates writing to anything
that implements std::io::Write. Similar code can be written for
std::fmt::Write.
use std::{fs::File, io::{BufWriter, Write}, path::Path};
use jiff::{civil::date, fmt::{StdIoWrite, temporal::DateTimePrinter}};
let zdt = date(2024, 6, 15).at(7, 0, 0, 0).in_tz("America/New_York")?;
let path = Path::new("/tmp/output");
let mut file = BufWriter::new(File::create(path)?);
DateTimePrinter::new().print_zoned(&zdt, StdIoWrite(&mut file)).unwrap();
file.flush()?;
assert_eq!(
std::fs::read_to_string(path)?,
"2024-06-15T07:00:00-04:00[America/New_York]",
);
# Ok::<(), Box<dyn std::error::Error>>(())
Implementations
impl DateTimePrinter
const fn new() -> DateTimePrinterCreate a new Temporal datetime printer with the default configuration.
const fn lowercase(self: Self, yes: bool) -> DateTimePrinterUse lowercase for the datetime separator and the
Z(Zulu) UTC offset.This is disabled by default.
Example
This example shows how to print a
Zonedvalue with a lowercase datetime separator.use ; const PRINTER: DateTimePrinter = new.lowercase; let zdt = date.at.in_tz?; let mut buf = Stringnew; // Printing to a `String` can never fail. PRINTER.print_zoned.unwrap; assert_eq!; # Ok::const fn separator(self: Self, ascii_char: u8) -> DateTimePrinterUse the given ASCII character to separate the date and time when printing
Zoned,Timestamporcivil::DateTimevalues.This is set to
Tby default.Example
This example shows how to print a
Zonedvalue with a different datetime separator.use ; // We use a weird non-standard character here, but typically one would // use this method with an ASCII space. const PRINTER: DateTimePrinter = new.separator; let zdt = date.at.in_tz?; let mut buf = Stringnew; // Printing to a `String` can never fail. PRINTER.print_zoned.unwrap; assert_eq!; # Ok::const fn precision(self: Self, precision: Option<u8>) -> DateTimePrinterSet the precision to use for formatting the fractional second component of a time.
The default is
None, which will automatically set the precision based on the value.When the precision is set to
N, you'll always get preciselyNdigits after a decimal point (unlessN==0, then no fractional component is printed), even if they are0.Example
use ; const PRINTER: DateTimePrinter = new.precision; let zdt = date.at.in_tz?; let mut buf = Stringnew; // Printing to a `String` can never fail. PRINTER.print_zoned.unwrap; assert_eq!; # Ok::Example: available via formatting machinery
When formatting datetime types that may contain a fractional second component, this can be set via Rust's formatting DSL. Specifically, it corresponds to the
std::fmt::Formatter::precisionsetting.use date; let zdt = date.at.in_tz?; assert_eq!; // Precision values greater than 9 are clamped to 9. assert_eq!; // A precision of 0 implies the entire fractional // component is always truncated. assert_eq!; # Ok::fn zoned_to_string(self: &Self, zdt: &Zoned) -> alloc::string::StringFormat a
Zoneddatetime into a string.This is a convenience routine for
DateTimePrinter::print_zonedwith aString.Example
use ; const PRINTER: DateTimePrinter = new; let zdt = date.at.in_tz?; assert_eq!; # Ok::fn timestamp_to_string(self: &Self, timestamp: &Timestamp) -> alloc::string::StringFormat a
Timestampdatetime into a string.This will always return an RFC 3339 compatible string with a
Zor Zulu offset. Zulu is chosen in accordance with RFC 9557's update to RFC 3339 that establishes the-00:00offset as equivalent to Zulu:If the time in UTC is known, but the offset to local time is unknown, this can be represented with an offset of "Z". (The original version of this specification provided -00:00 for this purpose, which is not allowed by ISO8601:2000 and therefore is less interoperable; Section 3.3 of RFC5322 describes a related convention for email, which does not have this problem). This differs semantically from an offset of +00:00, which implies that UTC is the preferred reference point for the specified time.
In other words, both Zulu time and
-00:00mean "the time in UTC is known, but the offset to local time is unknown."If you need to format an RFC 3339 timestamp with a specific offset, use
DateTimePrinter::timestamp_with_offset_to_string.This is a convenience routine for
DateTimePrinter::print_timestampwith aString.Example
use ; let timestamp = new .expect; assert_eq!;fn timestamp_with_offset_to_string(self: &Self, timestamp: &Timestamp, offset: Offset) -> alloc::string::StringFormat a
Timestampdatetime into a string with the given offset.This will always return an RFC 3339 compatible string with an offset.
This will never use either
Z(for Zulu time) or-00:00as an offset. This is because Zulu time (and-00:00) mean "the time in UTC is known, but the offset to local time is unknown." Since this routine accepts an explicit offset, the offset is known. For example,Offset::UTCwill be formatted as+00:00.To format an RFC 3339 string in Zulu time, use
DateTimePrinter::timestamp_to_string.This is a convenience routine for
DateTimePrinter::print_timestamp_with_offsetwith aString.Example
use ; const PRINTER: DateTimePrinter = new; let timestamp = new .expect; assert_eq!;Example:
Offset::UTCformats as+00:00use ; const PRINTER: DateTimePrinter = new; let timestamp = new .expect; assert_eq!;fn datetime_to_string(self: &Self, dt: &civil::DateTime) -> alloc::string::StringFormat a
civil::DateTimeinto a string.This is a convenience routine for
DateTimePrinter::print_datetimewith aString.Example
use ; const PRINTER: DateTimePrinter = new; let dt = date.at; assert_eq!;fn date_to_string(self: &Self, date: &civil::Date) -> alloc::string::StringFormat a
civil::Dateinto a string.This is a convenience routine for
DateTimePrinter::print_datewith aString.Example
use ; const PRINTER: DateTimePrinter = new; let d = date; assert_eq!;fn time_to_string(self: &Self, time: &civil::Time) -> alloc::string::StringFormat a
civil::Timeinto a string.This is a convenience routine for
DateTimePrinter::print_timewith aString.Example
use ; const PRINTER: DateTimePrinter = new; let t = time; assert_eq!;fn time_zone_to_string(self: &Self, tz: &TimeZone) -> Result<alloc::string::String, Error>Format a
TimeZoneinto a string.This is a convenience routine for
DateTimePrinter::print_time_zone.Errors
In some rare cases, serialization may fail when there is no succinct representation of a time zone. One specific case in which this occurs is when
TimeZoneis a user's system time zone derived from/etc/localtime, but where an IANA time zone identifier could not be found. This can occur, for example, when/etc/localtimeis not symlinked to an entry in/usr/share/zoneinfo.Example
use ; const PRINTER: DateTimePrinter = new; // IANA time zone let tz = get?; assert_eq!; # Ok::fn pieces_to_string(self: &Self, pieces: &Pieces<'_>) -> alloc::string::StringFormat
Piecesof a Temporal datetime.This is a convenience routine for
DateTimePrinter::print_pieceswith aString.Example
use ; const PRINTER: DateTimePrinter = new; let pieces = from; assert_eq!; let pieces = from; assert_eq!; let pieces = from; assert_eq!; # Ok::fn print_zoned<W: Write>(self: &Self, zdt: &Zoned, wtr: W) -> Result<(), Error>Print a
Zoneddatetime to the given writer.Errors
This only returns an error when writing to the given
Writeimplementation would fail. Some such implementations, like forStringandVec<u8>, never fail (unless memory allocation fails). In such cases, it would be appropriate to callunwrap()on the result.Example
use ; const PRINTER: DateTimePrinter = new; let zdt = date.at.in_tz?; let mut buf = Stringnew; // Printing to a `String` can never fail. PRINTER.print_zoned.unwrap; assert_eq!; # Ok::fn print_timestamp<W: Write>(self: &Self, timestamp: &Timestamp, wtr: W) -> Result<(), Error>Print a
Timestampdatetime to the given writer.This will always write an RFC 3339 compatible string with a
Zor Zulu offset. Zulu is chosen in accordance with RFC 9557's update to RFC 3339 that establishes the-00:00offset as equivalent to Zulu:If the time in UTC is known, but the offset to local time is unknown, this can be represented with an offset of "Z". (The original version of this specification provided -00:00 for this purpose, which is not allowed by ISO8601:2000 and therefore is less interoperable; Section 3.3 of RFC5322 describes a related convention for email, which does not have this problem). This differs semantically from an offset of +00:00, which implies that UTC is the preferred reference point for the specified time.
In other words, both Zulu time and
-00:00mean "the time in UTC is known, but the offset to local time is unknown."If you need to write an RFC 3339 timestamp with a specific offset, use
DateTimePrinter::print_timestamp_with_offset.Errors
This only returns an error when writing to the given
Writeimplementation would fail. Some such implementations, like forStringandVec<u8>, never fail (unless memory allocation fails). In such cases, it would be appropriate to callunwrap()on the result.Example
use ; let timestamp = new .expect; let mut buf = Stringnew; // Printing to a `String` can never fail. new.print_timestamp.unwrap; assert_eq!; # Ok::fn print_timestamp_with_offset<W: Write>(self: &Self, timestamp: &Timestamp, offset: Offset, wtr: W) -> Result<(), Error>Print a
Timestampdatetime to the given writer with the given offset.This will always write an RFC 3339 compatible string with an offset.
This will never write either
Z(for Zulu time) or-00:00as an offset. This is because Zulu time (and-00:00) mean "the time in UTC is known, but the offset to local time is unknown." Since this routine accepts an explicit offset, the offset is known. For example,Offset::UTCwill be formatted as+00:00.To write an RFC 3339 string in Zulu time, use
DateTimePrinter::print_timestamp.Errors
This only returns an error when writing to the given
Writeimplementation would fail. Some such implementations, like forStringandVec<u8>, never fail (unless memory allocation fails). In such cases, it would be appropriate to callunwrap()on the result.Example
use ; let timestamp = new .expect; let mut buf = Stringnew; // Printing to a `String` can never fail. new.print_timestamp_with_offset.unwrap; assert_eq!; # Ok::Example:
Offset::UTCformats as+00:00use ; let timestamp = new .expect; let mut buf = Stringnew; // Printing to a `String` can never fail. new.print_timestamp_with_offset.unwrap; assert_eq!; # Ok::fn print_datetime<W: Write>(self: &Self, dt: &civil::DateTime, wtr: W) -> Result<(), Error>Print a
civil::DateTimeto the given writer.Errors
This only returns an error when writing to the given
Writeimplementation would fail. Some such implementations, like forStringandVec<u8>, never fail (unless memory allocation fails). In such cases, it would be appropriate to callunwrap()on the result.Example
use ; const PRINTER: DateTimePrinter = new; let d = date.at; let mut buf = Stringnew; // Printing to a `String` can never fail. PRINTER.print_datetime.unwrap; assert_eq!; # Ok::fn print_date<W: Write>(self: &Self, date: &civil::Date, wtr: W) -> Result<(), Error>Print a
civil::Dateto the given writer.Errors
This only returns an error when writing to the given
Writeimplementation would fail. Some such implementations, like forStringandVec<u8>, never fail (unless memory allocation fails). In such cases, it would be appropriate to callunwrap()on the result.Example
use ; const PRINTER: DateTimePrinter = new; let d = date; let mut buf = Stringnew; // Printing to a `String` can never fail. PRINTER.print_date.unwrap; assert_eq!; # Ok::fn print_time<W: Write>(self: &Self, time: &civil::Time, wtr: W) -> Result<(), Error>Print a
civil::Timeto the given writer.Errors
This only returns an error when writing to the given
Writeimplementation would fail. Some such implementations, like forStringandVec<u8>, never fail (unless memory allocation fails). In such cases, it would be appropriate to callunwrap()on the result.Example
use ; const PRINTER: DateTimePrinter = new; let t = time; let mut buf = Stringnew; // Printing to a `String` can never fail. PRINTER.print_time.unwrap; assert_eq!; # Ok::fn print_time_zone<W: Write>(self: &Self, tz: &TimeZone, wtr: W) -> Result<(), Error>Print a
TimeZone.This will emit one of three different categories of strings:
- An IANA Time Zone Database identifier. For example,
America/New_YorkorUTC. - A fixed offset. For example,
-05:00or-00:44:30. - A POSIX time zone string. For example,
EST5EDT,M3.2.0,M11.1.0.
Differences with RFC 9557 annotations
Jiff's
Offsethas second precision. If aTimeZoneis a fixed offset and has fractional minutes, then they will be expressed in the[+-]HH:MM:SSformat. Otherwise, the:SSwill be omitted.This differs from RFC 3339 and RFC 9557 because neither support sub-minute resolution in UTC offsets. Indeed, if one were to format a
Zonedwith an offset that contains fractional minutes, the offset would be rounded to the nearest minute to preserve compatibility with RFC 3339 and RFC 9557. However, this routine does no such rounding. This is because there is no RFC standardizing the serialization of a lone time zone, and there is otherwise no need to reduce an offset's precision.Errors
In some rare cases, serialization may fail when there is no succinct representation of a time zone. One specific case in which this occurs is when
TimeZoneis a user's system time zone derived from/etc/localtime, but where an IANA time zone identifier could not be found. This can occur, for example, when/etc/localtimeis not symlinked to an entry in/usr/share/zoneinfo.An error can also occur when writing to the given
Writeimplementation would fail. Some such implementations, like forStringandVec<u8>, never fail (unless memory allocation fails).Example
use ; const PRINTER: DateTimePrinter = new; // IANA time zone let tz = get?; let mut buf = Stringnew; PRINTER.print_time_zone?; assert_eq!; // Fixed offset let tz = fixed; let mut buf = Stringnew; PRINTER.print_time_zone?; assert_eq!; // POSIX time zone let tz = posix?; let mut buf = Stringnew; PRINTER.print_time_zone?; assert_eq!; // The error case for a time zone that doesn't fall // into one of the three categories about is not easy // to create artificially. The only way, at time of // writing, to produce it is via `TimeZone::system()` // with a non-symlinked `/etc/timezone`. (Or `TZ` set // to the path of a similar file.) # Ok::- An IANA Time Zone Database identifier. For example,
fn print_pieces<W: Write>(self: &Self, pieces: &Pieces<'_>, wtr: W) -> Result<(), Error>Print the
Piecesof a Temporal datetime.Errors
This only returns an error when writing to the given
Writeimplementation would fail. Some such implementations, like forStringandVec<u8>, never fail (unless memory allocation fails). In such cases, it would be appropriate to callunwrap()on the result.Example
use ; const PRINTER: DateTimePrinter = new; let pieces = from .with_time_zone_name; let mut buf = Stringnew; // Printing to a `String` can never fail. PRINTER.print_pieces.unwrap; assert_eq!; # Ok::
impl Debug for DateTimePrinter
fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<'_>) -> $crate::fmt::Result
impl Freeze for DateTimePrinter
impl RefUnwindSafe for DateTimePrinter
impl Send for DateTimePrinter
impl Sync for DateTimePrinter
impl Unpin for DateTimePrinter
impl UnwindSafe for DateTimePrinter
impl<T> Any for DateTimePrinter
fn type_id(self: &Self) -> TypeId
impl<T> Borrow for DateTimePrinter
fn borrow(self: &Self) -> &T
impl<T> BorrowMut for DateTimePrinter
fn borrow_mut(self: &mut Self) -> &mut T
impl<T> From for DateTimePrinter
fn from(t: T) -> TReturns the argument unchanged.
impl<T, U> Into for DateTimePrinter
fn into(self: Self) -> UCalls
U::from(self).That is, this conversion is whatever the implementation of
[From]<T> for Uchooses to do.
impl<T, U> TryFrom for DateTimePrinter
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>
impl<T, U> TryInto for DateTimePrinter
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error>