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
|
/* Copyright (c) 2003-2004 CrystalClear Software, Inc.
* Subject to the Boost Software License, Version 1.0.
* (See accompanying file LICENSE-1.0 or http://www.boost.org/LICENSE-1.0)
* Author: Jeff Garland, Bart Garst
* $Date: 2005/04/17 21:49:11 $
*/
#include "boost/date_time/gregorian/gregorian.hpp"
//#include "boost/date_time/local_time/time_zone.hpp"
#include "boost/date_time/testfrmwk.hpp"
#include "boost/date_time/local_time/posix_time_zone.hpp"
#include <string>
#include <iostream>
int main(){
using namespace boost::local_time;
using namespace boost::posix_time;
using namespace boost::gregorian;
std::string specs[] = {"MST-07", "MST-07:00:00","EST-05EDT,M4.1.0,M10.5.0", "EST-05:00:00EDT+01:00:00,M4.1.0/02:00:00,M10.5.0/02:00:00","PST-08PDT,J46/1:30,J310","PST-08PDT,45,310/0:30:00"};
posix_time_zone nyc1(specs[2]);
posix_time_zone nyc2(specs[3]);
time_duration td = hours(-5);
check("Has DST", nyc1.has_dst() && nyc2.has_dst());
check("UTC offset", nyc1.base_utc_offset() == td);
check("UTC offsets match", nyc1.base_utc_offset() == nyc2.base_utc_offset());
check("Abbrevs", nyc1.std_zone_abbrev() == std::string("EST"));
check("Abbrevs", nyc2.std_zone_abbrev() == std::string("EST"));
check("Abbrevs", nyc1.dst_zone_abbrev() == std::string("EDT"));
check("Abbrevs", nyc2.dst_zone_abbrev() == std::string("EDT"));
// names not available for posix_time_zone, abbrevs used in their place
check("Names", nyc1.std_zone_name() == std::string("EST"));
check("Names", nyc2.std_zone_name() == std::string("EST"));
check("Names", nyc1.dst_zone_name() == std::string("EDT"));
check("Names", nyc2.dst_zone_name() == std::string("EDT"));
td = hours(1);
check("dst offset", nyc1.dst_offset() == td);
check("dst offsets match", nyc1.dst_offset() == nyc2.dst_offset());
check("dst start", nyc1.dst_local_start_time(2003) ==
ptime(date(2003,Apr,6),time_duration(2,0,0)));
check("dst starts match", nyc1.dst_local_start_time(2003) ==
nyc2.dst_local_start_time(2003));
check("dst end", nyc1.dst_local_end_time(2003) ==
ptime(date(2003,Oct,26),time_duration(2,0,0)));
check("dst ends match", nyc1.dst_local_end_time(2003) ==
nyc2.dst_local_end_time(2003));
check("to posix string",
nyc1.to_posix_string() == std::string("EST-05EDT+01,M4.1.0/02:00,M10.5.0/02:00"));
check("to posix string",
nyc2.to_posix_string() == std::string("EST-05EDT+01,M4.1.0/02:00,M10.5.0/02:00"));
posix_time_zone az1(specs[0]);
posix_time_zone az2(specs[1]);
td = hours(-7);
check("Has DST", !az1.has_dst() && !az2.has_dst());
check("UTC offset", az1.base_utc_offset() == td);
check("UTC offsets match", az1.base_utc_offset() == az2.base_utc_offset());
check("dst start in non-dst zone",
az1.dst_local_start_time(2005) == ptime(not_a_date_time));
check("dst end in non-dst zone",
az2.dst_local_end_time(2005) == ptime(not_a_date_time));
check("Abbrevs", az1.std_zone_abbrev() == std::string("MST"));
check("Abbrevs", az2.std_zone_abbrev() == std::string("MST"));
// non-dst zones default to empty strings for dst names & abbrevs
check("Abbrevs", az1.dst_zone_abbrev() == std::string(""));
check("Abbrevs", az2.dst_zone_abbrev() == std::string(""));
check("Names", az1.std_zone_name() == std::string("MST"));
check("Names", az2.std_zone_name() == std::string("MST"));
check("Names", az1.dst_zone_name() == std::string(""));
check("Names", az2.dst_zone_name() == std::string(""));
check("to posix string",
az1.to_posix_string() == std::string("MST-07"));
check("to posix string",
az2.to_posix_string() == std::string("MST-07"));
// bizzar time zone spec to fully test parsing
std::cout << "\nFictitious time zone" << std::endl;
posix_time_zone bz("BST+11:21:15BDT-00:28,M2.2.4/03:15:42,M11.5.2/01:08:53");
check("hast dst", bz.has_dst());
check("UTC offset", bz.base_utc_offset() == time_duration(11,21,15));
check("Abbrev", bz.std_zone_abbrev() == std::string("BST"));
check("Abbrev", bz.dst_zone_abbrev() == std::string("BDT"));
check("dst offset", bz.dst_offset() == time_duration(0,-28,0));
check("dst start", bz.dst_local_start_time(1962) ==
ptime(date(1962,Feb,8),time_duration(3,15,42)));
check("dst end", bz.dst_local_end_time(1962) ==
ptime(date(1962,Nov,27),time_duration(1,8,53)));
// only checking start & end rules w/ 'J' notation
std::cout << "\n'J' notation Start/End rule tests..." << std::endl;
posix_time_zone la1(specs[4]); // "PST-08PDT,J124,J310"
//posix_time_zone la1("PST-08PDT,J1,J365");// Jan1/Dec31
check("dst start", la1.dst_local_start_time(2003) ==
ptime(date(2003,Feb,15),time_duration(1,30,0)));
check("dst end", la1.dst_local_end_time(2003) ==
ptime(date(2003,Nov,6),time_duration(2,0,0)));
/* NOTE: la1 was created from a 'J' notation string but to_posix_string
* returns an 'n' notation string. The difference between the two
* is Feb-29 is always counted in an 'n' notation string and numbering
* starts at zero ('J' notation starts at one).
* Every possible date spec that can be written in 'J' notation can also
* be written in 'n' notation. The reverse is not true so 'n' notation
* is used as the output for to_posix_string(). */
check("to posix string",
la1.to_posix_string() == std::string("PST-08PDT+01,45/01:30,310/02:00"));
// only checking start & end rules w/ 'n' notation
std::cout << "\n'n' notation Start/End rule tests..." << std::endl;
posix_time_zone la2(specs[5]); // "PST-08PDT,124,310"
//posix_time_zone la2("PST-08PDT,0,365");// Jan1/Dec31
check("dst start", la2.dst_local_start_time(2003) ==
ptime(date(2003,Feb,15),time_duration(2,0,0)));
check("dst end", la2.dst_local_end_time(2003) ==
ptime(date(2003,Nov,6),time_duration(0,30,0)));
check("to posix string",
la2.to_posix_string() == std::string("PST-08PDT+01,45/02:00,310/00:30"));
// bad posix time zone strings tests
std::cout << "\nInvalid time zone string tests..." << std::endl;
try {
posix_time_zone badz("EST-13");
check("Exception not thrown: bad UTC offset", false);
}catch(bad_offset boff){
std::string msg(boff.what());
check("Exception caught: "+msg , true);
}
try {
posix_time_zone badz("EST-5EDT24:00:01,J124/1:30,J310");
check("Exception not thrown: bad DST adjust", false);
}catch(bad_adjustment badj){
std::string msg(badj.what());
check("Exception caught: "+msg , true);
}
try {
posix_time_zone badz("EST-5EDT01:00:00,J124/-1:30,J310");
check("Exception not thrown: bad DST start/end offset", false);
}catch(bad_offset boff){
std::string msg(boff.what());
check("Exception caught: "+msg , true);
}
try {
posix_time_zone badz("EST-5EDT01:00:00,J124/1:30,J370");
check("Exception not thrown: invalid date spec", false);
}catch(boost::gregorian::bad_day_of_month boff){
std::string msg(boff.what());
check("Exception caught: "+msg , true);
}catch(boost::gregorian::bad_month boff){
std::string msg(boff.what());
check("Exception caught: "+msg , true);
}catch(...){
check("Unexpected exception caught: ", false);
}
std::cout << "\nTest some Central Europe specs" << std::endl;
//Test a timezone spec on the positive side of the UTC line.
//This is the time for central europe which is one hour in front of UTC
//Note these Summer time transition rules aren't actually correct.
posix_time_zone cet_tz("CET+01:00:00EDT+01:00:00,M4.1.0/02:00:00,M10.5.0/02:00:00");
check("Has DST", cet_tz.has_dst());
check("UTC offset", cet_tz.base_utc_offset() == hours(1));
check("Abbrevs", cet_tz.std_zone_abbrev() == std::string("CET"));
// check("Abbrevs", nyc2.std_zone_abbrev() == std::string("EST"));
std::cout << "\nTest some Central Austrialia UTC+8:30" << std::endl;
//Test a timezone spec on the positive side of the UTC line.
//This is the time for central europe which is one hour in front of UTC
//Note these Summer time transition rules aren't actually correct.
posix_time_zone caus_tz("CAS+08:30:00CDT+01:00:00,M4.1.0/02:00:00,M10.5.0/02:00:00");
check("Has DST", caus_tz.has_dst());
check("UTC offset", caus_tz.base_utc_offset() == hours(8)+minutes(30));
check("Abbrevs", caus_tz.std_zone_abbrev() == std::string("CAS"));
// check("Abbrevs", nyc2.std_zone_abbrev() == std::string("EST"));
{
/**** first/last of month Julian & non-Julian tests ****/
// Mar-01 & Oct-31, count begins at 1
std::string spec("FST+3FDT,J60,J304");
posix_time_zone fl_1(spec);
check("Julian First/last of month", fl_1.dst_local_start_time(2003) ==
ptime(date(2003,Mar,1),hours(2)));
check("Julian First/last of month", fl_1.dst_local_end_time(2003) ==
ptime(date(2003,Oct,31),hours(2)));
check("Julian First/last of month", fl_1.dst_local_start_time(2004) ==
ptime(date(2004,Mar,1),hours(2)));
check("Julian First/last of month", fl_1.dst_local_end_time(2004) ==
ptime(date(2004,Oct,31),hours(2)));
// Mar-01 & Oct-31 Non-leap year, count begins at 0
spec = "FST+3FDT,59,304"; // "304" is not a mistake here, see posix_time_zone docs
posix_time_zone fl_2(spec);
try{
check("Non-Julian First/last of month", fl_2.dst_local_start_time(2003) ==
ptime(date(2003,Mar,1),hours(2)));
}catch(std::exception e){
check("Expected exception caught for Non-Julian day of 59, in non-leap year (Feb-29)", true);
}
check("Non-Julian First/last of month", fl_2.dst_local_end_time(2003) ==
ptime(date(2003,Oct,31),hours(2)));
// Mar-01 & Oct-31 leap year, count begins at 0
spec = "FST+3FDT,60,304";
posix_time_zone fl_3(spec);
check("Non-Julian First/last of month", fl_3.dst_local_start_time(2004) ==
ptime(date(2004,Mar,1),hours(2)));
check("Non-Julian First/last of month", fl_3.dst_local_end_time(2004) ==
ptime(date(2004,Oct,31),hours(2)));
}
printTestStats();
return 0;
}
|