]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | /* Copyright (c) 2003-2004 CrystalClear Software, Inc. |
2 | * Subject to the Boost Software License, Version 1.0. | |
3 | * (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) | |
4 | * Author: Jeff Garland, Bart Garst | |
5 | * $Date$ | |
6 | */ | |
7 | ||
8 | ||
9 | #include "boost/date_time/gregorian/gregorian.hpp" | |
10 | //#include "boost/date_time/local_time/time_zone.hpp" | |
11 | #include "../testfrmwk.hpp" | |
12 | ||
13 | #include "boost/date_time/local_time/posix_time_zone.hpp" | |
14 | ||
15 | #include <string> | |
16 | #include <iostream> | |
17 | ||
18 | int main(){ | |
19 | using namespace boost::local_time; | |
20 | using namespace boost::posix_time; | |
21 | using namespace boost::gregorian; | |
22 | ||
23 | typedef posix_time_zone_base<wchar_t> w_posix_time_zone; | |
24 | ||
25 | std::wstring specs[] = {L"MST-07", L"MST-07:00:00",L"EST-05EDT,M4.1.0,M10.5.0", L"EST-05:00:00EDT+01:00:00,M4.1.0/02:00:00,M10.5.0/02:00:00",L"PST-08PDT,J46/1:30,J310",L"PST-08PDT,45,310/0:30:00"}; | |
26 | ||
27 | w_posix_time_zone nyc1(specs[2]); | |
28 | w_posix_time_zone nyc2(specs[3]); | |
29 | time_duration td = hours(-5); | |
30 | ||
31 | check("Has DST", nyc1.has_dst() && nyc2.has_dst()); | |
32 | check("UTC offset", nyc1.base_utc_offset() == td); | |
33 | check("UTC offsets match", nyc1.base_utc_offset() == nyc2.base_utc_offset()); | |
34 | check("Abbrevs", nyc1.std_zone_abbrev() == std::wstring(L"EST")); | |
35 | check("Abbrevs", nyc2.std_zone_abbrev() == std::wstring(L"EST")); | |
36 | check("Abbrevs", nyc1.dst_zone_abbrev() == std::wstring(L"EDT")); | |
37 | check("Abbrevs", nyc2.dst_zone_abbrev() == std::wstring(L"EDT")); | |
38 | // names not available for w_posix_time_zone, abbrevs used in their place | |
39 | check("Names", nyc1.std_zone_name() == std::wstring(L"EST")); | |
40 | check("Names", nyc2.std_zone_name() == std::wstring(L"EST")); | |
41 | check("Names", nyc1.dst_zone_name() == std::wstring(L"EDT")); | |
42 | check("Names", nyc2.dst_zone_name() == std::wstring(L"EDT")); | |
43 | td = hours(1); | |
44 | check("dst offset", nyc1.dst_offset() == td); | |
45 | check("dst offsets match", nyc1.dst_offset() == nyc2.dst_offset()); | |
46 | check("dst start", nyc1.dst_local_start_time(2003) == | |
47 | ptime(date(2003,Apr,6),time_duration(2,0,0))); | |
48 | check("dst starts match", nyc1.dst_local_start_time(2003) == | |
49 | nyc2.dst_local_start_time(2003)); | |
50 | check("dst end", nyc1.dst_local_end_time(2003) == | |
51 | ptime(date(2003,Oct,26),time_duration(2,0,0))); | |
52 | check("dst ends match", nyc1.dst_local_end_time(2003) == | |
53 | nyc2.dst_local_end_time(2003)); | |
54 | check("to posix string", | |
55 | nyc1.to_posix_string() == std::wstring(L"EST-05EDT+01,M4.1.0/02:00,M10.5.0/02:00")); | |
56 | check("to posix string", | |
57 | nyc2.to_posix_string() == std::wstring(L"EST-05EDT+01,M4.1.0/02:00,M10.5.0/02:00")); | |
58 | ||
59 | ||
60 | w_posix_time_zone az1(specs[0]); | |
61 | w_posix_time_zone az2(specs[1]); | |
62 | td = hours(-7); | |
63 | ||
64 | check("Has DST", !az1.has_dst() && !az2.has_dst()); | |
65 | check("UTC offset", az1.base_utc_offset() == td); | |
66 | check("UTC offsets match", az1.base_utc_offset() == az2.base_utc_offset()); | |
67 | check("dst start in non-dst zone", | |
68 | az1.dst_local_start_time(2005) == ptime(not_a_date_time)); | |
69 | check("dst end in non-dst zone", | |
70 | az2.dst_local_end_time(2005) == ptime(not_a_date_time)); | |
71 | check("Abbrevs", az1.std_zone_abbrev() == std::wstring(L"MST")); | |
72 | check("Abbrevs", az2.std_zone_abbrev() == std::wstring(L"MST")); | |
73 | // non-dst zones default to empty strings for dst names & abbrevs | |
74 | check("Abbrevs", az1.dst_zone_abbrev() == std::wstring(L"")); | |
75 | check("Abbrevs", az2.dst_zone_abbrev() == std::wstring(L"")); | |
76 | check("Names", az1.std_zone_name() == std::wstring(L"MST")); | |
77 | check("Names", az2.std_zone_name() == std::wstring(L"MST")); | |
78 | check("Names", az1.dst_zone_name() == std::wstring(L"")); | |
79 | check("Names", az2.dst_zone_name() == std::wstring(L"")); | |
80 | check("to posix string", | |
81 | az1.to_posix_string() == std::wstring(L"MST-07")); | |
82 | check("to posix string", | |
83 | az2.to_posix_string() == std::wstring(L"MST-07")); | |
84 | ||
85 | ||
86 | // bizzar time zone spec to fully test parsing | |
87 | std::cout << "\nFictitious time zone" << std::endl; | |
88 | w_posix_time_zone bz(L"BST+11:21:15BDT-00:28,M2.2.4/03:15:42,M11.5.2/01:08:53"); | |
89 | check("hast dst", bz.has_dst()); | |
90 | check("UTC offset", bz.base_utc_offset() == time_duration(11,21,15)); | |
91 | check("Abbrev", bz.std_zone_abbrev() == std::wstring(L"BST")); | |
92 | check("Abbrev", bz.dst_zone_abbrev() == std::wstring(L"BDT")); | |
93 | check("dst offset", bz.dst_offset() == time_duration(0,-28,0)); | |
94 | check("dst start", bz.dst_local_start_time(1962) == | |
95 | ptime(date(1962,Feb,8),time_duration(3,15,42))); | |
96 | check("dst end", bz.dst_local_end_time(1962) == | |
97 | ptime(date(1962,Nov,27),time_duration(1,8,53))); | |
98 | ||
99 | // only checking start & end rules w/ 'J' notation | |
100 | std::cout << "\n'J' notation Start/End rule tests..." << std::endl; | |
101 | w_posix_time_zone la1(specs[4]); // "PST-08PDT,J124,J310" | |
102 | //w_posix_time_zone la1("PST-08PDT,J1,J365");// Jan1/Dec31 | |
103 | check("dst start", la1.dst_local_start_time(2003) == | |
104 | ptime(date(2003,Feb,15),time_duration(1,30,0))); | |
105 | check("dst end", la1.dst_local_end_time(2003) == | |
106 | ptime(date(2003,Nov,6),time_duration(2,0,0))); | |
107 | /* NOTE: la1 was created from a 'J' notation string but to_posix_string | |
108 | * returns an 'n' notation string. The difference between the two | |
109 | * is Feb-29 is always counted in an 'n' notation string and numbering | |
110 | * starts at zero ('J' notation starts at one). | |
111 | * Every possible date spec that can be written in 'J' notation can also | |
112 | * be written in 'n' notation. The reverse is not true so 'n' notation | |
113 | * is used as the output for to_posix_string(). */ | |
114 | check("to posix string", | |
115 | la1.to_posix_string() == std::wstring(L"PST-08PDT+01,45/01:30,310/02:00")); | |
116 | ||
117 | // only checking start & end rules w/ 'n' notation | |
118 | std::cout << "\n'n' notation Start/End rule tests..." << std::endl; | |
119 | w_posix_time_zone la2(specs[5]); // "PST-08PDT,124,310" | |
120 | //w_posix_time_zone la2("PST-08PDT,0,365");// Jan1/Dec31 | |
121 | check("dst start", la2.dst_local_start_time(2003) == | |
122 | ptime(date(2003,Feb,15),time_duration(2,0,0))); | |
123 | check("dst end", la2.dst_local_end_time(2003) == | |
124 | ptime(date(2003,Nov,6),time_duration(0,30,0))); | |
125 | check("to posix string", | |
126 | la2.to_posix_string() == std::wstring(L"PST-08PDT+01,45/02:00,310/00:30")); | |
127 | ||
128 | // bad posix time zone strings tests | |
129 | std::cout << "\nInvalid time zone string tests..." << std::endl; | |
130 | try { | |
131 | w_posix_time_zone badz(L"EST-13"); | |
132 | check("Exception not thrown: bad UTC offset", false); | |
133 | }catch(bad_offset& boff){ | |
134 | std::string msg(boff.what()); | |
135 | check("Exception caught: "+msg , true); | |
136 | } | |
137 | try { | |
138 | w_posix_time_zone badz(L"EST-5EDT24:00:01,J124/1:30,J310"); | |
139 | check("Exception not thrown: bad DST adjust", false); | |
140 | }catch(bad_adjustment& badj){ | |
141 | std::string msg(badj.what()); | |
142 | check("Exception caught: "+msg , true); | |
143 | } | |
144 | try { | |
145 | w_posix_time_zone badz(L"EST-5EDT01:00:00,J124/-1:30,J310"); | |
146 | check("Exception not thrown: bad DST start/end offset", false); | |
147 | }catch(bad_offset& boff){ | |
148 | std::string msg(boff.what()); | |
149 | check("Exception caught: "+msg , true); | |
150 | } | |
151 | try { | |
152 | w_posix_time_zone badz(L"EST-5EDT01:00:00,J124/1:30,J370"); | |
153 | check("Exception not thrown: invalid date spec", false); | |
154 | }catch(boost::gregorian::bad_day_of_month& boff){ | |
155 | std::string msg(boff.what()); | |
156 | check("Exception caught: "+msg , true); | |
157 | }catch(boost::gregorian::bad_month& boff){ | |
158 | std::string msg(boff.what()); | |
159 | check("Exception caught: "+msg , true); | |
160 | }catch(...){ | |
161 | check("Unexpected exception caught: ", false); | |
162 | } | |
163 | ||
164 | std::cout << "\nTest some Central Europe specs" << std::endl; | |
165 | ||
166 | //Test a timezone spec on the positive side of the UTC line. | |
167 | //This is the time for central europe which is one hour in front of UTC | |
168 | //Note these Summer time transition rules aren't actually correct. | |
169 | w_posix_time_zone cet_tz(L"CET+01:00:00EDT+01:00:00,M4.1.0/02:00:00,M10.5.0/02:00:00"); | |
170 | check("Has DST", cet_tz.has_dst()); | |
171 | check("UTC offset", cet_tz.base_utc_offset() == hours(1)); | |
172 | check("Abbrevs", cet_tz.std_zone_abbrev() == std::wstring(L"CET")); | |
173 | // check("Abbrevs", nyc2.std_zone_abbrev() == std::wstring("EST")); | |
174 | ||
175 | std::cout << "\nTest some Central Austrialia UTC+8:30" << std::endl; | |
176 | ||
177 | //Test a timezone spec on the positive side of the UTC line. | |
178 | //This is the time for central europe which is one hour in front of UTC | |
179 | //Note these Summer time transition rules aren't actually correct. | |
180 | w_posix_time_zone caus_tz(L"CAS+08:30:00CDT+01:00:00,M4.1.0/02:00:00,M10.5.0/02:00:00"); | |
181 | check("Has DST", caus_tz.has_dst()); | |
182 | check("UTC offset", caus_tz.base_utc_offset() == hours(8)+minutes(30)); | |
183 | check("Abbrevs", caus_tz.std_zone_abbrev() == std::wstring(L"CAS")); | |
184 | // check("Abbrevs", nyc2.std_zone_abbrev() == std::wstring("EST")); | |
185 | ||
186 | { | |
187 | /**** first/last of month Julian & non-Julian tests ****/ | |
188 | // Mar-01 & Oct-31, count begins at 1 | |
189 | std::wstring spec(L"FST+3FDT,J60,J304"); | |
190 | w_posix_time_zone fl_1(spec); | |
191 | check("Julian First/last of month", fl_1.dst_local_start_time(2003) == | |
192 | ptime(date(2003,Mar,1),hours(2))); | |
193 | check("Julian First/last of month", fl_1.dst_local_end_time(2003) == | |
194 | ptime(date(2003,Oct,31),hours(2))); | |
195 | check("Julian First/last of month", fl_1.dst_local_start_time(2004) == | |
196 | ptime(date(2004,Mar,1),hours(2))); | |
197 | check("Julian First/last of month", fl_1.dst_local_end_time(2004) == | |
198 | ptime(date(2004,Oct,31),hours(2))); | |
199 | ||
200 | // Mar-01 & Oct-31 Non-leap year, count begins at 0 | |
201 | spec = L"FST+3FDT,59,304"; // "304" is not a mistake here, see posix_time_zone docs | |
202 | w_posix_time_zone fl_2(spec); | |
203 | try{ | |
204 | check("Non-Julian First/last of month", fl_2.dst_local_start_time(2003) == | |
205 | ptime(date(2003,Mar,1),hours(2))); | |
b32b8144 | 206 | }catch(std::exception&){ |
7c673cae FG |
207 | check("Expected exception caught for Non-Julian day of 59, in non-leap year (Feb-29)", true); |
208 | } | |
209 | check("Non-Julian First/last of month", fl_2.dst_local_end_time(2003) == | |
210 | ptime(date(2003,Oct,31),hours(2))); | |
211 | ||
212 | // Mar-01 & Oct-31 leap year, count begins at 0 | |
213 | spec = L"FST+3FDT,60,304"; | |
214 | w_posix_time_zone fl_3(spec); | |
215 | check("Non-Julian First/last of month", fl_3.dst_local_start_time(2004) == | |
216 | ptime(date(2004,Mar,1),hours(2))); | |
217 | check("Non-Julian First/last of month", fl_3.dst_local_end_time(2004) == | |
218 | ptime(date(2004,Oct,31),hours(2))); | |
219 | } | |
220 | ||
221 | printTestStats(); | |
222 | return 0; | |
223 | } | |
224 |