1 //! Unit tests derived from Tom Scott's video on Numberphile,
2 //! [`The Problem with Time & Timezones'][video].
3 //! Note that not all tests are passing; the ones towards
4 //! the end of the video are not handled correctly (nor are
5 //! currently intended to be handled correctly) by chrono.
6 //!
7 //! [video]: https://www.youtube.com/watch?v=-5wpm-gesOY
8 
9 extern crate chrono;
10 extern crate chrono_tz;
11 
12 use chrono::{DateTime, TimeZone};
13 
14 use chrono_tz::Africa::Tripoli;
15 use chrono_tz::America::New_York;
16 use chrono_tz::Asia::Gaza;
17 use chrono_tz::Asia::Jerusalem;
18 use chrono_tz::Asia::Kathmandu;
19 use chrono_tz::Australia::Adelaide;
20 use chrono_tz::Etc::UTC;
21 use chrono_tz::Europe::London;
22 use chrono_tz::Europe::Moscow;
23 use chrono_tz::Pacific::Apia;
24 
seconds<Tz1: TimeZone, Tz2: TimeZone>(from: DateTime<Tz1>, to: DateTime<Tz2>) -> i6425 fn seconds<Tz1: TimeZone, Tz2: TimeZone>(from: DateTime<Tz1>, to: DateTime<Tz2>) -> i64 {
26     to.signed_duration_since(from).num_seconds()
27 }
28 
29 #[test]
london_5_days_ago_to_new_york()30 fn london_5_days_ago_to_new_york() {
31     let from = London.ymd(2013, 12, 25).and_hms(14, 0, 0);
32     let to = New_York.ymd(2013, 12, 30).and_hms(14, 0, 0);
33     assert_eq!(seconds(from, to), 60 * 60 * (24 * 5 + 5));
34 }
35 
36 #[test]
london_to_australia()37 fn london_to_australia() {
38     // at the time Tom was speaking, Adelaide was 10 1/2 hours ahead
39     // many other parts of Australia use different time zones
40     let from = London.ymd(2013, 12, 25).and_hms(14, 0, 0);
41     let to = Adelaide.ymd(2013, 12, 30).and_hms(14, 0, 0);
42     assert_eq!(seconds(from, to), 60 * 60 * (24 * 5 - 10) - 60 * 30);
43 }
44 
45 #[test]
london_to_nepal()46 fn london_to_nepal() {
47     // note Tom gets this wrong, it's 5 3/4 hours as he is speaking
48     let from = London.ymd(2013, 12, 25).and_hms(14, 0, 0);
49     let to = Kathmandu.ymd(2013, 12, 30).and_hms(14, 0, 0);
50     assert_eq!(seconds(from, to), 60 * 60 * (24 * 5 - 5) - 60 * 45);
51 }
52 
53 #[test]
autumn()54 fn autumn() {
55     let from = London.ymd(2013, 10, 25).and_hms(12, 0, 0);
56     let to = London.ymd(2013, 11, 1).and_hms(12, 0, 0);
57     assert_eq!(seconds(from, to), 60 * 60 * (24 * 7 + 1));
58 }
59 
60 #[test]
earlier_daylight_savings_in_new_york()61 fn earlier_daylight_savings_in_new_york() {
62     let from = New_York.ymd(2013, 10, 25).and_hms(12, 0, 0);
63     let to = New_York.ymd(2013, 11, 1).and_hms(12, 0, 0);
64     assert_eq!(seconds(from, to), 60 * 60 * (24 * 7));
65 }
66 
67 #[test]
southern_hemisphere_clocks_forward()68 fn southern_hemisphere_clocks_forward() {
69     let from = Adelaide.ymd(2013, 10, 1).and_hms(12, 0, 0);
70     let to = Adelaide.ymd(2013, 11, 1).and_hms(12, 0, 0);
71     assert_eq!(seconds(from, to), 60 * 60 * (24 * 31 - 1));
72 }
73 
74 #[test]
samoa_skips_a_day()75 fn samoa_skips_a_day() {
76     let from = Apia.ymd(2011, 12, 29).and_hms(12, 0, 0);
77     let to = Apia.ymd(2011, 12, 31).and_hms(12, 0, 0);
78     assert_eq!(seconds(from, to), 60 * 60 * 24);
79 }
80 
81 #[test]
double_bst()82 fn double_bst() {
83     let from = London.ymd(1942, 6, 1).and_hms(12, 0, 0);
84     let to = UTC.ymd(1942, 6, 1).and_hms(12, 0, 0);
85     assert_eq!(seconds(from, to), 60 * 60 * 2);
86 }
87 
88 #[test]
libya_2013()89 fn libya_2013() {
90     // Libya actually put their clocks *forward* in 2013, but not in any other year
91     let from = Tripoli.ymd(2012, 3, 1).and_hms(12, 0, 0);
92     let to = Tripoli.ymd(2012, 4, 1).and_hms(12, 0, 0);
93     assert_eq!(seconds(from, to), 60 * 60 * 24 * 31);
94 
95     let from = Tripoli.ymd(2013, 3, 1).and_hms(12, 0, 0);
96     let to = Tripoli.ymd(2013, 4, 1).and_hms(12, 0, 0);
97     assert_eq!(seconds(from, to), 60 * 60 * (24 * 31 - 1));
98 
99     let from = Tripoli.ymd(2014, 3, 1).and_hms(12, 0, 0);
100     let to = Tripoli.ymd(2014, 4, 1).and_hms(12, 0, 0);
101     assert_eq!(seconds(from, to), 60 * 60 * 24 * 31);
102 }
103 
104 #[test]
israel_palestine()105 fn israel_palestine() {
106     let from = Jerusalem.ymd(2016, 10, 29).and_hms(12, 0, 0);
107     let to = Gaza.ymd(2016, 10, 29).and_hms(12, 0, 0);
108     assert_eq!(seconds(from, to), 60 * 60);
109 }
110 
111 // FIXME doesn't currently work!
112 #[test]
113 #[ignore]
london_julian_to_gregorian()114 fn london_julian_to_gregorian() {
115     let from = London.ymd(1752, 9, 2).and_hms(12, 0, 0);
116     let to = London.ymd(1752, 9, 14).and_hms(12, 0, 0);
117     assert_eq!(seconds(from, to), 60 * 60 * 24);
118 }
119 
120 // FIXME doesn't currently work!
121 #[test]
122 #[ignore]
russian_julian_to_gregorian()123 fn russian_julian_to_gregorian() {
124     let from = Moscow.ymd(1918, 1, 31).and_hms(12, 0, 0);
125     let to = Moscow.ymd(1918, 2, 14).and_hms(12, 0, 0);
126     assert_eq!(seconds(from, to), 60 * 60 * 24);
127 }
128 
129 // FIXME doesn't currently work!
130 #[test]
131 #[ignore]
london_25_march()132 fn london_25_march() {
133     let from = London.ymd(924, 3, 24).and_hms(12, 0, 0);
134     let to = London.ymd(925, 3, 25).and_hms(12, 0, 0);
135     assert_eq!(seconds(from, to), 60 * 60 * 24);
136 }
137 
138 #[test]
leapsecond()139 fn leapsecond() {
140     let from = UTC.ymd(2016, 6, 30).and_hms(23, 59, 59);
141     let to = UTC.ymd(2016, 6, 30).and_hms_milli(23, 59, 59, 1000);
142     assert_eq!(seconds(from, to), 1);
143 }
144 
145 // FIXME doesn't currently work!
146 #[test]
147 #[ignore]
leapsecond_2()148 fn leapsecond_2() {
149     let from = UTC.ymd(2016, 6, 30).and_hms(23, 59, 59);
150     let to = UTC.ymd(2016, 7, 1).and_hms(0, 0, 0);
151     assert_eq!(seconds(from, to), 2);
152 }
153 
154 // FIXME doesn't currently work!
155 #[test]
156 #[ignore]
leapsecond_3()157 fn leapsecond_3() {
158     let from = UTC.ymd(2016, 6, 30).and_hms_milli(23, 59, 59, 1000);
159     let to = UTC.ymd(2016, 7, 1).and_hms(0, 0, 0);
160     assert_eq!(seconds(from, to), 1);
161 }
162