1 // Copyright 2011 Vicente J. Botet Escriba
2 // Copyright (c) Microsoft Corporation 2014
3 // Distributed under the Boost Software License, Version 1.0.
4 // See http://www.boost.org/LICENSE_1_0.txt
5
6 #include <boost/chrono/chrono_io.hpp>
7 #include <sstream>
8 #include <boost/detail/lightweight_test.hpp>
9 #include <boost/chrono/system_clocks.hpp>
10 #include <boost/chrono/thread_clock.hpp>
11 #include <boost/chrono/process_cpu_clocks.hpp>
12 #include <locale>
13 #include <ctime>
14 #include <cstdio>
15
16 template <typename Clock, typename D>
test_good_prefix(const char * str,D d)17 void test_good_prefix(const char* str, D d)
18 {
19 std::ostringstream out;
20 boost::chrono::time_point<Clock, D> tp(d);
21 out << tp;
22 BOOST_TEST(out.good());
23 //std::cout << "Expected= " << std::string(str) + boost::chrono::clock_string<Clock, char>::since() << std::endl;
24 //std::cout << "Obtained= " << out.str() << std::endl;
25 BOOST_TEST( (out.str() == std::string(str) + boost::chrono::clock_string<Clock, char>::since()));
26 }
27
28 template <typename D>
test_good_prefix_system_clock(const char * str,D d)29 void test_good_prefix_system_clock(const char* str, D d)
30 {
31 typedef boost::chrono::system_clock Clock;
32
33 std::ostringstream out;
34 boost::chrono::time_point<Clock, D> tp(d);
35 out << tp;
36 BOOST_TEST(out.good());
37
38 std::cout << "Expected= " << str << std::endl;
39 std::cout << "Obtained= " << out.str() << std::endl;
40 BOOST_TEST( (out.str() == std::string(str) ));
41 }
42
43 template <typename Clock, typename D>
test_good_symbol(const char * str,D d)44 void test_good_symbol(const char* str, D d)
45 {
46 std::ostringstream out;
47 boost::chrono::time_point<Clock, D> tp(d);
48 #if BOOST_CHRONO_VERSION>=2
49 out << boost::chrono::duration_fmt(boost::chrono::duration_style::symbol) << tp;
50 #else
51 out << boost::chrono::duration_short << tp;
52 #endif
53 BOOST_TEST(out.good());
54 BOOST_TEST( (out.str() == std::string(str) + boost::chrono::clock_string<Clock, char>::since()));
55 }
56
57 #if BOOST_CHRONO_VERSION>=2
58 template <typename D>
test_good_symbol_system_clock(const char * str,D d)59 void test_good_symbol_system_clock(const char* str, D d)
60 {
61 typedef boost::chrono::system_clock Clock;
62
63 std::ostringstream out;
64 boost::chrono::time_point<Clock, D> tp(d);
65 out << boost::chrono::duration_fmt(boost::chrono::duration_style::symbol) << tp;
66 BOOST_TEST(out.good());
67 std::cout << "Expected= " << str << std::endl;
68 std::cout << "Obtained= " << out.str() << std::endl;
69 BOOST_TEST( (out.str() == std::string(str) ));
70 }
71
72 template <typename D>
test_good_utc_fmt_system_clock(const char * str,const char * fmt,D d)73 void test_good_utc_fmt_system_clock(const char* str, const char* fmt, D d)
74 {
75 typedef boost::chrono::system_clock Clock;
76
77 std::ostringstream out;
78 boost::chrono::time_point<Clock, D> tp(d);
79 boost::chrono::time_fmt_io_saver<> fmts(out);
80 boost::chrono::timezone_io_saver tzs(out);
81 out << time_fmt(boost::chrono::timezone::utc, fmt) << tp;
82 BOOST_TEST(out.good());
83 std::cout << "Expected= " << str << std::endl;
84 std::cout << "Obtained= " << out.str() << std::endl;
85 BOOST_TEST_EQ( out.str() , std::string(str) );
86 }
87
88 template <typename D>
test_good_utc_fmt_system_clock2(const char * str,const char * fmt,D d)89 void test_good_utc_fmt_system_clock2(const char* str, const char* fmt, D d)
90 {
91 typedef boost::chrono::system_clock Clock;
92
93 std::ostringstream out;
94 boost::chrono::time_point<Clock, D> tp(d);
95 boost::chrono::time_fmt_io_saver<> fmts(out, fmt);
96 boost::chrono::timezone_io_saver tzs(out, boost::chrono::timezone::utc);
97 out << tp;
98 BOOST_TEST(out.good());
99 std::cout << "Expected= " << str << std::endl;
100 std::cout << "Obtained= " << out.str() << std::endl;
101 BOOST_TEST_EQ( out.str() , std::string(str) );
102 }
103
104 template<typename Clock, typename D>
test_good(const char * str,D d,boost::chrono::duration_style style)105 void test_good(const char* str, D d, boost::chrono::duration_style style)
106 {
107 std::ostringstream out;
108 boost::chrono::time_point<Clock,D> tp(d);
109 out << boost::chrono::duration_fmt(style) << tp;
110 BOOST_TEST(out.good());
111 BOOST_TEST((out.str() == std::string(str)+boost::chrono::clock_string<Clock,char>::since()));
112 }
113
114 template<typename D>
test_good_system_clock(const char * str,D d,boost::chrono::duration_style style)115 void test_good_system_clock(const char* str, D d, boost::chrono::duration_style style)
116 {
117 typedef boost::chrono::system_clock Clock;
118
119 std::ostringstream out;
120 boost::chrono::time_point<Clock,D> tp(d);
121 out << boost::chrono::duration_fmt(style) << tp;
122 BOOST_TEST(out.good());
123 std::cout << "Expected= " << str << std::endl;
124 std::cout << "Obtained= " << out.str() << std::endl;
125 BOOST_TEST((out.str() == std::string(str) ));
126 }
127 #endif
128
129 template <typename Clock>
check_all()130 void check_all()
131 {
132 using namespace boost::chrono;
133 using namespace boost;
134
135 #if BOOST_CHRONO_VERSION>=2
136 test_good<Clock>("2 hours", hours(2), duration_style::prefix);
137 test_good<Clock>("2 h", hours(2), duration_style::symbol);
138 #endif
139
140 test_good_prefix<Clock> ("2 hours", hours(2));
141 test_good_prefix<Clock> ("2 minutes", minutes(2));
142 test_good_prefix<Clock> ("2 seconds", seconds(2));
143 test_good_prefix<Clock> ("1 second", seconds(1));
144 test_good_prefix<Clock> ("-1 second", seconds(-1));
145 test_good_prefix<Clock> ("0 seconds", seconds(0));
146 test_good_prefix<Clock> ("2 milliseconds", milliseconds(2));
147 test_good_prefix<Clock> ("2 microseconds", microseconds(2));
148 test_good_prefix<Clock> ("2 nanoseconds", nanoseconds(2));
149 test_good_prefix<Clock> ("2 deciseconds", duration<boost::int_least64_t, deci> (2));
150 test_good_prefix<Clock> ("2 [1/30]seconds", duration<boost::int_least64_t, ratio<1, 30> > (2));
151
152 test_good_symbol<Clock> ("2 h", hours(2));
153 #if BOOST_CHRONO_VERSION>=2
154 test_good_symbol<Clock>("2 min", minutes(2));
155 #else
156 test_good_symbol<Clock> ("2 m", minutes(2));
157 #endif
158 test_good_symbol<Clock> ("2 s", seconds(2));
159 test_good_symbol<Clock> ("2 ms", milliseconds(2));
160 test_good_symbol<Clock> ("2 ns", nanoseconds(2));
161 test_good_symbol<Clock> ("2 ds", duration<boost::int_least64_t, deci> (2));
162 test_good_symbol<Clock> ("2 [1/30]s", duration<boost::int_least64_t, ratio<1, 30> > (2));
163 }
164
165 #if BOOST_CHRONO_VERSION >= 2
check_all_system_clock()166 void check_all_system_clock()
167 {
168 using namespace boost::chrono;
169 using namespace boost;
170
171 test_good_system_clock("1970-01-01 02:00:00.000000000 +0000", hours(2), duration_style::prefix);
172 test_good_system_clock("1970-01-01 02:00:00.000000000 +0000", hours(2), duration_style::symbol);
173
174 test_good_prefix_system_clock("1970-01-01 02:00:00.000000000 +0000", hours(2));
175 test_good_prefix_system_clock("1970-01-01 00:02:00.000000000 +0000", minutes(2));
176 test_good_prefix_system_clock("1970-01-01 00:00:02.000000000 +0000", seconds(2));
177 test_good_prefix_system_clock("1970-01-01 00:00:01.000000000 +0000", seconds(1));
178 test_good_prefix_system_clock("1969-12-31 23:59:59.000000000 +0000", seconds(-1));
179 test_good_prefix_system_clock("1970-01-01 00:00:00.000000000 +0000", seconds(0));
180 test_good_prefix_system_clock("1970-01-01 00:00:00.002000000 +0000", milliseconds(2));
181 test_good_prefix_system_clock("1970-01-01 00:00:00.000002000 +0000", microseconds(2));
182 test_good_prefix_system_clock("1970-01-01 00:00:00.000000002 +0000", nanoseconds(2));
183 test_good_prefix_system_clock("1970-01-01 00:00:00.200000000 +0000", duration<boost::int_least64_t, deci> (2));
184 test_good_prefix_system_clock("1970-01-01 00:00:00.066666667 +0000", duration<boost::int_least64_t, ratio<1, 30> > (2));
185
186 test_good_symbol_system_clock("1970-01-01 02:00:00.000000000 +0000", hours(2));
187 test_good_symbol_system_clock("1970-01-01 00:02:00.000000000 +0000", minutes(2));
188 test_good_symbol_system_clock("1970-01-01 00:00:02.000000000 +0000", seconds(2));
189 test_good_symbol_system_clock("1970-01-01 00:00:00.002000000 +0000", milliseconds(2));
190 test_good_symbol_system_clock("1970-01-01 00:00:00.000000002 +0000", nanoseconds(2));
191 test_good_symbol_system_clock("1970-01-01 00:00:00.200000000 +0000", duration<boost::int_least64_t, deci> (2));
192 test_good_symbol_system_clock("1970-01-01 00:00:00.066666667 +0000", duration<boost::int_least64_t, ratio<1, 30> > (2));
193
194 test_good_utc_fmt_system_clock("1970-01-01 02:00:00", "%Y-%m-%d %H:%M:%S", hours(2));
195 test_good_utc_fmt_system_clock("1970-01-01 02", "%Y-%m-%d %H", hours(2));
196 #if ! defined(BOOST_CHRONO_WINDOWS_API)
197 test_good_utc_fmt_system_clock ("1970-01-01 02:00:00", "%Y-%m-%d %T", hours(2));
198 test_good_utc_fmt_system_clock ("1970-01-01 02:00", "%Y-%m-%d %R", hours(2));
199 test_good_utc_fmt_system_clock ("% 1970-01-01 02:00", "%% %Y-%m-%d %R", hours(2));
200 test_good_utc_fmt_system_clock ("1970-01-01 02:00 Thursday January", "%Y-%m-%d %R %A %B", hours(2));
201 #endif
202 test_good_utc_fmt_system_clock2("1970-01-01 02:00:00", "%Y-%m-%d %H:%M:%S", hours(2));
203 test_good_utc_fmt_system_clock2("1970-01-01 02", "%Y-%m-%d %H", hours(2));
204 #if ! defined(BOOST_CHRONO_WINDOWS_API)
205 test_good_utc_fmt_system_clock2 ("1970-01-01 02:00:00", "%Y-%m-%d %T", hours(2));
206 test_good_utc_fmt_system_clock2 ("1970-01-01 02:00", "%Y-%m-%d %R", hours(2));
207 test_good_utc_fmt_system_clock2 ("% 1970-01-01 02:00", "%% %Y-%m-%d %R", hours(2));
208 test_good_utc_fmt_system_clock2 ("1970-01-01 02:00 Thursday January", "%Y-%m-%d %R %A %B", hours(2));
209 #endif
210 }
211
212
213 #endif
214 #if defined BOOST_CHRONO_INTERNAL_GMTIME
215 #elif BOOST_CHRONO_VERSION == 2
test_gmtime(std::time_t t)216 void test_gmtime(std::time_t t)
217 {
218 std::cout << "t " << t << std::endl;
219 std::puts(ctime(&t));
220 std::tm tm;
221 std::memset(&tm, 0, sizeof(std::tm));
222 if (boost::chrono::detail::internal_gmtime(&t, &tm))
223 {
224 tm.tm_isdst = -1;
225 (void)mktime(&tm);
226 std::tm tm2;
227 std::memset(&tm2, 0, sizeof(std::tm));
228 if (gmtime_r(&t, &tm2))
229 {
230 tm2.tm_isdst = -1;
231 (void)mktime(&tm2);
232
233 BOOST_TEST_EQ( tm.tm_year , tm2.tm_year );
234 BOOST_TEST_EQ( tm.tm_mon , tm2.tm_mon );
235 BOOST_TEST_EQ( tm.tm_mday , tm2.tm_mday );
236 BOOST_TEST_EQ( tm.tm_hour , tm2.tm_hour);
237 BOOST_TEST_EQ( tm.tm_min , tm2.tm_min );
238 BOOST_TEST_EQ( tm.tm_sec , tm2.tm_sec );
239 BOOST_TEST_EQ( tm.tm_wday , tm2.tm_wday );
240 BOOST_TEST_EQ( tm.tm_yday , tm2.tm_yday );
241 BOOST_TEST_EQ( tm.tm_isdst , tm2.tm_isdst );
242 }
243 }
244
245 }
246 #endif
247
248
main()249 int main()
250 {
251 #if defined BOOST_CHRONO_INTERNAL_GMTIME
252 #elif BOOST_CHRONO_VERSION == 2
253 test_gmtime( 0 );
254 test_gmtime( -1 );
255 test_gmtime( +1 );
256 test_gmtime( 0 - (3600 * 24) );
257 test_gmtime( -1 - (3600 * 24) );
258 test_gmtime( +1 - (3600 * 24) );
259 test_gmtime( 0 + (3600 * 24) );
260 test_gmtime( -1 + (3600 * 24) );
261 test_gmtime( +1 + (3600 * 24) );
262 test_gmtime( 0 + 365*(3600 * 24) );
263 test_gmtime( 0 + 10LL*365*(3600 * 24) );
264 test_gmtime( 0 + 15LL*365*(3600 * 24) );
265 test_gmtime( 0 + 17LL*365*(3600 * 24) );
266 test_gmtime( 0 + 18LL*365*(3600 * 24) );
267 test_gmtime( 0 + 19LL*365*(3600 * 24) );
268 test_gmtime( 0 + 19LL*365*(3600 * 24)+ (3600 * 24));
269 test_gmtime( 0 + 19LL*365*(3600 * 24)+ 3*(3600 * 24));
270 test_gmtime( 0 + 19LL*365*(3600 * 24)+ 4*(3600 * 24));
271 test_gmtime( 0 + 20LL*365*(3600 * 24) );
272 test_gmtime( 0 + 40LL*365*(3600 * 24) );
273 #endif
274
275 std::cout << "high_resolution_clock=" << std::endl;
276 check_all<boost::chrono::high_resolution_clock> ();
277 #ifdef BOOST_CHRONO_HAS_CLOCK_STEADY
278 std::cout << "steady_clock=" << std::endl;
279 check_all<boost::chrono::steady_clock> ();
280 #endif
281 std::cout << "system_clock=" << std::endl;
282 #if BOOST_CHRONO_VERSION >= 2 && defined BOOST_CHRONO_PROVIDES_DATE_IO_FOR_SYSTEM_CLOCK_TIME_POINT
283 check_all_system_clock();
284 #else
285 check_all<boost::chrono::system_clock> ();
286 #endif
287
288 #if defined(BOOST_CHRONO_HAS_THREAD_CLOCK)
289 std::cout << "thread_clock="<< std::endl;
290 check_all<boost::chrono::thread_clock>();
291 #endif
292
293 #if defined(BOOST_CHRONO_HAS_PROCESS_CLOCKS)
294 std::cout << "process_real_cpu_clock=" << std::endl;
295 check_all<boost::chrono::process_real_cpu_clock> ();
296 #if ! BOOST_OS_WINDOWS || BOOST_PLAT_WINDOWS_DESKTOP
297 std::cout << "process_user_cpu_clock=" << std::endl;
298 check_all<boost::chrono::process_user_cpu_clock> ();
299 std::cout << "process_system_cpu_clock=" << std::endl;
300 check_all<boost::chrono::process_system_cpu_clock> ();
301 std::cout << "process_cpu_clock=" << std::endl;
302 check_all<boost::chrono::process_cpu_clock> ();
303 #endif
304 #endif
305
306 #if defined BOOST_CHRONO_INTERNAL_GMTIME
307 #elif BOOST_CHRONO_VERSION == 2
308 boost::chrono::system_clock::time_point tp = boost::chrono::system_clock::now();
309 std::cout << tp << std::endl;
310 time_t t = boost::chrono::system_clock::to_time_t(tp);
311 test_gmtime( t );
312 #endif
313
314 return boost::report_errors();
315
316 }
317
318