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