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
use std::fmt; use cal::{LocalDate, LocalTime, LocalDateTime, DatePiece, TimePiece}; use cal::{Offset, OffsetDateTime}; use util::RangeExt; pub trait ISO: Sized { fn iso(&self) -> ISOString<Self> { ISOString(self) } fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result; } pub struct ISOString<'a, T: 'a>(&'a T); impl<'a, T> fmt::Display for ISOString<'a, T> where T: ISO { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { ISO::fmt(self.0, f) } } impl ISO for LocalDate { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { let year = self.year(); if year.is_within(0 .. 9999) { write!(f, "{:04}-{:02}-{:02}", year, self.month() as usize, self.day()) } else { write!(f, "{:+05}-{:02}-{:02}", year, self.month() as usize, self.day()) } } } impl ISO for LocalTime { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{:02}:{:02}:{:02}.{:03}", self.hour(), self.minute(), self.second(), self.millisecond()) } } impl ISO for LocalDateTime { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { try!(self.date().fmt(f)); try!(write!(f, "T")); self.time().fmt(f) } } impl ISO for Offset { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { if self.is_utc() { write!(f, "Z") } else { try!(f.write_str(if self.is_negative() { "-" } else { "+" })); match (self.hours(), self.minutes(), self.seconds()) { (h, 0, 0) => write!(f, "{:02}", h.abs()), (h, m, 0) => write!(f, "{:02}:{:02}", h.abs(), m.abs()), (h, m, s) => write!(f, "{:02}:{:02}:{:02}", h.abs(), m.abs(), s.abs()), } } } } impl ISO for OffsetDateTime { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{}{}", self.local.iso(), self.offset.iso()) } }