date/
lib.rs

1//! A notion of the calendar date.
2
3extern crate time;
4
5use std::fmt;
6use std::cmp::Ordering;
7
8/// A representation of a day in the Gregorian calendar.
9#[derive(Clone, Copy, Default, PartialEq, Eq, Ord, Debug)]
10pub struct Date {
11    /// The year.
12    pub year: u32,
13    /// The month.
14    pub month: u8,
15    /// The day.
16    pub day: u8,
17}
18
19impl fmt::Display for Date {
20    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
21        fmt::Debug::fmt(self, formatter)
22    }
23}
24
25impl PartialOrd for Date {
26    fn partial_cmp(&self, other: &Date) -> Option<Ordering> {
27        macro_rules! cmp(
28            ($one:expr, $two:expr) => (
29                if $one > $two {
30                    return Some(Ordering::Greater);
31                } else if $one < $two {
32                    return Some(Ordering::Less);
33                }
34            );
35        );
36
37        cmp!(self.year, other.year);
38        cmp!(self.month, other.month);
39        cmp!(self.day, other.day);
40
41        Some(Ordering::Equal)
42    }
43}
44
45impl Date {
46    /// Create a date by the specified year, month, and day.
47    #[inline]
48    pub fn new(year: u32, month: u8, day: u8) -> Date {
49        Date { year: year, month: month, day: day }
50    }
51
52    /// Return the UTC date specified in seconds counting from the Unix epoch.
53    pub fn at_utc(seconds: i64) -> Date {
54        let time = time::at_utc(time::Timespec { sec: seconds, nsec: 0 });
55        Date::new(time.tm_year as u32 + 1900, time.tm_mon as u8 + 1, time.tm_mday as u8)
56    }
57
58    /// Return the UTC date specified in seconds counting from January 1, 1904.
59    #[inline]
60    pub fn at_utc_1904(seconds: i64) -> Date {
61        Date::at_utc(seconds - 2082844800)
62    }
63}
64
65#[cfg(test)]
66mod test {
67    macro_rules! date(
68        ($year:expr, $month:expr, $day:expr) => (::Date::new($year, $month, $day));
69    );
70
71    #[test]
72    fn eq() {
73        assert_eq!(date!(2014, 8, 19), date!(2014, 8, 19));
74    }
75
76    #[test]
77    fn ord() {
78        assert!(date!(2014, 8, 19) < date!(2014, 8, 20));
79        assert!(date!(2014, 8, 19) > date!(2014, 8, 18));
80        assert!(date!(2014, 8, 19) < date!(2014, 9, 19));
81        assert!(date!(2014, 8, 19) > date!(2014, 7, 19));
82        assert!(date!(2014, 8, 19) < date!(2015, 8, 19));
83        assert!(date!(2014, 8, 19) > date!(2013, 8, 19));
84    }
85
86    #[test]
87    fn at_utc_1904() {
88        macro_rules! at(
89            ($seconds:expr) => (::Date::at_utc_1904($seconds));
90        );
91
92        assert_eq!(at!(0), date!(1904, 1, 1));
93        assert_eq!(at!(2678399), date!(1904, 1, 31));
94        assert_eq!(at!(2678400), date!(1904, 2, 1));
95        assert_eq!(at!(5184000), date!(1904, 3, 1));
96        assert_eq!(at!(3491078399), date!(2014, 8, 16));
97        assert_eq!(at!(3491078400), date!(2014, 8, 17));
98    }
99}