-
Notifications
You must be signed in to change notification settings - Fork 677
/
validate.cpp
165 lines (159 loc) · 4.71 KB
/
validate.cpp
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
#include "date/tz.h"
#include <iostream>
void
test_info(const date::time_zone* zone, const date::sys_info& info)
{
using namespace date;
using namespace std::chrono;
auto begin = info.begin;
auto end = info.end - microseconds{1};
auto mid = begin + (end - begin) /2;
using sys_microseconds = date::sys_time<microseconds>;
using zoned_microseconds = zoned_time<microseconds>;
zoned_microseconds local{zone};
if (begin > sys_days{jan/1/1700})
{
auto prev_local = local;
local = begin;
prev_local = begin - seconds{1};
auto slocal = local.get_local_time();
auto plocal = prev_local.get_local_time();
if (plocal < slocal - seconds{1})
{
assert(sys_microseconds{local} == begin);
try
{
local = plocal + (slocal - seconds{1} - plocal) / 2;
assert(false);
}
catch (const nonexistent_local_time&)
{
}
}
else if (plocal > slocal - seconds{1})
{
try
{
local = slocal - seconds{1} + (plocal - (slocal - seconds{1})) / 2;
assert(false);
}
catch (const ambiguous_local_time&)
{
}
}
}
local = mid;
assert(sys_microseconds{local} == mid);
if (end < sys_days{jan/1/3000})
{
local = end;
auto next_local = local;
next_local = info.end;
auto slocal = local.get_local_time();
auto nlocal = next_local.get_local_time();
if (nlocal < slocal + microseconds{1})
{
try
{
local = nlocal + (slocal + microseconds{1} - nlocal) / 2;
assert(false);
}
catch (const ambiguous_local_time&)
{
}
}
else if (nlocal > slocal + microseconds{1})
{
assert(sys_microseconds{local} == end);
try
{
local = slocal + microseconds{1} +
(nlocal - (slocal + microseconds{1})) / 2;
assert(false);
}
catch (const nonexistent_local_time&)
{
}
}
}
}
void
tzmain()
{
using namespace date;
using namespace std::chrono;
auto& db = get_tzdb();
std::vector<std::string> names;
#if USE_OS_TZDB
names.reserve(db.zones.size());
for (auto& zone : db.zones)
names.push_back(zone.name());
#else // !USE_OS_TZDB
names.reserve(db.zones.size() + db.links.size());
for (auto& zone : db.zones)
names.push_back(zone.name());
for (auto& link : db.links)
names.push_back(link.name());
std::sort(names.begin(), names.end());
#endif // !USE_OS_TZDB
std::cout << db.version << "\n\n";
for (auto const& name : names)
{
std::cout << name << '\n';
auto z = locate_zone(name);
auto begin = sys_days(jan/1/date::year::min()) + seconds{0};
auto end = sys_days(jan/1/2035) + seconds{0};
auto info = z->get_info(begin);
std::cout << "Initially: ";
if (info.offset >= seconds{0})
std::cout << '+';
std::cout << make_time(info.offset);
if (info.save == minutes{0})
std::cout << " standard ";
else
std::cout << " daylight ";
std::cout << info.abbrev << '\n';
test_info(z, info);
auto prev_offset = info.offset;
auto prev_abbrev = info.abbrev;
auto prev_save = info.save;
for (begin = info.end; begin < end; begin = info.end)
{
info = z->get_info(begin);
test_info(z, info);
if (info.offset == prev_offset && info.abbrev == prev_abbrev &&
info.save == prev_save)
continue;
auto dp = floor<days>(begin);
auto ymd = date::year_month_day(dp);
auto time = make_time(begin - dp);
std::cout << ymd << ' ' << time << "Z ";
if (info.offset >= seconds{0})
std::cout << '+';
std::cout << make_time(info.offset);
if (info.save == minutes{0})
std::cout << " standard ";
else
std::cout << " daylight ";
std::cout << info.abbrev << '\n';
prev_offset = info.offset;
prev_abbrev = info.abbrev;
prev_save = info.save;
}
std::cout << '\n';
}
}
int
main()
{
try
{
tzmain();
}
catch(const std::exception& ex)
{
std::cout << "An exception occured: " << ex.what() << std::endl;
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}