expedite/datetime/
date.rs1use time::{Tm};
2use datetime::time_change::TimeChange;
3
4#[derive(Clone, Debug)]
5#[derive(Eq, PartialEq)]
6pub struct Date {
7 pub year: u32,
8 pub month: u32,
9 pub day: u32,
10}
11
12static Y: u32 = 4716;
15static J: u32 = 1401;
16static M: u32 = 2;
17static N: u32 = 12;
18static R: u32 = 4;
19static P: u32 = 1461;
20static V: u32 = 3;
21static U: u32 = 5;
22static S: u32 = 153;
23static W: u32 = 2;
24static B: u32 = 274277;
25static C: u32 = 38;
26
27impl Date {
28 fn from_jdn(jdn: u32) -> Date {
29 let f = jdn + J + (((4u32.wrapping_mul(jdn) + B) / 146097) * 3) / 4 - C;
30 let e = R.wrapping_mul(f) + V;
31 let g = (e % P) / R;
32 let h = U * g + W;
33 let day = (h % S) / U + 1;
34 let month = ((h / S + M) % N) + 1;
35 let year = e / P - Y + (N + M - month) / N;
36
37 Date {
38 day: day,
39 month: month,
40 year: year as u32,
41 }
42 }
43
44 pub fn new(year: u32, month: u32, day: u32) -> Date {
45 Date {
46 day: day,
47 month: month,
48 year: year,
49 }
50 }
51
52 pub fn advance_days(&self, n: u32) -> Date {
53 let jdn = self.to_jdn() as u32;
54 Date::from_jdn((jdn + n) as u32)
55 }
56
57 pub fn advance_years(&self, n: u32) -> Date {
58 Date::new(self.year + n, self.month, self.day)
59 }
60
61 pub fn advance_months(&self, n: i32) -> Date {
62 if (n >= 0) {
63 self.add_months(n as u32)
64 } else {
65 self.subtract_months(-n as u32)
66 }
67 }
68
69 fn add_months(&self, n: u32) -> Date {
70 let remaining_in_year = 12 - self.month;
71 let after_this_year = n.wrapping_sub(remaining_in_year);
72
73 if (after_this_year > 0) {
74 let years = after_this_year / 12 + 1;
75 let months = after_this_year % 12;
76
77 Date::new(self.year + years as u32, months, self.day)
78 } else {
79 Date::new(self.year, self.month + n, self.day)
80 }
81 }
82
83 fn subtract_months(&self, n: u32) -> Date {
84 if (n > self.month) {
85 let years = n / 12;
86 let remaining_in_year = n % 12;
87 Date::new(self.year - years as u32,
88 12 - remaining_in_year + self.month,
89 self.day)
90 } else {
91 Date::new(self.year, self.month - n, self.day)
92 }
93 }
94
95 pub fn to_jdn(&self) -> u32 {
96 let month = self.month;
97
98 let a = (14 - self.month) / 12; let y: u32 = (self.year as u32) + 4800 - a;
100 let m = self.month + (12 * a) - 3; let mut jdn: u32 = self.day;
103 jdn += ((153 * m) + 2) / 5;
104 jdn += (365u32.wrapping_mul(y));
105 jdn += (y / 4);
106 jdn -= (y / 100);
107 jdn += (y / 400);
108 jdn -= 32045;
109
110 jdn as u32
111 }
112}
113
114pub trait ToDate {
115 fn to_date(&self) -> Date;
116}
117
118impl ToDate for Tm {
119 fn to_date(&self) -> Date {
120 Date {
121 day: self.tm_mday as u32,
122 month: self.tm_mon as u32,
123 year: self.tm_year as u32,
124 }
125 }
126}