]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | /* Copyright (c) 2002,2003 CrystalClear Software, Inc. |
2 | * Use, modification and distribution is subject to the | |
3 | * Boost Software License, Version 1.0. (See accompanying | |
4 | * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) | |
5 | * Author: Jeff Garland, Bart Garst | |
6 | */ | |
7 | ||
7c673cae FG |
8 | #include <boost/cstdint.hpp> |
9 | #include "boost/date_time/gregorian/gregorian.hpp" | |
10 | #include "../testfrmwk.hpp" | |
11fdf7f2 TL |
11 | #include <iostream> |
12 | #include <sstream> | |
13 | ||
14 | void test_yearlimit(int yr, bool allowed) | |
15 | { | |
16 | std::stringstream sdesc; | |
17 | sdesc << "should" << (allowed ? "" : " not") << " be able to make a date in year " << yr; | |
18 | ||
19 | try { | |
20 | boost::gregorian::date chkyr(yr, 1, 1); | |
21 | check(sdesc.str(), allowed); | |
22 | } | |
23 | catch (std::out_of_range&) { check(sdesc.str(), !allowed); } | |
24 | } | |
7c673cae FG |
25 | |
26 | int | |
27 | main() | |
28 | { | |
29 | ||
30 | using namespace boost::gregorian; | |
31 | ||
32 | //various constructors | |
33 | #if !defined(DATE_TIME_NO_DEFAULT_CONSTRUCTOR) | |
34 | date def; | |
35 | check("Default constructor", def == date(not_a_date_time)); | |
36 | #endif | |
20effc67 TL |
37 | |
38 | #ifdef BOOST_NO_CXX14_CONSTEXPR | |
39 | check("constexpr not configured", true); | |
40 | #else | |
41 | //check constexpr case | |
42 | { | |
43 | constexpr date d1(1900,1,1); | |
44 | static_assert(d1.day() == 1, "constexpr construction day()"); | |
45 | static_assert(d1.month() == 1, "constexpr construction month()"); | |
46 | static_assert(d1.year() == 1900, "constexpr construction year()"); | |
47 | constexpr date d2 = date(2000,12,31); | |
48 | constexpr date d3(d2); | |
49 | static_assert(d3.day() == 31, "constexpr construct and copy day()"); | |
50 | static_assert(d3.month() == 12, "constexpr construct and copy month()"); | |
51 | static_assert(d3.year() == 2000, "constexpr construct and copy year()"); | |
52 | check("constexpr tests compiled", true); | |
53 | } | |
54 | #endif | |
55 | ||
11fdf7f2 | 56 | |
7c673cae | 57 | date d1(1900,1,1); |
11fdf7f2 | 58 | date d2 = date(2000,1,1); |
7c673cae FG |
59 | date d3(d2); |
60 | check("Copy constructor", d3 == d2); | |
61 | date d4(2000,12,31); | |
62 | date d4a(2000,Dec,31); | |
63 | //d4a.print(std::cout); std::cout << std::endl; | |
64 | check("month_rep constructor", d4 == d4a); | |
65 | //std::cout << d3 << std::endl; | |
66 | //retrieval functions | |
67 | check_equal("1900-01-01 day is 01", d1.day(), 1); | |
68 | check_equal("1900-01-01 month is 01", d1.month(), 1); | |
69 | check_equal("1900-01-01 year is 1900", d1.year(), 1900); | |
70 | check_equal("2000-12-31 day is 31", d4.day(), 31); | |
71 | check_equal("2000-12-31 month is 12", d4.month(), 12); | |
72 | check_equal("2000-12-31 year is 2000", d4.year(), 2000); | |
73 | //operator< | |
74 | check("1900-01-01 is less than 2000-01-01", d1 < d2); | |
75 | check("2000-01-01 is NOT less than 2000-01-01", !(d1 < d1)); | |
76 | //operator<= | |
77 | check("2000-01-01 is less equal than 2000-01-01", d1 <= d1); | |
78 | //operator> | |
79 | check("2000-01-01 is greater than 1900-01-01", d2 > d1); | |
80 | check("2000-01-01 is NOT greater than 2000-01-01", !(d1 < d1)); | |
81 | //operator>= | |
82 | check("2000-01-01 is greater equal than 2000-01-01", d1 >= d1); | |
83 | //operator!= | |
84 | check("2000-01-01 is NOT equal to 1900-01-01", d2 != d1); | |
85 | //operator== | |
86 | check_equal("2000-01-01 is equal 2000-01-01", d3, d2); | |
87 | check("2000-01-01 is greater equal 2000-01-01", d3 >= d2); | |
88 | check("2000-01-01 is greater equal 2000-01-01", d3 <= d2); | |
89 | ||
90 | date::ymd_type ymd = d1.year_month_day(); | |
91 | check_equal("ymd year", ymd.year, 1900); | |
92 | check_equal("ymd month", ymd.month, 1); | |
93 | check_equal("ymd day", ymd.day, 1); | |
94 | ||
95 | //The max function will not compile with Borland 5.5 | |
96 | //Complains about must specialize basic_data<limits> ??? | |
97 | // std::cout << "Max date is " << (date::max)() << std::endl; | |
98 | // //std::cout << "Max date is " << (basic_date< date_limits<unsigned int,1900> >::max)() << std::endl; | |
99 | // //std::cout << "Max date is " << (date_limits<unsigned int, 1900>::max)() << std::endl; | |
100 | ||
101 | const date answers[] = {date(1900,Jan,1),date(1900,Jan,4),date(1900,Jan,7), | |
102 | date(1900,Jan,10),date(1900,Jan,13)}; | |
103 | date_duration off(3); | |
104 | date d5(1900,1,1); | |
105 | for (int i=0; i < 5; ++i) { | |
106 | //std::cout << d5 << " "; | |
107 | check(" addition ", d5 == answers[i]); | |
108 | d5 = d5 + off; | |
109 | } | |
110 | std::cout << std::endl; | |
111 | ||
112 | const date answers1[] = {date(2000,2,26),date(2000,2,28),date(2000,Mar,1)}; | |
113 | date d8(2000,Feb,26); | |
114 | for (int j=0; j < 3; ++j) { | |
115 | //std::cout << d8 << " "; | |
116 | check(" more addition ", d8 == answers1[j]); | |
117 | d8 = d8 + days(2); | |
118 | } | |
119 | // std::cout << std::endl; | |
120 | ||
121 | date d6(2000,2,28); | |
122 | date d7(2000,3,1); | |
123 | date_duration twoDays(2); | |
124 | date_duration negtwoDays(-2); | |
125 | date_duration zeroDays(0); | |
126 | check_equal("2000-03-01 - 2000-02-28 == 2 days", twoDays, (d7-d6)); | |
127 | check_equal("2000-02-28 - 2000-03-01 == - 2 days", negtwoDays, (d6-d7)); | |
128 | check_equal("2000-02-28 - 2000-02-28 == 0 days", zeroDays, (d6-d6)); | |
129 | check_equal("2000-02-28 + 2 days == 2000-03-01 ", d6 + twoDays, d7); | |
130 | check_equal("2000-03-01 - 2 days == 2000-02-28 ", d7 - twoDays, d6); | |
131 | check_equal("Add duration to date", date(1999,1,1) + date_duration(365), date(2000,1,1)); | |
132 | check_equal("Add zero days", date(1999,1,1) + zeroDays, date(1999,1,1)); | |
133 | //can't do this... | |
134 | //check("Add date to duration", date_duration(365) + date(1999,1,1) == date(2000,1,1)); | |
135 | ||
136 | { | |
137 | date d(2003,Oct,31); | |
138 | date_duration dd(55); | |
139 | d += dd; | |
140 | check("date += date_duration", d == date(2003,Dec,25)); | |
141 | d -= dd; | |
142 | check("date -= date_duration", d == date(2003,Oct,31)); | |
143 | /* special_values is more thoroughly tested later, | |
144 | * this is just a test of += & -= with special values */ | |
145 | d += date_duration(pos_infin); | |
146 | check("date += inf_dur", d == date(pos_infin)); | |
147 | d -= dd; | |
148 | check("inf_date -= dur", d == date(pos_infin)); | |
149 | } | |
150 | { | |
151 | date d(2003,Oct,31); | |
152 | date_duration dd1(pos_infin), dd2(neg_infin), dd3(not_a_date_time); | |
153 | check_equal("date + inf_dur", d + dd1, date(pos_infin)); | |
154 | check_equal("date + inf_dur", d + dd2, date(neg_infin)); | |
155 | check_equal("date + nan_dur", d + dd3, date(not_a_date_time)); | |
156 | check_equal("date - inf_dur", d - dd1, date(neg_infin)); | |
157 | check_equal("date - inf_dur", d - dd2, date(pos_infin)); | |
158 | check_equal("date - nan_dur", d - dd3, date(not_a_date_time)); | |
159 | check_equal("inf_date + inf_dur", date(pos_infin) + dd1, date(pos_infin)); | |
160 | check_equal("inf_date - inf_dur", date(pos_infin) - dd1, date(not_a_date_time)); | |
161 | check_equal("inf_date + inf_dur", date(neg_infin) + dd1, date(not_a_date_time)); | |
162 | check_equal("inf_date - inf_dur", date(neg_infin) - dd1, date(neg_infin)); | |
163 | } | |
164 | ||
165 | ||
166 | try { | |
167 | date d9(2000, Jan, 32); | |
168 | check("day out of range", false); | |
169 | //never reached if working -- but stops compiler warnings :-) | |
170 | std::cout << "Oops: " << to_iso_string(d9) << std::endl; | |
171 | } | |
172 | catch (bad_day_of_month&) { | |
173 | check("day out of range", true); | |
174 | } | |
175 | try { | |
176 | date d9(2000, Jan, 0); | |
177 | check("day out of range", false); | |
178 | //never reached if working -- but stops compiler warnings :-) | |
179 | std::cout << "Oops: " << to_iso_string(d9) << std::endl; | |
180 | } | |
181 | catch (bad_day_of_month&) { | |
182 | check("day out of range", true); | |
183 | } | |
184 | ||
185 | try { | |
186 | date d20(2000, Feb, 31); | |
187 | check("day out of range", false); | |
188 | //never reached if working -- but stops compiler warnings :-) | |
189 | std::cout << "Oops: " << to_iso_string(d20) << std::endl; | |
190 | } | |
191 | catch (bad_day_of_month&) { | |
192 | check("day out of range", true); | |
193 | } | |
194 | ||
195 | //more subtle -- one day past in a leap year | |
196 | try { | |
197 | date d21(2000, Feb, 30); | |
198 | check("day out of range", false); | |
199 | //never reached if working -- but stops compiler warnings :-) | |
200 | std::cout << "Oops: " << to_iso_string(d21) << std::endl; | |
201 | } | |
202 | catch (bad_day_of_month&) { | |
203 | check("day out of range", true); | |
204 | } | |
205 | ||
206 | //more subtle -- one day past in a leap year | |
207 | try { | |
208 | date d22(2000, Feb, 29); | |
209 | check("last day of month ok", true); | |
210 | std::cout << to_iso_string(d22) << std::endl; //stop compiler warning | |
211 | } | |
212 | catch (bad_day_of_month&) { | |
213 | check("last day of month -- oops bad exception", false); | |
214 | } | |
215 | ||
216 | //Not a leap year -- now Feb 29 is bad | |
217 | try { | |
218 | date d23(1999, Feb, 29); | |
219 | check("day out of range", false); | |
220 | //never reached if working -- but stops compiler warnings :-) | |
221 | std::cout << "Oops: " << to_iso_string(d23) << std::endl; | |
222 | } | |
223 | catch (bad_day_of_month&) { | |
224 | check("day out of range", true); | |
225 | } | |
226 | ||
227 | //check out some special values | |
228 | check("check not a date - false", !d7.is_not_a_date()); | |
229 | check("check positive infinity - false", !d7.is_pos_infinity()); | |
230 | check("check negative infinity - false", !d7.is_neg_infinity()); | |
231 | ||
232 | date d10(neg_infin); | |
233 | check("check negative infinity - true", d10.is_infinity()); | |
234 | d10 = d10 + twoDays; //still neg infinity | |
235 | check("check negative infinity - true", d10.is_neg_infinity()); | |
236 | ||
237 | date d11(pos_infin); | |
238 | check("check positive infinity - true", d11.is_infinity()); | |
239 | d11 = d11 + twoDays; | |
240 | check("check positive infinity add - true", d11.is_pos_infinity()); | |
241 | ||
242 | date d12(not_a_date_time); | |
243 | check("check not a date", d12.is_not_a_date()); | |
244 | check("check infinity compare ", d10 != d11); | |
245 | check("check infinity compare ", d10 < d11); | |
246 | check("check infinity nad compare ", d12 != d11); | |
247 | date d13(max_date_time); | |
248 | check("check infinity - max compare ", d13 < d11); | |
249 | check_equal("max date_time value ", d13, date(9999,Dec, 31)); | |
250 | std::cout << to_simple_string(d13) << std::endl; | |
251 | date d14(min_date_time); | |
252 | check("check infinity - min compare ", d14 > d10); | |
253 | std::cout << to_simple_string(d14) << std::endl; | |
254 | check_equal("min date_time value ", d14, date(1400,Jan, 1)); | |
255 | ||
256 | ||
257 | date d15(1400,1,1); | |
258 | std::cout << d15.day_of_week().as_long_string() << std::endl; | |
259 | check("check infinity - min compare ", d10 < d15); | |
260 | ||
261 | // most of this testing is in the gregorian_calendar tests | |
262 | std::cout << d15.julian_day() << std::endl; | |
263 | check_equal("check julian day ", d15.julian_day(), | |
264 | static_cast<boost::uint32_t>(2232400)); | |
265 | check_equal("check modjulian day ", d15.modjulian_day(), -167601); | |
266 | date d16(2004,2,29); | |
267 | check_equal("check julian day ", d16.julian_day(), | |
268 | static_cast<boost::uint32_t>(2453065)); | |
269 | check_equal("check modjulian day ", d16.modjulian_day(), | |
270 | static_cast<boost::uint32_t>(53064)); | |
271 | ||
272 | // most of this testing is in the gregorian_calendar tests | |
273 | date d31(2000, Jun, 1); | |
274 | check_equal("check iso week number ", d31.week_number(), 22); | |
275 | date d32(2000, Aug, 1); | |
276 | check_equal("check iso week number ", d32.week_number(), 31); | |
277 | date d33(2000, Oct, 1); | |
278 | check_equal("check iso week number ", d33.week_number(), 39); | |
279 | date d34(2000, Dec, 1); | |
280 | check_equal("check iso week number ", d34.week_number(), 48); | |
281 | date d35(2000, Dec, 24); | |
282 | check_equal("check iso week number ", d35.week_number(), 51); | |
283 | date d36(2000, Dec, 25); | |
284 | check_equal("check iso week number ", d36.week_number(), 52); | |
285 | date d37(2000, Dec, 31); | |
286 | check_equal("check iso week number ", d37.week_number(), 52); | |
287 | date d38(2001, Jan, 1); | |
288 | check_equal("check iso week number ", d38.week_number(), 1); | |
289 | ||
290 | try { | |
291 | int dayofyear1 = d38.day_of_year(); | |
292 | check_equal("check day of year number", dayofyear1, 1); | |
293 | check_equal("check day of year number", d37.day_of_year(), 366); | |
294 | date d39(2001,Dec,31); | |
295 | check_equal("check day of year number", d39.day_of_year(), 365); | |
296 | date d40(2000,Feb,29); | |
297 | check_equal("check day of year number", d40.day_of_year(), 60); | |
298 | date d41(1400,Jan,1); | |
299 | check_equal("check day of year number", d41.day_of_year(), 1); | |
300 | date d42(1400,Jan,1); | |
301 | check_equal("check day of year number", d42.day_of_year(), 1); | |
302 | date d43(2002,Nov,17); | |
303 | check_equal("check day of year number", d43.day_of_year(), 321); | |
304 | } | |
305 | catch(std::exception& e) { | |
306 | std::cout << e.what() << std::endl; | |
307 | check("check day of year number", false); | |
308 | } | |
309 | ||
310 | //converts to date and back -- should get same result | |
11fdf7f2 | 311 | check_equal("tm conversion functions 2000-1-1", date_from_tm(to_tm(d2)), d2); |
7c673cae FG |
312 | check_equal("tm conversion functions 1900-1-1", date_from_tm(to_tm(d1)), d1); |
313 | check_equal("tm conversion functions min date 1400-1-1 ", date_from_tm(to_tm(d14)), d14); | |
314 | check_equal("tm conversion functions max date 9999-12-31", date_from_tm(to_tm(d13)), d13); | |
315 | ||
316 | try{ | |
317 | date d(neg_infin); | |
318 | tm d_tm = to_tm(d); | |
319 | check("Exception not thrown (special_value to_tm)", false); | |
320 | std::cout << d_tm.tm_sec << std::endl; //does nothing useful but stops compiler from complaining about unused d_tm | |
b32b8144 | 321 | }catch(std::out_of_range&){ |
7c673cae FG |
322 | check("Caught expected exception (special_value to_tm)", true); |
323 | }catch(...){ | |
324 | check("Caught un-expected exception (special_value to_tm)", false); | |
325 | } | |
326 | ||
11fdf7f2 TL |
327 | // trac-13159 |
328 | test_yearlimit( 0, false); | |
329 | test_yearlimit( 1399, false); | |
330 | test_yearlimit( 1400, true); | |
331 | test_yearlimit( 1401, true); | |
332 | test_yearlimit( 9999, true); | |
333 | test_yearlimit(10000, false); | |
334 | test_yearlimit(10001, false); | |
7c673cae | 335 | |
11fdf7f2 | 336 | return printTestStats(); |
7c673cae FG |
337 | } |
338 |