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
use chrono::{DateTime, Duration, Utc}; pub trait DurationExtension { fn weeks(self) -> Duration; fn days(self) -> Duration; fn hours(self) -> Duration; fn minutes(self) -> Duration; fn seconds(self) -> Duration; fn milliseconds(self) -> Duration; fn microseconds(self) -> Duration; fn nanoseconds(self) -> Duration; } pub trait DateTimeExtension { fn before(self, other: DateTime<Utc>) -> DateTime<Utc>; fn after(self, other: DateTime<Utc>) -> DateTime<Utc>; fn ago(self) -> DateTime<Utc> where Self: DateTimeExtension + Sized, { self.before(Utc::now()) } fn from_now(self) -> DateTime<Utc> where Self: DateTimeExtension + Sized, { self.after(Utc::now()) } } macro_rules! duration_extension { ($($type:ident), +) => { impl DurationExtension for i64 { $( fn $type(self) -> Duration { Duration::$type(self) } )* } }; } duration_extension!( weeks, days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds ); impl DateTimeExtension for Duration { fn before(self, other: DateTime<Utc>) -> DateTime<Utc> { other - self } fn after(self, other: DateTime<Utc>) -> DateTime<Utc> { other + self } } #[cfg(test)] mod tests { use super::*; use chrono::{Duration, Utc}; #[test] fn duration() { assert_eq!(2.weeks(), Duration::weeks(2)); assert_eq!(2.days(), Duration::days(2)); assert_eq!(2.hours(), Duration::hours(2)); assert_eq!(2.minutes(), Duration::minutes(2)); assert_eq!(2.seconds(), Duration::seconds(2)); assert_eq!(2.milliseconds(), Duration::milliseconds(2)); assert_eq!(2.microseconds(), Duration::microseconds(2)); assert_eq!(2.nanoseconds(), Duration::nanoseconds(2)); } #[test] fn days_before() { let now = Utc::now(); assert_eq!(2.days().before(now), now - Duration::days(2)); } #[test] fn days_after() { let now = Utc::now(); assert_eq!(2.days().after(now), now + Duration::days(2)); } }