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