1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
use std::fmt;
use std::time::SystemTime;
use humantime::{
format_rfc3339_micros, format_rfc3339_millis, format_rfc3339_nanos, format_rfc3339_seconds,
};
use crate::fmt::{Formatter, TimestampPrecision};
impl Formatter {
/// Get a [`Timestamp`] for the current date and time in UTC.
///
/// # Examples
///
/// Include the current timestamp with the log record:
///
/// ```
/// use std::io::Write;
///
/// let mut builder = env_logger::Builder::new();
///
/// builder.format(|buf, record| {
/// let ts = buf.timestamp();
///
/// writeln!(buf, "{}: {}: {}", ts, record.level(), record.args())
/// });
/// ```
///
/// [`Timestamp`]: struct.Timestamp.html
pub fn timestamp(&self) -> Timestamp {
Timestamp {
time: SystemTime::now(),
precision: TimestampPrecision::Seconds,
}
}
/// Get a [`Timestamp`] for the current date and time in UTC with full
/// second precision.
pub fn timestamp_seconds(&self) -> Timestamp {
Timestamp {
time: SystemTime::now(),
precision: TimestampPrecision::Seconds,
}
}
/// Get a [`Timestamp`] for the current date and time in UTC with
/// millisecond precision.
pub fn timestamp_millis(&self) -> Timestamp {
Timestamp {
time: SystemTime::now(),
precision: TimestampPrecision::Millis,
}
}
/// Get a [`Timestamp`] for the current date and time in UTC with
/// microsecond precision.
pub fn timestamp_micros(&self) -> Timestamp {
Timestamp {
time: SystemTime::now(),
precision: TimestampPrecision::Micros,
}
}
/// Get a [`Timestamp`] for the current date and time in UTC with
/// nanosecond precision.
pub fn timestamp_nanos(&self) -> Timestamp {
Timestamp {
time: SystemTime::now(),
precision: TimestampPrecision::Nanos,
}
}
}
/// An [RFC3339] formatted timestamp.
///
/// The timestamp implements [`Display`] and can be written to a [`Formatter`].
///
/// [RFC3339]: https://www.ietf.org/rfc/rfc3339.txt
/// [`Display`]: https://doc.rust-lang.org/stable/std/fmt/trait.Display.html
/// [`Formatter`]: struct.Formatter.html
pub struct Timestamp {
time: SystemTime,
precision: TimestampPrecision,
}
impl fmt::Debug for Timestamp {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
/// A `Debug` wrapper for `Timestamp` that uses the `Display` implementation.
struct TimestampValue<'a>(&'a Timestamp);
impl<'a> fmt::Debug for TimestampValue<'a> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt::Display::fmt(&self.0, f)
}
}
f.debug_tuple("Timestamp")
.field(&TimestampValue(self))
.finish()
}
}
impl fmt::Display for Timestamp {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let formatter = match self.precision {
TimestampPrecision::Seconds => format_rfc3339_seconds,
TimestampPrecision::Millis => format_rfc3339_millis,
TimestampPrecision::Micros => format_rfc3339_micros,
TimestampPrecision::Nanos => format_rfc3339_nanos,
};
formatter(self.time).fmt(f)
}
}