8aedd47b2d3d5fdad559656d5ffeb24bb7d11b7f
[libdcp.git] / test / local_time_test.cc
1 /*
2     Copyright (C) 2014-2021 Carl Hetherington <cth@carlh.net>
3
4     This file is part of libdcp.
5
6     libdcp is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10
11     libdcp is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License
17     along with libdcp.  If not, see <http://www.gnu.org/licenses/>.
18
19     In addition, as a special exception, the copyright holders give
20     permission to link the code of portions of this program with the
21     OpenSSL library under certain conditions as described in each
22     individual source file, and distribute linked combinations
23     including the two.
24
25     You must obey the GNU General Public License in all respects
26     for all of the code used other than OpenSSL.  If you modify
27     file(s) with this exception, you may extend this exception to your
28     version of the file(s), but you are not obligated to do so.  If you
29     do not wish to do so, delete this exception statement from your
30     version.  If you delete this exception statement from all source
31     files in the program, then also delete it here.
32 */
33
34
35 #include "exceptions.h"
36 #include "local_time.h"
37 #include <boost/test/unit_test.hpp>
38
39
40 /** Check that dcp::LocalTime works */
41 BOOST_AUTO_TEST_CASE (local_time_basic_test)
42 {
43         /* Badly-formatted times */
44         BOOST_CHECK_THROW (dcp::LocalTime (""), dcp::TimeFormatError);
45         BOOST_CHECK_THROW (dcp::LocalTime ("XXX"), dcp::TimeFormatError);
46         BOOST_CHECK_THROW (dcp::LocalTime ("2013-01-05T18:06:59+04:0"), dcp::TimeFormatError);
47         BOOST_CHECK_THROW (dcp::LocalTime ("2013-01-05T18:06:59X04:00"), dcp::TimeFormatError);
48         BOOST_CHECK_THROW (dcp::LocalTime ("2013-01-05T18-06:59+04:00"), dcp::TimeFormatError);
49         BOOST_CHECK_THROW (dcp::LocalTime ("2013!01-05T18:06:59+04:00"), dcp::TimeFormatError);
50
51         /* Correctly-formatted */
52
53         {
54                 dcp::LocalTime t ("2013-01-05T18:06:59+04:00");
55                 BOOST_CHECK_EQUAL (t._year, 2013);
56                 BOOST_CHECK_EQUAL (t._month, 1);
57                 BOOST_CHECK_EQUAL (t._day, 5);
58                 BOOST_CHECK_EQUAL (t._hour, 18);
59                 BOOST_CHECK_EQUAL (t._minute, 6);
60                 BOOST_CHECK_EQUAL (t._second, 59);
61                 BOOST_CHECK(t._offset == dcp::UTCOffset(4, 0));
62                 BOOST_CHECK_EQUAL (t.as_string(), "2013-01-05T18:06:59+04:00");
63         }
64
65         {
66                 dcp::LocalTime t ("2011-11-20T01:06:59-09:30");
67                 BOOST_CHECK_EQUAL (t._year, 2011);
68                 BOOST_CHECK_EQUAL (t._month, 11);
69                 BOOST_CHECK_EQUAL (t._day, 20);
70                 BOOST_CHECK_EQUAL (t._hour, 1);
71                 BOOST_CHECK_EQUAL (t._minute, 6);
72                 BOOST_CHECK_EQUAL (t._second, 59);
73                 BOOST_CHECK(t._offset == dcp::UTCOffset(-9, -30));
74                 BOOST_CHECK_EQUAL (t.as_string(), "2011-11-20T01:06:59-09:30");
75         }
76
77         {
78                 dcp::LocalTime t ("2011-11-20T01:06:59.456-09:30");
79                 BOOST_CHECK_EQUAL (t._year, 2011);
80                 BOOST_CHECK_EQUAL (t._month, 11);
81                 BOOST_CHECK_EQUAL (t._day, 20);
82                 BOOST_CHECK_EQUAL (t._hour, 1);
83                 BOOST_CHECK_EQUAL (t._minute, 6);
84                 BOOST_CHECK_EQUAL (t._second, 59);
85                 BOOST_CHECK_EQUAL (t._millisecond, 456);
86                 BOOST_CHECK(t._offset == dcp::UTCOffset(-9, -30));
87                 BOOST_CHECK_EQUAL (t.as_string(true), "2011-11-20T01:06:59.456-09:30");
88         }
89
90         {
91                 dcp::LocalTime t ("2011-11-20T01:06:59.456-09:30");
92                 BOOST_CHECK_EQUAL (t._year, 2011);
93                 BOOST_CHECK_EQUAL (t._month, 11);
94                 BOOST_CHECK_EQUAL (t._day, 20);
95                 BOOST_CHECK_EQUAL (t._hour, 1);
96                 BOOST_CHECK_EQUAL (t._minute, 6);
97                 BOOST_CHECK_EQUAL (t._second, 59);
98                 BOOST_CHECK_EQUAL (t._millisecond, 456);
99                 BOOST_CHECK(t._offset == dcp::UTCOffset(-9, -30));
100                 BOOST_CHECK_EQUAL (t.as_string(true, false), "2011-11-20T01:06:59.456");
101         }
102
103         {
104                 dcp::LocalTime t ("2011-11-20T01:06:59.456-09:30");
105                 BOOST_CHECK_EQUAL (t._year, 2011);
106                 BOOST_CHECK_EQUAL (t._month, 11);
107                 BOOST_CHECK_EQUAL (t._day, 20);
108                 BOOST_CHECK_EQUAL (t._hour, 1);
109                 BOOST_CHECK_EQUAL (t._minute, 6);
110                 BOOST_CHECK_EQUAL (t._second, 59);
111                 BOOST_CHECK_EQUAL (t._millisecond, 456);
112                 BOOST_CHECK(t._offset == dcp::UTCOffset(-9, -30));
113                 BOOST_CHECK_EQUAL (t.as_string(false, false), "2011-11-20T01:06:59");
114         }
115
116         {
117                 /* Construction from boost::posix_time::ptime */
118                 dcp::LocalTime b (boost::posix_time::time_from_string ("2002-01-20 19:03:56"));
119                 BOOST_CHECK_EQUAL (b._year, 2002);
120                 BOOST_CHECK_EQUAL (b._month, 1);
121                 BOOST_CHECK_EQUAL (b._day, 20);
122                 BOOST_CHECK_EQUAL (b._hour, 19);
123                 BOOST_CHECK_EQUAL (b._minute, 3);
124                 BOOST_CHECK_EQUAL (b._second, 56);
125         }
126
127         {
128                 /* Construction from boost::posix_time::ptime with milliseconds */
129                 dcp::LocalTime b (boost::posix_time::time_from_string ("2002-01-20 19:03:56.491"));
130                 BOOST_CHECK_EQUAL (b._year, 2002);
131                 BOOST_CHECK_EQUAL (b._month, 1);
132                 BOOST_CHECK_EQUAL (b._day, 20);
133                 BOOST_CHECK_EQUAL (b._hour, 19);
134                 BOOST_CHECK_EQUAL (b._minute, 3);
135                 BOOST_CHECK_EQUAL (b._second, 56);
136                 BOOST_CHECK_EQUAL (b._millisecond, 491);
137         }
138
139         {
140                 dcp::LocalTime b ("2015-11-18T19:26:45");
141                 BOOST_CHECK_EQUAL (b._year, 2015);
142                 BOOST_CHECK_EQUAL (b._month, 11);
143                 BOOST_CHECK_EQUAL (b._day, 18);
144                 BOOST_CHECK_EQUAL (b._hour, 19);
145                 BOOST_CHECK_EQUAL (b._minute, 26);
146                 BOOST_CHECK_EQUAL (b._second, 45);
147                 BOOST_CHECK_EQUAL (b._millisecond, 0);
148                 BOOST_CHECK(b._offset == dcp::UTCOffset());
149         }
150
151         /* Check negative times with non-zero timezone offset minutes */
152         {
153                 dcp::LocalTime t ("2013-01-05T18:06:59-04:30");
154                 BOOST_CHECK_EQUAL (t._year, 2013);
155                 BOOST_CHECK_EQUAL (t._month, 1);
156                 BOOST_CHECK_EQUAL (t._day, 5);
157                 BOOST_CHECK_EQUAL (t._hour, 18);
158                 BOOST_CHECK_EQUAL (t._minute, 6);
159                 BOOST_CHECK_EQUAL (t._second, 59);
160                 BOOST_CHECK(t._offset == dcp::UTCOffset(-4, -30));
161                 BOOST_CHECK_EQUAL (t.as_string(), "2013-01-05T18:06:59-04:30");
162         }
163 }
164
165
166 BOOST_AUTO_TEST_CASE (local_time_add_minutes_test)
167 {
168         {
169                 dcp::LocalTime t("2018-01-01T10:00:00+01:00");
170                 t.add_minutes (3);
171                 BOOST_CHECK_EQUAL (t.as_string(), "2018-01-01T10:03:00+01:00");
172         }
173
174         {
175                 dcp::LocalTime t("2018-01-01T10:00:15+01:00");
176                 t.add_minutes (3);
177                 BOOST_CHECK_EQUAL (t.as_string(), "2018-01-01T10:03:15+01:00");
178         }
179
180         {
181                 dcp::LocalTime t("2018-01-01T10:40:20+01:00");
182                 t.add_minutes (23);
183                 BOOST_CHECK_EQUAL (t.as_string(), "2018-01-01T11:03:20+01:00");
184         }
185
186         {
187                 dcp::LocalTime t("2018-01-01T10:40:20+01:00");
188                 t.add_minutes (123);
189                 BOOST_CHECK_EQUAL (t.as_string(), "2018-01-01T12:43:20+01:00");
190         }
191
192         {
193                 dcp::LocalTime t("2018-01-01T23:55:00+01:00");
194                 t.add_minutes (7);
195                 BOOST_CHECK_EQUAL (t.as_string(), "2018-01-02T00:02:00+01:00");
196         }
197
198         {
199                 dcp::LocalTime t("2018-01-31T23:55:00+01:00");
200                 t.add_minutes (7);
201                 BOOST_CHECK_EQUAL (t.as_string(), "2018-02-01T00:02:00+01:00");
202         }
203
204         {
205                 dcp::LocalTime t("2018-01-31T23:55:00.123");
206                 t.add_minutes (7);
207                 BOOST_CHECK_EQUAL (t, dcp::LocalTime("2018-02-01T00:02:00.123"));
208         }
209 }
210
211
212 BOOST_AUTO_TEST_CASE (local_time_add_months_test)
213 {
214         {
215                 dcp::LocalTime t("2013-06-23T18:06:59.123");
216                 t.add_months(-1);
217                 BOOST_CHECK_EQUAL (t, dcp::LocalTime("2013-05-23T18:06:59.123"));
218                 t.add_months(1);
219                 BOOST_CHECK_EQUAL (t, dcp::LocalTime("2013-06-23T18:06:59.123"));
220                 t.add_months(1);
221                 BOOST_CHECK_EQUAL (t, dcp::LocalTime("2013-07-23T18:06:59.123"));
222                 t.add_months(4);
223                 BOOST_CHECK_EQUAL (t, dcp::LocalTime("2013-11-23T18:06:59.123"));
224                 t.add_months(2);
225                 BOOST_CHECK_EQUAL (t, dcp::LocalTime("2014-01-23T18:06:59.123"));
226                 t.add_months(-14);
227                 BOOST_CHECK_EQUAL (t, dcp::LocalTime("2012-11-23T18:06:59.123"));
228                 t.add_months(14);
229                 BOOST_CHECK_EQUAL (t, dcp::LocalTime("2014-01-23T18:06:59.123"));
230         }
231
232         {
233                 dcp::LocalTime t("2018-01-30T11:00:00+01:00");
234                 t.add_months (1);
235                 BOOST_CHECK_EQUAL (t.as_string(), "2018-02-28T11:00:00+01:00");
236         }
237 }
238
239
240 BOOST_AUTO_TEST_CASE (local_time_from_asn1_utctime_test)
241 {
242         BOOST_CHECK_EQUAL (dcp::LocalTime::from_asn1_utc_time("991231235952").as_string(), "1999-12-31T23:59:52+00:00");
243         BOOST_CHECK_EQUAL (dcp::LocalTime::from_asn1_utc_time("210215165952").as_string(), "2021-02-15T16:59:52+00:00");
244 }
245
246
247 BOOST_AUTO_TEST_CASE (local_time_from_asn1_generalized_time_test)
248 {
249         BOOST_CHECK_EQUAL (dcp::LocalTime::from_asn1_generalized_time("19991231235952").as_string(), "1999-12-31T23:59:52+00:00");
250         BOOST_CHECK_EQUAL (dcp::LocalTime::from_asn1_generalized_time("20210215165952").as_string(), "2021-02-15T16:59:52+00:00");
251 }
252
253
254 BOOST_AUTO_TEST_CASE(local_time_comparison_test)
255 {
256         BOOST_CHECK(dcp::LocalTime("2014-01-01T10:00:00") < dcp::LocalTime("2014-01-01T10:05:00"));
257         BOOST_CHECK(dcp::LocalTime("2014-01-01T10:00:00") < dcp::LocalTime("2015-01-01T10:00:00"));
258         BOOST_CHECK(dcp::LocalTime("2014-01-01T10:00:00") < dcp::LocalTime("2014-01-01T11:00:00"));
259         BOOST_CHECK(dcp::LocalTime("2014-10-10T10:00:00") < dcp::LocalTime("2014-10-10T10:00:01"));
260         BOOST_CHECK(!(dcp::LocalTime("2014-10-10T10:00:00") < dcp::LocalTime("2014-10-10T10:00:00")));
261         BOOST_CHECK(dcp::LocalTime("2014-10-10T10:00:00+01:00") < dcp::LocalTime("2014-10-10T10:00:00"));
262         BOOST_CHECK(dcp::LocalTime("2014-10-10T10:00:00+01:30") < dcp::LocalTime("2014-10-10T10:00:00"));
263         BOOST_CHECK(dcp::LocalTime("2014-10-10T10:00:00+01:00") < dcp::LocalTime("2014-10-10T10:00:01+01:00"));
264         BOOST_CHECK(dcp::LocalTime("2014-01-01T10:00:00") < dcp::LocalTime("2014-01-01T10:05:00"));
265         BOOST_CHECK(dcp::LocalTime("2014-10-10T10:00:00") < dcp::LocalTime("2014-10-10T10:00:00-01:30"));
266
267         BOOST_CHECK(dcp::LocalTime("2014-01-01T10:05:00") > dcp::LocalTime("2014-01-01T10:00:00"));
268         BOOST_CHECK(dcp::LocalTime("2014-10-10T10:00:00-01:30") > dcp::LocalTime("2014-10-10T10:00:00"));
269         BOOST_CHECK(dcp::LocalTime("2014-01-01T10:05:00") > dcp::LocalTime("2014-01-01T10:00:00"));
270         BOOST_CHECK(dcp::LocalTime("2015-01-01T10:00:00") > dcp::LocalTime("2014-01-01T10:00:00"));
271         BOOST_CHECK(dcp::LocalTime("2014-01-01T11:00:00") > dcp::LocalTime("2014-01-01T10:00:00"));
272         BOOST_CHECK(dcp::LocalTime("2014-10-10T10:00:01") > dcp::LocalTime("2014-10-10T10:00:00"));
273         BOOST_CHECK(!(dcp::LocalTime("2014-10-10T10:00:00") > dcp::LocalTime("2014-10-10T10:00:00")));
274         BOOST_CHECK(dcp::LocalTime("2014-10-10T10:00:00") > dcp::LocalTime("2014-10-10T10:00:00+01:00"));
275         BOOST_CHECK(dcp::LocalTime("2014-10-10T10:00:00") > dcp::LocalTime("2014-10-10T10:00:00+01:30"));
276         BOOST_CHECK(dcp::LocalTime("2014-10-10T10:00:01+01:00") > dcp::LocalTime("2014-10-10T10:00:00+01:00"));
277
278         BOOST_CHECK(dcp::LocalTime("2014-01-01T10:00:00") != dcp::LocalTime("2014-01-01T10:05:00"));
279         BOOST_CHECK(dcp::LocalTime("2014-01-01T10:00:00") == dcp::LocalTime("2014-01-01T10:00:00"));
280         BOOST_CHECK(dcp::LocalTime("2014-01-01T10:00:00+02:00") == dcp::LocalTime("2014-01-01T08:00:00"));
281         BOOST_CHECK(dcp::LocalTime("2014-01-01T10:00:00+02:00") == dcp::LocalTime("2014-01-01T11:00:00+03:00"));
282 }