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