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