Scarab  v3.2.0
Project 8 C++ Utility Library
date.h
Go to the documentation of this file.
1 #ifndef DATE_H
2 #define DATE_H
3 
4 // The MIT License (MIT)
5 //
6 // Copyright (c) 2015, 2016, 2017 Howard Hinnant
7 // Copyright (c) 2016 Adrian Colomitchi
8 // Copyright (c) 2017 Florian Dang
9 // Copyright (c) 2017 Paul Thompson
10 //
11 // Permission is hereby granted, free of charge, to any person obtaining a copy
12 // of this software and associated documentation files (the "Software"), to deal
13 // in the Software without restriction, including without limitation the rights
14 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15 // copies of the Software, and to permit persons to whom the Software is
16 // furnished to do so, subject to the following conditions:
17 //
18 // The above copyright notice and this permission notice shall be included in all
19 // copies or substantial portions of the Software.
20 //
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27 // SOFTWARE.
28 //
29 // Our apologies. When the previous paragraph was written, lowercase had not yet
30 // been invented (that would involve another several millennia of evolution).
31 // We did not mean to shout.
32 
33 #ifndef HAS_STRING_VIEW
34 # if __cplusplus >= 201703
35 # define HAS_STRING_VIEW 1
36 # else
37 # define HAS_STRING_VIEW 0
38 # endif
39 #endif // HAS_STRING_VIEW
40 
41 #include <cassert>
42 #include <algorithm>
43 #include <cctype>
44 #include <chrono>
45 #include <climits>
46 #if !(__cplusplus >= 201402)
47 # include <cmath>
48 #endif
49 #include <cstddef>
50 #include <cstdint>
51 #include <cstdlib>
52 #include <ctime>
53 #include <ios>
54 #include <istream>
55 #include <iterator>
56 #include <limits>
57 #include <locale>
58 #include <memory>
59 #include <ostream>
60 #include <ratio>
61 #include <sstream>
62 #include <stdexcept>
63 #include <string>
64 #if HAS_STRING_VIEW
65 # include <string_view>
66 #endif
67 #include <utility>
68 #include <type_traits>
69 
70 #ifdef __GNUC__
71 # pragma GCC diagnostic push
72 # pragma GCC diagnostic ignored "-Wpedantic"
73 # if __GNUC__ < 5
74  // GCC 4.9 Bug 61489 Wrong warning with -Wmissing-field-initializers
75 # pragma GCC diagnostic ignored "-Wmissing-field-initializers"
76 # endif
77 #endif
78 
79 namespace date
80 {
81 
82 //---------------+
83 // Configuration |
84 //---------------+
85 
86 #ifndef ONLY_C_LOCALE
87 # define ONLY_C_LOCALE 0
88 #endif
89 
90 #if defined(_MSC_VER) && (!defined(__clang__) || (_MSC_VER < 1910))
91 // MSVC
92 # if _MSC_VER < 1910
93 // before VS2017
94 # define CONSTDATA const
95 # define CONSTCD11
96 # define CONSTCD14
97 # define NOEXCEPT _NOEXCEPT
98 # else
99 // VS2017 and later
100 # define CONSTDATA constexpr const
101 # define CONSTCD11 constexpr
102 # define CONSTCD14 constexpr
103 # define NOEXCEPT noexcept
104 # endif
105 
106 #elif defined(__SUNPRO_CC) && __SUNPRO_CC <= 0x5150
107 // Oracle Developer Studio 12.6 and earlier
108 # define CONSTDATA constexpr const
109 # define CONSTCD11 constexpr
110 # define CONSTCD14
111 # define NOEXCEPT noexcept
112 
113 #elif __cplusplus >= 201402
114 // C++14
115 # define CONSTDATA constexpr const
116 # define CONSTCD11 constexpr
117 # define CONSTCD14 constexpr
118 # define NOEXCEPT noexcept
119 #else
120 // C++11
121 # define CONSTDATA constexpr const
122 # define CONSTCD11 constexpr
123 # define CONSTCD14
124 # define NOEXCEPT noexcept
125 #endif
126 
127 #ifndef HAS_VOID_T
128 # if __cplusplus >= 201703
129 # define HAS_VOID_T 1
130 # else
131 # define HAS_VOID_T 0
132 # endif
133 #endif // HAS_VOID_T
134 
135 // Protect from Oracle sun macro
136 #ifdef sun
137 # undef sun
138 #endif
139 
140 //-----------+
141 // Interface |
142 //-----------+
143 
144 // durations
145 
146 using days = std::chrono::duration
147  <int, std::ratio_multiply<std::ratio<24>, std::chrono::hours::period>>;
148 
149 using weeks = std::chrono::duration
150  <int, std::ratio_multiply<std::ratio<7>, days::period>>;
151 
152 using years = std::chrono::duration
153  <int, std::ratio_multiply<std::ratio<146097, 400>, days::period>>;
154 
155 using months = std::chrono::duration
156  <int, std::ratio_divide<years::period, std::ratio<12>>>;
157 
158 // time_point
159 
160 template <class Duration>
161  using sys_time = std::chrono::time_point<std::chrono::system_clock, Duration>;
162 
165 
166 struct local_t {};
167 
168 template <class Duration>
169  using local_time = std::chrono::time_point<local_t, Duration>;
170 
173 
174 // types
175 
176 struct last_spec
177 {
178  explicit last_spec() = default;
179 };
180 
181 class day;
182 class month;
183 class year;
184 
185 class weekday;
186 class weekday_indexed;
187 class weekday_last;
188 
189 class month_day;
190 class month_day_last;
191 class month_weekday;
192 class month_weekday_last;
193 
194 class year_month;
195 
196 class year_month_day;
197 class year_month_day_last;
198 class year_month_weekday;
200 
201 // date composition operators
202 
203 CONSTCD11 year_month operator/(const year& y, const month& m) NOEXCEPT;
204 CONSTCD11 year_month operator/(const year& y, int m) NOEXCEPT;
205 
206 CONSTCD11 month_day operator/(const day& d, const month& m) NOEXCEPT;
207 CONSTCD11 month_day operator/(const day& d, int m) NOEXCEPT;
208 CONSTCD11 month_day operator/(const month& m, const day& d) NOEXCEPT;
209 CONSTCD11 month_day operator/(const month& m, int d) NOEXCEPT;
210 CONSTCD11 month_day operator/(int m, const day& d) NOEXCEPT;
211 
216 
221 
226 
233 
234 CONSTCD11
236 CONSTCD11
238 CONSTCD11
240 CONSTCD11
242 CONSTCD11
244 
245 CONSTCD11
247 operator/(const year_month& ym, const weekday_indexed& wdi) NOEXCEPT;
248 
249 CONSTCD11
251 operator/(const year& y, const month_weekday& mwd) NOEXCEPT;
252 
253 CONSTCD11
255 operator/(int y, const month_weekday& mwd) NOEXCEPT;
256 
257 CONSTCD11
259 operator/(const month_weekday& mwd, const year& y) NOEXCEPT;
260 
261 CONSTCD11
263 operator/(const month_weekday& mwd, int y) NOEXCEPT;
264 
265 CONSTCD11
267 operator/(const year_month& ym, const weekday_last& wdl) NOEXCEPT;
268 
269 CONSTCD11
271 operator/(const year& y, const month_weekday_last& mwdl) NOEXCEPT;
272 
273 CONSTCD11
275 operator/(int y, const month_weekday_last& mwdl) NOEXCEPT;
276 
277 CONSTCD11
279 operator/(const month_weekday_last& mwdl, const year& y) NOEXCEPT;
280 
281 CONSTCD11
283 operator/(const month_weekday_last& mwdl, int y) NOEXCEPT;
284 
285 // Detailed interface
286 
287 // day
288 
289 class day
290 {
291  unsigned char d_;
292 
293 public:
294  day() = default;
295  explicit CONSTCD11 day(unsigned d) NOEXCEPT;
296 
297  CONSTCD14 day& operator++() NOEXCEPT;
298  CONSTCD14 day operator++(int) NOEXCEPT;
299  CONSTCD14 day& operator--() NOEXCEPT;
300  CONSTCD14 day operator--(int) NOEXCEPT;
301 
302  CONSTCD14 day& operator+=(const days& d) NOEXCEPT;
303  CONSTCD14 day& operator-=(const days& d) NOEXCEPT;
304 
305  CONSTCD11 explicit operator unsigned() const NOEXCEPT;
306  CONSTCD11 bool ok() const NOEXCEPT;
307 };
308 
309 CONSTCD11 bool operator==(const day& x, const day& y) NOEXCEPT;
310 CONSTCD11 bool operator!=(const day& x, const day& y) NOEXCEPT;
311 CONSTCD11 bool operator< (const day& x, const day& y) NOEXCEPT;
312 CONSTCD11 bool operator> (const day& x, const day& y) NOEXCEPT;
313 CONSTCD11 bool operator<=(const day& x, const day& y) NOEXCEPT;
314 CONSTCD11 bool operator>=(const day& x, const day& y) NOEXCEPT;
315 
316 CONSTCD11 day operator+(const day& x, const days& y) NOEXCEPT;
317 CONSTCD11 day operator+(const days& x, const day& y) NOEXCEPT;
318 CONSTCD11 day operator-(const day& x, const days& y) NOEXCEPT;
319 CONSTCD11 days operator-(const day& x, const day& y) NOEXCEPT;
320 
321 template<class CharT, class Traits>
322 std::basic_ostream<CharT, Traits>&
323 operator<<(std::basic_ostream<CharT, Traits>& os, const day& d);
324 
325 // month
326 
327 class month
328 {
329  unsigned char m_;
330 
331 public:
332  month() = default;
333  explicit CONSTCD11 month(unsigned m) NOEXCEPT;
334 
335  CONSTCD14 month& operator++() NOEXCEPT;
336  CONSTCD14 month operator++(int) NOEXCEPT;
337  CONSTCD14 month& operator--() NOEXCEPT;
338  CONSTCD14 month operator--(int) NOEXCEPT;
339 
340  CONSTCD14 month& operator+=(const months& m) NOEXCEPT;
341  CONSTCD14 month& operator-=(const months& m) NOEXCEPT;
342 
343  CONSTCD11 explicit operator unsigned() const NOEXCEPT;
344  CONSTCD11 bool ok() const NOEXCEPT;
345 };
346 
347 CONSTCD11 bool operator==(const month& x, const month& y) NOEXCEPT;
348 CONSTCD11 bool operator!=(const month& x, const month& y) NOEXCEPT;
349 CONSTCD11 bool operator< (const month& x, const month& y) NOEXCEPT;
350 CONSTCD11 bool operator> (const month& x, const month& y) NOEXCEPT;
351 CONSTCD11 bool operator<=(const month& x, const month& y) NOEXCEPT;
352 CONSTCD11 bool operator>=(const month& x, const month& y) NOEXCEPT;
353 
354 CONSTCD14 month operator+(const month& x, const months& y) NOEXCEPT;
355 CONSTCD14 month operator+(const months& x, const month& y) NOEXCEPT;
356 CONSTCD14 month operator-(const month& x, const months& y) NOEXCEPT;
357 CONSTCD14 months operator-(const month& x, const month& y) NOEXCEPT;
358 
359 template<class CharT, class Traits>
360 std::basic_ostream<CharT, Traits>&
361 operator<<(std::basic_ostream<CharT, Traits>& os, const month& m);
362 
363 // year
364 
365 class year
366 {
367  short y_;
368 
369 public:
370  year() = default;
371  explicit CONSTCD11 year(int y) NOEXCEPT;
372 
373  CONSTCD14 year& operator++() NOEXCEPT;
374  CONSTCD14 year operator++(int) NOEXCEPT;
375  CONSTCD14 year& operator--() NOEXCEPT;
376  CONSTCD14 year operator--(int) NOEXCEPT;
377 
378  CONSTCD14 year& operator+=(const years& y) NOEXCEPT;
379  CONSTCD14 year& operator-=(const years& y) NOEXCEPT;
380 
381  CONSTCD11 year operator-() const NOEXCEPT;
382  CONSTCD11 year operator+() const NOEXCEPT;
383 
384  CONSTCD11 bool is_leap() const NOEXCEPT;
385 
386  CONSTCD11 explicit operator int() const NOEXCEPT;
387  CONSTCD11 bool ok() const NOEXCEPT;
388 
389  static CONSTCD11 year min() NOEXCEPT;
390  static CONSTCD11 year max() NOEXCEPT;
391 };
392 
393 CONSTCD11 bool operator==(const year& x, const year& y) NOEXCEPT;
394 CONSTCD11 bool operator!=(const year& x, const year& y) NOEXCEPT;
395 CONSTCD11 bool operator< (const year& x, const year& y) NOEXCEPT;
396 CONSTCD11 bool operator> (const year& x, const year& y) NOEXCEPT;
397 CONSTCD11 bool operator<=(const year& x, const year& y) NOEXCEPT;
398 CONSTCD11 bool operator>=(const year& x, const year& y) NOEXCEPT;
399 
400 CONSTCD11 year operator+(const year& x, const years& y) NOEXCEPT;
401 CONSTCD11 year operator+(const years& x, const year& y) NOEXCEPT;
402 CONSTCD11 year operator-(const year& x, const years& y) NOEXCEPT;
403 CONSTCD11 years operator-(const year& x, const year& y) NOEXCEPT;
404 
405 template<class CharT, class Traits>
406 std::basic_ostream<CharT, Traits>&
407 operator<<(std::basic_ostream<CharT, Traits>& os, const year& y);
408 
409 // weekday
410 
411 class weekday
412 {
413  unsigned char wd_;
414 public:
415  weekday() = default;
416  explicit CONSTCD11 weekday(unsigned wd) NOEXCEPT;
417  CONSTCD11 weekday(const sys_days& dp) NOEXCEPT;
418  CONSTCD11 explicit weekday(const local_days& dp) NOEXCEPT;
419 
420  CONSTCD14 weekday& operator++() NOEXCEPT;
421  CONSTCD14 weekday operator++(int) NOEXCEPT;
422  CONSTCD14 weekday& operator--() NOEXCEPT;
423  CONSTCD14 weekday operator--(int) NOEXCEPT;
424 
425  CONSTCD14 weekday& operator+=(const days& d) NOEXCEPT;
426  CONSTCD14 weekday& operator-=(const days& d) NOEXCEPT;
427 
428  CONSTCD11 explicit operator unsigned() const NOEXCEPT;
429  CONSTCD11 bool ok() const NOEXCEPT;
430 
431  CONSTCD11 weekday_indexed operator[](unsigned index) const NOEXCEPT;
432  CONSTCD11 weekday_last operator[](last_spec) const NOEXCEPT;
433 
434 private:
435  static CONSTCD11 unsigned char weekday_from_days(int z) NOEXCEPT;
436 };
437 
438 CONSTCD11 bool operator==(const weekday& x, const weekday& y) NOEXCEPT;
439 CONSTCD11 bool operator!=(const weekday& x, const weekday& y) NOEXCEPT;
440 
441 CONSTCD14 weekday operator+(const weekday& x, const days& y) NOEXCEPT;
442 CONSTCD14 weekday operator+(const days& x, const weekday& y) NOEXCEPT;
443 CONSTCD14 weekday operator-(const weekday& x, const days& y) NOEXCEPT;
444 CONSTCD14 days operator-(const weekday& x, const weekday& y) NOEXCEPT;
445 
446 template<class CharT, class Traits>
447 std::basic_ostream<CharT, Traits>&
448 operator<<(std::basic_ostream<CharT, Traits>& os, const weekday& wd);
449 
450 // weekday_indexed
451 
453 {
454  unsigned char wd_ : 4;
455  unsigned char index_ : 4;
456 
457 public:
458  weekday_indexed() = default;
459  CONSTCD11 weekday_indexed(const date::weekday& wd, unsigned index) NOEXCEPT;
460 
461  CONSTCD11 date::weekday weekday() const NOEXCEPT;
462  CONSTCD11 unsigned index() const NOEXCEPT;
463  CONSTCD11 bool ok() const NOEXCEPT;
464 };
465 
466 CONSTCD11 bool operator==(const weekday_indexed& x, const weekday_indexed& y) NOEXCEPT;
467 CONSTCD11 bool operator!=(const weekday_indexed& x, const weekday_indexed& y) NOEXCEPT;
468 
469 template<class CharT, class Traits>
470 std::basic_ostream<CharT, Traits>&
471 operator<<(std::basic_ostream<CharT, Traits>& os, const weekday_indexed& wdi);
472 
473 // weekday_last
474 
476 {
478 
479 public:
480  explicit CONSTCD11 weekday_last(const date::weekday& wd) NOEXCEPT;
481 
482  CONSTCD11 date::weekday weekday() const NOEXCEPT;
483  CONSTCD11 bool ok() const NOEXCEPT;
484 };
485 
486 CONSTCD11 bool operator==(const weekday_last& x, const weekday_last& y) NOEXCEPT;
487 CONSTCD11 bool operator!=(const weekday_last& x, const weekday_last& y) NOEXCEPT;
488 
489 template<class CharT, class Traits>
490 std::basic_ostream<CharT, Traits>&
491 operator<<(std::basic_ostream<CharT, Traits>& os, const weekday_last& wdl);
492 
493 // year_month
494 
496 {
499 
500 public:
501  year_month() = default;
502  CONSTCD11 year_month(const date::year& y, const date::month& m) NOEXCEPT;
503 
504  CONSTCD11 date::year year() const NOEXCEPT;
505  CONSTCD11 date::month month() const NOEXCEPT;
506 
507  CONSTCD14 year_month& operator+=(const months& dm) NOEXCEPT;
508  CONSTCD14 year_month& operator-=(const months& dm) NOEXCEPT;
509  CONSTCD14 year_month& operator+=(const years& dy) NOEXCEPT;
510  CONSTCD14 year_month& operator-=(const years& dy) NOEXCEPT;
511 
512  CONSTCD11 bool ok() const NOEXCEPT;
513 };
514 
515 CONSTCD11 bool operator==(const year_month& x, const year_month& y) NOEXCEPT;
516 CONSTCD11 bool operator!=(const year_month& x, const year_month& y) NOEXCEPT;
517 CONSTCD11 bool operator< (const year_month& x, const year_month& y) NOEXCEPT;
518 CONSTCD11 bool operator> (const year_month& x, const year_month& y) NOEXCEPT;
519 CONSTCD11 bool operator<=(const year_month& x, const year_month& y) NOEXCEPT;
520 CONSTCD11 bool operator>=(const year_month& x, const year_month& y) NOEXCEPT;
521 
522 CONSTCD14 year_month operator+(const year_month& ym, const months& dm) NOEXCEPT;
523 CONSTCD14 year_month operator+(const months& dm, const year_month& ym) NOEXCEPT;
524 CONSTCD14 year_month operator-(const year_month& ym, const months& dm) NOEXCEPT;
525 
526 CONSTCD11 months operator-(const year_month& x, const year_month& y) NOEXCEPT;
527 CONSTCD11 year_month operator+(const year_month& ym, const years& dy) NOEXCEPT;
528 CONSTCD11 year_month operator+(const years& dy, const year_month& ym) NOEXCEPT;
529 CONSTCD11 year_month operator-(const year_month& ym, const years& dy) NOEXCEPT;
530 
531 template<class CharT, class Traits>
532 std::basic_ostream<CharT, Traits>&
533 operator<<(std::basic_ostream<CharT, Traits>& os, const year_month& ym);
534 
535 // month_day
536 
538 {
541 
542 public:
543  month_day() = default;
544  CONSTCD11 month_day(const date::month& m, const date::day& d) NOEXCEPT;
545 
546  CONSTCD11 date::month month() const NOEXCEPT;
547  CONSTCD11 date::day day() const NOEXCEPT;
548 
549  CONSTCD14 bool ok() const NOEXCEPT;
550 };
551 
552 CONSTCD11 bool operator==(const month_day& x, const month_day& y) NOEXCEPT;
553 CONSTCD11 bool operator!=(const month_day& x, const month_day& y) NOEXCEPT;
554 CONSTCD11 bool operator< (const month_day& x, const month_day& y) NOEXCEPT;
555 CONSTCD11 bool operator> (const month_day& x, const month_day& y) NOEXCEPT;
556 CONSTCD11 bool operator<=(const month_day& x, const month_day& y) NOEXCEPT;
557 CONSTCD11 bool operator>=(const month_day& x, const month_day& y) NOEXCEPT;
558 
559 template<class CharT, class Traits>
560 std::basic_ostream<CharT, Traits>&
561 operator<<(std::basic_ostream<CharT, Traits>& os, const month_day& md);
562 
563 // month_day_last
564 
566 {
568 
569 public:
570  CONSTCD11 explicit month_day_last(const date::month& m) NOEXCEPT;
571 
572  CONSTCD11 date::month month() const NOEXCEPT;
573  CONSTCD11 bool ok() const NOEXCEPT;
574 };
575 
576 CONSTCD11 bool operator==(const month_day_last& x, const month_day_last& y) NOEXCEPT;
577 CONSTCD11 bool operator!=(const month_day_last& x, const month_day_last& y) NOEXCEPT;
578 CONSTCD11 bool operator< (const month_day_last& x, const month_day_last& y) NOEXCEPT;
579 CONSTCD11 bool operator> (const month_day_last& x, const month_day_last& y) NOEXCEPT;
580 CONSTCD11 bool operator<=(const month_day_last& x, const month_day_last& y) NOEXCEPT;
581 CONSTCD11 bool operator>=(const month_day_last& x, const month_day_last& y) NOEXCEPT;
582 
583 template<class CharT, class Traits>
584 std::basic_ostream<CharT, Traits>&
585 operator<<(std::basic_ostream<CharT, Traits>& os, const month_day_last& mdl);
586 
587 // month_weekday
588 
590 {
593 public:
594  CONSTCD11 month_weekday(const date::month& m,
595  const date::weekday_indexed& wdi) NOEXCEPT;
596 
597  CONSTCD11 date::month month() const NOEXCEPT;
598  CONSTCD11 date::weekday_indexed weekday_indexed() const NOEXCEPT;
599 
600  CONSTCD11 bool ok() const NOEXCEPT;
601 };
602 
603 CONSTCD11 bool operator==(const month_weekday& x, const month_weekday& y) NOEXCEPT;
604 CONSTCD11 bool operator!=(const month_weekday& x, const month_weekday& y) NOEXCEPT;
605 
606 template<class CharT, class Traits>
607 std::basic_ostream<CharT, Traits>&
608 operator<<(std::basic_ostream<CharT, Traits>& os, const month_weekday& mwd);
609 
610 // month_weekday_last
611 
613 {
616 
617 public:
618  CONSTCD11 month_weekday_last(const date::month& m,
619  const date::weekday_last& wd) NOEXCEPT;
620 
621  CONSTCD11 date::month month() const NOEXCEPT;
622  CONSTCD11 date::weekday_last weekday_last() const NOEXCEPT;
623 
624  CONSTCD11 bool ok() const NOEXCEPT;
625 };
626 
627 CONSTCD11
628  bool operator==(const month_weekday_last& x, const month_weekday_last& y) NOEXCEPT;
629 CONSTCD11
630  bool operator!=(const month_weekday_last& x, const month_weekday_last& y) NOEXCEPT;
631 
632 template<class CharT, class Traits>
633 std::basic_ostream<CharT, Traits>&
634 operator<<(std::basic_ostream<CharT, Traits>& os, const month_weekday_last& mwdl);
635 
636 // class year_month_day
637 
639 {
643 
644 public:
645  year_month_day() = default;
646  CONSTCD11 year_month_day(const date::year& y, const date::month& m,
647  const date::day& d) NOEXCEPT;
648  CONSTCD14 year_month_day(const year_month_day_last& ymdl) NOEXCEPT;
649 
650  CONSTCD14 year_month_day(sys_days dp) NOEXCEPT;
651  CONSTCD14 explicit year_month_day(local_days dp) NOEXCEPT;
652 
653  CONSTCD14 year_month_day& operator+=(const months& m) NOEXCEPT;
654  CONSTCD14 year_month_day& operator-=(const months& m) NOEXCEPT;
655  CONSTCD14 year_month_day& operator+=(const years& y) NOEXCEPT;
656  CONSTCD14 year_month_day& operator-=(const years& y) NOEXCEPT;
657 
658  CONSTCD11 date::year year() const NOEXCEPT;
659  CONSTCD11 date::month month() const NOEXCEPT;
660  CONSTCD11 date::day day() const NOEXCEPT;
661 
662  CONSTCD14 operator sys_days() const NOEXCEPT;
663  CONSTCD14 explicit operator local_days() const NOEXCEPT;
664  CONSTCD14 bool ok() const NOEXCEPT;
665 
666 private:
667  static CONSTCD14 year_month_day from_days(days dp) NOEXCEPT;
668  CONSTCD14 days to_days() const NOEXCEPT;
669 };
670 
671 CONSTCD11 bool operator==(const year_month_day& x, const year_month_day& y) NOEXCEPT;
672 CONSTCD11 bool operator!=(const year_month_day& x, const year_month_day& y) NOEXCEPT;
673 CONSTCD11 bool operator< (const year_month_day& x, const year_month_day& y) NOEXCEPT;
674 CONSTCD11 bool operator> (const year_month_day& x, const year_month_day& y) NOEXCEPT;
675 CONSTCD11 bool operator<=(const year_month_day& x, const year_month_day& y) NOEXCEPT;
676 CONSTCD11 bool operator>=(const year_month_day& x, const year_month_day& y) NOEXCEPT;
677 
678 CONSTCD14 year_month_day operator+(const year_month_day& ymd, const months& dm) NOEXCEPT;
679 CONSTCD14 year_month_day operator+(const months& dm, const year_month_day& ymd) NOEXCEPT;
680 CONSTCD14 year_month_day operator-(const year_month_day& ymd, const months& dm) NOEXCEPT;
681 CONSTCD11 year_month_day operator+(const year_month_day& ymd, const years& dy) NOEXCEPT;
682 CONSTCD11 year_month_day operator+(const years& dy, const year_month_day& ymd) NOEXCEPT;
683 CONSTCD11 year_month_day operator-(const year_month_day& ymd, const years& dy) NOEXCEPT;
684 
685 template<class CharT, class Traits>
686 std::basic_ostream<CharT, Traits>&
687 operator<<(std::basic_ostream<CharT, Traits>& os, const year_month_day& ymd);
688 
689 // year_month_day_last
690 
692 {
695 
696 public:
697  CONSTCD11 year_month_day_last(const date::year& y,
698  const date::month_day_last& mdl) NOEXCEPT;
699 
700  CONSTCD14 year_month_day_last& operator+=(const months& m) NOEXCEPT;
701  CONSTCD14 year_month_day_last& operator-=(const months& m) NOEXCEPT;
702  CONSTCD14 year_month_day_last& operator+=(const years& y) NOEXCEPT;
703  CONSTCD14 year_month_day_last& operator-=(const years& y) NOEXCEPT;
704 
705  CONSTCD11 date::year year() const NOEXCEPT;
706  CONSTCD11 date::month month() const NOEXCEPT;
707  CONSTCD11 date::month_day_last month_day_last() const NOEXCEPT;
708  CONSTCD14 date::day day() const NOEXCEPT;
709 
710  CONSTCD14 operator sys_days() const NOEXCEPT;
711  CONSTCD14 explicit operator local_days() const NOEXCEPT;
712  CONSTCD11 bool ok() const NOEXCEPT;
713 };
714 
715 CONSTCD11
716  bool operator==(const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT;
717 CONSTCD11
718  bool operator!=(const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT;
719 CONSTCD11
720  bool operator< (const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT;
721 CONSTCD11
722  bool operator> (const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT;
723 CONSTCD11
724  bool operator<=(const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT;
725 CONSTCD11
726  bool operator>=(const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT;
727 
728 CONSTCD14
729 year_month_day_last
730 operator+(const year_month_day_last& ymdl, const months& dm) NOEXCEPT;
731 
732 CONSTCD14
733 year_month_day_last
734 operator+(const months& dm, const year_month_day_last& ymdl) NOEXCEPT;
735 
736 CONSTCD11
737 year_month_day_last
738 operator+(const year_month_day_last& ymdl, const years& dy) NOEXCEPT;
739 
740 CONSTCD11
741 year_month_day_last
742 operator+(const years& dy, const year_month_day_last& ymdl) NOEXCEPT;
743 
744 CONSTCD14
745 year_month_day_last
746 operator-(const year_month_day_last& ymdl, const months& dm) NOEXCEPT;
747 
748 CONSTCD11
749 year_month_day_last
750 operator-(const year_month_day_last& ymdl, const years& dy) NOEXCEPT;
751 
752 template<class CharT, class Traits>
753 std::basic_ostream<CharT, Traits>&
754 operator<<(std::basic_ostream<CharT, Traits>& os, const year_month_day_last& ymdl);
755 
756 // year_month_weekday
757 
759 {
763 
764 public:
765  year_month_weekday() = default;
766  CONSTCD11 year_month_weekday(const date::year& y, const date::month& m,
767  const date::weekday_indexed& wdi) NOEXCEPT;
768  CONSTCD14 year_month_weekday(const sys_days& dp) NOEXCEPT;
769  CONSTCD14 explicit year_month_weekday(const local_days& dp) NOEXCEPT;
770 
771  CONSTCD14 year_month_weekday& operator+=(const months& m) NOEXCEPT;
772  CONSTCD14 year_month_weekday& operator-=(const months& m) NOEXCEPT;
773  CONSTCD14 year_month_weekday& operator+=(const years& y) NOEXCEPT;
774  CONSTCD14 year_month_weekday& operator-=(const years& y) NOEXCEPT;
775 
776  CONSTCD11 date::year year() const NOEXCEPT;
777  CONSTCD11 date::month month() const NOEXCEPT;
778  CONSTCD11 date::weekday weekday() const NOEXCEPT;
779  CONSTCD11 unsigned index() const NOEXCEPT;
780  CONSTCD11 date::weekday_indexed weekday_indexed() const NOEXCEPT;
781 
782  CONSTCD14 operator sys_days() const NOEXCEPT;
783  CONSTCD14 explicit operator local_days() const NOEXCEPT;
784  CONSTCD14 bool ok() const NOEXCEPT;
785 
786 private:
787  static CONSTCD14 year_month_weekday from_days(days dp) NOEXCEPT;
788  CONSTCD14 days to_days() const NOEXCEPT;
789 };
790 
791 CONSTCD11
792  bool operator==(const year_month_weekday& x, const year_month_weekday& y) NOEXCEPT;
793 CONSTCD11
794  bool operator!=(const year_month_weekday& x, const year_month_weekday& y) NOEXCEPT;
795 
796 CONSTCD14
797 year_month_weekday
798 operator+(const year_month_weekday& ymwd, const months& dm) NOEXCEPT;
799 
800 CONSTCD14
801 year_month_weekday
802 operator+(const months& dm, const year_month_weekday& ymwd) NOEXCEPT;
803 
804 CONSTCD11
805 year_month_weekday
806 operator+(const year_month_weekday& ymwd, const years& dy) NOEXCEPT;
807 
808 CONSTCD11
809 year_month_weekday
810 operator+(const years& dy, const year_month_weekday& ymwd) NOEXCEPT;
811 
812 CONSTCD14
813 year_month_weekday
814 operator-(const year_month_weekday& ymwd, const months& dm) NOEXCEPT;
815 
816 CONSTCD11
817 year_month_weekday
818 operator-(const year_month_weekday& ymwd, const years& dy) NOEXCEPT;
819 
820 template<class CharT, class Traits>
821 std::basic_ostream<CharT, Traits>&
822 operator<<(std::basic_ostream<CharT, Traits>& os, const year_month_weekday& ymwdi);
823 
824 // year_month_weekday_last
825 
827 {
831 
832 public:
833  CONSTCD11 year_month_weekday_last(const date::year& y, const date::month& m,
834  const date::weekday_last& wdl) NOEXCEPT;
835 
836  CONSTCD14 year_month_weekday_last& operator+=(const months& m) NOEXCEPT;
837  CONSTCD14 year_month_weekday_last& operator-=(const months& m) NOEXCEPT;
838  CONSTCD14 year_month_weekday_last& operator+=(const years& y) NOEXCEPT;
839  CONSTCD14 year_month_weekday_last& operator-=(const years& y) NOEXCEPT;
840 
841  CONSTCD11 date::year year() const NOEXCEPT;
842  CONSTCD11 date::month month() const NOEXCEPT;
843  CONSTCD11 date::weekday weekday() const NOEXCEPT;
844  CONSTCD11 date::weekday_last weekday_last() const NOEXCEPT;
845 
846  CONSTCD14 operator sys_days() const NOEXCEPT;
847  CONSTCD14 explicit operator local_days() const NOEXCEPT;
848  CONSTCD11 bool ok() const NOEXCEPT;
849 
850 private:
851  CONSTCD14 days to_days() const NOEXCEPT;
852 };
853 
854 CONSTCD11
855 bool
856 operator==(const year_month_weekday_last& x, const year_month_weekday_last& y) NOEXCEPT;
857 
858 CONSTCD11
859 bool
860 operator!=(const year_month_weekday_last& x, const year_month_weekday_last& y) NOEXCEPT;
861 
862 CONSTCD14
863 year_month_weekday_last
864 operator+(const year_month_weekday_last& ymwdl, const months& dm) NOEXCEPT;
865 
866 CONSTCD14
867 year_month_weekday_last
868 operator+(const months& dm, const year_month_weekday_last& ymwdl) NOEXCEPT;
869 
870 CONSTCD11
871 year_month_weekday_last
872 operator+(const year_month_weekday_last& ymwdl, const years& dy) NOEXCEPT;
873 
874 CONSTCD11
875 year_month_weekday_last
876 operator+(const years& dy, const year_month_weekday_last& ymwdl) NOEXCEPT;
877 
878 CONSTCD14
879 year_month_weekday_last
880 operator-(const year_month_weekday_last& ymwdl, const months& dm) NOEXCEPT;
881 
882 CONSTCD11
883 year_month_weekday_last
884 operator-(const year_month_weekday_last& ymwdl, const years& dy) NOEXCEPT;
885 
886 template<class CharT, class Traits>
887 std::basic_ostream<CharT, Traits>&
888 operator<<(std::basic_ostream<CharT, Traits>& os, const year_month_weekday_last& ymwdl);
889 
890 #if !defined(_MSC_VER) || (_MSC_VER >= 1900)
891 inline namespace literals
892 {
893 
894 CONSTCD11 date::day operator "" _d(unsigned long long d) NOEXCEPT;
895 CONSTCD11 date::year operator "" _y(unsigned long long y) NOEXCEPT;
896 
897 // CONSTDATA date::month jan{1};
898 // CONSTDATA date::month feb{2};
899 // CONSTDATA date::month mar{3};
900 // CONSTDATA date::month apr{4};
901 // CONSTDATA date::month may{5};
902 // CONSTDATA date::month jun{6};
903 // CONSTDATA date::month jul{7};
904 // CONSTDATA date::month aug{8};
905 // CONSTDATA date::month sep{9};
906 // CONSTDATA date::month oct{10};
907 // CONSTDATA date::month nov{11};
908 // CONSTDATA date::month dec{12};
909 //
910 // CONSTDATA date::weekday sun{0u};
911 // CONSTDATA date::weekday mon{1u};
912 // CONSTDATA date::weekday tue{2u};
913 // CONSTDATA date::weekday wed{3u};
914 // CONSTDATA date::weekday thu{4u};
915 // CONSTDATA date::weekday fri{5u};
916 // CONSTDATA date::weekday sat{6u};
917 
918 } // inline namespace literals
919 #endif // !defined(_MSC_VER) || (_MSC_VER >= 1900)
920 
921 #if HAS_VOID_T
922 
923 template <class T, class = std::void_t<>>
924 struct is_clock
925  : std::false_type
926 {};
927 
928 template <class T>
929 struct is_clock<T, std::void_t<decltype(T::now()), typename T::rep, typename T::period,
930  typename T::duration, typename T::time_point,
931  decltype(T::is_steady)>>
932  : std::true_type
933 {};
934 
935 #endif // HAS_VOID_T
936 
937 //----------------+
938 // Implementation |
939 //----------------+
940 
941 // utilities
942 namespace detail {
943 
944 template<class CharT, class Traits = std::char_traits<CharT>>
946 {
947  std::basic_ostream<CharT, Traits>& os_;
948  CharT fill_;
949  std::ios::fmtflags flags_;
950  std::locale loc_;
951 
952 public:
954  {
955  os_.fill(fill_);
956  os_.flags(flags_);
957  os_.imbue(loc_);
958  }
959 
960  save_stream(const save_stream&) = delete;
961  save_stream& operator=(const save_stream&) = delete;
962 
963  explicit save_stream(std::basic_ostream<CharT, Traits>& os)
964  : os_(os)
965  , fill_(os.fill())
966  , flags_(os.flags())
967  , loc_(os.getloc())
968  {}
969 };
970 
971 template <class T>
973 {
974  static const int digits = std::numeric_limits<T>::digits;
975  using type = typename std::conditional
976  <
977  digits < 32,
978  std::int32_t,
979  typename std::conditional
980  <
981  digits < 64,
982  std::int64_t,
983 #ifdef __SIZEOF_INT128__
984  __int128
985 #else
986  std::int64_t
987 #endif
988  >::type
990 };
991 
992 template <class T>
993 CONSTCD11
994 inline
995 typename std::enable_if
996 <
997  !std::chrono::treat_as_floating_point<T>::value,
998  T
999 >::type
1000 trunc(T t) NOEXCEPT
1001 {
1002  return t;
1003 }
1004 
1005 template <class T>
1006 CONSTCD14
1007 inline
1008 typename std::enable_if
1009 <
1010  std::chrono::treat_as_floating_point<T>::value,
1011  T
1012 >::type
1013 trunc(T t) NOEXCEPT
1014 {
1015  using namespace std;
1016  using I = typename choose_trunc_type<T>::type;
1017  CONSTDATA auto digits = numeric_limits<T>::digits;
1018  static_assert(digits < numeric_limits<I>::digits, "");
1019  CONSTDATA auto max = I{1} << (digits-1);
1020  CONSTDATA auto min = -max;
1021  const auto negative = t < T{0};
1022  if (min <= t && t <= max && t != 0 && t == t)
1023  {
1024  t = static_cast<T>(static_cast<I>(t));
1025  if (t == 0 && negative)
1026  t = -t;
1027  }
1028  return t;
1029 }
1030 
1031 template <std::intmax_t Xp, std::intmax_t Yp>
1033 {
1034  static const std::intmax_t value = static_gcd<Yp, Xp % Yp>::value;
1035 };
1036 
1037 template <std::intmax_t Xp>
1038 struct static_gcd<Xp, 0>
1039 {
1040  static const std::intmax_t value = Xp;
1041 };
1042 
1043 template <>
1044 struct static_gcd<0, 0>
1045 {
1046  static const std::intmax_t value = 1;
1047 };
1048 
1049 template <class R1, class R2>
1051 {
1052 private:
1053  static const std::intmax_t gcd_n1_n2 = static_gcd<R1::num, R2::num>::value;
1054  static const std::intmax_t gcd_d1_d2 = static_gcd<R1::den, R2::den>::value;
1055  static const std::intmax_t n1 = R1::num / gcd_n1_n2;
1056  static const std::intmax_t d1 = R1::den / gcd_d1_d2;
1057  static const std::intmax_t n2 = R2::num / gcd_n1_n2;
1058  static const std::intmax_t d2 = R2::den / gcd_d1_d2;
1059  static const std::intmax_t max = -((std::intmax_t(1) <<
1060  (sizeof(std::intmax_t) * CHAR_BIT - 1)) + 1);
1061 
1062  template <std::intmax_t Xp, std::intmax_t Yp, bool overflow>
1063  struct mul // overflow == false
1064  {
1065  static const std::intmax_t value = Xp * Yp;
1066  };
1067 
1068  template <std::intmax_t Xp, std::intmax_t Yp>
1069  struct mul<Xp, Yp, true>
1070  {
1071  static const std::intmax_t value = 1;
1072  };
1073 
1074 public:
1075  static const bool value = (n1 <= max / d2) && (n2 <= max / d1);
1076  typedef std::ratio<mul<n1, d2, !value>::value,
1078 };
1079 
1080 } // detail
1081 
1082 // trunc towards zero
1083 template <class To, class Rep, class Period>
1084 CONSTCD11
1085 inline
1086 typename std::enable_if
1087 <
1089  To
1090 >::type
1091 trunc(const std::chrono::duration<Rep, Period>& d)
1092 {
1093  return To{detail::trunc(std::chrono::duration_cast<To>(d).count())};
1094 }
1095 
1096 template <class To, class Rep, class Period>
1097 CONSTCD11
1098 inline
1099 typename std::enable_if
1100 <
1101  !detail::no_overflow<Period, typename To::period>::value,
1102  To
1103 >::type
1104 trunc(const std::chrono::duration<Rep, Period>& d)
1105 {
1106  using namespace std::chrono;
1107  using rep = typename std::common_type<Rep, typename To::rep>::type;
1108  return To{detail::trunc(duration_cast<To>(duration_cast<duration<rep>>(d)).count())};
1109 }
1110 
1111 #ifndef HAS_CHRONO_ROUNDING
1112 # if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 190023918 || (_MSC_FULL_VER >= 190000000 && defined (__clang__)))
1113 # define HAS_CHRONO_ROUNDING 1
1114 # elif defined(__cpp_lib_chrono) && __cplusplus > 201402 && __cpp_lib_chrono >= 201510
1115 # define HAS_CHRONO_ROUNDING 1
1116 # elif defined(_LIBCPP_VERSION) && __cplusplus > 201402 && _LIBCPP_VERSION >= 3800
1117 # define HAS_CHRONO_ROUNDING 1
1118 # else
1119 # define HAS_CHRONO_ROUNDING 0
1120 # endif
1121 #endif // HAS_CHRONO_ROUNDING
1122 
1123 #if HAS_CHRONO_ROUNDING == 0
1124 
1125 // round down
1126 template <class To, class Rep, class Period>
1127 CONSTCD14
1128 inline
1129 typename std::enable_if
1130 <
1131  detail::no_overflow<Period, typename To::period>::value,
1132  To
1133 >::type
1134 floor(const std::chrono::duration<Rep, Period>& d)
1135 {
1136  auto t = trunc<To>(d);
1137  if (t > d)
1138  return t - To{1};
1139  return t;
1140 }
1141 
1142 template <class To, class Rep, class Period>
1143 CONSTCD14
1144 inline
1145 typename std::enable_if
1146 <
1147  !detail::no_overflow<Period, typename To::period>::value,
1148  To
1149 >::type
1150 floor(const std::chrono::duration<Rep, Period>& d)
1151 {
1152  using namespace std::chrono;
1153  using rep = typename std::common_type<Rep, typename To::rep>::type;
1154  return floor<To>(floor<duration<rep>>(d));
1155 }
1156 
1157 // round to nearest, to even on tie
1158 template <class To, class Rep, class Period>
1159 CONSTCD14
1160 inline
1161 To
1162 round(const std::chrono::duration<Rep, Period>& d)
1163 {
1164  auto t0 = floor<To>(d);
1165  auto t1 = t0 + To{1};
1166  if (t1 == To{0} && t0 < To{0})
1167  t1 = -t1;
1168  auto diff0 = d - t0;
1169  auto diff1 = t1 - d;
1170  if (diff0 == diff1)
1171  {
1172  if (t0 - trunc<To>(t0/2)*2 == To{0})
1173  return t0;
1174  return t1;
1175  }
1176  if (diff0 < diff1)
1177  return t0;
1178  return t1;
1179 }
1180 
1181 // round up
1182 template <class To, class Rep, class Period>
1183 CONSTCD14
1184 inline
1185 To
1186 ceil(const std::chrono::duration<Rep, Period>& d)
1187 {
1188  auto t = trunc<To>(d);
1189  if (t < d)
1190  return t + To{1};
1191  return t;
1192 }
1193 
1194 template <class Rep, class Period,
1195  class = typename std::enable_if
1196  <
1198  >::type>
1199 CONSTCD11
1200 std::chrono::duration<Rep, Period>
1201 abs(std::chrono::duration<Rep, Period> d)
1202 {
1203  return d >= d.zero() ? d : -d;
1204 }
1205 
1206 // round down
1207 template <class To, class Clock, class FromDuration>
1208 CONSTCD11
1209 inline
1210 std::chrono::time_point<Clock, To>
1211 floor(const std::chrono::time_point<Clock, FromDuration>& tp)
1212 {
1213  using std::chrono::time_point;
1214  return time_point<Clock, To>{date::floor<To>(tp.time_since_epoch())};
1215 }
1216 
1217 // round to nearest, to even on tie
1218 template <class To, class Clock, class FromDuration>
1219 CONSTCD11
1220 inline
1221 std::chrono::time_point<Clock, To>
1222 round(const std::chrono::time_point<Clock, FromDuration>& tp)
1223 {
1224  using std::chrono::time_point;
1225  return time_point<Clock, To>{round<To>(tp.time_since_epoch())};
1226 }
1227 
1228 // round up
1229 template <class To, class Clock, class FromDuration>
1230 CONSTCD11
1231 inline
1232 std::chrono::time_point<Clock, To>
1233 ceil(const std::chrono::time_point<Clock, FromDuration>& tp)
1234 {
1235  using std::chrono::time_point;
1236  return time_point<Clock, To>{ceil<To>(tp.time_since_epoch())};
1237 }
1238 
1239 #else // HAS_CHRONO_ROUNDING == 1
1240 
1241 using std::chrono::floor;
1242 using std::chrono::ceil;
1243 using std::chrono::round;
1244 using std::chrono::abs;
1245 
1246 #endif // HAS_CHRONO_ROUNDING
1247 
1248 // trunc towards zero
1249 template <class To, class Clock, class FromDuration>
1250 CONSTCD11
1251 inline
1252 std::chrono::time_point<Clock, To>
1253 trunc(const std::chrono::time_point<Clock, FromDuration>& tp)
1254 {
1255  using std::chrono::time_point;
1256  return time_point<Clock, To>{trunc<To>(tp.time_since_epoch())};
1257 }
1258 
1259 // day
1260 
1261 CONSTCD11 inline day::day(unsigned d) NOEXCEPT : d_(static_cast<unsigned char>(d)) {}
1262 CONSTCD14 inline day& day::operator++() NOEXCEPT {++d_; return *this;}
1263 CONSTCD14 inline day day::operator++(int) NOEXCEPT {auto tmp(*this); ++(*this); return tmp;}
1264 CONSTCD14 inline day& day::operator--() NOEXCEPT {--d_; return *this;}
1265 CONSTCD14 inline day day::operator--(int) NOEXCEPT {auto tmp(*this); --(*this); return tmp;}
1266 CONSTCD14 inline day& day::operator+=(const days& d) NOEXCEPT {*this = *this + d; return *this;}
1267 CONSTCD14 inline day& day::operator-=(const days& d) NOEXCEPT {*this = *this - d; return *this;}
1268 CONSTCD11 inline day::operator unsigned() const NOEXCEPT {return d_;}
1269 CONSTCD11 inline bool day::ok() const NOEXCEPT {return 1 <= d_ && d_ <= 31;}
1270 
1271 CONSTCD11
1272 inline
1273 bool
1274 operator==(const day& x, const day& y) NOEXCEPT
1275 {
1276  return static_cast<unsigned>(x) == static_cast<unsigned>(y);
1277 }
1278 
1279 CONSTCD11
1280 inline
1281 bool
1282 operator!=(const day& x, const day& y) NOEXCEPT
1283 {
1284  return !(x == y);
1285 }
1286 
1287 CONSTCD11
1288 inline
1289 bool
1290 operator<(const day& x, const day& y) NOEXCEPT
1291 {
1292  return static_cast<unsigned>(x) < static_cast<unsigned>(y);
1293 }
1294 
1295 CONSTCD11
1296 inline
1297 bool
1298 operator>(const day& x, const day& y) NOEXCEPT
1299 {
1300  return y < x;
1301 }
1302 
1303 CONSTCD11
1304 inline
1305 bool
1306 operator<=(const day& x, const day& y) NOEXCEPT
1307 {
1308  return !(y < x);
1309 }
1310 
1311 CONSTCD11
1312 inline
1313 bool
1314 operator>=(const day& x, const day& y) NOEXCEPT
1315 {
1316  return !(x < y);
1317 }
1318 
1319 CONSTCD11
1320 inline
1321 days
1322 operator-(const day& x, const day& y) NOEXCEPT
1323 {
1324  return days{static_cast<days::rep>(static_cast<unsigned>(x)
1325  - static_cast<unsigned>(y))};
1326 }
1327 
1328 CONSTCD11
1329 inline
1330 day
1331 operator+(const day& x, const days& y) NOEXCEPT
1332 {
1333  return day{static_cast<unsigned>(x) + static_cast<unsigned>(y.count())};
1334 }
1335 
1336 CONSTCD11
1337 inline
1338 day
1339 operator+(const days& x, const day& y) NOEXCEPT
1340 {
1341  return y + x;
1342 }
1343 
1344 CONSTCD11
1345 inline
1346 day
1347 operator-(const day& x, const days& y) NOEXCEPT
1348 {
1349  return x + -y;
1350 }
1351 
1352 template<class CharT, class Traits>
1353 inline
1354 std::basic_ostream<CharT, Traits>&
1355 operator<<(std::basic_ostream<CharT, Traits>& os, const day& d)
1356 {
1358  os.fill('0');
1359  os.flags(std::ios::dec | std::ios::right);
1360  os.width(2);
1361  os << static_cast<unsigned>(d);
1362  return os;
1363 }
1364 
1365 // month
1366 
1367 CONSTCD11 inline month::month(unsigned m) NOEXCEPT : m_(static_cast<decltype(m_)>(m)) {}
1368 CONSTCD14 inline month& month::operator++() NOEXCEPT {if (++m_ == 13) m_ = 1; return *this;}
1369 CONSTCD14 inline month month::operator++(int) NOEXCEPT {auto tmp(*this); ++(*this); return tmp;}
1370 CONSTCD14 inline month& month::operator--() NOEXCEPT {if (--m_ == 0) m_ = 12; return *this;}
1371 CONSTCD14 inline month month::operator--(int) NOEXCEPT {auto tmp(*this); --(*this); return tmp;}
1372 
1373 CONSTCD14
1374 inline
1375 month&
1376 month::operator+=(const months& m) NOEXCEPT
1377 {
1378  *this = *this + m;
1379  return *this;
1380 }
1381 
1382 CONSTCD14
1383 inline
1384 month&
1385 month::operator-=(const months& m) NOEXCEPT
1386 {
1387  *this = *this - m;
1388  return *this;
1389 }
1390 
1391 CONSTCD11 inline month::operator unsigned() const NOEXCEPT {return m_;}
1392 CONSTCD11 inline bool month::ok() const NOEXCEPT {return 1 <= m_ && m_ <= 12;}
1393 
1394 CONSTCD11
1395 inline
1396 bool
1397 operator==(const month& x, const month& y) NOEXCEPT
1398 {
1399  return static_cast<unsigned>(x) == static_cast<unsigned>(y);
1400 }
1401 
1402 CONSTCD11
1403 inline
1404 bool
1405 operator!=(const month& x, const month& y) NOEXCEPT
1406 {
1407  return !(x == y);
1408 }
1409 
1410 CONSTCD11
1411 inline
1412 bool
1413 operator<(const month& x, const month& y) NOEXCEPT
1414 {
1415  return static_cast<unsigned>(x) < static_cast<unsigned>(y);
1416 }
1417 
1418 CONSTCD11
1419 inline
1420 bool
1421 operator>(const month& x, const month& y) NOEXCEPT
1422 {
1423  return y < x;
1424 }
1425 
1426 CONSTCD11
1427 inline
1428 bool
1429 operator<=(const month& x, const month& y) NOEXCEPT
1430 {
1431  return !(y < x);
1432 }
1433 
1434 CONSTCD11
1435 inline
1436 bool
1437 operator>=(const month& x, const month& y) NOEXCEPT
1438 {
1439  return !(x < y);
1440 }
1441 
1442 CONSTCD14
1443 inline
1444 months
1445 operator-(const month& x, const month& y) NOEXCEPT
1446 {
1447  auto const d = static_cast<unsigned>(x) - static_cast<unsigned>(y);
1448  return months(d <= 11 ? d : d + 12);
1449 }
1450 
1451 CONSTCD14
1452 inline
1453 month
1454 operator+(const month& x, const months& y) NOEXCEPT
1455 {
1456  auto const mu = static_cast<long long>(static_cast<unsigned>(x)) - 1 + y.count();
1457  auto const yr = (mu >= 0 ? mu : mu-11) / 12;
1458  return month{static_cast<unsigned>(mu - yr * 12 + 1)};
1459 }
1460 
1461 CONSTCD14
1462 inline
1463 month
1464 operator+(const months& x, const month& y) NOEXCEPT
1465 {
1466  return y + x;
1467 }
1468 
1469 CONSTCD14
1470 inline
1471 month
1472 operator-(const month& x, const months& y) NOEXCEPT
1473 {
1474  return x + -y;
1475 }
1476 
1477 template<class CharT, class Traits>
1478 inline
1479 std::basic_ostream<CharT, Traits>&
1480 operator<<(std::basic_ostream<CharT, Traits>& os, const month& m)
1481 {
1482  switch (static_cast<unsigned>(m))
1483  {
1484  case 1:
1485  os << "Jan";
1486  break;
1487  case 2:
1488  os << "Feb";
1489  break;
1490  case 3:
1491  os << "Mar";
1492  break;
1493  case 4:
1494  os << "Apr";
1495  break;
1496  case 5:
1497  os << "May";
1498  break;
1499  case 6:
1500  os << "Jun";
1501  break;
1502  case 7:
1503  os << "Jul";
1504  break;
1505  case 8:
1506  os << "Aug";
1507  break;
1508  case 9:
1509  os << "Sep";
1510  break;
1511  case 10:
1512  os << "Oct";
1513  break;
1514  case 11:
1515  os << "Nov";
1516  break;
1517  case 12:
1518  os << "Dec";
1519  break;
1520  default:
1521  os << static_cast<unsigned>(m) << " is not a valid month";
1522  break;
1523  }
1524  return os;
1525 }
1526 
1527 // year
1528 
1529 CONSTCD11 inline year::year(int y) NOEXCEPT : y_(static_cast<decltype(y_)>(y)) {}
1530 CONSTCD14 inline year& year::operator++() NOEXCEPT {++y_; return *this;}
1531 CONSTCD14 inline year year::operator++(int) NOEXCEPT {auto tmp(*this); ++(*this); return tmp;}
1532 CONSTCD14 inline year& year::operator--() NOEXCEPT {--y_; return *this;}
1533 CONSTCD14 inline year year::operator--(int) NOEXCEPT {auto tmp(*this); --(*this); return tmp;}
1534 CONSTCD14 inline year& year::operator+=(const years& y) NOEXCEPT {*this = *this + y; return *this;}
1535 CONSTCD14 inline year& year::operator-=(const years& y) NOEXCEPT {*this = *this - y; return *this;}
1536 CONSTCD11 inline year year::operator-() const NOEXCEPT {return year{-y_};}
1537 CONSTCD11 inline year year::operator+() const NOEXCEPT {return *this;}
1538 
1539 CONSTCD11
1540 inline
1541 bool
1542 year::is_leap() const NOEXCEPT
1543 {
1544  return y_ % 4 == 0 && (y_ % 100 != 0 || y_ % 400 == 0);
1545 }
1546 
1547 CONSTCD11 inline year::operator int() const NOEXCEPT {return y_;}
1548 
1549 CONSTCD11
1550 inline
1551 bool
1552 year::ok() const NOEXCEPT
1553 {
1554  return y_ != std::numeric_limits<short>::min();
1555 }
1556 
1557 CONSTCD11
1558 inline
1559 year
1560 year::min() NOEXCEPT
1561 {
1562  return year{-32767};
1563 }
1564 
1565 CONSTCD11
1566 inline
1567 year
1568 year::max() NOEXCEPT
1569 {
1570  return year{32767};
1571 }
1572 
1573 CONSTCD11
1574 inline
1575 bool
1576 operator==(const year& x, const year& y) NOEXCEPT
1577 {
1578  return static_cast<int>(x) == static_cast<int>(y);
1579 }
1580 
1581 CONSTCD11
1582 inline
1583 bool
1584 operator!=(const year& x, const year& y) NOEXCEPT
1585 {
1586  return !(x == y);
1587 }
1588 
1589 CONSTCD11
1590 inline
1591 bool
1592 operator<(const year& x, const year& y) NOEXCEPT
1593 {
1594  return static_cast<int>(x) < static_cast<int>(y);
1595 }
1596 
1597 CONSTCD11
1598 inline
1599 bool
1600 operator>(const year& x, const year& y) NOEXCEPT
1601 {
1602  return y < x;
1603 }
1604 
1605 CONSTCD11
1606 inline
1607 bool
1608 operator<=(const year& x, const year& y) NOEXCEPT
1609 {
1610  return !(y < x);
1611 }
1612 
1613 CONSTCD11
1614 inline
1615 bool
1616 operator>=(const year& x, const year& y) NOEXCEPT
1617 {
1618  return !(x < y);
1619 }
1620 
1621 CONSTCD11
1622 inline
1623 years
1624 operator-(const year& x, const year& y) NOEXCEPT
1625 {
1626  return years{static_cast<int>(x) - static_cast<int>(y)};
1627 }
1628 
1629 CONSTCD11
1630 inline
1631 year
1632 operator+(const year& x, const years& y) NOEXCEPT
1633 {
1634  return year{static_cast<int>(x) + y.count()};
1635 }
1636 
1637 CONSTCD11
1638 inline
1639 year
1640 operator+(const years& x, const year& y) NOEXCEPT
1641 {
1642  return y + x;
1643 }
1644 
1645 CONSTCD11
1646 inline
1647 year
1648 operator-(const year& x, const years& y) NOEXCEPT
1649 {
1650  return year{static_cast<int>(x) - y.count()};
1651 }
1652 
1653 template<class CharT, class Traits>
1654 inline
1655 std::basic_ostream<CharT, Traits>&
1656 operator<<(std::basic_ostream<CharT, Traits>& os, const year& y)
1657 {
1659  os.fill('0');
1660  os.flags(std::ios::dec | std::ios::internal);
1661  os.width(4 + (y < year{0}));
1662  os << static_cast<int>(y);
1663  return os;
1664 }
1665 
1666 // weekday
1667 
1668 CONSTCD11
1669 inline
1670 unsigned char
1672 {
1673  return static_cast<unsigned char>(static_cast<unsigned>(
1674  z >= -4 ? (z+4) % 7 : (z+5) % 7 + 6));
1675 }
1676 
1677 CONSTCD11
1678 inline
1680  : wd_(static_cast<decltype(wd_)>(wd))
1681  {}
1682 
1683 CONSTCD11
1684 inline
1686  : wd_(weekday_from_days(dp.time_since_epoch().count()))
1687  {}
1688 
1689 CONSTCD11
1690 inline
1692  : wd_(weekday_from_days(dp.time_since_epoch().count()))
1693  {}
1694 
1695 CONSTCD14 inline weekday& weekday::operator++() NOEXCEPT {if (++wd_ == 7) wd_ = 0; return *this;}
1696 CONSTCD14 inline weekday weekday::operator++(int) NOEXCEPT {auto tmp(*this); ++(*this); return tmp;}
1697 CONSTCD14 inline weekday& weekday::operator--() NOEXCEPT {if (wd_-- == 0) wd_ = 6; return *this;}
1698 CONSTCD14 inline weekday weekday::operator--(int) NOEXCEPT {auto tmp(*this); --(*this); return tmp;}
1699 
1700 CONSTCD14
1701 inline
1702 weekday&
1703 weekday::operator+=(const days& d) NOEXCEPT
1704 {
1705  *this = *this + d;
1706  return *this;
1707 }
1708 
1709 CONSTCD14
1710 inline
1711 weekday&
1712 weekday::operator-=(const days& d) NOEXCEPT
1713 {
1714  *this = *this - d;
1715  return *this;
1716 }
1717 
1718 CONSTCD11
1719 inline
1720 weekday::operator unsigned() const NOEXCEPT
1721 {
1722  return static_cast<unsigned>(wd_);
1723 }
1724 
1725 CONSTCD11 inline bool weekday::ok() const NOEXCEPT {return wd_ <= 6;}
1726 
1727 CONSTCD11
1728 inline
1729 bool
1730 operator==(const weekday& x, const weekday& y) NOEXCEPT
1731 {
1732  return static_cast<unsigned>(x) == static_cast<unsigned>(y);
1733 }
1734 
1735 CONSTCD11
1736 inline
1737 bool
1738 operator!=(const weekday& x, const weekday& y) NOEXCEPT
1739 {
1740  return !(x == y);
1741 }
1742 
1743 CONSTCD14
1744 inline
1745 days
1746 operator-(const weekday& x, const weekday& y) NOEXCEPT
1747 {
1748  auto const diff = static_cast<unsigned>(x) - static_cast<unsigned>(y);
1749  return days{diff <= 6 ? diff : diff + 7};
1750 }
1751 
1752 CONSTCD14
1753 inline
1754 weekday
1755 operator+(const weekday& x, const days& y) NOEXCEPT
1756 {
1757  auto const wdu = static_cast<long long>(static_cast<unsigned>(x)) + y.count();
1758  auto const wk = (wdu >= 0 ? wdu : wdu-6) / 7;
1759  return weekday{static_cast<unsigned>(wdu - wk * 7)};
1760 }
1761 
1762 CONSTCD14
1763 inline
1764 weekday
1765 operator+(const days& x, const weekday& y) NOEXCEPT
1766 {
1767  return y + x;
1768 }
1769 
1770 CONSTCD14
1771 inline
1772 weekday
1773 operator-(const weekday& x, const days& y) NOEXCEPT
1774 {
1775  return x + -y;
1776 }
1777 
1778 template<class CharT, class Traits>
1779 inline
1780 std::basic_ostream<CharT, Traits>&
1781 operator<<(std::basic_ostream<CharT, Traits>& os, const weekday& wd)
1782 {
1783  switch (static_cast<unsigned>(wd))
1784  {
1785  case 0:
1786  os << "Sun";
1787  break;
1788  case 1:
1789  os << "Mon";
1790  break;
1791  case 2:
1792  os << "Tue";
1793  break;
1794  case 3:
1795  os << "Wed";
1796  break;
1797  case 4:
1798  os << "Thu";
1799  break;
1800  case 5:
1801  os << "Fri";
1802  break;
1803  case 6:
1804  os << "Sat";
1805  break;
1806  default:
1807  os << static_cast<unsigned>(wd) << " is not a valid weekday";
1808  break;
1809  }
1810  return os;
1811 }
1812 
1813 #if !defined(_MSC_VER) || (_MSC_VER >= 1900)
1814 inline namespace literals
1815 {
1816 
1817 CONSTCD11
1818 inline
1819 date::day
1820 operator "" _d(unsigned long long d) NOEXCEPT
1821 {
1822  return date::day{static_cast<unsigned>(d)};
1823 }
1824 
1825 CONSTCD11
1826 inline
1827 date::year
1828 operator "" _y(unsigned long long y) NOEXCEPT
1829 {
1830  return date::year(static_cast<int>(y));
1831 }
1832 #endif // !defined(_MSC_VER) || (_MSC_VER >= 1900)
1833 
1835 
1848 
1856 
1857 #if !defined(_MSC_VER) || (_MSC_VER >= 1900)
1858 } // inline namespace literals
1859 #endif
1860 
1861 // weekday_indexed
1862 
1863 CONSTCD11
1864 inline
1865 weekday
1867 {
1868  return date::weekday{static_cast<unsigned>(wd_)};
1869 }
1870 
1871 CONSTCD11 inline unsigned weekday_indexed::index() const NOEXCEPT {return index_;}
1872 
1873 CONSTCD11
1874 inline
1875 bool
1876 weekday_indexed::ok() const NOEXCEPT
1877 {
1878  return weekday().ok() && 1 <= index_ && index_ <= 5;
1879 }
1880 
1881 #ifdef __GNUC__
1882 # pragma GCC diagnostic push
1883 # pragma GCC diagnostic ignored "-Wconversion"
1884 #endif // __GNUC__
1885 
1886 CONSTCD11
1887 inline
1889  : wd_(static_cast<decltype(wd_)>(static_cast<unsigned>(wd)))
1890  , index_(static_cast<decltype(index_)>(index))
1891  {}
1892 
1893 #ifdef __GNUC__
1894 # pragma GCC diagnostic pop
1895 #endif // __GNUC__
1896 
1897 template<class CharT, class Traits>
1898 inline
1899 std::basic_ostream<CharT, Traits>&
1900 operator<<(std::basic_ostream<CharT, Traits>& os, const weekday_indexed& wdi)
1901 {
1902  return os << wdi.weekday() << '[' << wdi.index() << ']';
1903 }
1904 
1905 CONSTCD11
1906 inline
1907 weekday_indexed
1908 weekday::operator[](unsigned index) const NOEXCEPT
1909 {
1910  return {*this, index};
1911 }
1912 
1913 CONSTCD11
1914 inline
1915 bool
1916 operator==(const weekday_indexed& x, const weekday_indexed& y) NOEXCEPT
1917 {
1918  return x.weekday() == y.weekday() && x.index() == y.index();
1919 }
1920 
1921 CONSTCD11
1922 inline
1923 bool
1924 operator!=(const weekday_indexed& x, const weekday_indexed& y) NOEXCEPT
1925 {
1926  return !(x == y);
1927 }
1928 
1929 // weekday_last
1930 
1931 CONSTCD11 inline date::weekday weekday_last::weekday() const NOEXCEPT {return wd_;}
1932 CONSTCD11 inline bool weekday_last::ok() const NOEXCEPT {return wd_.ok();}
1934 
1935 CONSTCD11
1936 inline
1937 bool
1938 operator==(const weekday_last& x, const weekday_last& y) NOEXCEPT
1939 {
1940  return x.weekday() == y.weekday();
1941 }
1942 
1943 CONSTCD11
1944 inline
1945 bool
1946 operator!=(const weekday_last& x, const weekday_last& y) NOEXCEPT
1947 {
1948  return !(x == y);
1949 }
1950 
1951 template<class CharT, class Traits>
1952 inline
1953 std::basic_ostream<CharT, Traits>&
1954 operator<<(std::basic_ostream<CharT, Traits>& os, const weekday_last& wdl)
1955 {
1956  return os << wdl.weekday() << "[last]";
1957 }
1958 
1959 CONSTCD11
1960 inline
1961 weekday_last
1963 {
1964  return weekday_last{*this};
1965 }
1966 
1967 // year_month
1968 
1969 CONSTCD11
1970 inline
1972  : y_(y)
1973  , m_(m)
1974  {}
1975 
1976 CONSTCD11 inline year year_month::year() const NOEXCEPT {return y_;}
1977 CONSTCD11 inline month year_month::month() const NOEXCEPT {return m_;}
1978 CONSTCD11 inline bool year_month::ok() const NOEXCEPT {return y_.ok() && m_.ok();}
1979 
1980 CONSTCD14
1981 inline
1982 year_month&
1983 year_month::operator+=(const months& dm) NOEXCEPT
1984 {
1985  *this = *this + dm;
1986  return *this;
1987 }
1988 
1989 CONSTCD14
1990 inline
1991 year_month&
1992 year_month::operator-=(const months& dm) NOEXCEPT
1993 {
1994  *this = *this - dm;
1995  return *this;
1996 }
1997 
1998 CONSTCD14
1999 inline
2000 year_month&
2001 year_month::operator+=(const years& dy) NOEXCEPT
2002 {
2003  *this = *this + dy;
2004  return *this;
2005 }
2006 
2007 CONSTCD14
2008 inline
2009 year_month&
2010 year_month::operator-=(const years& dy) NOEXCEPT
2011 {
2012  *this = *this - dy;
2013  return *this;
2014 }
2015 
2016 CONSTCD11
2017 inline
2018 bool
2019 operator==(const year_month& x, const year_month& y) NOEXCEPT
2020 {
2021  return x.year() == y.year() && x.month() == y.month();
2022 }
2023 
2024 CONSTCD11
2025 inline
2026 bool
2027 operator!=(const year_month& x, const year_month& y) NOEXCEPT
2028 {
2029  return !(x == y);
2030 }
2031 
2032 CONSTCD11
2033 inline
2034 bool
2035 operator<(const year_month& x, const year_month& y) NOEXCEPT
2036 {
2037  return x.year() < y.year() ? true
2038  : (x.year() > y.year() ? false
2039  : (x.month() < y.month()));
2040 }
2041 
2042 CONSTCD11
2043 inline
2044 bool
2045 operator>(const year_month& x, const year_month& y) NOEXCEPT
2046 {
2047  return y < x;
2048 }
2049 
2050 CONSTCD11
2051 inline
2052 bool
2053 operator<=(const year_month& x, const year_month& y) NOEXCEPT
2054 {
2055  return !(y < x);
2056 }
2057 
2058 CONSTCD11
2059 inline
2060 bool
2061 operator>=(const year_month& x, const year_month& y) NOEXCEPT
2062 {
2063  return !(x < y);
2064 }
2065 
2066 CONSTCD14
2067 inline
2068 year_month
2069 operator+(const year_month& ym, const months& dm) NOEXCEPT
2070 {
2071  auto dmi = static_cast<int>(static_cast<unsigned>(ym.month())) - 1 + dm.count();
2072  auto dy = (dmi >= 0 ? dmi : dmi-11) / 12;
2073  dmi = dmi - dy * 12 + 1;
2074  return (ym.year() + years(dy)) / month(static_cast<unsigned>(dmi));
2075 }
2076 
2077 CONSTCD14
2078 inline
2079 year_month
2080 operator+(const months& dm, const year_month& ym) NOEXCEPT
2081 {
2082  return ym + dm;
2083 }
2084 
2085 CONSTCD14
2086 inline
2087 year_month
2088 operator-(const year_month& ym, const months& dm) NOEXCEPT
2089 {
2090  return ym + -dm;
2091 }
2092 
2093 CONSTCD11
2094 inline
2095 months
2096 operator-(const year_month& x, const year_month& y) NOEXCEPT
2097 {
2098  return (x.year() - y.year()) +
2099  months(static_cast<unsigned>(x.month()) - static_cast<unsigned>(y.month()));
2100 }
2101 
2102 CONSTCD11
2103 inline
2104 year_month
2105 operator+(const year_month& ym, const years& dy) NOEXCEPT
2106 {
2107  return (ym.year() + dy) / ym.month();
2108 }
2109 
2110 CONSTCD11
2111 inline
2112 year_month
2113 operator+(const years& dy, const year_month& ym) NOEXCEPT
2114 {
2115  return ym + dy;
2116 }
2117 
2118 CONSTCD11
2119 inline
2120 year_month
2121 operator-(const year_month& ym, const years& dy) NOEXCEPT
2122 {
2123  return ym + -dy;
2124 }
2125 
2126 template<class CharT, class Traits>
2127 inline
2128 std::basic_ostream<CharT, Traits>&
2129 operator<<(std::basic_ostream<CharT, Traits>& os, const year_month& ym)
2130 {
2131  return os << ym.year() << '/' << ym.month();
2132 }
2133 
2134 // month_day
2135 
2136 CONSTCD11
2137 inline
2139  : m_(m)
2140  , d_(d)
2141  {}
2142 
2143 CONSTCD11 inline date::month month_day::month() const NOEXCEPT {return m_;}
2144 CONSTCD11 inline date::day month_day::day() const NOEXCEPT {return d_;}
2145 
2146 CONSTCD14
2147 inline
2148 bool
2149 month_day::ok() const NOEXCEPT
2150 {
2151  CONSTDATA date::day d[] =
2152  {
2153  date::day(31), date::day(29), date::day(31),
2154  date::day(30), date::day(31), date::day(30),
2155  date::day(31), date::day(31), date::day(30),
2156  date::day(31), date::day(30), date::day(31)
2157  };
2158  return m_.ok() && date::day{1} <= d_ && d_ <= d[static_cast<unsigned>(m_)-1];
2159 }
2160 
2161 CONSTCD11
2162 inline
2163 bool
2164 operator==(const month_day& x, const month_day& y) NOEXCEPT
2165 {
2166  return x.month() == y.month() && x.day() == y.day();
2167 }
2168 
2169 CONSTCD11
2170 inline
2171 bool
2172 operator!=(const month_day& x, const month_day& y) NOEXCEPT
2173 {
2174  return !(x == y);
2175 }
2176 
2177 CONSTCD11
2178 inline
2179 bool
2180 operator<(const month_day& x, const month_day& y) NOEXCEPT
2181 {
2182  return x.month() < y.month() ? true
2183  : (x.month() > y.month() ? false
2184  : (x.day() < y.day()));
2185 }
2186 
2187 CONSTCD11
2188 inline
2189 bool
2190 operator>(const month_day& x, const month_day& y) NOEXCEPT
2191 {
2192  return y < x;
2193 }
2194 
2195 CONSTCD11
2196 inline
2197 bool
2198 operator<=(const month_day& x, const month_day& y) NOEXCEPT
2199 {
2200  return !(y < x);
2201 }
2202 
2203 CONSTCD11
2204 inline
2205 bool
2206 operator>=(const month_day& x, const month_day& y) NOEXCEPT
2207 {
2208  return !(x < y);
2209 }
2210 
2211 template<class CharT, class Traits>
2212 inline
2213 std::basic_ostream<CharT, Traits>&
2214 operator<<(std::basic_ostream<CharT, Traits>& os, const month_day& md)
2215 {
2216  return os << md.month() << '/' << md.day();
2217 }
2218 
2219 // month_day_last
2220 
2221 CONSTCD11 inline month month_day_last::month() const NOEXCEPT {return m_;}
2222 CONSTCD11 inline bool month_day_last::ok() const NOEXCEPT {return m_.ok();}
2224 
2225 CONSTCD11
2226 inline
2227 bool
2228 operator==(const month_day_last& x, const month_day_last& y) NOEXCEPT
2229 {
2230  return x.month() == y.month();
2231 }
2232 
2233 CONSTCD11
2234 inline
2235 bool
2236 operator!=(const month_day_last& x, const month_day_last& y) NOEXCEPT
2237 {
2238  return !(x == y);
2239 }
2240 
2241 CONSTCD11
2242 inline
2243 bool
2244 operator<(const month_day_last& x, const month_day_last& y) NOEXCEPT
2245 {
2246  return x.month() < y.month();
2247 }
2248 
2249 CONSTCD11
2250 inline
2251 bool
2252 operator>(const month_day_last& x, const month_day_last& y) NOEXCEPT
2253 {
2254  return y < x;
2255 }
2256 
2257 CONSTCD11
2258 inline
2259 bool
2260 operator<=(const month_day_last& x, const month_day_last& y) NOEXCEPT
2261 {
2262  return !(y < x);
2263 }
2264 
2265 CONSTCD11
2266 inline
2267 bool
2268 operator>=(const month_day_last& x, const month_day_last& y) NOEXCEPT
2269 {
2270  return !(x < y);
2271 }
2272 
2273 template<class CharT, class Traits>
2274 inline
2275 std::basic_ostream<CharT, Traits>&
2276 operator<<(std::basic_ostream<CharT, Traits>& os, const month_day_last& mdl)
2277 {
2278  return os << mdl.month() << "/last";
2279 }
2280 
2281 // month_weekday
2282 
2283 CONSTCD11
2284 inline
2286  const date::weekday_indexed& wdi) NOEXCEPT
2287  : m_(m)
2288  , wdi_(wdi)
2289  {}
2290 
2291 CONSTCD11 inline month month_weekday::month() const NOEXCEPT {return m_;}
2292 
2293 CONSTCD11
2294 inline
2295 weekday_indexed
2297 {
2298  return wdi_;
2299 }
2300 
2301 CONSTCD11
2302 inline
2303 bool
2304 month_weekday::ok() const NOEXCEPT
2305 {
2306  return m_.ok() && wdi_.ok();
2307 }
2308 
2309 CONSTCD11
2310 inline
2311 bool
2312 operator==(const month_weekday& x, const month_weekday& y) NOEXCEPT
2313 {
2314  return x.month() == y.month() && x.weekday_indexed() == y.weekday_indexed();
2315 }
2316 
2317 CONSTCD11
2318 inline
2319 bool
2320 operator!=(const month_weekday& x, const month_weekday& y) NOEXCEPT
2321 {
2322  return !(x == y);
2323 }
2324 
2325 template<class CharT, class Traits>
2326 inline
2327 std::basic_ostream<CharT, Traits>&
2328 operator<<(std::basic_ostream<CharT, Traits>& os, const month_weekday& mwd)
2329 {
2330  return os << mwd.month() << '/' << mwd.weekday_indexed();
2331 }
2332 
2333 // month_weekday_last
2334 
2335 CONSTCD11
2336 inline
2338  const date::weekday_last& wdl) NOEXCEPT
2339  : m_(m)
2340  , wdl_(wdl)
2341  {}
2342 
2343 CONSTCD11 inline month month_weekday_last::month() const NOEXCEPT {return m_;}
2344 
2345 CONSTCD11
2346 inline
2347 weekday_last
2349 {
2350  return wdl_;
2351 }
2352 
2353 CONSTCD11
2354 inline
2355 bool
2356 month_weekday_last::ok() const NOEXCEPT
2357 {
2358  return m_.ok() && wdl_.ok();
2359 }
2360 
2361 CONSTCD11
2362 inline
2363 bool
2364 operator==(const month_weekday_last& x, const month_weekday_last& y) NOEXCEPT
2365 {
2366  return x.month() == y.month() && x.weekday_last() == y.weekday_last();
2367 }
2368 
2369 CONSTCD11
2370 inline
2371 bool
2372 operator!=(const month_weekday_last& x, const month_weekday_last& y) NOEXCEPT
2373 {
2374  return !(x == y);
2375 }
2376 
2377 template<class CharT, class Traits>
2378 inline
2379 std::basic_ostream<CharT, Traits>&
2380 operator<<(std::basic_ostream<CharT, Traits>& os, const month_weekday_last& mwdl)
2381 {
2382  return os << mwdl.month() << '/' << mwdl.weekday_last();
2383 }
2384 
2385 // year_month_day_last
2386 
2387 CONSTCD11
2388 inline
2390  const date::month_day_last& mdl) NOEXCEPT
2391  : y_(y)
2392  , mdl_(mdl)
2393  {}
2394 
2395 CONSTCD14
2396 inline
2397 year_month_day_last&
2399 {
2400  *this = *this + m;
2401  return *this;
2402 }
2403 
2404 CONSTCD14
2405 inline
2406 year_month_day_last&
2408 {
2409  *this = *this - m;
2410  return *this;
2411 }
2412 
2413 CONSTCD14
2414 inline
2415 year_month_day_last&
2417 {
2418  *this = *this + y;
2419  return *this;
2420 }
2421 
2422 CONSTCD14
2423 inline
2424 year_month_day_last&
2426 {
2427  *this = *this - y;
2428  return *this;
2429 }
2430 
2431 CONSTCD11 inline year year_month_day_last::year() const NOEXCEPT {return y_;}
2432 CONSTCD11 inline month year_month_day_last::month() const NOEXCEPT {return mdl_.month();}
2433 
2434 CONSTCD11
2435 inline
2436 month_day_last
2438 {
2439  return mdl_;
2440 }
2441 
2442 CONSTCD14
2443 inline
2444 day
2446 {
2447  CONSTDATA date::day d[] =
2448  {
2449  date::day(31), date::day(28), date::day(31),
2450  date::day(30), date::day(31), date::day(30),
2451  date::day(31), date::day(31), date::day(30),
2452  date::day(31), date::day(30), date::day(31)
2453  };
2454  return month() != feb || !y_.is_leap() ?
2455  d[static_cast<unsigned>(month()) - 1] : date::day{29};
2456 }
2457 
2458 CONSTCD14
2459 inline
2460 year_month_day_last::operator sys_days() const NOEXCEPT
2461 {
2462  return sys_days(year()/month()/day());
2463 }
2464 
2465 CONSTCD14
2466 inline
2467 year_month_day_last::operator local_days() const NOEXCEPT
2468 {
2469  return local_days(year()/month()/day());
2470 }
2471 
2472 CONSTCD11
2473 inline
2474 bool
2475 year_month_day_last::ok() const NOEXCEPT
2476 {
2477  return y_.ok() && mdl_.ok();
2478 }
2479 
2480 CONSTCD11
2481 inline
2482 bool
2483 operator==(const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT
2484 {
2485  return x.year() == y.year() && x.month_day_last() == y.month_day_last();
2486 }
2487 
2488 CONSTCD11
2489 inline
2490 bool
2491 operator!=(const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT
2492 {
2493  return !(x == y);
2494 }
2495 
2496 CONSTCD11
2497 inline
2498 bool
2499 operator<(const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT
2500 {
2501  return x.year() < y.year() ? true
2502  : (x.year() > y.year() ? false
2503  : (x.month_day_last() < y.month_day_last()));
2504 }
2505 
2506 CONSTCD11
2507 inline
2508 bool
2509 operator>(const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT
2510 {
2511  return y < x;
2512 }
2513 
2514 CONSTCD11
2515 inline
2516 bool
2517 operator<=(const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT
2518 {
2519  return !(y < x);
2520 }
2521 
2522 CONSTCD11
2523 inline
2524 bool
2525 operator>=(const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT
2526 {
2527  return !(x < y);
2528 }
2529 
2530 template<class CharT, class Traits>
2531 inline
2532 std::basic_ostream<CharT, Traits>&
2533 operator<<(std::basic_ostream<CharT, Traits>& os, const year_month_day_last& ymdl)
2534 {
2535  return os << ymdl.year() << '/' << ymdl.month_day_last();
2536 }
2537 
2538 CONSTCD14
2539 inline
2540 year_month_day_last
2541 operator+(const year_month_day_last& ymdl, const months& dm) NOEXCEPT
2542 {
2543  return (ymdl.year() / ymdl.month() + dm) / last;
2544 }
2545 
2546 CONSTCD14
2547 inline
2548 year_month_day_last
2549 operator+(const months& dm, const year_month_day_last& ymdl) NOEXCEPT
2550 {
2551  return ymdl + dm;
2552 }
2553 
2554 CONSTCD14
2555 inline
2556 year_month_day_last
2557 operator-(const year_month_day_last& ymdl, const months& dm) NOEXCEPT
2558 {
2559  return ymdl + (-dm);
2560 }
2561 
2562 CONSTCD11
2563 inline
2564 year_month_day_last
2565 operator+(const year_month_day_last& ymdl, const years& dy) NOEXCEPT
2566 {
2567  return {ymdl.year()+dy, ymdl.month_day_last()};
2568 }
2569 
2570 CONSTCD11
2571 inline
2572 year_month_day_last
2573 operator+(const years& dy, const year_month_day_last& ymdl) NOEXCEPT
2574 {
2575  return ymdl + dy;
2576 }
2577 
2578 CONSTCD11
2579 inline
2580 year_month_day_last
2581 operator-(const year_month_day_last& ymdl, const years& dy) NOEXCEPT
2582 {
2583  return ymdl + (-dy);
2584 }
2585 
2586 // year_month_day
2587 
2588 CONSTCD11
2589 inline
2591  const date::day& d) NOEXCEPT
2592  : y_(y)
2593  , m_(m)
2594  , d_(d)
2595  {}
2596 
2597 CONSTCD14
2598 inline
2599 year_month_day::year_month_day(const year_month_day_last& ymdl) NOEXCEPT
2600  : y_(ymdl.year())
2601  , m_(ymdl.month())
2602  , d_(ymdl.day())
2603  {}
2604 
2605 CONSTCD14
2606 inline
2608  : year_month_day(from_days(dp.time_since_epoch()))
2609  {}
2610 
2611 CONSTCD14
2612 inline
2614  : year_month_day(from_days(dp.time_since_epoch()))
2615  {}
2616 
2617 CONSTCD11 inline year year_month_day::year() const NOEXCEPT {return y_;}
2618 CONSTCD11 inline month year_month_day::month() const NOEXCEPT {return m_;}
2619 CONSTCD11 inline day year_month_day::day() const NOEXCEPT {return d_;}
2620 
2621 CONSTCD14
2622 inline
2623 year_month_day&
2625 {
2626  *this = *this + m;
2627  return *this;
2628 }
2629 
2630 CONSTCD14
2631 inline
2632 year_month_day&
2634 {
2635  *this = *this - m;
2636  return *this;
2637 }
2638 
2639 CONSTCD14
2640 inline
2641 year_month_day&
2643 {
2644  *this = *this + y;
2645  return *this;
2646 }
2647 
2648 CONSTCD14
2649 inline
2650 year_month_day&
2652 {
2653  *this = *this - y;
2654  return *this;
2655 }
2656 
2657 CONSTCD14
2658 inline
2659 days
2660 year_month_day::to_days() const NOEXCEPT
2661 {
2662  static_assert(std::numeric_limits<unsigned>::digits >= 18,
2663  "This algorithm has not been ported to a 16 bit unsigned integer");
2664  static_assert(std::numeric_limits<int>::digits >= 20,
2665  "This algorithm has not been ported to a 16 bit signed integer");
2666  auto const y = static_cast<int>(y_) - (m_ <= feb);
2667  auto const m = static_cast<unsigned>(m_);
2668  auto const d = static_cast<unsigned>(d_);
2669  auto const era = (y >= 0 ? y : y-399) / 400;
2670  auto const yoe = static_cast<unsigned>(y - era * 400); // [0, 399]
2671  auto const doy = (153*(m > 2 ? m-3 : m+9) + 2)/5 + d-1; // [0, 365]
2672  auto const doe = yoe * 365 + yoe/4 - yoe/100 + doy; // [0, 146096]
2673  return days{era * 146097 + static_cast<int>(doe) - 719468};
2674 }
2675 
2676 CONSTCD14
2677 inline
2678 year_month_day::operator sys_days() const NOEXCEPT
2679 {
2680  return sys_days{to_days()};
2681 }
2682 
2683 CONSTCD14
2684 inline
2685 year_month_day::operator local_days() const NOEXCEPT
2686 {
2687  return local_days{to_days()};
2688 }
2689 
2690 CONSTCD14
2691 inline
2692 bool
2693 year_month_day::ok() const NOEXCEPT
2694 {
2695  if (!(y_.ok() && m_.ok()))
2696  return false;
2697  return date::day{1} <= d_ && d_ <= (y_ / m_ / last).day();
2698 }
2699 
2700 CONSTCD11
2701 inline
2702 bool
2703 operator==(const year_month_day& x, const year_month_day& y) NOEXCEPT
2704 {
2705  return x.year() == y.year() && x.month() == y.month() && x.day() == y.day();
2706 }
2707 
2708 CONSTCD11
2709 inline
2710 bool
2711 operator!=(const year_month_day& x, const year_month_day& y) NOEXCEPT
2712 {
2713  return !(x == y);
2714 }
2715 
2716 CONSTCD11
2717 inline
2718 bool
2719 operator<(const year_month_day& x, const year_month_day& y) NOEXCEPT
2720 {
2721  return x.year() < y.year() ? true
2722  : (x.year() > y.year() ? false
2723  : (x.month() < y.month() ? true
2724  : (x.month() > y.month() ? false
2725  : (x.day() < y.day()))));
2726 }
2727 
2728 CONSTCD11
2729 inline
2730 bool
2731 operator>(const year_month_day& x, const year_month_day& y) NOEXCEPT
2732 {
2733  return y < x;
2734 }
2735 
2736 CONSTCD11
2737 inline
2738 bool
2739 operator<=(const year_month_day& x, const year_month_day& y) NOEXCEPT
2740 {
2741  return !(y < x);
2742 }
2743 
2744 CONSTCD11
2745 inline
2746 bool
2747 operator>=(const year_month_day& x, const year_month_day& y) NOEXCEPT
2748 {
2749  return !(x < y);
2750 }
2751 
2752 template<class CharT, class Traits>
2753 inline
2754 std::basic_ostream<CharT, Traits>&
2755 operator<<(std::basic_ostream<CharT, Traits>& os, const year_month_day& ymd)
2756 {
2758  os.fill('0');
2759  os.flags(std::ios::dec | std::ios::right);
2760  os << ymd.year() << '-';
2761  os.width(2);
2762  os << static_cast<unsigned>(ymd.month()) << '-';
2763  os << ymd.day();
2764  return os;
2765 }
2766 
2767 CONSTCD14
2768 inline
2769 year_month_day
2771 {
2772  static_assert(std::numeric_limits<unsigned>::digits >= 18,
2773  "This algorithm has not been ported to a 16 bit unsigned integer");
2774  static_assert(std::numeric_limits<int>::digits >= 20,
2775  "This algorithm has not been ported to a 16 bit signed integer");
2776  auto const z = dp.count() + 719468;
2777  auto const era = (z >= 0 ? z : z - 146096) / 146097;
2778  auto const doe = static_cast<unsigned>(z - era * 146097); // [0, 146096]
2779  auto const yoe = (doe - doe/1460 + doe/36524 - doe/146096) / 365; // [0, 399]
2780  auto const y = static_cast<days::rep>(yoe) + era * 400;
2781  auto const doy = doe - (365*yoe + yoe/4 - yoe/100); // [0, 365]
2782  auto const mp = (5*doy + 2)/153; // [0, 11]
2783  auto const d = doy - (153*mp+2)/5 + 1; // [1, 31]
2784  auto const m = mp < 10 ? mp+3 : mp-9; // [1, 12]
2785  return year_month_day{date::year{y + (m <= 2)}, date::month(m), date::day(d)};
2786 }
2787 
2788 CONSTCD14
2789 inline
2790 year_month_day
2791 operator+(const year_month_day& ymd, const months& dm) NOEXCEPT
2792 {
2793  return (ymd.year() / ymd.month() + dm) / ymd.day();
2794 }
2795 
2796 CONSTCD14
2797 inline
2798 year_month_day
2799 operator+(const months& dm, const year_month_day& ymd) NOEXCEPT
2800 {
2801  return ymd + dm;
2802 }
2803 
2804 CONSTCD14
2805 inline
2806 year_month_day
2807 operator-(const year_month_day& ymd, const months& dm) NOEXCEPT
2808 {
2809  return ymd + (-dm);
2810 }
2811 
2812 CONSTCD11
2813 inline
2814 year_month_day
2815 operator+(const year_month_day& ymd, const years& dy) NOEXCEPT
2816 {
2817  return (ymd.year() + dy) / ymd.month() / ymd.day();
2818 }
2819 
2820 CONSTCD11
2821 inline
2822 year_month_day
2823 operator+(const years& dy, const year_month_day& ymd) NOEXCEPT
2824 {
2825  return ymd + dy;
2826 }
2827 
2828 CONSTCD11
2829 inline
2830 year_month_day
2831 operator-(const year_month_day& ymd, const years& dy) NOEXCEPT
2832 {
2833  return ymd + (-dy);
2834 }
2835 
2836 // year_month_weekday
2837 
2838 CONSTCD11
2839 inline
2841  const date::weekday_indexed& wdi)
2842  NOEXCEPT
2843  : y_(y)
2844  , m_(m)
2845  , wdi_(wdi)
2846  {}
2847 
2848 CONSTCD14
2849 inline
2851  : year_month_weekday(from_days(dp.time_since_epoch()))
2852  {}
2853 
2854 CONSTCD14
2855 inline
2857  : year_month_weekday(from_days(dp.time_since_epoch()))
2858  {}
2859 
2860 CONSTCD14
2861 inline
2862 year_month_weekday&
2864 {
2865  *this = *this + m;
2866  return *this;
2867 }
2868 
2869 CONSTCD14
2870 inline
2871 year_month_weekday&
2873 {
2874  *this = *this - m;
2875  return *this;
2876 }
2877 
2878 CONSTCD14
2879 inline
2880 year_month_weekday&
2882 {
2883  *this = *this + y;
2884  return *this;
2885 }
2886 
2887 CONSTCD14
2888 inline
2889 year_month_weekday&
2891 {
2892  *this = *this - y;
2893  return *this;
2894 }
2895 
2896 CONSTCD11 inline year year_month_weekday::year() const NOEXCEPT {return y_;}
2897 CONSTCD11 inline month year_month_weekday::month() const NOEXCEPT {return m_;}
2898 
2899 CONSTCD11
2900 inline
2901 weekday
2903 {
2904  return wdi_.weekday();
2905 }
2906 
2907 CONSTCD11
2908 inline
2909 unsigned
2911 {
2912  return wdi_.index();
2913 }
2914 
2915 CONSTCD11
2916 inline
2917 weekday_indexed
2919 {
2920  return wdi_;
2921 }
2922 
2923 CONSTCD14
2924 inline
2925 year_month_weekday::operator sys_days() const NOEXCEPT
2926 {
2927  return sys_days{to_days()};
2928 }
2929 
2930 CONSTCD14
2931 inline
2932 year_month_weekday::operator local_days() const NOEXCEPT
2933 {
2934  return local_days{to_days()};
2935 }
2936 
2937 CONSTCD14
2938 inline
2939 bool
2940 year_month_weekday::ok() const NOEXCEPT
2941 {
2942  if (!y_.ok() || !m_.ok() || !wdi_.weekday().ok() || wdi_.index() < 1)
2943  return false;
2944  if (wdi_.index() <= 4)
2945  return true;
2946  auto d2 = wdi_.weekday() - date::weekday(static_cast<sys_days>(y_/m_/1)) + days((wdi_.index()-1)*7 + 1);
2947  return static_cast<unsigned>(d2.count()) <= static_cast<unsigned>((y_/m_/last).day());
2948 }
2949 
2950 CONSTCD14
2951 inline
2952 year_month_weekday
2954 {
2955  sys_days dp{d};
2956  auto const wd = date::weekday(dp);
2957  auto const ymd = year_month_day(dp);
2958  return {ymd.year(), ymd.month(), wd[(static_cast<unsigned>(ymd.day())-1)/7+1]};
2959 }
2960 
2961 CONSTCD14
2962 inline
2963 days
2965 {
2966  auto d = sys_days(y_/m_/1);
2967  return (d + (wdi_.weekday() - date::weekday(d) + days{(wdi_.index()-1)*7})
2968  ).time_since_epoch();
2969 }
2970 
2971 CONSTCD11
2972 inline
2973 bool
2974 operator==(const year_month_weekday& x, const year_month_weekday& y) NOEXCEPT
2975 {
2976  return x.year() == y.year() && x.month() == y.month() &&
2977  x.weekday_indexed() == y.weekday_indexed();
2978 }
2979 
2980 CONSTCD11
2981 inline
2982 bool
2983 operator!=(const year_month_weekday& x, const year_month_weekday& y) NOEXCEPT
2984 {
2985  return !(x == y);
2986 }
2987 
2988 template<class CharT, class Traits>
2989 inline
2990 std::basic_ostream<CharT, Traits>&
2991 operator<<(std::basic_ostream<CharT, Traits>& os, const year_month_weekday& ymwdi)
2992 {
2993  return os << ymwdi.year() << '/' << ymwdi.month()
2994  << '/' << ymwdi.weekday_indexed();
2995 }
2996 
2997 CONSTCD14
2998 inline
2999 year_month_weekday
3000 operator+(const year_month_weekday& ymwd, const months& dm) NOEXCEPT
3001 {
3002  return (ymwd.year() / ymwd.month() + dm) / ymwd.weekday_indexed();
3003 }
3004 
3005 CONSTCD14
3006 inline
3007 year_month_weekday
3008 operator+(const months& dm, const year_month_weekday& ymwd) NOEXCEPT
3009 {
3010  return ymwd + dm;
3011 }
3012 
3013 CONSTCD14
3014 inline
3015 year_month_weekday
3016 operator-(const year_month_weekday& ymwd, const months& dm) NOEXCEPT
3017 {
3018  return ymwd + (-dm);
3019 }
3020 
3021 CONSTCD11
3022 inline
3023 year_month_weekday
3024 operator+(const year_month_weekday& ymwd, const years& dy) NOEXCEPT
3025 {
3026  return {ymwd.year()+dy, ymwd.month(), ymwd.weekday_indexed()};
3027 }
3028 
3029 CONSTCD11
3030 inline
3031 year_month_weekday
3032 operator+(const years& dy, const year_month_weekday& ymwd) NOEXCEPT
3033 {
3034  return ymwd + dy;
3035 }
3036 
3037 CONSTCD11
3038 inline
3039 year_month_weekday
3040 operator-(const year_month_weekday& ymwd, const years& dy) NOEXCEPT
3041 {
3042  return ymwd + (-dy);
3043 }
3044 
3045 // year_month_weekday_last
3046 
3047 CONSTCD11
3048 inline
3050  const date::month& m,
3051  const date::weekday_last& wdl) NOEXCEPT
3052  : y_(y)
3053  , m_(m)
3054  , wdl_(wdl)
3055  {}
3056 
3057 CONSTCD14
3058 inline
3059 year_month_weekday_last&
3061 {
3062  *this = *this + m;
3063  return *this;
3064 }
3065 
3066 CONSTCD14
3067 inline
3068 year_month_weekday_last&
3070 {
3071  *this = *this - m;
3072  return *this;
3073 }
3074 
3075 CONSTCD14
3076 inline
3077 year_month_weekday_last&
3079 {
3080  *this = *this + y;
3081  return *this;
3082 }
3083 
3084 CONSTCD14
3085 inline
3086 year_month_weekday_last&
3088 {
3089  *this = *this - y;
3090  return *this;
3091 }
3092 
3093 CONSTCD11 inline year year_month_weekday_last::year() const NOEXCEPT {return y_;}
3094 CONSTCD11 inline month year_month_weekday_last::month() const NOEXCEPT {return m_;}
3095 
3096 CONSTCD11
3097 inline
3098 weekday
3100 {
3101  return wdl_.weekday();
3102 }
3103 
3104 CONSTCD11
3105 inline
3106 weekday_last
3108 {
3109  return wdl_;
3110 }
3111 
3112 CONSTCD14
3113 inline
3114 year_month_weekday_last::operator sys_days() const NOEXCEPT
3115 {
3116  return sys_days{to_days()};
3117 }
3118 
3119 CONSTCD14
3120 inline
3121 year_month_weekday_last::operator local_days() const NOEXCEPT
3122 {
3123  return local_days{to_days()};
3124 }
3125 
3126 CONSTCD11
3127 inline
3128 bool
3130 {
3131  return y_.ok() && m_.ok() && wdl_.ok();
3132 }
3133 
3134 CONSTCD14
3135 inline
3136 days
3138 {
3139  auto const d = sys_days(y_/m_/last);
3140  return (d - (date::weekday{d} - wdl_.weekday())).time_since_epoch();
3141 }
3142 
3143 CONSTCD11
3144 inline
3145 bool
3146 operator==(const year_month_weekday_last& x, const year_month_weekday_last& y) NOEXCEPT
3147 {
3148  return x.year() == y.year() && x.month() == y.month() &&
3149  x.weekday_last() == y.weekday_last();
3150 }
3151 
3152 CONSTCD11
3153 inline
3154 bool
3155 operator!=(const year_month_weekday_last& x, const year_month_weekday_last& y) NOEXCEPT
3156 {
3157  return !(x == y);
3158 }
3159 
3160 template<class CharT, class Traits>
3161 inline
3162 std::basic_ostream<CharT, Traits>&
3163 operator<<(std::basic_ostream<CharT, Traits>& os, const year_month_weekday_last& ymwdl)
3164 {
3165  return os << ymwdl.year() << '/' << ymwdl.month() << '/' << ymwdl.weekday_last();
3166 }
3167 
3168 CONSTCD14
3169 inline
3170 year_month_weekday_last
3171 operator+(const year_month_weekday_last& ymwdl, const months& dm) NOEXCEPT
3172 {
3173  return (ymwdl.year() / ymwdl.month() + dm) / ymwdl.weekday_last();
3174 }
3175 
3176 CONSTCD14
3177 inline
3178 year_month_weekday_last
3179 operator+(const months& dm, const year_month_weekday_last& ymwdl) NOEXCEPT
3180 {
3181  return ymwdl + dm;
3182 }
3183 
3184 CONSTCD14
3185 inline
3186 year_month_weekday_last
3187 operator-(const year_month_weekday_last& ymwdl, const months& dm) NOEXCEPT
3188 {
3189  return ymwdl + (-dm);
3190 }
3191 
3192 CONSTCD11
3193 inline
3194 year_month_weekday_last
3195 operator+(const year_month_weekday_last& ymwdl, const years& dy) NOEXCEPT
3196 {
3197  return {ymwdl.year()+dy, ymwdl.month(), ymwdl.weekday_last()};
3198 }
3199 
3200 CONSTCD11
3201 inline
3202 year_month_weekday_last
3203 operator+(const years& dy, const year_month_weekday_last& ymwdl) NOEXCEPT
3204 {
3205  return ymwdl + dy;
3206 }
3207 
3208 CONSTCD11
3209 inline
3210 year_month_weekday_last
3211 operator-(const year_month_weekday_last& ymwdl, const years& dy) NOEXCEPT
3212 {
3213  return ymwdl + (-dy);
3214 }
3215 
3216 // year_month from operator/()
3217 
3218 CONSTCD11
3219 inline
3220 year_month
3221 operator/(const year& y, const month& m) NOEXCEPT
3222 {
3223  return {y, m};
3224 }
3225 
3226 CONSTCD11
3227 inline
3228 year_month
3229 operator/(const year& y, int m) NOEXCEPT
3230 {
3231  return y / month(static_cast<unsigned>(m));
3232 }
3233 
3234 // month_day from operator/()
3235 
3236 CONSTCD11
3237 inline
3238 month_day
3239 operator/(const month& m, const day& d) NOEXCEPT
3240 {
3241  return {m, d};
3242 }
3243 
3244 CONSTCD11
3245 inline
3246 month_day
3247 operator/(const day& d, const month& m) NOEXCEPT
3248 {
3249  return m / d;
3250 }
3251 
3252 CONSTCD11
3253 inline
3254 month_day
3255 operator/(const month& m, int d) NOEXCEPT
3256 {
3257  return m / day(static_cast<unsigned>(d));
3258 }
3259 
3260 CONSTCD11
3261 inline
3262 month_day
3263 operator/(int m, const day& d) NOEXCEPT
3264 {
3265  return month(static_cast<unsigned>(m)) / d;
3266 }
3267 
3268 CONSTCD11 inline month_day operator/(const day& d, int m) NOEXCEPT {return m / d;}
3269 
3270 // month_day_last from operator/()
3271 
3272 CONSTCD11
3273 inline
3274 month_day_last
3275 operator/(const month& m, last_spec) NOEXCEPT
3276 {
3277  return month_day_last{m};
3278 }
3279 
3280 CONSTCD11
3281 inline
3282 month_day_last
3283 operator/(last_spec, const month& m) NOEXCEPT
3284 {
3285  return m/last;
3286 }
3287 
3288 CONSTCD11
3289 inline
3290 month_day_last
3291 operator/(int m, last_spec) NOEXCEPT
3292 {
3293  return month(static_cast<unsigned>(m))/last;
3294 }
3295 
3296 CONSTCD11
3297 inline
3298 month_day_last
3299 operator/(last_spec, int m) NOEXCEPT
3300 {
3301  return m/last;
3302 }
3303 
3304 // month_weekday from operator/()
3305 
3306 CONSTCD11
3307 inline
3308 month_weekday
3309 operator/(const month& m, const weekday_indexed& wdi) NOEXCEPT
3310 {
3311  return {m, wdi};
3312 }
3313 
3314 CONSTCD11
3315 inline
3316 month_weekday
3317 operator/(const weekday_indexed& wdi, const month& m) NOEXCEPT
3318 {
3319  return m / wdi;
3320 }
3321 
3322 CONSTCD11
3323 inline
3324 month_weekday
3325 operator/(int m, const weekday_indexed& wdi) NOEXCEPT
3326 {
3327  return month(static_cast<unsigned>(m)) / wdi;
3328 }
3329 
3330 CONSTCD11
3331 inline
3332 month_weekday
3333 operator/(const weekday_indexed& wdi, int m) NOEXCEPT
3334 {
3335  return m / wdi;
3336 }
3337 
3338 // month_weekday_last from operator/()
3339 
3340 CONSTCD11
3341 inline
3342 month_weekday_last
3343 operator/(const month& m, const weekday_last& wdl) NOEXCEPT
3344 {
3345  return {m, wdl};
3346 }
3347 
3348 CONSTCD11
3349 inline
3350 month_weekday_last
3351 operator/(const weekday_last& wdl, const month& m) NOEXCEPT
3352 {
3353  return m / wdl;
3354 }
3355 
3356 CONSTCD11
3357 inline
3358 month_weekday_last
3359 operator/(int m, const weekday_last& wdl) NOEXCEPT
3360 {
3361  return month(static_cast<unsigned>(m)) / wdl;
3362 }
3363 
3364 CONSTCD11
3365 inline
3366 month_weekday_last
3367 operator/(const weekday_last& wdl, int m) NOEXCEPT
3368 {
3369  return m / wdl;
3370 }
3371 
3372 // year_month_day from operator/()
3373 
3374 CONSTCD11
3375 inline
3376 year_month_day
3377 operator/(const year_month& ym, const day& d) NOEXCEPT
3378 {
3379  return {ym.year(), ym.month(), d};
3380 }
3381 
3382 CONSTCD11
3383 inline
3384 year_month_day
3385 operator/(const year_month& ym, int d) NOEXCEPT
3386 {
3387  return ym / day(static_cast<unsigned>(d));
3388 }
3389 
3390 CONSTCD11
3391 inline
3392 year_month_day
3393 operator/(const year& y, const month_day& md) NOEXCEPT
3394 {
3395  return y / md.month() / md.day();
3396 }
3397 
3398 CONSTCD11
3399 inline
3400 year_month_day
3401 operator/(int y, const month_day& md) NOEXCEPT
3402 {
3403  return year(y) / md;
3404 }
3405 
3406 CONSTCD11
3407 inline
3408 year_month_day
3409 operator/(const month_day& md, const year& y) NOEXCEPT
3410 {
3411  return y / md;
3412 }
3413 
3414 CONSTCD11
3415 inline
3416 year_month_day
3417 operator/(const month_day& md, int y) NOEXCEPT
3418 {
3419  return year(y) / md;
3420 }
3421 
3422 // year_month_day_last from operator/()
3423 
3424 CONSTCD11
3425 inline
3426 year_month_day_last
3427 operator/(const year_month& ym, last_spec) NOEXCEPT
3428 {
3429  return {ym.year(), month_day_last{ym.month()}};
3430 }
3431 
3432 CONSTCD11
3433 inline
3434 year_month_day_last
3435 operator/(const year& y, const month_day_last& mdl) NOEXCEPT
3436 {
3437  return {y, mdl};
3438 }
3439 
3440 CONSTCD11
3441 inline
3442 year_month_day_last
3443 operator/(int y, const month_day_last& mdl) NOEXCEPT
3444 {
3445  return year(y) / mdl;
3446 }
3447 
3448 CONSTCD11
3449 inline
3450 year_month_day_last
3451 operator/(const month_day_last& mdl, const year& y) NOEXCEPT
3452 {
3453  return y / mdl;
3454 }
3455 
3456 CONSTCD11
3457 inline
3458 year_month_day_last
3459 operator/(const month_day_last& mdl, int y) NOEXCEPT
3460 {
3461  return year(y) / mdl;
3462 }
3463 
3464 // year_month_weekday from operator/()
3465 
3466 CONSTCD11
3467 inline
3468 year_month_weekday
3469 operator/(const year_month& ym, const weekday_indexed& wdi) NOEXCEPT
3470 {
3471  return {ym.year(), ym.month(), wdi};
3472 }
3473 
3474 CONSTCD11
3475 inline
3476 year_month_weekday
3477 operator/(const year& y, const month_weekday& mwd) NOEXCEPT
3478 {
3479  return {y, mwd.month(), mwd.weekday_indexed()};
3480 }
3481 
3482 CONSTCD11
3483 inline
3484 year_month_weekday
3485 operator/(int y, const month_weekday& mwd) NOEXCEPT
3486 {
3487  return year(y) / mwd;
3488 }
3489 
3490 CONSTCD11
3491 inline
3492 year_month_weekday
3493 operator/(const month_weekday& mwd, const year& y) NOEXCEPT
3494 {
3495  return y / mwd;
3496 }
3497 
3498 CONSTCD11
3499 inline
3500 year_month_weekday
3501 operator/(const month_weekday& mwd, int y) NOEXCEPT
3502 {
3503  return year(y) / mwd;
3504 }
3505 
3506 // year_month_weekday_last from operator/()
3507 
3508 CONSTCD11
3509 inline
3510 year_month_weekday_last
3511 operator/(const year_month& ym, const weekday_last& wdl) NOEXCEPT
3512 {
3513  return {ym.year(), ym.month(), wdl};
3514 }
3515 
3516 CONSTCD11
3517 inline
3518 year_month_weekday_last
3519 operator/(const year& y, const month_weekday_last& mwdl) NOEXCEPT
3520 {
3521  return {y, mwdl.month(), mwdl.weekday_last()};
3522 }
3523 
3524 CONSTCD11
3525 inline
3526 year_month_weekday_last
3527 operator/(int y, const month_weekday_last& mwdl) NOEXCEPT
3528 {
3529  return year(y) / mwdl;
3530 }
3531 
3532 CONSTCD11
3533 inline
3534 year_month_weekday_last
3535 operator/(const month_weekday_last& mwdl, const year& y) NOEXCEPT
3536 {
3537  return y / mwdl;
3538 }
3539 
3540 CONSTCD11
3541 inline
3542 year_month_weekday_last
3543 operator/(const month_weekday_last& mwdl, int y) NOEXCEPT
3544 {
3545  return year(y) / mwdl;
3546 }
3547 
3548 template <class Duration>
3549 struct fields;
3550 
3551 template <class CharT, class Traits, class Duration>
3552 std::basic_ostream<CharT, Traits>&
3553 to_stream(std::basic_ostream<CharT, Traits>& os, const CharT* fmt,
3554  const fields<Duration>& fds, const std::string* abbrev = nullptr,
3555  const std::chrono::seconds* offset_sec = nullptr);
3556 
3557 template <class CharT, class Traits, class Duration, class Alloc>
3558 std::basic_istream<CharT, Traits>&
3559 from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
3560  fields<Duration>& fds, std::basic_string<CharT, Traits, Alloc>* abbrev = nullptr,
3561  std::chrono::minutes* offset = nullptr);
3562 
3563 // time_of_day
3564 
3565 enum {am = 1, pm};
3566 
3567 namespace detail
3568 {
3569 
3570 // width<n>::value is the number of fractional decimal digits in 1/n
3571 // width<0>::value and width<1>::value are defined to be 0
3572 // If 1/n takes more than 18 fractional decimal digits,
3573 // the result is truncated to 19.
3574 // Example: width<2>::value == 1
3575 // Example: width<3>::value == 19
3576 // Example: width<4>::value == 2
3577 // Example: width<10>::value == 1
3578 // Example: width<1000>::value == 3
3579 template <std::uint64_t n, std::uint64_t d = 10, unsigned w = 0,
3580  bool should_continue = !(n < 2) && d != 0 && (w < 19)>
3581 struct width
3582 {
3583  static CONSTDATA unsigned value = 1 + width<n, d%n*10, w+1>::value;
3584 };
3585 
3586 template <std::uint64_t n, std::uint64_t d, unsigned w>
3588 {
3589  static CONSTDATA unsigned value = 0;
3590 };
3591 
3592 template <unsigned exp>
3594 {
3595 private:
3596  static CONSTDATA std::uint64_t h = static_pow10<exp/2>::value;
3597 public:
3598  static CONSTDATA std::uint64_t value = h * h * (exp % 2 ? 10 : 1);
3599 };
3600 
3601 template <>
3602 struct static_pow10<0>
3603 {
3604  static CONSTDATA std::uint64_t value = 1;
3605 };
3606 
3607 template <class Rep, unsigned w, bool in_range = (w < 19)>
3608 struct make_precision
3609 {
3610  using type = std::chrono::duration<Rep,
3611  std::ratio<1, static_pow10<w>::value>>;
3612  static CONSTDATA unsigned width = w;
3613 };
3614 
3615 template <class Rep, unsigned w>
3617 {
3618  using type = std::chrono::duration<Rep, std::micro>;
3619  static CONSTDATA unsigned width = 6;
3620 };
3621 
3622 template <class Duration,
3623  unsigned w = width<std::common_type<
3624  Duration,
3625  std::chrono::seconds>::type::period::den>::value>
3627 {
3628 public:
3629  using rep = typename std::common_type<Duration, std::chrono::seconds>::type::rep;
3632 
3633 private:
3634  std::chrono::seconds s_;
3636 
3637 public:
3639  : s_()
3640  , sub_s_()
3641  {}
3642 
3643  CONSTCD11 explicit decimal_format_seconds(const Duration& d) NOEXCEPT
3644  : s_(std::chrono::duration_cast<std::chrono::seconds>(d))
3645  , sub_s_(std::chrono::duration_cast<precision>(d - s_))
3646  {}
3647 
3648  CONSTCD14 std::chrono::seconds& seconds() NOEXCEPT {return s_;}
3649  CONSTCD11 std::chrono::seconds seconds() const NOEXCEPT {return s_;}
3650  CONSTCD11 precision subseconds() const NOEXCEPT {return sub_s_;}
3651 
3653  {
3654  return s_ + sub_s_;
3655  }
3656 
3657  CONSTCD11 bool in_conventional_range() const NOEXCEPT
3658  {
3659  using namespace std::chrono;
3660  return sub_s_ < std::chrono::seconds{1} && s_ < minutes{1};
3661  }
3662 
3663  template <class CharT, class Traits>
3664  friend
3665  std::basic_ostream<CharT, Traits>&
3666  operator<<(std::basic_ostream<CharT, Traits>& os, const decimal_format_seconds& x)
3667  {
3669  os.fill('0');
3670  os.flags(std::ios::dec | std::ios::right);
3671  os.width(2);
3672  os << x.s_.count() <<
3673  std::use_facet<std::numpunct<char>>(os.getloc()).decimal_point();
3674  os.width(width);
3675  os << static_cast<std::int64_t>(x.sub_s_.count());
3676  return os;
3677  }
3678 };
3679 
3680 template <class Duration>
3681 class decimal_format_seconds<Duration, 0>
3682 {
3683  static CONSTDATA unsigned w = 0;
3684 public:
3685  using rep = typename std::common_type<Duration, std::chrono::seconds>::type::rep;
3686  using precision = std::chrono::duration<rep>;
3688 private:
3689 
3690  std::chrono::seconds s_;
3691 
3692 public:
3695  : s_(s)
3696  {}
3697 
3698  CONSTCD14 std::chrono::seconds& seconds() NOEXCEPT {return s_;}
3699  CONSTCD11 std::chrono::seconds seconds() const NOEXCEPT {return s_;}
3700  CONSTCD14 precision to_duration() const NOEXCEPT {return s_;}
3701 
3702  CONSTCD11 bool in_conventional_range() const NOEXCEPT
3703  {
3704  using namespace std::chrono;
3705  return s_ < minutes{1};
3706  }
3707 
3708  template <class CharT, class Traits>
3709  friend
3710  std::basic_ostream<CharT, Traits>&
3711  operator<<(std::basic_ostream<CharT, Traits>& os, const decimal_format_seconds& x)
3712  {
3714  os.fill('0');
3715  os.flags(std::ios::dec | std::ios::right);
3716  os.width(2);
3717  os << x.s_.count();
3718  return os;
3719  }
3720 };
3721 
3722 enum class classify
3723 {
3724  not_valid,
3725  hour,
3726  minute,
3727  second,
3728  subsecond
3729 };
3730 
3731 template <class Duration>
3733 {
3734  static CONSTDATA classify value =
3735  std::is_convertible<Duration, std::chrono::hours>::value
3736  ? classify::hour :
3737  std::is_convertible<Duration, std::chrono::minutes>::value
3738  ? classify::minute :
3739  std::is_convertible<Duration, std::chrono::seconds>::value
3740  ? classify::second :
3741  std::chrono::treat_as_floating_point<typename Duration::rep>::value
3742  ? classify::not_valid :
3743  classify::subsecond;
3744 };
3745 
3746 template <class Rep, class Period>
3747 inline
3748 CONSTCD11
3749 typename std::enable_if
3750  <
3752  std::chrono::duration<Rep, Period>
3753  >::type
3754 abs(std::chrono::duration<Rep, Period> d)
3755 {
3756  return d >= d.zero() ? d : -d;
3757 }
3758 
3759 template <class Rep, class Period>
3760 inline
3761 CONSTCD11
3762 typename std::enable_if
3763  <
3764  !std::numeric_limits<Rep>::is_signed,
3765  std::chrono::duration<Rep, Period>
3766  >::type
3767 abs(std::chrono::duration<Rep, Period> d)
3768 {
3769  return d;
3770 }
3771 
3773 {
3774 protected:
3775  std::chrono::hours h_;
3776  unsigned char mode_;
3777  bool neg_;
3778 
3779  enum {is24hr};
3780 
3782  : h_(0)
3783  , mode_(static_cast<decltype(mode_)>(is24hr))
3784  , neg_(false)
3785  {}
3786 
3787 
3788  CONSTCD11 time_of_day_base(std::chrono::hours h, bool neg, unsigned m) NOEXCEPT
3789  : h_(detail::abs(h))
3790  , mode_(static_cast<decltype(mode_)>(m))
3791  , neg_(neg)
3792  {}
3793 
3794  CONSTCD14 void make24() NOEXCEPT;
3795  CONSTCD14 void make12() NOEXCEPT;
3796 
3797  CONSTCD14 std::chrono::hours to24hr() const;
3798 
3799  CONSTCD11 bool in_conventional_range() const NOEXCEPT
3800  {
3801  return !neg_ && h_ < days{1};
3802  }
3803 };
3804 
3805 CONSTCD14
3806 inline
3807 std::chrono::hours
3808 time_of_day_base::to24hr() const
3809 {
3810  auto h = h_;
3811  if (mode_ == am || mode_ == pm)
3812  {
3813  CONSTDATA auto h12 = std::chrono::hours(12);
3814  if (mode_ == pm)
3815  {
3816  if (h != h12)
3817  h = h + h12;
3818  }
3819  else if (h == h12)
3820  h = std::chrono::hours(0);
3821  }
3822  return h;
3823 }
3824 
3825 CONSTCD14
3826 inline
3827 void
3828 time_of_day_base::make24() NOEXCEPT
3829 {
3830  h_ = to24hr();
3831  mode_ = is24hr;
3832 }
3833 
3834 CONSTCD14
3835 inline
3836 void
3837 time_of_day_base::make12() NOEXCEPT
3838 {
3839  if (mode_ == is24hr)
3840  {
3841  CONSTDATA auto h12 = std::chrono::hours(12);
3842  if (h_ >= h12)
3843  {
3844  if (h_ > h12)
3845  h_ = h_ - h12;
3846  mode_ = pm;
3847  }
3848  else
3849  {
3850  if (h_ == std::chrono::hours(0))
3851  h_ = h12;
3852  mode_ = am;
3853  }
3854  }
3855 }
3856 
3857 template <class Duration, detail::classify = detail::classify_duration<Duration>::value>
3859 
3860 template <class Rep, class Period>
3861 class time_of_day_storage<std::chrono::duration<Rep, Period>, detail::classify::hour>
3862  : private detail::time_of_day_base
3863 {
3865 
3866 public:
3867  using precision = std::chrono::hours;
3868 
3869 #if !defined(_MSC_VER) || _MSC_VER >= 1900
3870  CONSTCD11 time_of_day_storage() NOEXCEPT = default;
3871 #else
3872  CONSTCD11 time_of_day_storage() = default;
3873 #endif /* !defined(_MSC_VER) || _MSC_VER >= 1900 */
3874 
3875  CONSTCD11 explicit time_of_day_storage(std::chrono::hours since_midnight) NOEXCEPT
3876  : base(since_midnight, since_midnight < std::chrono::hours{0}, is24hr)
3877  {}
3878 
3879  CONSTCD11 explicit time_of_day_storage(std::chrono::hours h, unsigned md) NOEXCEPT
3880  : base(h, h < std::chrono::hours{0}, md)
3881  {}
3882 
3883  CONSTCD11 std::chrono::hours hours() const NOEXCEPT {return h_;}
3884  CONSTCD11 unsigned mode() const NOEXCEPT {return mode_;}
3885 
3886  CONSTCD14 explicit operator precision() const NOEXCEPT
3887  {
3888  auto p = to24hr();
3889  if (neg_)
3890  p = -p;
3891  return p;
3892  }
3893 
3895  {
3896  return static_cast<precision>(*this);
3897  }
3898 
3899  CONSTCD14 time_of_day_storage& make24() NOEXCEPT {base::make24(); return *this;}
3900  CONSTCD14 time_of_day_storage& make12() NOEXCEPT {base::make12(); return *this;}
3901 
3902  CONSTCD11 bool in_conventional_range() const NOEXCEPT
3903  {
3904  return base::in_conventional_range();
3905  }
3906 
3907  template<class CharT, class Traits>
3908  friend
3909  std::basic_ostream<CharT, Traits>&
3910  operator<<(std::basic_ostream<CharT, Traits>& os, const time_of_day_storage& t)
3911  {
3912  using namespace std;
3914  if (t.neg_)
3915  os << '-';
3916  os.fill('0');
3917  os.flags(std::ios::dec | std::ios::right);
3918  if (t.mode_ != am && t.mode_ != pm)
3919  os.width(2);
3920  os << t.h_.count();
3921  switch (t.mode_)
3922  {
3923  case time_of_day_storage::is24hr:
3924  os << "00";
3925  break;
3926  case am:
3927  os << "am";
3928  break;
3929  case pm:
3930  os << "pm";
3931  break;
3932  }
3933  return os;
3934  }
3935 };
3936 
3937 template <class Rep, class Period>
3938 class time_of_day_storage<std::chrono::duration<Rep, Period>, detail::classify::minute>
3939  : private detail::time_of_day_base
3940 {
3942 
3943  std::chrono::minutes m_;
3944 
3945 public:
3946  using precision = std::chrono::minutes;
3947 
3949  : base()
3950  , m_(0)
3951  {}
3952 
3953  CONSTCD11 explicit time_of_day_storage(std::chrono::minutes since_midnight) NOEXCEPT
3954  : base(std::chrono::duration_cast<std::chrono::hours>(since_midnight),
3955  since_midnight < std::chrono::minutes{0}, is24hr)
3956  , m_(detail::abs(since_midnight) - h_)
3957  {}
3958 
3959  CONSTCD11 explicit time_of_day_storage(std::chrono::hours h, std::chrono::minutes m,
3960  unsigned md) NOEXCEPT
3961  : base(h, false, md)
3962  , m_(m)
3963  {}
3964 
3965  CONSTCD11 std::chrono::hours hours() const NOEXCEPT {return h_;}
3966  CONSTCD11 std::chrono::minutes minutes() const NOEXCEPT {return m_;}
3967  CONSTCD11 unsigned mode() const NOEXCEPT {return mode_;}
3968 
3969  CONSTCD14 explicit operator precision() const NOEXCEPT
3970  {
3971  auto p = to24hr() + m_;
3972  if (neg_)
3973  p = -p;
3974  return p;
3975  }
3976 
3978  {
3979  return static_cast<precision>(*this);
3980  }
3981 
3982  CONSTCD14 time_of_day_storage& make24() NOEXCEPT {base::make24(); return *this;}
3983  CONSTCD14 time_of_day_storage& make12() NOEXCEPT {base::make12(); return *this;}
3984 
3985  CONSTCD11 bool in_conventional_range() const NOEXCEPT
3986  {
3987  return base::in_conventional_range() && m_ < std::chrono::hours{1};
3988  }
3989 
3990  template<class CharT, class Traits>
3991  friend
3992  std::basic_ostream<CharT, Traits>&
3993  operator<<(std::basic_ostream<CharT, Traits>& os, const time_of_day_storage& t)
3994  {
3995  using namespace std;
3997  if (t.neg_)
3998  os << '-';
3999  os.fill('0');
4000  os.flags(std::ios::dec | std::ios::right);
4001  if (t.mode_ != am && t.mode_ != pm)
4002  os.width(2);
4003  os << t.h_.count() << ':';
4004  os.width(2);
4005  os << t.m_.count();
4006  switch (t.mode_)
4007  {
4008  case am:
4009  os << "am";
4010  break;
4011  case pm:
4012  os << "pm";
4013  break;
4014  }
4015  return os;
4016  }
4017 };
4018 
4019 template <class Rep, class Period>
4020 class time_of_day_storage<std::chrono::duration<Rep, Period>, detail::classify::second>
4021  : private detail::time_of_day_base
4022 {
4025 
4026  std::chrono::minutes m_;
4028 
4029 public:
4030  using precision = std::chrono::seconds;
4031 
4033  : base()
4034  , m_(0)
4035  , s_()
4036  {}
4037 
4038  CONSTCD11 explicit time_of_day_storage(std::chrono::seconds since_midnight) NOEXCEPT
4039  : base(std::chrono::duration_cast<std::chrono::hours>(since_midnight),
4040  since_midnight < std::chrono::seconds{0}, is24hr)
4041  , m_(std::chrono::duration_cast<std::chrono::minutes>(detail::abs(since_midnight) - h_))
4042  , s_(detail::abs(since_midnight) - h_ - m_)
4043  {}
4044 
4045  CONSTCD11 explicit time_of_day_storage(std::chrono::hours h, std::chrono::minutes m,
4046  std::chrono::seconds s, unsigned md) NOEXCEPT
4047  : base(h, false, md)
4048  , m_(m)
4049  , s_(s)
4050  {}
4051 
4052  CONSTCD11 std::chrono::hours hours() const NOEXCEPT {return h_;}
4053  CONSTCD11 std::chrono::minutes minutes() const NOEXCEPT {return m_;}
4054  CONSTCD14 std::chrono::seconds& seconds() NOEXCEPT {return s_.seconds();}
4055  CONSTCD11 std::chrono::seconds seconds() const NOEXCEPT {return s_.seconds();}
4056  CONSTCD11 unsigned mode() const NOEXCEPT {return mode_;}
4057 
4058  CONSTCD14 explicit operator precision() const NOEXCEPT
4059  {
4060  auto p = to24hr() + s_.to_duration() + m_;
4061  if (neg_)
4062  p = -p;
4063  return p;
4064  }
4065 
4067  {
4068  return static_cast<precision>(*this);
4069  }
4070 
4071  CONSTCD14 time_of_day_storage& make24() NOEXCEPT {base::make24(); return *this;}
4072  CONSTCD14 time_of_day_storage& make12() NOEXCEPT {base::make12(); return *this;}
4073 
4074  CONSTCD11 bool in_conventional_range() const NOEXCEPT
4075  {
4076  return base::in_conventional_range() && m_ < std::chrono::hours{1} &&
4077  s_.in_conventional_range();
4078  }
4079 
4080  template<class CharT, class Traits>
4081  friend
4082  std::basic_ostream<CharT, Traits>&
4083  operator<<(std::basic_ostream<CharT, Traits>& os, const time_of_day_storage& t)
4084  {
4085  using namespace std;
4087  if (t.neg_)
4088  os << '-';
4089  os.fill('0');
4090  os.flags(std::ios::dec | std::ios::right);
4091  if (t.mode_ != am && t.mode_ != pm)
4092  os.width(2);
4093  os << t.h_.count() << ':';
4094  os.width(2);
4095  os << t.m_.count() << ':' << t.s_;
4096  switch (t.mode_)
4097  {
4098  case am:
4099  os << "am";
4100  break;
4101  case pm:
4102  os << "pm";
4103  break;
4104  }
4105  return os;
4106  }
4107 
4108  template <class CharT, class Traits, class Duration>
4109  friend
4110  std::basic_ostream<CharT, Traits>&
4111  date::to_stream(std::basic_ostream<CharT, Traits>& os, const CharT* fmt,
4112  const fields<Duration>& fds, const std::string* abbrev,
4113  const std::chrono::seconds* offset_sec);
4114 
4115  template <class CharT, class Traits, class Duration, class Alloc>
4116  friend
4117  std::basic_istream<CharT, Traits>&
4118  date::from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
4119  fields<Duration>& fds,
4120  std::basic_string<CharT, Traits, Alloc>* abbrev, std::chrono::minutes* offset);
4121 };
4122 
4123 template <class Rep, class Period>
4124 class time_of_day_storage<std::chrono::duration<Rep, Period>, detail::classify::subsecond>
4125  : private detail::time_of_day_base
4126 {
4127 public:
4128  using Duration = std::chrono::duration<Rep, Period>;
4129  using dfs = decimal_format_seconds<typename std::common_type<Duration,
4130  std::chrono::seconds>::type>;
4131  using precision = typename dfs::precision;
4132 
4133 private:
4135 
4136  std::chrono::minutes m_;
4138 
4139 public:
4141  : base()
4142  , m_(0)
4143  , s_()
4144  {}
4145 
4146  CONSTCD11 explicit time_of_day_storage(Duration since_midnight) NOEXCEPT
4147  : base(date::trunc<std::chrono::hours>(since_midnight),
4148  since_midnight < Duration{0}, is24hr)
4149  , m_(date::trunc<std::chrono::minutes>(detail::abs(since_midnight) - h_))
4150  , s_(detail::abs(since_midnight) - h_ - m_)
4151  {}
4152 
4153  CONSTCD11 explicit time_of_day_storage(std::chrono::hours h, std::chrono::minutes m,
4154  std::chrono::seconds s, precision sub_s,
4155  unsigned md) NOEXCEPT
4156  : base(h, false, md)
4157  , m_(m)
4158  , s_(s + sub_s)
4159  {}
4160 
4161  CONSTCD11 std::chrono::hours hours() const NOEXCEPT {return h_;}
4162  CONSTCD11 std::chrono::minutes minutes() const NOEXCEPT {return m_;}
4163  CONSTCD14 std::chrono::seconds& seconds() NOEXCEPT {return s_.seconds();}
4164  CONSTCD11 std::chrono::seconds seconds() const NOEXCEPT {return s_.seconds();}
4165  CONSTCD11 precision subseconds() const NOEXCEPT {return s_.subseconds();}
4166  CONSTCD11 unsigned mode() const NOEXCEPT {return mode_;}
4167 
4168  CONSTCD14 explicit operator precision() const NOEXCEPT
4169  {
4170  auto p = to24hr() + s_.to_duration() + m_;
4171  if (neg_)
4172  p = -p;
4173  return p;
4174  }
4175 
4177  {
4178  return static_cast<precision>(*this);
4179  }
4180 
4181  CONSTCD14 time_of_day_storage& make24() NOEXCEPT {base::make24(); return *this;}
4182  CONSTCD14 time_of_day_storage& make12() NOEXCEPT {base::make12(); return *this;}
4183 
4184  CONSTCD11 bool in_conventional_range() const NOEXCEPT
4185  {
4186  return base::in_conventional_range() && m_ < std::chrono::hours{1} &&
4187  s_.in_conventional_range();
4188  }
4189 
4190  template<class CharT, class Traits>
4191  friend
4192  std::basic_ostream<CharT, Traits>&
4193  operator<<(std::basic_ostream<CharT, Traits>& os, const time_of_day_storage& t)
4194  {
4195  using namespace std;
4197  if (t.neg_)
4198  os << '-';
4199  os.fill('0');
4200  os.flags(std::ios::dec | std::ios::right);
4201  if (t.mode_ != am && t.mode_ != pm)
4202  os.width(2);
4203  os << t.h_.count() << ':';
4204  os.width(2);
4205  os << t.m_.count() << ':' << t.s_;
4206  switch (t.mode_)
4207  {
4208  case am:
4209  os << "am";
4210  break;
4211  case pm:
4212  os << "pm";
4213  break;
4214  }
4215  return os;
4216  }
4217 
4218  template <class CharT, class Traits, class Duration>
4219  friend
4220  std::basic_ostream<CharT, Traits>&
4221  date::to_stream(std::basic_ostream<CharT, Traits>& os, const CharT* fmt,
4222  const fields<Duration>& fds, const std::string* abbrev,
4223  const std::chrono::seconds* offset_sec);
4224 
4225  template <class CharT, class Traits, class Duration, class Alloc>
4226  friend
4227  std::basic_istream<CharT, Traits>&
4228  date::from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
4229  fields<Duration>& fds,
4230  std::basic_string<CharT, Traits, Alloc>* abbrev, std::chrono::minutes* offset);
4231 };
4232 
4233 } // namespace detail
4234 
4235 template <class Duration>
4237  : public detail::time_of_day_storage<Duration>
4238 {
4240 public:
4241 #if !defined(_MSC_VER) || _MSC_VER >= 1900
4242  CONSTCD11 time_of_day() NOEXCEPT = default;
4243 #else
4244  CONSTCD11 time_of_day() = default;
4245 #endif /* !defined(_MSC_VER) || _MSC_VER >= 1900 */
4246 
4247  CONSTCD11 explicit time_of_day(Duration since_midnight) NOEXCEPT
4248  : base(since_midnight)
4249  {}
4250 
4251  template <class Arg0, class Arg1, class ...Args>
4252  CONSTCD11
4253  explicit time_of_day(Arg0&& arg0, Arg1&& arg1, Args&& ...args) NOEXCEPT
4254  : base(std::forward<Arg0>(arg0), std::forward<Arg1>(arg1), std::forward<Args>(args)...)
4255  {}
4256 };
4257 
4258 template <class Rep, class Period,
4259  class = typename std::enable_if
4260  <!std::chrono::treat_as_floating_point<Rep>::value>::type>
4261 CONSTCD11
4262 inline
4264 make_time(const std::chrono::duration<Rep, Period>& d)
4265 {
4267 }
4268 
4269 CONSTCD11
4270 inline
4272 make_time(const std::chrono::hours& h, unsigned md)
4273 {
4274  return time_of_day<std::chrono::hours>(h, md);
4275 }
4276 
4277 CONSTCD11
4278 inline
4280 make_time(const std::chrono::hours& h, const std::chrono::minutes& m,
4281  unsigned md)
4282 {
4283  return time_of_day<std::chrono::minutes>(h, m, md);
4284 }
4285 
4286 CONSTCD11
4287 inline
4289 make_time(const std::chrono::hours& h, const std::chrono::minutes& m,
4290  const std::chrono::seconds& s, unsigned md)
4291 {
4292  return time_of_day<std::chrono::seconds>(h, m, s, md);
4293 }
4294 
4295 template <class Rep, class Period,
4296  class = typename std::enable_if<std::ratio_less<Period,
4297  std::ratio<1>>::value>::type>
4298 CONSTCD11
4299 inline
4301 make_time(const std::chrono::hours& h, const std::chrono::minutes& m,
4302  const std::chrono::seconds& s, const std::chrono::duration<Rep, Period>& sub_s,
4303  unsigned md)
4304 {
4305  return time_of_day<std::chrono::duration<Rep, Period>>(h, m, s, sub_s, md);
4306 }
4307 
4308 template <class CharT, class Traits, class Duration>
4309 inline
4310 typename std::enable_if
4311 <
4312  !std::chrono::treat_as_floating_point<typename Duration::rep>::value &&
4313  std::ratio_less<typename Duration::period, days::period>::value
4314  , std::basic_ostream<CharT, Traits>&
4315 >::type
4316 operator<<(std::basic_ostream<CharT, Traits>& os, const sys_time<Duration>& tp)
4317 {
4318  auto const dp = date::floor<days>(tp);
4319  return os << year_month_day(dp) << ' ' << make_time(tp-dp);
4320 }
4321 
4322 template <class CharT, class Traits>
4323 inline
4324 std::basic_ostream<CharT, Traits>&
4325 operator<<(std::basic_ostream<CharT, Traits>& os, const sys_days& dp)
4326 {
4327  return os << year_month_day(dp);
4328 }
4329 
4330 template <class CharT, class Traits, class Duration>
4331 inline
4332 std::basic_ostream<CharT, Traits>&
4333 operator<<(std::basic_ostream<CharT, Traits>& os, const local_time<Duration>& ut)
4334 {
4335  return (os << sys_time<Duration>{ut.time_since_epoch()});
4336 }
4337 
4338 // to_stream
4339 
4340 template <class Duration>
4341 struct fields
4342 {
4343  year_month_day ymd{year{0}/0/0};
4344  weekday wd{7u};
4346 
4347  fields() = default;
4348 
4349  fields(year_month_day ymd_) : ymd(ymd_) {}
4350  fields(weekday wd_) : wd(wd_) {}
4351  fields(time_of_day<Duration> tod_) : tod(tod_) {}
4352 
4353  fields(year_month_day ymd_, weekday wd_) : ymd(ymd_), wd(wd_) {}
4354  fields(year_month_day ymd_, time_of_day<Duration> tod_) : ymd(ymd_), tod(tod_) {}
4355 
4356  fields(weekday wd_, time_of_day<Duration> tod_) : wd(wd_), tod(tod_) {}
4357 
4358  fields(year_month_day ymd_, weekday wd_, time_of_day<Duration> tod_)
4359  : ymd(ymd_)
4360  , wd(wd_)
4361  , tod(tod_)
4362  {}
4363 };
4364 
4365 namespace detail
4366 {
4367 
4368 template <class CharT, class Traits, class Duration>
4369 unsigned
4370 extract_weekday(std::basic_ostream<CharT, Traits>& os, const fields<Duration>& fds)
4371 {
4372  if (!fds.ymd.ok() && !fds.wd.ok())
4373  {
4374  // fds does not contain a valid weekday
4375  os.setstate(std::ios::failbit);
4376  return 7;
4377  }
4378  unsigned wd;
4379  if (fds.ymd.ok())
4380  {
4381  wd = static_cast<unsigned>(weekday{fds.ymd});
4382  if (fds.wd.ok() && wd != static_cast<unsigned>(fds.wd))
4383  {
4384  // fds.ymd and fds.wd are inconsistent
4385  os.setstate(std::ios::failbit);
4386  return 7;
4387  }
4388  }
4389  else
4390  wd = static_cast<unsigned>(fds.wd);
4391  return wd;
4392 }
4393 
4394 template <class CharT, class Traits, class Duration>
4395 unsigned
4396 extract_month(std::basic_ostream<CharT, Traits>& os, const fields<Duration>& fds)
4397 {
4398  if (!fds.ymd.month().ok())
4399  {
4400  // fds does not contain a valid month
4401  os.setstate(std::ios::failbit);
4402  return 0;
4403  }
4404  return static_cast<unsigned>(fds.ymd.month());
4405 }
4406 
4407 } // namespace detail
4408 
4409 #if ONLY_C_LOCALE
4410 
4411 namespace detail
4412 {
4413 
4414 inline
4415 std::pair<const std::string*, const std::string*>
4416 weekday_names()
4417 {
4418  using namespace std;
4419  static const string nm[] =
4420  {
4421  "Sunday",
4422  "Monday",
4423  "Tuesday",
4424  "Wednesday",
4425  "Thursday",
4426  "Friday",
4427  "Saturday",
4428  "Sun",
4429  "Mon",
4430  "Tue",
4431  "Wed",
4432  "Thu",
4433  "Fri",
4434  "Sat"
4435  };
4436  return make_pair(nm, nm+sizeof(nm)/sizeof(nm[0]));
4437 }
4438 
4439 inline
4440 std::pair<const std::string*, const std::string*>
4441 month_names()
4442 {
4443  using namespace std;
4444  static const string nm[] =
4445  {
4446  "January",
4447  "February",
4448  "March",
4449  "April",
4450  "May",
4451  "June",
4452  "July",
4453  "August",
4454  "September",
4455  "October",
4456  "November",
4457  "December",
4458  "Jan",
4459  "Feb",
4460  "Mar",
4461  "Apr",
4462  "May",
4463  "Jun",
4464  "Jul",
4465  "Aug",
4466  "Sep",
4467  "Oct",
4468  "Nov",
4469  "Dec"
4470  };
4471  return make_pair(nm, nm+sizeof(nm)/sizeof(nm[0]));
4472 }
4473 
4474 inline
4475 std::pair<const std::string*, const std::string*>
4476 ampm_names()
4477 {
4478  using namespace std;
4479  static const string nm[] =
4480  {
4481  "AM",
4482  "PM"
4483  };
4484  return make_pair(nm, nm+sizeof(nm)/sizeof(nm[0]));
4485 }
4486 
4487 template <class CharT, class Traits, class FwdIter>
4488 FwdIter
4489 scan_keyword(std::basic_istream<CharT, Traits>& is, FwdIter kb, FwdIter ke)
4490 {
4491  using namespace std;
4492  size_t nkw = static_cast<size_t>(std::distance(kb, ke));
4493  const unsigned char doesnt_match = '\0';
4494  const unsigned char might_match = '\1';
4495  const unsigned char does_match = '\2';
4496  unsigned char statbuf[100];
4497  unsigned char* status = statbuf;
4498  unique_ptr<unsigned char, void(*)(void*)> stat_hold(0, free);
4499  if (nkw > sizeof(statbuf))
4500  {
4501  status = (unsigned char*)malloc(nkw);
4502  if (status == nullptr)
4503  throw bad_alloc();
4504  stat_hold.reset(status);
4505  }
4506  size_t n_might_match = nkw; // At this point, any keyword might match
4507  size_t n_does_match = 0; // but none of them definitely do
4508  // Initialize all statuses to might_match, except for "" keywords are does_match
4509  unsigned char* st = status;
4510  for (auto ky = kb; ky != ke; ++ky, ++st)
4511  {
4512  if (!ky->empty())
4513  *st = might_match;
4514  else
4515  {
4516  *st = does_match;
4517  --n_might_match;
4518  ++n_does_match;
4519  }
4520  }
4521  // While there might be a match, test keywords against the next CharT
4522  for (size_t indx = 0; is && n_might_match > 0; ++indx)
4523  {
4524  // Peek at the next CharT but don't consume it
4525  auto ic = is.peek();
4526  if (ic == EOF)
4527  {
4528  is.setstate(ios::eofbit);
4529  break;
4530  }
4531  auto c = static_cast<char>(toupper(ic));
4532  bool consume = false;
4533  // For each keyword which might match, see if the indx character is c
4534  // If a match if found, consume c
4535  // If a match is found, and that is the last character in the keyword,
4536  // then that keyword matches.
4537  // If the keyword doesn't match this character, then change the keyword
4538  // to doesn't match
4539  st = status;
4540  for (auto ky = kb; ky != ke; ++ky, ++st)
4541  {
4542  if (*st == might_match)
4543  {
4544  if (c == static_cast<char>(toupper((*ky)[indx])))
4545  {
4546  consume = true;
4547  if (ky->size() == indx+1)
4548  {
4549  *st = does_match;
4550  --n_might_match;
4551  ++n_does_match;
4552  }
4553  }
4554  else
4555  {
4556  *st = doesnt_match;
4557  --n_might_match;
4558  }
4559  }
4560  }
4561  // consume if we matched a character
4562  if (consume)
4563  {
4564  (void)is.get();
4565  // If we consumed a character and there might be a matched keyword that
4566  // was marked matched on a previous iteration, then such keywords
4567  // are now marked as not matching.
4568  if (n_might_match + n_does_match > 1)
4569  {
4570  st = status;
4571  for (auto ky = kb; ky != ke; ++ky, ++st)
4572  {
4573  if (*st == does_match && ky->size() != indx+1)
4574  {
4575  *st = doesnt_match;
4576  --n_does_match;
4577  }
4578  }
4579  }
4580  }
4581  }
4582  // We've exited the loop because we hit eof and/or we have no more "might matches".
4583  // Return the first matching result
4584  for (st = status; kb != ke; ++kb, ++st)
4585  if (*st == does_match)
4586  break;
4587  if (kb == ke)
4588  is.setstate(ios_base::failbit);
4589  return kb;
4590 }
4591 
4592 } // namespace detail
4593 
4594 #endif // ONLY_C_LOCALE
4595 
4596 template <class CharT, class Traits, class Duration>
4597 std::basic_ostream<CharT, Traits>&
4598 to_stream(std::basic_ostream<CharT, Traits>& os, const CharT* fmt,
4599  const fields<Duration>& fds, const std::string* abbrev,
4600  const std::chrono::seconds* offset_sec)
4601 {
4602  using namespace std;
4603  using namespace std::chrono;
4604  using namespace detail;
4605  tm tm{};
4606 #if !ONLY_C_LOCALE
4607  auto& facet = use_facet<time_put<CharT>>(os.getloc());
4608 #endif
4609  const CharT* command = nullptr;
4610  CharT modified = CharT{};
4611  for (; *fmt; ++fmt)
4612  {
4613  switch (*fmt)
4614  {
4615  case 'a':
4616  case 'A':
4617  if (command)
4618  {
4619  if (modified == CharT{})
4620  {
4621  tm.tm_wday = static_cast<int>(extract_weekday(os, fds));
4622  if (os.fail())
4623  return os;
4624 #if !ONLY_C_LOCALE
4625  const CharT f[] = {'%', *fmt};
4626  facet.put(os, os, os.fill(), &tm, begin(f), end(f));
4627 #else // ONLY_C_LOCALE
4628  os << weekday_names().first[tm.tm_wday+7*(*fmt == 'a')];
4629 #endif // ONLY_C_LOCALE
4630  }
4631  else
4632  {
4633  os << CharT{'%'} << modified << *fmt;
4634  modified = CharT{};
4635  }
4636  command = nullptr;
4637  }
4638  else
4639  os << *fmt;
4640  break;
4641  case 'b':
4642  case 'B':
4643  case 'h':
4644  if (command)
4645  {
4646  if (modified == CharT{})
4647  {
4648  tm.tm_mon = static_cast<int>(extract_month(os, fds)) - 1;
4649 #if !ONLY_C_LOCALE
4650  const CharT f[] = {'%', *fmt};
4651  facet.put(os, os, os.fill(), &tm, begin(f), end(f));
4652 #else // ONLY_C_LOCALE
4653  os << month_names().first[tm.tm_mon+12*(*fmt == 'b')];
4654 #endif // ONLY_C_LOCALE
4655  }
4656  else
4657  {
4658  os << CharT{'%'} << modified << *fmt;
4659  modified = CharT{};
4660  }
4661  command = nullptr;
4662  }
4663  else
4664  os << *fmt;
4665  break;
4666  case 'c':
4667  case 'x':
4668  if (command)
4669  {
4670  if (modified == CharT{'O'})
4671  os << CharT{'%'} << modified << *fmt;
4672  else
4673  {
4674 #if !ONLY_C_LOCALE
4675  tm = std::tm{};
4676  auto const& ymd = fds.ymd;
4677  auto ld = local_days(ymd);
4678  tm.tm_sec = static_cast<int>(fds.tod.seconds().count());
4679  tm.tm_min = static_cast<int>(fds.tod.minutes().count());
4680  tm.tm_hour = static_cast<int>(fds.tod.hours().count());
4681  tm.tm_mday = static_cast<int>(static_cast<unsigned>(ymd.day()));
4682  tm.tm_mon = static_cast<int>(extract_month(os, fds) - 1);
4683  tm.tm_year = static_cast<int>(ymd.year()) - 1900;
4684  tm.tm_wday = static_cast<int>(extract_weekday(os, fds));
4685  if (os.fail())
4686  return os;
4687  tm.tm_yday = static_cast<int>((ld - local_days(ymd.year()/1/1)).count());
4688  CharT f[3] = {'%'};
4689  auto fe = begin(f) + 1;
4690  if (modified == CharT{'E'})
4691  *fe++ = modified;
4692  *fe++ = *fmt;
4693  facet.put(os, os, os.fill(), &tm, begin(f), fe);
4694 #else // ONLY_C_LOCALE
4695  if (*fmt == 'c')
4696  {
4697  auto wd = static_cast<int>(extract_weekday(os, fds));
4698  os << weekday_names().first[static_cast<unsigned>(wd)+7]
4699  << ' ';
4700  os << month_names().first[extract_month(os, fds)-1+12] << ' ';
4701  auto d = static_cast<int>(static_cast<unsigned>(fds.ymd.day()));
4702  if (d < 10)
4703  os << ' ';
4704  os << d << ' '
4705  << make_time(duration_cast<seconds>(fds.tod.to_duration()))
4706  << ' ' << fds.ymd.year();
4707 
4708  }
4709  else // *fmt == 'x'
4710  {
4711  auto const& ymd = fds.ymd;
4712  save_stream<CharT, Traits> _(os);
4713  os.fill('0');
4714  os.flags(std::ios::dec | std::ios::right);
4715  os.width(2);
4716  os << static_cast<unsigned>(ymd.month()) << CharT{'/'};
4717  os.width(2);
4718  os << static_cast<unsigned>(ymd.day()) << CharT{'/'};
4719  os.width(2);
4720  os << static_cast<int>(ymd.year()) % 100;
4721  }
4722 #endif // ONLY_C_LOCALE
4723  }
4724  command = nullptr;
4725  modified = CharT{};
4726  }
4727  else
4728  os << *fmt;
4729  break;
4730  case 'C':
4731  if (command)
4732  {
4733  auto y = static_cast<int>(fds.ymd.year());
4734 #if !ONLY_C_LOCALE
4735  if (modified == CharT{})
4736  {
4737 #endif
4738  save_stream<CharT, Traits> _(os);
4739  os.fill('0');
4740  os.flags(std::ios::dec | std::ios::right);
4741  if (y >= 0)
4742  {
4743  os.width(2);
4744  os << y/100;
4745  }
4746  else
4747  {
4748  os << CharT{'-'};
4749  os.width(2);
4750  os << -(y-99)/100;
4751  }
4752 #if !ONLY_C_LOCALE
4753  }
4754  else if (modified == CharT{'E'})
4755  {
4756  tm.tm_year = y - 1900;
4757  CharT f[3] = {'%', 'E', 'C'};
4758  facet.put(os, os, os.fill(), &tm, begin(f), end(f));
4759  }
4760  else
4761  {
4762  os << CharT{'%'} << modified << *fmt;
4763  }
4764 #endif
4765  command = nullptr;
4766  modified = CharT{};
4767  }
4768  else
4769  os << *fmt;
4770  break;
4771  case 'd':
4772  case 'e':
4773  if (command)
4774  {
4775  auto d = static_cast<int>(static_cast<unsigned>(fds.ymd.day()));
4776 #if !ONLY_C_LOCALE
4777  if (modified == CharT{})
4778  {
4779 #endif
4780  save_stream<CharT, Traits> _(os);
4781  if (*fmt == CharT{'d'})
4782  os.fill('0');
4783  os.flags(std::ios::dec | std::ios::right);
4784  os.width(2);
4785  os << d;
4786 #if !ONLY_C_LOCALE
4787  }
4788  else if (modified == CharT{'O'})
4789  {
4790  tm.tm_mday = d;
4791  CharT f[3] = {'%', 'O', *fmt};
4792  facet.put(os, os, os.fill(), &tm, begin(f), end(f));
4793  }
4794  else
4795  {
4796  os << CharT{'%'} << modified << *fmt;
4797  }
4798 #endif
4799  command = nullptr;
4800  modified = CharT{};
4801  }
4802  else
4803  os << *fmt;
4804  break;
4805  case 'D':
4806  if (command)
4807  {
4808  if (modified == CharT{})
4809  {
4810  auto const& ymd = fds.ymd;
4811  save_stream<CharT, Traits> _(os);
4812  os.fill('0');
4813  os.flags(std::ios::dec | std::ios::right);
4814  os.width(2);
4815  os << static_cast<unsigned>(ymd.month()) << CharT{'/'};
4816  os.width(2);
4817  os << static_cast<unsigned>(ymd.day()) << CharT{'/'};
4818  os.width(2);
4819  os << static_cast<int>(ymd.year()) % 100;
4820  }
4821  else
4822  {
4823  os << CharT{'%'} << modified << *fmt;
4824  modified = CharT{};
4825  }
4826  command = nullptr;
4827  }
4828  else
4829  os << *fmt;
4830  break;
4831  case 'F':
4832  if (command)
4833  {
4834  if (modified == CharT{})
4835  {
4836  auto const& ymd = fds.ymd;
4837  save_stream<CharT, Traits> _(os);
4838  os.fill('0');
4839  os.flags(std::ios::dec | std::ios::right);
4840  os.width(4);
4841  os << static_cast<int>(ymd.year()) << CharT{'-'};
4842  os.width(2);
4843  os << static_cast<unsigned>(ymd.month()) << CharT{'-'};
4844  os.width(2);
4845  os << static_cast<unsigned>(ymd.day());
4846  }
4847  else
4848  {
4849  os << CharT{'%'} << modified << *fmt;
4850  modified = CharT{};
4851  }
4852  command = nullptr;
4853  }
4854  else
4855  os << *fmt;
4856  break;
4857  case 'g':
4858  case 'G':
4859  if (command)
4860  {
4861  if (modified == CharT{})
4862  {
4863  auto ld = local_days(fds.ymd);
4864  auto y = year_month_day{ld + days{3}}.year();
4865  auto start = local_days((y - years{1})/date::dec/thu[last]) + (mon-thu);
4866  if (ld < start)
4867  --y;
4868  if (*fmt == CharT{'G'})
4869  os << y;
4870  else
4871  {
4872  save_stream<CharT, Traits> _(os);
4873  os.fill('0');
4874  os.flags(std::ios::dec | std::ios::right);
4875  os.width(2);
4876  os << std::abs(static_cast<int>(y)) % 100;
4877  }
4878  }
4879  else
4880  {
4881  os << CharT{'%'} << modified << *fmt;
4882  modified = CharT{};
4883  }
4884  command = nullptr;
4885  }
4886  else
4887  os << *fmt;
4888  break;
4889  case 'H':
4890  case 'I':
4891  if (command)
4892  {
4893  auto hms = fds.tod;
4894 #if !ONLY_C_LOCALE
4895  if (modified == CharT{})
4896  {
4897 #endif
4898  if (*fmt == CharT{'I'})
4899  hms.make12();
4900  if (hms.hours() < hours{10})
4901  os << CharT{'0'};
4902  os << hms.hours().count();
4903 #if !ONLY_C_LOCALE
4904  }
4905  else if (modified == CharT{'O'})
4906  {
4907  const CharT f[] = {'%', modified, *fmt};
4908  tm.tm_hour = static_cast<int>(hms.hours().count());
4909  facet.put(os, os, os.fill(), &tm, begin(f), end(f));
4910  }
4911  else
4912  {
4913  os << CharT{'%'} << modified << *fmt;
4914  }
4915 #endif
4916  modified = CharT{};
4917  command = nullptr;
4918  }
4919  else
4920  os << *fmt;
4921  break;
4922  case 'j':
4923  if (command)
4924  {
4925  if (modified == CharT{})
4926  {
4927  auto ld = local_days(fds.ymd);
4928  auto y = fds.ymd.year();
4929  auto doy = ld - local_days(y/jan/1) + days{1};
4930  save_stream<CharT, Traits> _(os);
4931  os.fill('0');
4932  os.flags(std::ios::dec | std::ios::right);
4933  os.width(3);
4934  os << doy.count();
4935  }
4936  else
4937  {
4938  os << CharT{'%'} << modified << *fmt;
4939  modified = CharT{};
4940  }
4941  command = nullptr;
4942  }
4943  else
4944  os << *fmt;
4945  break;
4946  case 'm':
4947  if (command)
4948  {
4949  auto m = static_cast<unsigned>(fds.ymd.month());
4950 #if !ONLY_C_LOCALE
4951  if (modified == CharT{})
4952  {
4953 #endif
4954  if (m < 10)
4955  os << CharT{'0'};
4956  os << m;
4957 #if !ONLY_C_LOCALE
4958  }
4959  else if (modified == CharT{'O'})
4960  {
4961  const CharT f[] = {'%', modified, *fmt};
4962  tm.tm_mon = static_cast<int>(m-1);
4963  facet.put(os, os, os.fill(), &tm, begin(f), end(f));
4964  }
4965  else
4966  {
4967  os << CharT{'%'} << modified << *fmt;
4968  }
4969 #endif
4970  modified = CharT{};
4971  command = nullptr;
4972  }
4973  else
4974  os << *fmt;
4975  break;
4976  case 'M':
4977  if (command)
4978  {
4979 #if !ONLY_C_LOCALE
4980  if (modified == CharT{})
4981  {
4982 #endif
4983  if (fds.tod.minutes() < minutes{10})
4984  os << CharT{'0'};
4985  os << fds.tod.minutes().count();
4986 #if !ONLY_C_LOCALE
4987  }
4988  else if (modified == CharT{'O'})
4989  {
4990  const CharT f[] = {'%', modified, *fmt};
4991  tm.tm_min = static_cast<int>(fds.tod.minutes().count());
4992  facet.put(os, os, os.fill(), &tm, begin(f), end(f));
4993  }
4994  else
4995  {
4996  os << CharT{'%'} << modified << *fmt;
4997  }
4998 #endif
4999  modified = CharT{};
5000  command = nullptr;
5001  }
5002  else
5003  os << *fmt;
5004  break;
5005  case 'n':
5006  if (command)
5007  {
5008  if (modified == CharT{})
5009  os << CharT{'\n'};
5010  else
5011  {
5012  os << CharT{'%'} << modified << *fmt;
5013  modified = CharT{};
5014  }
5015  command = nullptr;
5016  }
5017  else
5018  os << *fmt;
5019  break;
5020  case 'p':
5021  if (command)
5022  {
5023 #if !ONLY_C_LOCALE
5024  if (modified == CharT{})
5025  {
5026  const CharT f[] = {'%', *fmt};
5027  tm.tm_hour = static_cast<int>(fds.tod.hours().count());
5028  facet.put(os, os, os.fill(), &tm, begin(f), end(f));
5029  }
5030  else
5031  {
5032  os << CharT{'%'} << modified << *fmt;
5033  }
5034 #else
5035  if (fds.tod.hours() < hours{12})
5036  os << ampm_names().first[0];
5037  else
5038  os << ampm_names().first[1];
5039 #endif
5040  modified = CharT{};
5041  command = nullptr;
5042  }
5043  else
5044  os << *fmt;
5045  break;
5046  case 'r':
5047  if (command)
5048  {
5049 #if !ONLY_C_LOCALE
5050  if (modified == CharT{})
5051  {
5052  const CharT f[] = {'%', *fmt};
5053  tm.tm_hour = static_cast<int>(fds.tod.hours().count());
5054  tm.tm_min = static_cast<int>(fds.tod.minutes().count());
5055  tm.tm_sec = static_cast<int>(fds.tod.seconds().count());
5056  facet.put(os, os, os.fill(), &tm, begin(f), end(f));
5057  }
5058  else
5059  {
5060  os << CharT{'%'} << modified << *fmt;
5061  }
5062 #else
5063  time_of_day<seconds> tod(duration_cast<seconds>(fds.tod.to_duration()));
5064  tod.make12();
5065  save_stream<CharT, Traits> _(os);
5066  os.fill('0');
5067  os.width(2);
5068  os << tod.hours().count() << CharT{':'};
5069  os.width(2);
5070  os << tod.minutes().count() << CharT{':'};
5071  os.width(2);
5072  os << tod.seconds().count() << CharT{' '};
5073  tod.make24();
5074  if (tod.hours() < hours{12})
5075  os << ampm_names().first[0];
5076  else
5077  os << ampm_names().first[1];
5078 #endif
5079  modified = CharT{};
5080  command = nullptr;
5081  }
5082  else
5083  os << *fmt;
5084  break;
5085  case 'R':
5086  if (command)
5087  {
5088  if (modified == CharT{})
5089  {
5090  if (fds.tod.hours() < hours{10})
5091  os << CharT{'0'};
5092  os << fds.tod.hours().count() << CharT{':'};
5093  if (fds.tod.minutes() < minutes{10})
5094  os << CharT{'0'};
5095  os << fds.tod.minutes().count();
5096  }
5097  else
5098  {
5099  os << CharT{'%'} << modified << *fmt;
5100  modified = CharT{};
5101  }
5102  command = nullptr;
5103  }
5104  else
5105  os << *fmt;
5106  break;
5107  case 'S':
5108  if (command)
5109  {
5110 #if !ONLY_C_LOCALE
5111  if (modified == CharT{})
5112  {
5113 #endif
5114  os << fds.tod.s_;
5115 #if !ONLY_C_LOCALE
5116  }
5117  else if (modified == CharT{'O'})
5118  {
5119  const CharT f[] = {'%', modified, *fmt};
5120  tm.tm_sec = static_cast<int>(fds.tod.s_.seconds().count());
5121  facet.put(os, os, os.fill(), &tm, begin(f), end(f));
5122  }
5123  else
5124  {
5125  os << CharT{'%'} << modified << *fmt;
5126  }
5127 #endif
5128  modified = CharT{};
5129  command = nullptr;
5130  }
5131  else
5132  os << *fmt;
5133  break;
5134  case 't':
5135  if (command)
5136  {
5137  if (modified == CharT{})
5138  os << CharT{'\t'};
5139  else
5140  {
5141  os << CharT{'%'} << modified << *fmt;
5142  modified = CharT{};
5143  }
5144  command = nullptr;
5145  }
5146  else
5147  os << *fmt;
5148  break;
5149  case 'T':
5150  if (command)
5151  {
5152  if (modified == CharT{})
5153  {
5154  os << fds.tod;
5155  }
5156  else
5157  {
5158  os << CharT{'%'} << modified << *fmt;
5159  modified = CharT{};
5160  }
5161  command = nullptr;
5162  }
5163  else
5164  os << *fmt;
5165  break;
5166  case 'u':
5167  if (command)
5168  {
5169  auto wd = extract_weekday(os, fds);
5170  if (os.fail())
5171  return os;
5172 #if !ONLY_C_LOCALE
5173  if (modified == CharT{})
5174  {
5175 #endif
5176  os << (wd != 0 ? wd : 7u);
5177 #if !ONLY_C_LOCALE
5178  }
5179  else if (modified == CharT{'O'})
5180  {
5181  const CharT f[] = {'%', modified, *fmt};
5182  tm.tm_wday = static_cast<int>(wd);
5183  facet.put(os, os, os.fill(), &tm, begin(f), end(f));
5184  }
5185  else
5186  {
5187  os << CharT{'%'} << modified << *fmt;
5188  }
5189 #endif
5190  modified = CharT{};
5191  command = nullptr;
5192  }
5193  else
5194  os << *fmt;
5195  break;
5196  case 'U':
5197  if (command)
5198  {
5199  auto const& ymd = fds.ymd;
5200  auto ld = local_days(ymd);
5201 #if !ONLY_C_LOCALE
5202  if (modified == CharT{})
5203  {
5204 #endif
5205  auto st = local_days(sun[1]/jan/ymd.year());
5206  if (ld < st)
5207  os << CharT{'0'} << CharT{'0'};
5208  else
5209  {
5210  auto wn = duration_cast<weeks>(ld - st).count() + 1;
5211  if (wn < 10)
5212  os << CharT{'0'};
5213  os << wn;
5214  }
5215  #if !ONLY_C_LOCALE
5216  }
5217  else if (modified == CharT{'O'})
5218  {
5219  const CharT f[] = {'%', modified, *fmt};
5220  tm.tm_year = static_cast<int>(ymd.year()) - 1900;
5221  tm.tm_wday = static_cast<int>(extract_weekday(os, fds));
5222  if (os.fail())
5223  return os;
5224  tm.tm_yday = static_cast<int>((ld - local_days(ymd.year()/1/1)).count());
5225  facet.put(os, os, os.fill(), &tm, begin(f), end(f));
5226  }
5227  else
5228  {
5229  os << CharT{'%'} << modified << *fmt;
5230  }
5231 #endif
5232  modified = CharT{};
5233  command = nullptr;
5234  }
5235  else
5236  os << *fmt;
5237  break;
5238  case 'V':
5239  if (command)
5240  {
5241  auto ld = local_days(fds.ymd);
5242 #if !ONLY_C_LOCALE
5243  if (modified == CharT{})
5244  {
5245 #endif
5246  auto y = year_month_day{ld + days{3}}.year();
5247  auto st = local_days((y - years{1})/12/thu[last]) + (mon-thu);
5248  if (ld < st)
5249  {
5250  --y;
5251  st = local_days((y - years{1})/12/thu[last]) + (mon-thu);
5252  }
5253  auto wn = duration_cast<weeks>(ld - st).count() + 1;
5254  if (wn < 10)
5255  os << CharT{'0'};
5256  os << wn;
5257 #if !ONLY_C_LOCALE
5258  }
5259  else if (modified == CharT{'O'})
5260  {
5261  const CharT f[] = {'%', modified, *fmt};
5262  auto const& ymd = fds.ymd;
5263  tm.tm_year = static_cast<int>(ymd.year()) - 1900;
5264  tm.tm_wday = static_cast<int>(extract_weekday(os, fds));
5265  if (os.fail())
5266  return os;
5267  tm.tm_yday = static_cast<int>((ld - local_days(ymd.year()/1/1)).count());
5268  facet.put(os, os, os.fill(), &tm, begin(f), end(f));
5269  }
5270  else
5271  {
5272  os << CharT{'%'} << modified << *fmt;
5273  }
5274 #endif
5275  modified = CharT{};
5276  command = nullptr;
5277  }
5278  else
5279  os << *fmt;
5280  break;
5281  case 'w':
5282  if (command)
5283  {
5284  auto wd = extract_weekday(os, fds);
5285  if (os.fail())
5286  return os;
5287 #if !ONLY_C_LOCALE
5288  if (modified == CharT{})
5289  {
5290 #endif
5291  os << wd;
5292 #if !ONLY_C_LOCALE
5293  }
5294  else if (modified == CharT{'O'})
5295  {
5296  const CharT f[] = {'%', modified, *fmt};
5297  tm.tm_wday = static_cast<int>(wd);
5298  facet.put(os, os, os.fill(), &tm, begin(f), end(f));
5299  }
5300  else
5301  {
5302  os << CharT{'%'} << modified << *fmt;
5303  }
5304 #endif
5305  modified = CharT{};
5306  command = nullptr;
5307  }
5308  else
5309  os << *fmt;
5310  break;
5311  case 'W':
5312  if (command)
5313  {
5314  auto const& ymd = fds.ymd;
5315  auto ld = local_days(ymd);
5316 #if !ONLY_C_LOCALE
5317  if (modified == CharT{})
5318  {
5319 #endif
5320  auto st = local_days(mon[1]/jan/ymd.year());
5321  if (ld < st)
5322  os << CharT{'0'} << CharT{'0'};
5323  else
5324  {
5325  auto wn = duration_cast<weeks>(ld - st).count() + 1;
5326  if (wn < 10)
5327  os << CharT{'0'};
5328  os << wn;
5329  }
5330 #if !ONLY_C_LOCALE
5331  }
5332  else if (modified == CharT{'O'})
5333  {
5334  const CharT f[] = {'%', modified, *fmt};
5335  tm.tm_year = static_cast<int>(ymd.year()) - 1900;
5336  tm.tm_wday = static_cast<int>(extract_weekday(os, fds));
5337  if (os.fail())
5338  return os;
5339  tm.tm_yday = static_cast<int>((ld - local_days(ymd.year()/1/1)).count());
5340  facet.put(os, os, os.fill(), &tm, begin(f), end(f));
5341  }
5342  else
5343  {
5344  os << CharT{'%'} << modified << *fmt;
5345  }
5346 #endif
5347  modified = CharT{};
5348  command = nullptr;
5349  }
5350  else
5351  os << *fmt;
5352  break;
5353  case 'X':
5354  if (command)
5355  {
5356 #if !ONLY_C_LOCALE
5357  if (modified == CharT{'O'})
5358  os << CharT{'%'} << modified << *fmt;
5359  else
5360  {
5361  tm = std::tm{};
5362  tm.tm_sec = static_cast<int>(fds.tod.seconds().count());
5363  tm.tm_min = static_cast<int>(fds.tod.minutes().count());
5364  tm.tm_hour = static_cast<int>(fds.tod.hours().count());
5365  CharT f[3] = {'%'};
5366  auto fe = begin(f) + 1;
5367  if (modified == CharT{'E'})
5368  *fe++ = modified;
5369  *fe++ = *fmt;
5370  facet.put(os, os, os.fill(), &tm, begin(f), fe);
5371  }
5372 #else
5373  os << fds.tod;
5374 #endif
5375  command = nullptr;
5376  modified = CharT{};
5377  }
5378  else
5379  os << *fmt;
5380  break;
5381  case 'y':
5382  if (command)
5383  {
5384  auto y = static_cast<int>(fds.ymd.year());
5385 #if !ONLY_C_LOCALE
5386  if (modified == CharT{})
5387  {
5388 #endif
5389  y = std::abs(y) % 100;
5390  if (y < 10)
5391  os << CharT{'0'};
5392  os << y;
5393 #if !ONLY_C_LOCALE
5394  }
5395  else
5396  {
5397  const CharT f[] = {'%', modified, *fmt};
5398  tm.tm_year = y - 1900;
5399  facet.put(os, os, os.fill(), &tm, begin(f), end(f));
5400  }
5401 #endif
5402  modified = CharT{};
5403  command = nullptr;
5404  }
5405  else
5406  os << *fmt;
5407  break;
5408  case 'Y':
5409  if (command)
5410  {
5411  auto y = fds.ymd.year();
5412 #if !ONLY_C_LOCALE
5413  if (modified == CharT{})
5414  {
5415 #endif
5416  os << y;
5417 #if !ONLY_C_LOCALE
5418  }
5419  else if (modified == CharT{'E'})
5420  {
5421  const CharT f[] = {'%', modified, *fmt};
5422  tm.tm_year = static_cast<int>(y) - 1900;
5423  facet.put(os, os, os.fill(), &tm, begin(f), end(f));
5424  }
5425  else
5426  {
5427  os << CharT{'%'} << modified << *fmt;
5428  }
5429 #endif
5430  modified = CharT{};
5431  command = nullptr;
5432  }
5433  else
5434  os << *fmt;
5435  break;
5436  case 'z':
5437  if (command)
5438  {
5439  if (offset_sec == nullptr)
5440  {
5441  // Can not format %z with unknown offset
5442  os.setstate(ios::failbit);
5443  return os;
5444  }
5445  auto m = duration_cast<minutes>(*offset_sec);
5446  auto neg = m < minutes{0};
5447  m = date::abs(m);
5448  auto h = duration_cast<hours>(m);
5449  m -= h;
5450  if (neg)
5451  os << CharT{'-'};
5452  else
5453  os << CharT{'+'};
5454  if (h < hours{10})
5455  os << CharT{'0'};
5456  os << h.count();
5457  if (modified != CharT{})
5458  os << CharT{':'};
5459  if (m < minutes{10})
5460  os << CharT{'0'};
5461  os << m.count();
5462  command = nullptr;
5463  modified = CharT{};
5464  }
5465  else
5466  os << *fmt;
5467  break;
5468  case 'Z':
5469  if (command)
5470  {
5471  if (modified == CharT{})
5472  {
5473  if (abbrev == nullptr)
5474  {
5475  // Can not format %Z with unknown time_zone
5476  os.setstate(ios::failbit);
5477  return os;
5478  }
5479  for (auto c : *abbrev)
5480  os << CharT(c);
5481  }
5482  else
5483  {
5484  os << CharT{'%'} << modified << *fmt;
5485  modified = CharT{};
5486  }
5487  command = nullptr;
5488  }
5489  else
5490  os << *fmt;
5491  break;
5492  case 'E':
5493  case 'O':
5494  if (command)
5495  {
5496  if (modified == CharT{})
5497  {
5498  modified = *fmt;
5499  }
5500  else
5501  {
5502  os << CharT{'%'} << modified << *fmt;
5503  command = nullptr;
5504  modified = CharT{};
5505  }
5506  }
5507  else
5508  os << *fmt;
5509  break;
5510  case '%':
5511  if (command)
5512  {
5513  if (modified == CharT{})
5514  {
5515  os << CharT{'%'};
5516  command = nullptr;
5517  }
5518  else
5519  {
5520  os << CharT{'%'} << modified << CharT{'%'};
5521  command = nullptr;
5522  modified = CharT{};
5523  }
5524  }
5525  else
5526  command = fmt;
5527  break;
5528  default:
5529  if (command)
5530  {
5531  os << CharT{'%'};
5532  command = nullptr;
5533  }
5534  if (modified != CharT{})
5535  {
5536  os << modified;
5537  modified = CharT{};
5538  }
5539  os << *fmt;
5540  break;
5541  }
5542  }
5543  if (command)
5544  os << CharT{'%'};
5545  if (modified != CharT{})
5546  os << modified;
5547  return os;
5548 }
5549 
5550 template <class CharT, class Traits>
5551 inline
5552 std::basic_ostream<CharT, Traits>&
5553 to_stream(std::basic_ostream<CharT, Traits>& os, const CharT* fmt, const year& y)
5554 {
5555  using CT = std::chrono::seconds;
5556  fields<CT> fds{y/0/0};
5557  return to_stream(os, fmt, fds);
5558 }
5559 
5560 template <class CharT, class Traits>
5561 inline
5562 std::basic_ostream<CharT, Traits>&
5563 to_stream(std::basic_ostream<CharT, Traits>& os, const CharT* fmt, const month& m)
5564 {
5565  using CT = std::chrono::seconds;
5566  fields<CT> fds{m/0/0};
5567  return to_stream(os, fmt, fds);
5568 }
5569 
5570 template <class CharT, class Traits>
5571 inline
5572 std::basic_ostream<CharT, Traits>&
5573 to_stream(std::basic_ostream<CharT, Traits>& os, const CharT* fmt, const day& d)
5574 {
5575  using CT = std::chrono::seconds;
5576  fields<CT> fds{d/0/0};
5577  return to_stream(os, fmt, fds);
5578 }
5579 
5580 template <class CharT, class Traits>
5581 inline
5582 std::basic_ostream<CharT, Traits>&
5583 to_stream(std::basic_ostream<CharT, Traits>& os, const CharT* fmt, const weekday& wd)
5584 {
5585  using CT = std::chrono::seconds;
5586  fields<CT> fds{wd};
5587  return to_stream(os, fmt, fds);
5588 }
5589 
5590 template <class CharT, class Traits>
5591 inline
5592 std::basic_ostream<CharT, Traits>&
5593 to_stream(std::basic_ostream<CharT, Traits>& os, const CharT* fmt, const year_month& ym)
5594 {
5595  using CT = std::chrono::seconds;
5596  fields<CT> fds{ym/0};
5597  return to_stream(os, fmt, fds);
5598 }
5599 
5600 template <class CharT, class Traits>
5601 inline
5602 std::basic_ostream<CharT, Traits>&
5603 to_stream(std::basic_ostream<CharT, Traits>& os, const CharT* fmt, const month_day& md)
5604 {
5605  using CT = std::chrono::seconds;
5606  fields<CT> fds{md/0};
5607  return to_stream(os, fmt, fds);
5608 }
5609 
5610 template <class CharT, class Traits>
5611 inline
5612 std::basic_ostream<CharT, Traits>&
5613 to_stream(std::basic_ostream<CharT, Traits>& os, const CharT* fmt,
5614  const year_month_day& ymd)
5615 {
5616  using CT = std::chrono::seconds;
5617  fields<CT> fds{ymd};
5618  return to_stream(os, fmt, fds);
5619 }
5620 
5621 template <class CharT, class Traits, class Rep, class Period>
5622 inline
5623 std::basic_ostream<CharT, Traits>&
5624 to_stream(std::basic_ostream<CharT, Traits>& os, const CharT* fmt,
5625  const std::chrono::duration<Rep, Period>& d)
5626 {
5627  using Duration = std::chrono::duration<Rep, Period>;
5629  fields<CT> fds{time_of_day<CT>{d}};
5630  return to_stream(os, fmt, fds);
5631 }
5632 
5633 template <class CharT, class Traits, class Duration>
5634 std::basic_ostream<CharT, Traits>&
5635 to_stream(std::basic_ostream<CharT, Traits>& os, const CharT* fmt,
5636  const local_time<Duration>& tp, const std::string* abbrev = nullptr,
5637  const std::chrono::seconds* offset_sec = nullptr)
5638 {
5640  auto ld = floor<days>(tp);
5641  fields<CT> fds{year_month_day{ld}, time_of_day<CT>{tp-local_seconds{ld}}};
5642  return to_stream(os, fmt, fds, abbrev, offset_sec);
5643 }
5644 
5645 template <class CharT, class Traits, class Duration>
5646 std::basic_ostream<CharT, Traits>&
5647 to_stream(std::basic_ostream<CharT, Traits>& os, const CharT* fmt,
5648  const sys_time<Duration>& tp)
5649 {
5650  using namespace std::chrono;
5651  using CT = typename std::common_type<Duration, seconds>::type;
5652  const std::string abbrev("UTC");
5653  CONSTDATA seconds offset{0};
5654  auto sd = floor<days>(tp);
5655  fields<CT> fds{year_month_day{sd}, time_of_day<CT>{tp-sys_seconds{sd}}};
5656  return to_stream(os, fmt, fds, &abbrev, &offset);
5657 }
5658 
5659 // format
5660 
5661 template <class CharT, class Streamable>
5662 auto
5663 format(const std::locale& loc, const CharT* fmt, const Streamable& tp)
5664  -> decltype(to_stream(std::declval<std::basic_ostream<CharT>&>(), fmt, tp),
5665  std::basic_string<CharT>{})
5666 {
5667  std::basic_ostringstream<CharT> os;
5668  os.exceptions(std::ios::failbit | std::ios::badbit);
5669  os.imbue(loc);
5670  to_stream(os, fmt, tp);
5671  return os.str();
5672 }
5673 
5674 template <class CharT, class Streamable>
5675 auto
5676 format(const CharT* fmt, const Streamable& tp)
5677  -> decltype(to_stream(std::declval<std::basic_ostream<CharT>&>(), fmt, tp),
5678  std::basic_string<CharT>{})
5679 {
5680  std::basic_ostringstream<CharT> os;
5681  os.exceptions(std::ios::failbit | std::ios::badbit);
5682  to_stream(os, fmt, tp);
5683  return os.str();
5684 }
5685 
5686 template <class CharT, class Traits, class Alloc, class Streamable>
5687 auto
5688 format(const std::locale& loc, const std::basic_string<CharT, Traits, Alloc>& fmt,
5689  const Streamable& tp)
5690  -> decltype(to_stream(std::declval<std::basic_ostream<CharT, Traits>&>(), fmt.c_str(), tp),
5691  std::basic_string<CharT, Traits, Alloc>{})
5692 {
5693  std::basic_ostringstream<CharT, Traits, Alloc> os;
5694  os.exceptions(std::ios::failbit | std::ios::badbit);
5695  os.imbue(loc);
5696  to_stream(os, fmt.c_str(), tp);
5697  return os.str();
5698 }
5699 
5700 template <class CharT, class Traits, class Alloc, class Streamable>
5701 auto
5702 format(const std::basic_string<CharT, Traits, Alloc>& fmt, const Streamable& tp)
5703  -> decltype(to_stream(std::declval<std::basic_ostream<CharT, Traits>&>(), fmt.c_str(), tp),
5704  std::basic_string<CharT, Traits, Alloc>{})
5705 {
5706  std::basic_ostringstream<CharT, Traits, Alloc> os;
5707  os.exceptions(std::ios::failbit | std::ios::badbit);
5708  to_stream(os, fmt.c_str(), tp);
5709  return os.str();
5710 }
5711 
5712 // parse
5713 
5714 namespace detail
5715 {
5716 
5717 template <class CharT, class Traits>
5718 bool
5719 read_char(std::basic_istream<CharT, Traits>& is, CharT fmt, std::ios::iostate& err)
5720 {
5721  auto ic = is.get();
5722  if (Traits::eq_int_type(ic, Traits::eof()) ||
5723  !Traits::eq(Traits::to_char_type(ic), fmt))
5724  {
5725  err |= std::ios::failbit;
5726  is.setstate(std::ios::failbit);
5727  return false;
5728  }
5729  return true;
5730 }
5731 
5732 template <class CharT, class Traits>
5733 unsigned
5734 read_unsigned(std::basic_istream<CharT, Traits>& is, unsigned m = 1, unsigned M = 10)
5735 {
5736  unsigned x = 0;
5737  unsigned count = 0;
5738  while (true)
5739  {
5740  auto ic = is.peek();
5741  if (Traits::eq_int_type(ic, Traits::eof()))
5742  break;
5743  auto c = static_cast<char>(Traits::to_char_type(ic));
5744  if (!('0' <= c && c <= '9'))
5745  break;
5746  (void)is.get();
5747  ++count;
5748  x = 10*x + static_cast<unsigned>(c - '0');
5749  if (count == M)
5750  break;
5751  }
5752  if (count < m)
5753  is.setstate(std::ios::failbit);
5754  return x;
5755 }
5756 
5757 template <class CharT, class Traits>
5758 int
5759 read_signed(std::basic_istream<CharT, Traits>& is, unsigned m = 1, unsigned M = 10)
5760 {
5761  auto ic = is.peek();
5762  if (!Traits::eq_int_type(ic, Traits::eof()))
5763  {
5764  auto c = static_cast<char>(Traits::to_char_type(ic));
5765  if (('0' <= c && c <= '9') || c == '-' || c == '+')
5766  {
5767  if (c == '-' || c == '+')
5768  (void)is.get();
5769  auto x = static_cast<int>(read_unsigned(is, std::max(m, 1u), M));
5770  if (!is.fail())
5771  {
5772  if (c == '-')
5773  x = -x;
5774  return x;
5775  }
5776  }
5777  }
5778  if (m > 0)
5779  is.setstate(std::ios::failbit);
5780  return 0;
5781 }
5782 
5783 template <class CharT, class Traits>
5784 long double
5785 read_long_double(std::basic_istream<CharT, Traits>& is, unsigned m = 1, unsigned M = 10)
5786 {
5787  using namespace std;
5788  unsigned count = 0;
5789  auto decimal_point = Traits::to_int_type(
5790  use_facet<numpunct<CharT>>(is.getloc()).decimal_point());
5791  string buf;
5792  while (true)
5793  {
5794  auto ic = is.peek();
5795  if (Traits::eq_int_type(ic, Traits::eof()))
5796  break;
5797  if (Traits::eq_int_type(ic, decimal_point))
5798  {
5799  buf += '.';
5800  decimal_point = Traits::eof();
5801  is.get();
5802  }
5803  else
5804  {
5805  auto c = static_cast<char>(Traits::to_char_type(ic));
5806  if (!('0' <= c && c <= '9'))
5807  break;
5808  buf += c;
5809  (void)is.get();
5810  }
5811  if (++count == M)
5812  break;
5813  }
5814  if (count < m)
5815  {
5816  is.setstate(std::ios::failbit);
5817  return 0;
5818  }
5819  return std::stold(buf);
5820 }
5821 
5822 struct rs
5823 {
5824  int& i;
5825  unsigned m;
5826  unsigned M;
5827 };
5828 
5829 struct ru
5830 {
5831  int& i;
5832  unsigned m;
5833  unsigned M;
5834 };
5835 
5836 struct rld
5837 {
5838  long double& i;
5839  unsigned m;
5840  unsigned M;
5841 };
5842 
5843 template <class CharT, class Traits>
5844 void
5845 read(std::basic_istream<CharT, Traits>&)
5846 {
5847 }
5848 
5849 template <class CharT, class Traits, class ...Args>
5850 void
5851 read(std::basic_istream<CharT, Traits>& is, CharT a0, Args&& ...args);
5852 
5853 template <class CharT, class Traits, class ...Args>
5854 void
5855 read(std::basic_istream<CharT, Traits>& is, rs a0, Args&& ...args);
5856 
5857 template <class CharT, class Traits, class ...Args>
5858 void
5859 read(std::basic_istream<CharT, Traits>& is, ru a0, Args&& ...args);
5860 
5861 template <class CharT, class Traits, class ...Args>
5862 void
5863 read(std::basic_istream<CharT, Traits>& is, int a0, Args&& ...args);
5864 
5865 template <class CharT, class Traits, class ...Args>
5866 void
5867 read(std::basic_istream<CharT, Traits>& is, rld a0, Args&& ...args);
5868 
5869 template <class CharT, class Traits, class ...Args>
5870 void
5871 read(std::basic_istream<CharT, Traits>& is, CharT a0, Args&& ...args)
5872 {
5873  // No-op if a0 == CharT{}
5874  if (a0 != CharT{})
5875  {
5876  auto ic = is.peek();
5877  if (Traits::eq_int_type(ic, Traits::eof()))
5878  {
5879  is.setstate(std::ios::failbit | std::ios::eofbit);
5880  return;
5881  }
5882  if (!Traits::eq(Traits::to_char_type(ic), a0))
5883  {
5884  is.setstate(std::ios::failbit);
5885  return;
5886  }
5887  (void)is.get();
5888  }
5889  read(is, std::forward<Args>(args)...);
5890 }
5891 
5892 template <class CharT, class Traits, class ...Args>
5893 void
5894 read(std::basic_istream<CharT, Traits>& is, rs a0, Args&& ...args)
5895 {
5896  auto x = read_signed(is, a0.m, a0.M);
5897  if (is.fail())
5898  return;
5899  a0.i = x;
5900  read(is, std::forward<Args>(args)...);
5901 }
5902 
5903 template <class CharT, class Traits, class ...Args>
5904 void
5905 read(std::basic_istream<CharT, Traits>& is, ru a0, Args&& ...args)
5906 {
5907  auto x = read_unsigned(is, a0.m, a0.M);
5908  if (is.fail())
5909  return;
5910  a0.i = static_cast<int>(x);
5911  read(is, std::forward<Args>(args)...);
5912 }
5913 
5914 template <class CharT, class Traits, class ...Args>
5915 void
5916 read(std::basic_istream<CharT, Traits>& is, int a0, Args&& ...args)
5917 {
5918  if (a0 != -1)
5919  {
5920  auto u = static_cast<unsigned>(a0);
5921  CharT buf[std::numeric_limits<unsigned>::digits10+2] = {};
5922  auto e = buf;
5923  do
5924  {
5925  *e++ = CharT(u % 10) + CharT{'0'};
5926  u /= 10;
5927  } while (u > 0);
5928  std::reverse(buf, e);
5929  for (auto p = buf; p != e && is.rdstate() == std::ios::goodbit; ++p)
5930  read(is, *p);
5931  }
5932  if (is.rdstate() == std::ios::goodbit)
5933  read(is, std::forward<Args>(args)...);
5934 }
5935 
5936 template <class CharT, class Traits, class ...Args>
5937 void
5938 read(std::basic_istream<CharT, Traits>& is, rld a0, Args&& ...args)
5939 {
5940  auto x = read_long_double(is, a0.m, a0.M);
5941  if (is.fail())
5942  return;
5943  a0.i = x;
5944  read(is, std::forward<Args>(args)...);
5945 }
5946 
5947 } // namespace detail;
5948 
5949 template <class CharT, class Traits, class Duration, class Alloc = std::allocator<CharT>>
5950 std::basic_istream<CharT, Traits>&
5951 from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
5952  fields<Duration>& fds, std::basic_string<CharT, Traits, Alloc>* abbrev,
5953  std::chrono::minutes* offset)
5954 {
5955  using namespace std;
5956  using namespace std::chrono;
5957  typename basic_istream<CharT, Traits>::sentry ok{is, true};
5958  if (ok)
5959  {
5960 #if !ONLY_C_LOCALE
5961  auto& f = use_facet<time_get<CharT>>(is.getloc());
5962  std::tm tm{};
5963 #endif
5964  std::basic_string<CharT, Traits, Alloc> temp_abbrev;
5965  minutes temp_offset{};
5966  const CharT* command = nullptr;
5967  auto modified = CharT{};
5968  auto width = -1;
5969  CONSTDATA int not_a_year = numeric_limits<short>::min();
5970  int Y = not_a_year;
5971  CONSTDATA int not_a_century = not_a_year / 100;
5972  int C = not_a_century;
5973  CONSTDATA int not_a_2digit_year = 100;
5974  int y = not_a_2digit_year;
5975  int m{};
5976  int d{};
5977  int j{};
5978  CONSTDATA int not_a_weekday = 7;
5979  int wd = not_a_weekday;
5980  CONSTDATA int not_a_hour_12_value = 0;
5981  int I = not_a_hour_12_value;
5982  hours h{};
5983  minutes min{};
5984  Duration s{};
5985  int g = not_a_2digit_year;
5986  int G = not_a_year;
5987  CONSTDATA int not_a_week_num = 100;
5988  int V = not_a_week_num;
5989  int U = not_a_week_num;
5990  int W = not_a_week_num;
5991  using detail::read;
5992  using detail::rs;
5993  using detail::ru;
5994  using detail::rld;
5995  for (; *fmt && is.rdstate() == std::ios::goodbit; ++fmt)
5996  {
5997  switch (*fmt)
5998  {
5999  case 'a':
6000  case 'A':
6001  if (command)
6002  {
6003 #if !ONLY_C_LOCALE
6004  ios_base::iostate err = ios_base::goodbit;
6005  f.get(is, nullptr, is, err, &tm, command, fmt+1);
6006  if ((err & ios::failbit) == 0)
6007  wd = tm.tm_wday;
6008  is.setstate(err);
6009 #else
6010  auto nm = detail::weekday_names();
6011  auto i = detail::scan_keyword(is, nm.first, nm.second) - nm.first;
6012  if (!is.fail())
6013  wd = i % 7;
6014 #endif
6015  command = nullptr;
6016  width = -1;
6017  modified = CharT{};
6018  }
6019  else
6020  read(is, *fmt);
6021  break;
6022  case 'b':
6023  case 'B':
6024  case 'h':
6025  if (command)
6026  {
6027 #if !ONLY_C_LOCALE
6028  ios_base::iostate err = ios_base::goodbit;
6029  f.get(is, nullptr, is, err, &tm, command, fmt+1);
6030  if ((err & ios::failbit) == 0)
6031  m = tm.tm_mon + 1;
6032  is.setstate(err);
6033 #else
6034  auto nm = detail::month_names();
6035  auto i = detail::scan_keyword(is, nm.first, nm.second) - nm.first;
6036  if (!is.fail())
6037  m = i % 12 + 1;
6038 #endif
6039  command = nullptr;
6040  width = -1;
6041  modified = CharT{};
6042  }
6043  else
6044  read(is, *fmt);
6045  break;
6046  case 'c':
6047  if (command)
6048  {
6049 #if !ONLY_C_LOCALE
6050  ios_base::iostate err = ios_base::goodbit;
6051  f.get(is, nullptr, is, err, &tm, command, fmt+1);
6052  if ((err & ios::failbit) == 0)
6053  {
6054  Y = tm.tm_year + 1900;
6055  m = tm.tm_mon + 1;
6056  d = tm.tm_mday;
6057  h = hours{tm.tm_hour};
6058  min = minutes{tm.tm_min};
6059  s = duration_cast<Duration>(seconds{tm.tm_sec});
6060  }
6061  is.setstate(err);
6062 #else
6063  auto nm = detail::weekday_names();
6064  auto i = detail::scan_keyword(is, nm.first, nm.second) - nm.first;
6065  if (is.fail())
6066  goto broken;
6067  wd = i % 7;
6068  ws(is);
6069  nm = detail::month_names();
6070  i = detail::scan_keyword(is, nm.first, nm.second) - nm.first;
6071  if (is.fail())
6072  goto broken;
6073  m = i % 12 + 1;
6074  ws(is);
6075  read(is, rs{d, 1, 2});
6076  if (is.fail())
6077  goto broken;
6078  ws(is);
6080  CONSTDATA auto w = Duration::period::den == 1 ? 2 : 3 + dfs::width;
6081  int H;
6082  int M;
6083  long double S;
6084  read(is, ru{H, 1, 2}, CharT{':'}, ru{M, 1, 2},
6085  CharT{':'}, rld{S, 1, w});
6086  if (is.fail())
6087  goto broken;
6088  h = hours{H};
6089  min = minutes{M};
6090  s = round<Duration>(duration<long double>{S});
6091  ws(is);
6092  read(is, rs{Y, 1, 4u});
6093 #endif
6094  command = nullptr;
6095  width = -1;
6096  modified = CharT{};
6097  }
6098  else
6099  read(is, *fmt);
6100  break;
6101  case 'x':
6102  if (command)
6103  {
6104 #if !ONLY_C_LOCALE
6105  ios_base::iostate err = ios_base::goodbit;
6106  f.get(is, nullptr, is, err, &tm, command, fmt+1);
6107  if ((err & ios::failbit) == 0)
6108  {
6109  Y = tm.tm_year + 1900;
6110  m = tm.tm_mon + 1;
6111  d = tm.tm_mday;
6112  }
6113  is.setstate(err);
6114 #else
6115  read(is, ru{m, 1, 2}, CharT{'/'}, ru{d, 1, 2}, CharT{'/'},
6116  rs{y, 1, 2});
6117 #endif
6118  command = nullptr;
6119  width = -1;
6120  modified = CharT{};
6121  }
6122  else
6123  read(is, *fmt);
6124  break;
6125  case 'X':
6126  if (command)
6127  {
6128 #if !ONLY_C_LOCALE
6129  ios_base::iostate err = ios_base::goodbit;
6130  f.get(is, nullptr, is, err, &tm, command, fmt+1);
6131  if ((err & ios::failbit) == 0)
6132  {
6133  h = hours{tm.tm_hour};
6134  min = minutes{tm.tm_min};
6135  s = duration_cast<Duration>(seconds{tm.tm_sec});
6136  }
6137  is.setstate(err);
6138 #else
6140  CONSTDATA auto w = Duration::period::den == 1 ? 2 : 3 + dfs::width;
6141  int H;
6142  int M;
6143  long double S;
6144  read(is, ru{H, 1, 2}, CharT{':'}, ru{M, 1, 2},
6145  CharT{':'}, rld{S, 1, w});
6146  if (!is.fail())
6147  {
6148  h = hours{H};
6149  min = minutes{M};
6150  s = round<Duration>(duration<long double>{S});
6151  }
6152 #endif
6153  command = nullptr;
6154  width = -1;
6155  modified = CharT{};
6156  }
6157  else
6158  read(is, *fmt);
6159  break;
6160  case 'C':
6161  if (command)
6162  {
6163 #if !ONLY_C_LOCALE
6164  if (modified == CharT{})
6165  {
6166 #endif
6167  read(is, rs{C, 1, width == -1 ? 2u : static_cast<unsigned>(width)});
6168 #if !ONLY_C_LOCALE
6169  }
6170  else
6171  {
6172  ios_base::iostate err = ios_base::goodbit;
6173  f.get(is, nullptr, is, err, &tm, command, fmt+1);
6174  if ((err & ios::failbit) == 0)
6175  {
6176  auto tY = tm.tm_year + 1900;
6177  C = (tY >= 0 ? tY : tY-99) / 100;
6178  }
6179  is.setstate(err);
6180  }
6181 #endif
6182  command = nullptr;
6183  width = -1;
6184  modified = CharT{};
6185  }
6186  else
6187  read(is, *fmt);
6188  break;
6189  case 'D':
6190  if (command)
6191  {
6192  if (modified == CharT{})
6193  read(is, ru{m, 1, 2}, CharT{'\0'}, CharT{'/'}, CharT{'\0'},
6194  ru{d, 1, 2}, CharT{'\0'}, CharT{'/'}, CharT{'\0'},
6195  rs{y, 1, 2});
6196  else
6197  read(is, CharT{'%'}, width, modified, *fmt);
6198  command = nullptr;
6199  width = -1;
6200  modified = CharT{};
6201  }
6202  else
6203  read(is, *fmt);
6204  break;
6205  case 'F':
6206  if (command)
6207  {
6208  if (modified == CharT{})
6209  read(is, rs{Y, 1, width == -1 ? 4u : static_cast<unsigned>(width)},
6210  CharT{'-'}, ru{m, 1, 2}, CharT{'-'}, ru{d, 1, 2});
6211  else
6212  read(is, CharT{'%'}, width, modified, *fmt);
6213  command = nullptr;
6214  width = -1;
6215  modified = CharT{};
6216  }
6217  else
6218  read(is, *fmt);
6219  break;
6220  case 'd':
6221  case 'e':
6222  if (command)
6223  {
6224 #if !ONLY_C_LOCALE
6225  if (modified == CharT{})
6226 #endif
6227  read(is, rs{d, 1, width == -1 ? 2u : static_cast<unsigned>(width)});
6228 #if !ONLY_C_LOCALE
6229  else if (modified == CharT{'O'})
6230  {
6231  ios_base::iostate err = ios_base::goodbit;
6232  f.get(is, nullptr, is, err, &tm, command, fmt+1);
6233  command = nullptr;
6234  width = -1;
6235  modified = CharT{};
6236  if ((err & ios::failbit) == 0)
6237  d = tm.tm_mday;
6238  is.setstate(err);
6239  }
6240  else
6241  read(is, CharT{'%'}, width, modified, *fmt);
6242 #endif
6243  command = nullptr;
6244  width = -1;
6245  modified = CharT{};
6246  }
6247  else
6248  read(is, *fmt);
6249  break;
6250  case 'H':
6251  if (command)
6252  {
6253 #if !ONLY_C_LOCALE
6254  if (modified == CharT{})
6255  {
6256 #endif
6257  int H;
6258  read(is, ru{H, 1, width == -1 ? 2u : static_cast<unsigned>(width)});
6259  if (!is.fail())
6260  h = hours{H};
6261 #if !ONLY_C_LOCALE
6262  }
6263  else if (modified == CharT{'O'})
6264  {
6265  ios_base::iostate err = ios_base::goodbit;
6266  f.get(is, nullptr, is, err, &tm, command, fmt+1);
6267  if ((err & ios::failbit) == 0)
6268  h = hours{tm.tm_hour};
6269  is.setstate(err);
6270  }
6271  else
6272  read(is, CharT{'%'}, width, modified, *fmt);
6273 #endif
6274  command = nullptr;
6275  width = -1;
6276  modified = CharT{};
6277  }
6278  else
6279  read(is, *fmt);
6280  break;
6281  case 'I':
6282  if (command)
6283  {
6284  if (modified == CharT{})
6285  {
6286  // reads in an hour into I, but most be in [1, 12]
6287  read(is, rs{I, 1, width == -1 ? 2u : static_cast<unsigned>(width)});
6288  if (I != not_a_hour_12_value)
6289  {
6290  if (!(1 <= I && I <= 12))
6291  {
6292  I = not_a_hour_12_value;
6293  goto broken;
6294  }
6295  }
6296  }
6297  else
6298  read(is, CharT{'%'}, width, modified, *fmt);
6299  command = nullptr;
6300  width = -1;
6301  modified = CharT{};
6302  }
6303  else
6304  read(is, *fmt);
6305  break;
6306  case 'j':
6307  if (command)
6308  {
6309  if (modified == CharT{})
6310  read(is, ru{j, 1, width == -1 ? 3u : static_cast<unsigned>(width)});
6311  else
6312  read(is, CharT{'%'}, width, modified, *fmt);
6313  command = nullptr;
6314  width = -1;
6315  modified = CharT{};
6316  }
6317  else
6318  read(is, *fmt);
6319  break;
6320  case 'M':
6321  if (command)
6322  {
6323 #if !ONLY_C_LOCALE
6324  if (modified == CharT{})
6325  {
6326 #endif
6327  int M;
6328  read(is, ru{M, 1, width == -1 ? 2u : static_cast<unsigned>(width)});
6329  if (!is.fail())
6330  min = minutes{M};
6331 #if !ONLY_C_LOCALE
6332  }
6333  else if (modified == CharT{'O'})
6334  {
6335  ios_base::iostate err = ios_base::goodbit;
6336  f.get(is, nullptr, is, err, &tm, command, fmt+1);
6337  if ((err & ios::failbit) == 0)
6338  min = minutes{tm.tm_min};
6339  is.setstate(err);
6340  }
6341  else
6342  read(is, CharT{'%'}, width, modified, *fmt);
6343 #endif
6344  command = nullptr;
6345  width = -1;
6346  modified = CharT{};
6347  }
6348  else
6349  read(is, *fmt);
6350  break;
6351  case 'm':
6352  if (command)
6353  {
6354 #if !ONLY_C_LOCALE
6355  if (modified == CharT{})
6356 #endif
6357  read(is, rs{m, 1, width == -1 ? 2u : static_cast<unsigned>(width)});
6358 #if !ONLY_C_LOCALE
6359  else if (modified == CharT{'O'})
6360  {
6361  ios_base::iostate err = ios_base::goodbit;
6362  f.get(is, nullptr, is, err, &tm, command, fmt+1);
6363  if ((err & ios::failbit) == 0)
6364  m = tm.tm_mon + 1;
6365  is.setstate(err);
6366  }
6367  else
6368  read(is, CharT{'%'}, width, modified, *fmt);
6369 #endif
6370  command = nullptr;
6371  width = -1;
6372  modified = CharT{};
6373  }
6374  else
6375  read(is, *fmt);
6376  break;
6377  case 'n':
6378  case 't':
6379  if (command)
6380  {
6381  // %n matches a single white space character
6382  // %t matches 0 or 1 white space characters
6383  auto ic = is.peek();
6384  if (Traits::eq_int_type(ic, Traits::eof()))
6385  {
6386  ios_base::iostate err = ios_base::eofbit;
6387  if (*fmt == 'n')
6388  err |= ios_base::failbit;
6389  is.setstate(err);
6390  break;
6391  }
6392  if (isspace(ic))
6393  {
6394  (void)is.get();
6395  }
6396  else if (*fmt == 'n')
6397  is.setstate(ios_base::failbit);
6398  command = nullptr;
6399  width = -1;
6400  modified = CharT{};
6401  }
6402  else
6403  read(is, *fmt);
6404  break;
6405  case 'p':
6406  // Error if haven't yet seen %I
6407  if (command)
6408  {
6409 #if !ONLY_C_LOCALE
6410  if (modified == CharT{})
6411  {
6412  if (I == not_a_hour_12_value)
6413  goto broken;
6414  tm = std::tm{};
6415  tm.tm_hour = I;
6416  ios_base::iostate err = ios_base::goodbit;
6417  f.get(is, nullptr, is, err, &tm, command, fmt+1);
6418  if (err & ios::failbit)
6419  goto broken;
6420  h = hours{tm.tm_hour};
6421  I = not_a_hour_12_value;
6422  }
6423  else
6424  read(is, CharT{'%'}, width, modified, *fmt);
6425 #else
6426  if (I == not_a_hour_12_value)
6427  goto broken;
6428  auto nm = detail::ampm_names();
6429  auto i = detail::scan_keyword(is, nm.first, nm.second) - nm.first;
6430  if (is.fail())
6431  goto broken;
6432  h = hours{I};
6433  if (i == 1)
6434  {
6435  if (h != hours{12})
6436  h += hours{12};
6437  }
6438  else if (h == hours{12})
6439  h = hours{0};
6440  I = not_a_hour_12_value;
6441 #endif
6442  command = nullptr;
6443  width = -1;
6444  modified = CharT{};
6445  }
6446  else
6447  read(is, *fmt);
6448 
6449  break;
6450  case 'r':
6451  if (command)
6452  {
6453 #if !ONLY_C_LOCALE
6454  ios_base::iostate err = ios_base::goodbit;
6455  f.get(is, nullptr, is, err, &tm, command, fmt+1);
6456  if ((err & ios::failbit) == 0)
6457  {
6458  h = hours{tm.tm_hour};
6459  min = minutes{tm.tm_min};
6460  s = duration_cast<Duration>(seconds{tm.tm_sec});
6461  }
6462  is.setstate(err);
6463 #else
6465  CONSTDATA auto w = Duration::period::den == 1 ? 2 : 3 + dfs::width;
6466  int H;
6467  int M;
6468  long double S;
6469  read(is, ru{H, 1, 2}, CharT{':'}, ru{M, 1, 2},
6470  CharT{':'}, rld{S, 1, w});
6471  if (is.fail() || !(1 <= H && H <= 12))
6472  goto broken;
6473  ws(is);
6474  auto nm = detail::ampm_names();
6475  auto i = detail::scan_keyword(is, nm.first, nm.second) - nm.first;
6476  if (is.fail())
6477  goto broken;
6478  h = hours{H};
6479  if (i == 1)
6480  {
6481  if (h != hours{12})
6482  h += hours{12};
6483  }
6484  else if (h == hours{12})
6485  h = hours{0};
6486  min = minutes{M};
6487  s = round<Duration>(duration<long double>{S});
6488 #endif
6489  command = nullptr;
6490  width = -1;
6491  modified = CharT{};
6492  }
6493  else
6494  read(is, *fmt);
6495  break;
6496  case 'R':
6497  if (command)
6498  {
6499  if (modified == CharT{})
6500  {
6501  int H, M;
6502  read(is, ru{H, 1, 2}, CharT{'\0'}, CharT{':'}, CharT{'\0'},
6503  ru{M, 1, 2}, CharT{'\0'});
6504  if (!is.fail())
6505  {
6506  h = hours{H};
6507  min = minutes{M};
6508  }
6509  }
6510  else
6511  read(is, CharT{'%'}, width, modified, *fmt);
6512  command = nullptr;
6513  width = -1;
6514  modified = CharT{};
6515  }
6516  else
6517  read(is, *fmt);
6518  break;
6519  case 'S':
6520  if (command)
6521  {
6522  #if !ONLY_C_LOCALE
6523  if (modified == CharT{})
6524  {
6525 #endif
6527  CONSTDATA auto w = Duration::period::den == 1 ? 2 : 3 + dfs::width;
6528  long double S;
6529  read(is, rld{S, 1, width == -1 ? w : static_cast<unsigned>(width)});
6530  if (!is.fail())
6531  s = round<Duration>(duration<long double>{S});
6532 #if !ONLY_C_LOCALE
6533  }
6534  else if (modified == CharT{'O'})
6535  {
6536  ios_base::iostate err = ios_base::goodbit;
6537  f.get(is, nullptr, is, err, &tm, command, fmt+1);
6538  if ((err & ios::failbit) == 0)
6539  s = duration_cast<Duration>(seconds{tm.tm_sec});
6540  is.setstate(err);
6541  }
6542  else
6543  read(is, CharT{'%'}, width, modified, *fmt);
6544 #endif
6545  command = nullptr;
6546  width = -1;
6547  modified = CharT{};
6548  }
6549  else
6550  read(is, *fmt);
6551  break;
6552  case 'T':
6553  if (command)
6554  {
6555  if (modified == CharT{})
6556  {
6558  CONSTDATA auto w = Duration::period::den == 1 ? 2 : 3 + dfs::width;
6559  int H;
6560  int M;
6561  long double S;
6562  read(is, ru{H, 1, 2}, CharT{':'}, ru{M, 1, 2},
6563  CharT{':'}, rld{S, 1, w});
6564  if (!is.fail())
6565  {
6566  h = hours{H};
6567  min = minutes{M};
6568  s = round<Duration>(duration<long double>{S});
6569  }
6570  }
6571  else
6572  read(is, CharT{'%'}, width, modified, *fmt);
6573  command = nullptr;
6574  width = -1;
6575  modified = CharT{};
6576  }
6577  else
6578  read(is, *fmt);
6579  break;
6580  case 'Y':
6581  if (command)
6582  {
6583 #if !ONLY_C_LOCALE
6584  if (modified == CharT{})
6585 #endif
6586  read(is, rs{Y, 1, width == -1 ? 4u : static_cast<unsigned>(width)});
6587 #if !ONLY_C_LOCALE
6588  else if (modified == CharT{'E'})
6589  {
6590  ios_base::iostate err = ios_base::goodbit;
6591  f.get(is, nullptr, is, err, &tm, command, fmt+1);
6592  if ((err & ios::failbit) == 0)
6593  Y = tm.tm_year + 1900;
6594  is.setstate(err);
6595  }
6596  else
6597  read(is, CharT{'%'}, width, modified, *fmt);
6598 #endif
6599  command = nullptr;
6600  width = -1;
6601  modified = CharT{};
6602  }
6603  else
6604  read(is, *fmt);
6605  break;
6606  case 'y':
6607  if (command)
6608  {
6609 #if !ONLY_C_LOCALE
6610  if (modified == CharT{})
6611 #endif
6612  read(is, ru{y, 1, width == -1 ? 2u : static_cast<unsigned>(width)});
6613 #if !ONLY_C_LOCALE
6614  else
6615  {
6616  ios_base::iostate err = ios_base::goodbit;
6617  f.get(is, nullptr, is, err, &tm, command, fmt+1);
6618  if ((err & ios::failbit) == 0)
6619  Y = tm.tm_year + 1900;
6620  is.setstate(err);
6621  }
6622 #endif
6623  command = nullptr;
6624  width = -1;
6625  modified = CharT{};
6626  }
6627  else
6628  read(is, *fmt);
6629  break;
6630  case 'g':
6631  if (command)
6632  {
6633  if (modified == CharT{})
6634  read(is, ru{g, 1, width == -1 ? 2u : static_cast<unsigned>(width)});
6635  else
6636  read(is, CharT{'%'}, width, modified, *fmt);
6637  command = nullptr;
6638  width = -1;
6639  modified = CharT{};
6640  }
6641  else
6642  read(is, *fmt);
6643  break;
6644  case 'G':
6645  if (command)
6646  {
6647  if (modified == CharT{})
6648  read(is, rs{G, 1, width == -1 ? 4u : static_cast<unsigned>(width)});
6649  else
6650  read(is, CharT{'%'}, width, modified, *fmt);
6651  command = nullptr;
6652  width = -1;
6653  modified = CharT{};
6654  }
6655  else
6656  read(is, *fmt);
6657  break;
6658  case 'U':
6659  if (command)
6660  {
6661  if (modified == CharT{})
6662  read(is, ru{U, 1, width == -1 ? 2u : static_cast<unsigned>(width)});
6663  else
6664  read(is, CharT{'%'}, width, modified, *fmt);
6665  command = nullptr;
6666  width = -1;
6667  modified = CharT{};
6668  }
6669  else
6670  read(is, *fmt);
6671  break;
6672  case 'V':
6673  if (command)
6674  {
6675  if (modified == CharT{})
6676  read(is, ru{V, 1, width == -1 ? 2u : static_cast<unsigned>(width)});
6677  else
6678  read(is, CharT{'%'}, width, modified, *fmt);
6679  command = nullptr;
6680  width = -1;
6681  modified = CharT{};
6682  }
6683  else
6684  read(is, *fmt);
6685  break;
6686  case 'W':
6687  if (command)
6688  {
6689  if (modified == CharT{})
6690  read(is, ru{W, 1, width == -1 ? 2u : static_cast<unsigned>(width)});
6691  else
6692  read(is, CharT{'%'}, width, modified, *fmt);
6693  command = nullptr;
6694  width = -1;
6695  modified = CharT{};
6696  }
6697  else
6698  read(is, *fmt);
6699  break;
6700  case 'u':
6701  case 'w':
6702  if (command)
6703  {
6704 #if !ONLY_C_LOCALE
6705  if (modified == CharT{})
6706  {
6707 #endif
6708  read(is, ru{wd, 1, width == -1 ? 1u : static_cast<unsigned>(width)});
6709  if (!is.fail() && *fmt == 'u')
6710  {
6711  if (wd == 7)
6712  wd = 0;
6713  else if (wd == 0)
6714  wd = 7;
6715  }
6716 #if !ONLY_C_LOCALE
6717  }
6718  else if (modified == CharT{'O'})
6719  {
6720  ios_base::iostate err = ios_base::goodbit;
6721  f.get(is, nullptr, is, err, &tm, command, fmt+1);
6722  if ((err & ios::failbit) == 0)
6723  wd = tm.tm_wday;
6724  is.setstate(err);
6725  }
6726  else
6727  read(is, CharT{'%'}, width, modified, *fmt);
6728 #endif
6729  command = nullptr;
6730  width = -1;
6731  modified = CharT{};
6732  }
6733  else
6734  read(is, *fmt);
6735  break;
6736  case 'E':
6737  case 'O':
6738  if (command)
6739  {
6740  if (modified == CharT{})
6741  {
6742  modified = *fmt;
6743  }
6744  else
6745  {
6746  read(is, CharT{'%'}, width, modified, *fmt);
6747  command = nullptr;
6748  width = -1;
6749  modified = CharT{};
6750  }
6751  }
6752  else
6753  read(is, *fmt);
6754  break;
6755  case '%':
6756  if (command)
6757  {
6758  if (modified == CharT{})
6759  read(is, *fmt);
6760  else
6761  read(is, CharT{'%'}, width, modified, *fmt);
6762  command = nullptr;
6763  width = -1;
6764  modified = CharT{};
6765  }
6766  else
6767  command = fmt;
6768  break;
6769  case 'z':
6770  if (command)
6771  {
6772  int H, M;
6773  if (modified == CharT{})
6774  read(is, rs{H, 2, 2}, ru{M, 2, 2});
6775  else
6776  read(is, rs{H, 1, 2}, CharT{':'}, ru{M, 2, 2});
6777  if (!is.fail())
6778  temp_offset = hours{ H } + minutes{ H < 0 ? -M : M };
6779  command = nullptr;
6780  width = -1;
6781  modified = CharT{};
6782  }
6783  else
6784  read(is, *fmt);
6785  break;
6786  case 'Z':
6787  if (command)
6788  {
6789  if (modified == CharT{})
6790  {
6791  if (!temp_abbrev.empty())
6792  is.setstate(ios::failbit);
6793  else
6794  {
6795  while (is.rdstate() == std::ios::goodbit)
6796  {
6797  auto i = is.rdbuf()->sgetc();
6798  if (Traits::eq_int_type(i, Traits::eof()))
6799  {
6800  is.setstate(ios::eofbit);
6801  break;
6802  }
6803  auto wc = Traits::to_char_type(i);
6804  auto c = static_cast<char>(wc);
6805  // is c a valid time zone name or abbreviation character?
6806  if (!(CharT{1} < wc && wc < CharT{127}) || !(isalnum(c) ||
6807  c == '_' || c == '/' || c == '-' || c == '+'))
6808  break;
6809  temp_abbrev.push_back(c);
6810  is.rdbuf()->sbumpc();
6811  }
6812  if (temp_abbrev.empty())
6813  is.setstate(ios::failbit);
6814  }
6815  }
6816  else
6817  read(is, CharT{'%'}, width, modified, *fmt);
6818  command = nullptr;
6819  width = -1;
6820  modified = CharT{};
6821  }
6822  else
6823  read(is, *fmt);
6824  break;
6825  default:
6826  if (command)
6827  {
6828  if (width == -1 && modified == CharT{} && '0' <= *fmt && *fmt <= '9')
6829  {
6830  width = static_cast<char>(*fmt) - '0';
6831  while ('0' <= fmt[1] && fmt[1] <= '9')
6832  width = 10*width + static_cast<char>(*++fmt) - '0';
6833  }
6834  else
6835  {
6836  if (modified == CharT{})
6837  read(is, CharT{'%'}, width, *fmt);
6838  else
6839  read(is, CharT{'%'}, width, modified, *fmt);
6840  command = nullptr;
6841  width = -1;
6842  modified = CharT{};
6843  }
6844  }
6845  else // !command
6846  {
6847  if (isspace(*fmt))
6848  ws(is); // space matches 0 or more white space characters
6849  else
6850  read(is, *fmt);
6851  }
6852  break;
6853  }
6854  }
6855  // is.rdstate() != ios::goodbit || *fmt == CharT{}
6856  if (is.rdstate() == ios::goodbit && command)
6857  {
6858  if (modified == CharT{})
6859  read(is, CharT{'%'}, width);
6860  else
6861  read(is, CharT{'%'}, width, modified);
6862  }
6863  if (is.rdstate() != ios::goodbit && *fmt != CharT{} && !is.fail())
6864  is.setstate(ios::failbit);
6865  if (!is.fail())
6866  {
6867  if (y != not_a_2digit_year)
6868  {
6869  // Convert y and an optional C to Y
6870  if (!(0 <= y && y <= 99))
6871  goto broken;
6872  if (C == not_a_century)
6873  {
6874  if (Y == not_a_year)
6875  {
6876  if (y >= 69)
6877  C = 19;
6878  else
6879  C = 20;
6880  }
6881  else
6882  {
6883  C = (Y >= 0 ? Y : Y-100) / 100;
6884  }
6885  }
6886  int tY;
6887  if (C >= 0)
6888  tY = 100*C + y;
6889  else
6890  tY = 100*(C+1) - (y == 0 ? 100 : y);
6891  if (Y != not_a_year && Y != tY)
6892  goto broken;
6893  Y = tY;
6894  }
6895  if (g != not_a_2digit_year)
6896  {
6897  // Convert g and an optional C to G
6898  if (!(0 <= g && g <= 99))
6899  goto broken;
6900  if (C == not_a_century)
6901  {
6902  if (G == not_a_year)
6903  {
6904  if (g >= 69)
6905  C = 19;
6906  else
6907  C = 20;
6908  }
6909  else
6910  {
6911  C = (G >= 0 ? G : G-100) / 100;
6912  }
6913  }
6914  int tG;
6915  if (C >= 0)
6916  tG = 100*C + g;
6917  else
6918  tG = 100*(C+1) - (g == 0 ? 100 : g);
6919  if (G != not_a_year && G != tG)
6920  goto broken;
6921  G = tG;
6922  }
6923  if (G != not_a_year)
6924  {
6925  // Convert G, V and wd to Y, m and d
6926  if (V == not_a_week_num || wd == not_a_weekday)
6927  goto broken;
6928  auto ymd = year_month_day{local_days(year{G-1}/dec/thu[last]) +
6929  (mon-thu) + weeks{V-1} +
6930  (weekday{static_cast<unsigned>(wd)}-mon)};
6931  if (Y == not_a_year)
6932  Y = static_cast<int>(ymd.year());
6933  else if (year{Y} != ymd.year())
6934  goto broken;
6935  if (m == 0)
6936  m = static_cast<int>(static_cast<unsigned>(ymd.month()));
6937  else if (month(static_cast<unsigned>(m)) != ymd.month())
6938  goto broken;
6939  if (d == 0)
6940  d = static_cast<int>(static_cast<unsigned>(ymd.day()));
6941  else if (day(static_cast<unsigned>(d)) != ymd.day())
6942  goto broken;
6943  }
6944  if (j != 0 && Y != not_a_year)
6945  {
6946  auto ymd = year_month_day{local_days(year{Y}/1/1) + days{j-1}};
6947  if (m == 0)
6948  m = static_cast<int>(static_cast<unsigned>(ymd.month()));
6949  else if (month(static_cast<unsigned>(m)) != ymd.month())
6950  goto broken;
6951  if (d == 0)
6952  d = static_cast<int>(static_cast<unsigned>(ymd.day()));
6953  else if (day(static_cast<unsigned>(d)) != ymd.day())
6954  goto broken;
6955  }
6956  if (U != not_a_week_num && Y != not_a_year)
6957  {
6958  if (wd == not_a_weekday)
6959  goto broken;
6960  sys_days sd;
6961  if (U == 0)
6962  sd = year{Y-1}/dec/weekday{static_cast<unsigned>(wd)}[last];
6963  else
6964  sd = sys_days(year{Y}/jan/sun[1]) + weeks{U-1} +
6965  (weekday{static_cast<unsigned>(wd)} - sun);
6966  year_month_day ymd = sd;
6967  if (year{Y} != ymd.year())
6968  goto broken;
6969  if (m == 0)
6970  m = static_cast<int>(static_cast<unsigned>(ymd.month()));
6971  else if (month(static_cast<unsigned>(m)) != ymd.month())
6972  goto broken;
6973  if (d == 0)
6974  d = static_cast<int>(static_cast<unsigned>(ymd.day()));
6975  else if (day(static_cast<unsigned>(d)) != ymd.day())
6976  goto broken;
6977  }
6978  if (W != not_a_week_num && Y != not_a_year)
6979  {
6980  if (wd == not_a_weekday)
6981  goto broken;
6982  sys_days sd;
6983  if (W == 0)
6984  sd = year{Y-1}/dec/weekday{static_cast<unsigned>(wd)}[last];
6985  else
6986  sd = sys_days(year{Y}/jan/mon[1]) + weeks{W-1} +
6987  (weekday{static_cast<unsigned>(wd)} - mon);
6988  year_month_day ymd = sd;
6989  if (year{Y} != ymd.year())
6990  goto broken;
6991  if (m == 0)
6992  m = static_cast<int>(static_cast<unsigned>(ymd.month()));
6993  else if (month(static_cast<unsigned>(m)) != ymd.month())
6994  goto broken;
6995  if (d == 0)
6996  d = static_cast<int>(static_cast<unsigned>(ymd.day()));
6997  else if (day(static_cast<unsigned>(d)) != ymd.day())
6998  goto broken;
6999  }
7000  if (Y < static_cast<int>(year::min()) || Y > static_cast<int>(year::max()))
7001  Y = not_a_year;
7002  auto ymd = year{Y}/m/d;
7003  if (wd != not_a_weekday && ymd.ok())
7004  {
7005  if (weekday{static_cast<unsigned>(wd)} != weekday(ymd))
7006  goto broken;
7007  }
7008  fds.ymd = ymd;
7009  fds.tod = time_of_day<Duration>(hours{h} + minutes{min});
7011  if (wd != not_a_weekday)
7012  fds.wd = weekday{static_cast<unsigned>(wd)};
7013  if (abbrev != nullptr)
7014  *abbrev = std::move(temp_abbrev);
7015  if (offset != nullptr)
7016  *offset = temp_offset;
7017  }
7018  return is;
7019  }
7020 broken:
7021  is.setstate(ios_base::failbit);
7022  return is;
7023 }
7024 
7025 template <class CharT, class Traits, class Alloc = std::allocator<CharT>>
7026 std::basic_istream<CharT, Traits>&
7027 from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt, year& y,
7028  std::basic_string<CharT, Traits, Alloc>* abbrev = nullptr,
7029  std::chrono::minutes* offset = nullptr)
7030 {
7031  using namespace std;
7032  using namespace std::chrono;
7033  using CT = seconds;
7034  fields<CT> fds{};
7035  from_stream(is, fmt, fds, abbrev, offset);
7036  if (!fds.ymd.year().ok())
7037  is.setstate(ios::failbit);
7038  if (!is.fail())
7039  y = fds.ymd.year();
7040  return is;
7041 }
7042 
7043 template <class CharT, class Traits, class Alloc = std::allocator<CharT>>
7044 std::basic_istream<CharT, Traits>&
7045 from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt, month& m,
7046  std::basic_string<CharT, Traits, Alloc>* abbrev = nullptr,
7047  std::chrono::minutes* offset = nullptr)
7048 {
7049  using namespace std;
7050  using namespace std::chrono;
7051  using CT = seconds;
7052  fields<CT> fds{};
7053  from_stream(is, fmt, fds, abbrev, offset);
7054  if (!fds.ymd.month().ok())
7055  is.setstate(ios::failbit);
7056  if (!is.fail())
7057  m = fds.ymd.month();
7058  return is;
7059 }
7060 
7061 template <class CharT, class Traits, class Alloc = std::allocator<CharT>>
7062 std::basic_istream<CharT, Traits>&
7063 from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt, day& d,
7064  std::basic_string<CharT, Traits, Alloc>* abbrev = nullptr,
7065  std::chrono::minutes* offset = nullptr)
7066 {
7067  using namespace std;
7068  using namespace std::chrono;
7069  using CT = seconds;
7070  fields<CT> fds{};
7071  from_stream(is, fmt, fds, abbrev, offset);
7072  if (!fds.ymd.day().ok())
7073  is.setstate(ios::failbit);
7074  if (!is.fail())
7075  d = fds.ymd.day();
7076  return is;
7077 }
7078 
7079 template <class CharT, class Traits, class Alloc = std::allocator<CharT>>
7080 std::basic_istream<CharT, Traits>&
7081 from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt, weekday& wd,
7082  std::basic_string<CharT, Traits, Alloc>* abbrev = nullptr,
7083  std::chrono::minutes* offset = nullptr)
7084 {
7085  using namespace std;
7086  using namespace std::chrono;
7087  using CT = seconds;
7088  fields<CT> fds{};
7089  from_stream(is, fmt, fds, abbrev, offset);
7090  if (!fds.wd.ok())
7091  is.setstate(ios::failbit);
7092  if (!is.fail())
7093  wd = fds.wd;
7094  return is;
7095 }
7096 
7097 template <class CharT, class Traits, class Alloc = std::allocator<CharT>>
7098 std::basic_istream<CharT, Traits>&
7099 from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt, year_month& ym,
7100  std::basic_string<CharT, Traits, Alloc>* abbrev = nullptr,
7101  std::chrono::minutes* offset = nullptr)
7102 {
7103  using namespace std;
7104  using namespace std::chrono;
7105  using CT = seconds;
7106  fields<CT> fds{};
7107  from_stream(is, fmt, fds, abbrev, offset);
7108  if (!fds.ymd.month().ok())
7109  is.setstate(ios::failbit);
7110  if (!is.fail())
7111  ym = fds.ymd.year()/fds.ymd.month();
7112  return is;
7113 }
7114 
7115 template <class CharT, class Traits, class Alloc = std::allocator<CharT>>
7116 std::basic_istream<CharT, Traits>&
7117 from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt, month_day& md,
7118  std::basic_string<CharT, Traits, Alloc>* abbrev = nullptr,
7119  std::chrono::minutes* offset = nullptr)
7120 {
7121  using namespace std;
7122  using namespace std::chrono;
7123  using CT = seconds;
7124  fields<CT> fds{};
7125  from_stream(is, fmt, fds, abbrev, offset);
7126  if (!fds.ymd.month().ok() || !fds.ymd.day().ok())
7127  is.setstate(ios::failbit);
7128  if (!is.fail())
7129  md = fds.ymd.month()/fds.ymd.day();
7130  return is;
7131 }
7132 
7133 template <class CharT, class Traits, class Alloc = std::allocator<CharT>>
7134 std::basic_istream<CharT, Traits>&
7135 from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
7136  year_month_day& ymd, std::basic_string<CharT, Traits, Alloc>* abbrev = nullptr,
7137  std::chrono::minutes* offset = nullptr)
7138 {
7139  using namespace std;
7140  using namespace std::chrono;
7141  using CT = seconds;
7142  fields<CT> fds{};
7143  from_stream(is, fmt, fds, abbrev, offset);
7144  if (!fds.ymd.ok())
7145  is.setstate(ios::failbit);
7146  if (!is.fail())
7147  ymd = fds.ymd;
7148  return is;
7149 }
7150 
7151 template <class Duration, class CharT, class Traits, class Alloc = std::allocator<CharT>>
7152 std::basic_istream<CharT, Traits>&
7153 from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
7154  sys_time<Duration>& tp, std::basic_string<CharT, Traits, Alloc>* abbrev = nullptr,
7155  std::chrono::minutes* offset = nullptr)
7156 {
7157  using namespace std;
7158  using namespace std::chrono;
7159  using CT = typename common_type<Duration, seconds>::type;
7160  minutes offset_local{};
7161  auto offptr = offset ? offset : &offset_local;
7162  fields<CT> fds{};
7163  from_stream(is, fmt, fds, abbrev, offptr);
7164  if (!fds.ymd.ok() || !fds.tod.in_conventional_range())
7165  is.setstate(ios::failbit);
7166  if (!is.fail())
7167  tp = round<Duration>(sys_days(fds.ymd) - *offptr + fds.tod.to_duration());
7168  return is;
7169 }
7170 
7171 template <class Duration, class CharT, class Traits, class Alloc = std::allocator<CharT>>
7172 std::basic_istream<CharT, Traits>&
7173 from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
7174  local_time<Duration>& tp, std::basic_string<CharT, Traits, Alloc>* abbrev = nullptr,
7175  std::chrono::minutes* offset = nullptr)
7176 {
7177  using namespace std;
7178  using namespace std::chrono;
7179  using CT = typename common_type<Duration, seconds>::type;
7180  fields<CT> fds{};
7181  from_stream(is, fmt, fds, abbrev, offset);
7182  if (!fds.ymd.ok() || !fds.tod.in_conventional_range())
7183  is.setstate(ios::failbit);
7184  if (!is.fail())
7185  tp = round<Duration>(local_seconds{local_days(fds.ymd)} + fds.tod.to_duration());
7186  return is;
7187 }
7188 
7189 template <class Rep, class Period, class CharT, class Traits, class Alloc = std::allocator<CharT>>
7190 std::basic_istream<CharT, Traits>&
7191 from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
7192  std::chrono::duration<Rep, Period>& d,
7193  std::basic_string<CharT, Traits, Alloc>* abbrev = nullptr,
7194  std::chrono::minutes* offset = nullptr)
7195 {
7196  using namespace std;
7197  using namespace std::chrono;
7198  using Duration = std::chrono::duration<Rep, Period>;
7199  using CT = typename common_type<Duration, seconds>::type;
7200  fields<CT> fds{};
7201  from_stream(is, fmt, fds, abbrev, offset);
7202  if (!is.fail())
7203  d = duration_cast<Duration>(fds.tod.to_duration());
7204  return is;
7205 }
7206 
7207 template <class Parsable, class CharT, class Traits = std::char_traits<CharT>,
7208  class Alloc = std::allocator<CharT>>
7210 {
7211  const std::basic_string<CharT, Traits, Alloc> format_;
7212  Parsable& tp_;
7213  std::basic_string<CharT, Traits, Alloc>* abbrev_;
7214  std::chrono::minutes* offset_;
7215 
7216 public:
7217  parse_manip(std::basic_string<CharT, Traits, Alloc> format, Parsable& tp,
7218  std::basic_string<CharT, Traits, Alloc>* abbrev = nullptr,
7219  std::chrono::minutes* offset = nullptr)
7220  : format_(std::move(format))
7221  , tp_(tp)
7222  , abbrev_(abbrev)
7223  , offset_(offset)
7224  {}
7225 
7226 };
7227 
7228 template <class Parsable, class CharT, class Traits, class Alloc>
7229 std::basic_istream<CharT, Traits>&
7230 operator>>(std::basic_istream<CharT, Traits>& is,
7232 {
7233  return from_stream(is, x.format_.c_str(), x.tp_, x.abbrev_, x.offset_);
7234 }
7235 
7236 template <class Parsable, class CharT, class Traits, class Alloc>
7237 inline
7238 auto
7239 parse(const std::basic_string<CharT, Traits, Alloc>& format, Parsable& tp)
7240  -> decltype(from_stream(std::declval<std::basic_istream<CharT, Traits>&>(),
7241  format.c_str(), tp),
7243 {
7244  return {format, tp};
7245 }
7246 
7247 template <class Parsable, class CharT, class Traits, class Alloc>
7248 inline
7249 auto
7250 parse(const std::basic_string<CharT, Traits, Alloc>& format, Parsable& tp,
7251  std::basic_string<CharT, Traits, Alloc>& abbrev)
7252  -> decltype(from_stream(std::declval<std::basic_istream<CharT, Traits>&>(),
7253  format.c_str(), tp, &abbrev),
7255 {
7256  return {format, tp, &abbrev};
7257 }
7258 
7259 template <class Parsable, class CharT, class Traits, class Alloc>
7260 inline
7261 auto
7262 parse(const std::basic_string<CharT, Traits, Alloc>& format, Parsable& tp,
7263  std::chrono::minutes& offset)
7264  -> decltype(from_stream(std::declval<std::basic_istream<CharT, Traits>&>(),
7265  format.c_str(), tp, nullptr, &offset),
7266  parse_manip<Parsable, CharT, Traits, Alloc>{format, tp, nullptr, &offset})
7267 {
7268  return {format, tp, nullptr, &offset};
7269 }
7270 
7271 template <class Parsable, class CharT, class Traits, class Alloc>
7272 inline
7273 auto
7274 parse(const std::basic_string<CharT, Traits, Alloc>& format, Parsable& tp,
7275  std::basic_string<CharT, Traits, Alloc>& abbrev, std::chrono::minutes& offset)
7276  -> decltype(from_stream(std::declval<std::basic_istream<CharT, Traits>&>(),
7277  format.c_str(), tp, &abbrev, &offset),
7278  parse_manip<Parsable, CharT, Traits, Alloc>{format, tp, &abbrev, &offset})
7279 {
7280  return {format, tp, &abbrev, &offset};
7281 }
7282 
7283 // const CharT* formats
7284 
7285 template <class Parsable, class CharT>
7286 inline
7287 auto
7288 parse(const CharT* format, Parsable& tp)
7289  -> decltype(from_stream(std::declval<std::basic_istream<CharT>&>(), format, tp),
7291 {
7292  return {format, tp};
7293 }
7294 
7295 template <class Parsable, class CharT, class Traits, class Alloc>
7296 inline
7297 auto
7298 parse(const CharT* format, Parsable& tp, std::basic_string<CharT, Traits, Alloc>& abbrev)
7299  -> decltype(from_stream(std::declval<std::basic_istream<CharT, Traits>&>(), format,
7300  tp, &abbrev),
7302 {
7303  return {format, tp, &abbrev};
7304 }
7305 
7306 template <class Parsable, class CharT>
7307 inline
7308 auto
7309 parse(const CharT* format, Parsable& tp, std::chrono::minutes& offset)
7310  -> decltype(from_stream(std::declval<std::basic_istream<CharT>&>(), format,
7311  tp, nullptr, &offset),
7312  parse_manip<Parsable, CharT>{format, tp, nullptr, &offset})
7313 {
7314  return {format, tp, nullptr, &offset};
7315 }
7316 
7317 template <class Parsable, class CharT, class Traits, class Alloc>
7318 inline
7319 auto
7320 parse(const CharT* format, Parsable& tp,
7321  std::basic_string<CharT, Traits, Alloc>& abbrev, std::chrono::minutes& offset)
7322  -> decltype(from_stream(std::declval<std::basic_istream<CharT, Traits>&>(), format,
7323  tp, &abbrev, &offset),
7324  parse_manip<Parsable, CharT, Traits, Alloc>{format, tp, &abbrev, &offset})
7325 {
7326  return {format, tp, &abbrev, &offset};
7327 }
7328 
7329 // duration streaming
7330 
7331 namespace detail
7332 {
7333 
7334 #if __cplusplus >= 201402 && (!defined(__EDG_VERSION__) || __EDG_VERSION__ > 411) \
7335  && (!defined(__SUNPRO_CC) || __SUNPRO_CC > 0x5150)
7336 
7337 template <class CharT, std::size_t N>
7338 class string_literal
7339 {
7340  CharT p_[N];
7341 
7342 public:
7343  using const_iterator = const CharT*;
7344 
7345  string_literal(string_literal const&) = default;
7346  string_literal& operator=(string_literal const&) = delete;
7347 
7348  template <std::size_t N1 = 2,
7349  class = std::enable_if_t<N1 == N>>
7350  CONSTCD14 string_literal(CharT c) NOEXCEPT
7351  : p_{c}
7352  {
7353  }
7354 
7355  CONSTCD14 string_literal(const CharT(&a)[N]) NOEXCEPT
7356  : p_{}
7357  {
7358  for (std::size_t i = 0; i < N; ++i)
7359  p_[i] = a[i];
7360  }
7361 
7362  template <class U = CharT, class = std::enable_if_t<1 < sizeof(U)>>
7363  CONSTCD14 string_literal(const char(&a)[N]) NOEXCEPT
7364  : p_{}
7365  {
7366  for (std::size_t i = 0; i < N; ++i)
7367  p_[i] = a[i];
7368  }
7369 
7370  template <class CharT2, class = std::enable_if_t<!std::is_same<CharT2, CharT>{}>>
7371  CONSTCD14 string_literal(string_literal<CharT2, N> const& a) NOEXCEPT
7372  : p_{}
7373  {
7374  for (std::size_t i = 0; i < N; ++i)
7375  p_[i] = a[i];
7376  }
7377 
7378  template <std::size_t N1, std::size_t N2,
7379  class = std::enable_if_t<N1 + N2 - 1 == N>>
7380  CONSTCD14 string_literal(const string_literal<CharT, N1>& x,
7381  const string_literal<CharT, N2>& y) NOEXCEPT
7382  : p_{}
7383  {
7384  std::size_t i = 0;
7385  for (; i < N1-1; ++i)
7386  p_[i] = x[i];
7387  for (std::size_t j = 0; j < N2; ++j, ++i)
7388  p_[i] = y[j];
7389  }
7390 
7391  CONSTCD14 const CharT* data() const NOEXCEPT {return p_;}
7392  CONSTCD14 std::size_t size() const NOEXCEPT {return N-1;}
7393 
7394  CONSTCD14 const_iterator begin() const NOEXCEPT {return p_;}
7395  CONSTCD14 const_iterator end() const NOEXCEPT {return p_ + N-1;}
7396 
7397  CONSTCD14 CharT const& operator[](std::size_t n) const NOEXCEPT
7398  {
7399  return p_[n];
7400  }
7401 
7402  template <class Traits>
7403  friend
7404  std::basic_ostream<CharT, Traits>&
7405  operator<<(std::basic_ostream<CharT, Traits>& os, const string_literal& s)
7406  {
7407  return os << s.p_;
7408  }
7409 };
7410 
7411 template <class CharT1, class CharT2, std::size_t N1, std::size_t N2>
7412 CONSTCD14
7413 inline
7414 string_literal<std::conditional_t<sizeof(CharT2) <= sizeof(CharT1), CharT1, CharT2>,
7415  N1 + N2 - 1>
7416 operator+(const string_literal<CharT1, N1>& x, const string_literal<CharT2, N2>& y) NOEXCEPT
7417 {
7418  using CharT = std::conditional_t<sizeof(CharT2) <= sizeof(CharT1), CharT1, CharT2>;
7419  return string_literal<CharT, N1 + N2 - 1>{string_literal<CharT, N1>{x},
7420  string_literal<CharT, N2>{y}};
7421 }
7422 
7423 template <class CharT, class Traits, class Alloc, std::size_t N>
7424 inline
7425 std::basic_string<CharT, Traits, Alloc>
7426 operator+(std::basic_string<CharT, Traits, Alloc> x,
7427  const string_literal<CharT, N>& y) NOEXCEPT
7428 {
7429  x.append(y.data(), y.size());
7430  return x;
7431 }
7432 
7433 template <class CharT, std::size_t N>
7434 CONSTCD14
7435 inline
7436 string_literal<CharT, N>
7437 msl(const CharT(&a)[N]) NOEXCEPT
7438 {
7439  return string_literal<CharT, N>{a};
7440 }
7441 
7442 template <class CharT,
7443  class = std::enable_if_t<std::is_same<CharT, char>{} ||
7444  std::is_same<CharT, wchar_t>{} ||
7445  std::is_same<CharT, char16_t>{} ||
7446  std::is_same<CharT, char32_t>{}>>
7447 CONSTCD14
7448 inline
7449 string_literal<CharT, 2>
7450 msl(CharT c) NOEXCEPT
7451 {
7452  return string_literal<CharT, 2>{c};
7453 }
7454 
7455 CONSTCD14
7456 inline
7457 std::size_t
7458 to_string_len(std::intmax_t i)
7459 {
7460  std::size_t r = 0;
7461  do
7462  {
7463  i /= 10;
7464  ++r;
7465  } while (i > 0);
7466  return r;
7467 }
7468 
7469 template <std::intmax_t N>
7470 CONSTCD14
7471 inline
7473 <
7474  N < 10,
7475  string_literal<char, to_string_len(N)+1>
7476 >
7477 msl() NOEXCEPT
7478 {
7479  return msl(char(N % 10 + '0'));
7480 }
7481 
7482 template <std::intmax_t N>
7483 CONSTCD14
7484 inline
7486 <
7487  10 <= N,
7488  string_literal<char, to_string_len(N)+1>
7489 >
7490 msl() NOEXCEPT
7491 {
7492  return msl<N/10>() + msl(char(N % 10 + '0'));
7493 }
7494 
7495 template <class CharT, std::intmax_t N, std::intmax_t D>
7496 CONSTCD14
7497 inline
7498 std::enable_if_t
7499 <
7500  std::ratio<N, D>::type::den != 1,
7501  string_literal<CharT, to_string_len(std::ratio<N, D>::type::num) +
7502  to_string_len(std::ratio<N, D>::type::den) + 4>
7503 >
7504 msl(std::ratio<N, D>) NOEXCEPT
7505 {
7506  using R = typename std::ratio<N, D>::type;
7507  return msl(CharT{'['}) + msl<R::num>() + msl(CharT{'/'}) +
7508  msl<R::den>() + msl(CharT{']'});
7509 }
7510 
7511 template <class CharT, std::intmax_t N, std::intmax_t D>
7512 CONSTCD14
7513 inline
7514 std::enable_if_t
7515 <
7516  std::ratio<N, D>::type::den == 1,
7517  string_literal<CharT, to_string_len(std::ratio<N, D>::type::num) + 3>
7518 >
7519 msl(std::ratio<N, D>) NOEXCEPT
7520 {
7521  using R = typename std::ratio<N, D>::type;
7522  return msl(CharT{'['}) + msl<R::num>() + msl(CharT{']'});
7523 }
7524 
7525 template <class CharT>
7526 CONSTCD14
7527 inline
7528 auto
7529 msl(std::atto) NOEXCEPT
7530 {
7531  return msl(CharT{'a'});
7532 }
7533 
7534 template <class CharT>
7535 CONSTCD14
7536 inline
7537 auto
7538 msl(std::femto) NOEXCEPT
7539 {
7540  return msl(CharT{'f'});
7541 }
7542 
7543 template <class CharT>
7544 CONSTCD14
7545 inline
7546 auto
7547 msl(std::pico) NOEXCEPT
7548 {
7549  return msl(CharT{'p'});
7550 }
7551 
7552 template <class CharT>
7553 CONSTCD14
7554 inline
7555 auto
7556 msl(std::nano) NOEXCEPT
7557 {
7558  return msl(CharT{'n'});
7559 }
7560 
7561 template <class CharT>
7562 CONSTCD14
7563 inline
7564 std::enable_if_t
7565 <
7566  std::is_same<CharT, char>{},
7567  string_literal<char, 3>
7568 >
7569 msl(std::micro) NOEXCEPT
7570 {
7571  return string_literal<char, 3>{"\xC2\xB5"};
7572 }
7573 
7574 template <class CharT>
7575 CONSTCD14
7576 inline
7577 std::enable_if_t
7578 <
7579  !std::is_same<CharT, char>{},
7580  string_literal<CharT, 2>
7581 >
7582 msl(std::micro) NOEXCEPT
7583 {
7584  return string_literal<CharT, 2>{CharT{static_cast<unsigned char>('\xB5')}};
7585 }
7586 
7587 template <class CharT>
7588 CONSTCD14
7589 inline
7590 auto
7591 msl(std::milli) NOEXCEPT
7592 {
7593  return msl(CharT{'m'});
7594 }
7595 
7596 template <class CharT>
7597 CONSTCD14
7598 inline
7599 auto
7600 msl(std::centi) NOEXCEPT
7601 {
7602  return msl(CharT{'c'});
7603 }
7604 
7605 template <class CharT>
7606 CONSTCD14
7607 inline
7608 auto
7609 msl(std::deci) NOEXCEPT
7610 {
7611  return msl(CharT{'d'});
7612 }
7613 
7614 template <class CharT>
7615 CONSTCD14
7616 inline
7617 auto
7618 msl(std::deca) NOEXCEPT
7619 {
7620  return string_literal<CharT, 3>{"da"};
7621 }
7622 
7623 template <class CharT>
7624 CONSTCD14
7625 inline
7626 auto
7627 msl(std::hecto) NOEXCEPT
7628 {
7629  return msl(CharT{'h'});
7630 }
7631 
7632 template <class CharT>
7633 CONSTCD14
7634 inline
7635 auto
7636 msl(std::kilo) NOEXCEPT
7637 {
7638  return msl(CharT{'k'});
7639 }
7640 
7641 template <class CharT>
7642 CONSTCD14
7643 inline
7644 auto
7645 msl(std::mega) NOEXCEPT
7646 {
7647  return msl(CharT{'M'});
7648 }
7649 
7650 template <class CharT>
7651 CONSTCD14
7652 inline
7653 auto
7654 msl(std::giga) NOEXCEPT
7655 {
7656  return msl(CharT{'G'});
7657 }
7658 
7659 template <class CharT>
7660 CONSTCD14
7661 inline
7662 auto
7663 msl(std::tera) NOEXCEPT
7664 {
7665  return msl(CharT{'T'});
7666 }
7667 
7668 template <class CharT>
7669 CONSTCD14
7670 inline
7671 auto
7672 msl(std::peta) NOEXCEPT
7673 {
7674  return msl(CharT{'P'});
7675 }
7676 
7677 template <class CharT>
7678 CONSTCD14
7679 inline
7680 auto
7681 msl(std::exa) NOEXCEPT
7682 {
7683  return msl(CharT{'E'});
7684 }
7685 
7686 template <class CharT, class Period>
7687 CONSTCD14
7688 auto
7689 get_units(Period p)
7690 {
7691  return msl<CharT>(p) + string_literal<CharT, 2>{"s"};
7692 }
7693 
7694 template <class CharT>
7695 CONSTCD14
7696 auto
7697 get_units(std::ratio<1>)
7698 {
7699  return string_literal<CharT, 2>{"s"};
7700 }
7701 
7702 template <class CharT>
7703 CONSTCD14
7704 auto
7705 get_units(std::ratio<60>)
7706 {
7707  return string_literal<CharT, 4>{"min"};
7708 }
7709 
7710 template <class CharT>
7711 CONSTCD14
7712 auto
7713 get_units(std::ratio<3600>)
7714 {
7715  return string_literal<CharT, 2>{"h"};
7716 }
7717 
7718 #else // __cplusplus < 201402 || (defined(__EDG_VERSION__) && __EDG_VERSION__ <= 411)
7719 
7720 inline
7721 std::string
7722 to_string(std::uint64_t x)
7723 {
7724  return std::to_string(x);
7725 }
7726 
7727 template <class CharT>
7728 std::basic_string<CharT>
7729 to_string(std::uint64_t x)
7730 {
7731  auto y = std::to_string(x);
7732  return std::basic_string<CharT>(y.begin(), y.end());
7733 }
7734 
7735 template <class CharT, std::intmax_t N, std::intmax_t D>
7736 inline
7737 typename std::enable_if
7738 <
7739  std::ratio<N, D>::type::den != 1,
7740  std::basic_string<CharT>
7741 >::type
7742 msl(std::ratio<N, D>)
7743 {
7744  using R = typename std::ratio<N, D>::type;
7745  return std::basic_string<CharT>(1, '[') + to_string<CharT>(R::num) + CharT{'/'} +
7746  to_string<CharT>(R::den) + CharT{']'};
7747 }
7748 
7749 template <class CharT, std::intmax_t N, std::intmax_t D>
7750 inline
7751 typename std::enable_if
7752 <
7753  std::ratio<N, D>::type::den == 1,
7754  std::basic_string<CharT>
7755 >::type
7756 msl(std::ratio<N, D>)
7757 {
7758  using R = typename std::ratio<N, D>::type;
7759  return std::basic_string<CharT>(1, '[') + to_string<CharT>(R::num) + CharT{']'};
7760 }
7761 
7762 template <class CharT>
7763 inline
7764 std::basic_string<CharT>
7765 msl(std::atto)
7766 {
7767  return {'a'};
7768 }
7769 
7770 template <class CharT>
7771 inline
7772 std::basic_string<CharT>
7773 msl(std::femto)
7774 {
7775  return {'f'};
7776 }
7777 
7778 template <class CharT>
7779 inline
7780 std::basic_string<CharT>
7781 msl(std::pico)
7782 {
7783  return {'p'};
7784 }
7785 
7786 template <class CharT>
7787 inline
7788 std::basic_string<CharT>
7789 msl(std::nano)
7790 {
7791  return {'n'};
7792 }
7793 
7794 template <class CharT>
7795 inline
7796 typename std::enable_if
7797 <
7798  std::is_same<CharT, char>::value,
7799  std::string
7800 >::type
7801 msl(std::micro)
7802 {
7803  return "\xC2\xB5";
7804 }
7805 
7806 template <class CharT>
7807 inline
7808 typename std::enable_if
7809 <
7810  !std::is_same<CharT, char>::value,
7811  std::basic_string<CharT>
7812 >::type
7813 msl(std::micro)
7814 {
7815  return {CharT(static_cast<unsigned char>('\xB5'))};
7816 }
7817 
7818 template <class CharT>
7819 inline
7820 std::basic_string<CharT>
7821 msl(std::milli)
7822 {
7823  return {'m'};
7824 }
7825 
7826 template <class CharT>
7827 inline
7828 std::basic_string<CharT>
7829 msl(std::centi)
7830 {
7831  return {'c'};
7832 }
7833 
7834 template <class CharT>
7835 inline
7836 std::basic_string<CharT>
7837 msl(std::deci)
7838 {
7839  return {'d'};
7840 }
7841 
7842 template <class CharT>
7843 inline
7844 std::basic_string<CharT>
7845 msl(std::deca)
7846 {
7847  return {'d', 'a'};
7848 }
7849 
7850 template <class CharT>
7851 inline
7852 std::basic_string<CharT>
7853 msl(std::hecto)
7854 {
7855  return {'h'};
7856 }
7857 
7858 template <class CharT>
7859 inline
7860 std::basic_string<CharT>
7861 msl(std::kilo)
7862 {
7863  return {'k'};
7864 }
7865 
7866 template <class CharT>
7867 inline
7868 std::basic_string<CharT>
7869 msl(std::mega)
7870 {
7871  return {'M'};
7872 }
7873 
7874 template <class CharT>
7875 inline
7876 std::basic_string<CharT>
7877 msl(std::giga)
7878 {
7879  return {'G'};
7880 }
7881 
7882 template <class CharT>
7883 inline
7884 std::basic_string<CharT>
7885 msl(std::tera)
7886 {
7887  return {'T'};
7888 }
7889 
7890 template <class CharT>
7891 inline
7892 std::basic_string<CharT>
7893 msl(std::peta)
7894 {
7895  return {'P'};
7896 }
7897 
7898 template <class CharT>
7899 inline
7900 std::basic_string<CharT>
7901 msl(std::exa)
7902 {
7903  return {'E'};
7904 }
7905 
7906 template <class CharT, class Period>
7907 std::basic_string<CharT>
7908 get_units(Period p)
7909 {
7910  return msl<CharT>(p) + CharT{'s'};
7911 }
7912 
7913 template <class CharT>
7914 std::basic_string<CharT>
7915 get_units(std::ratio<1>)
7916 {
7917  return {'s'};
7918 }
7919 
7920 template <class CharT>
7921 std::basic_string<CharT>
7922 get_units(std::ratio<60>)
7923 {
7924  return {'m', 'i', 'n'};
7925 }
7926 
7927 template <class CharT>
7928 std::basic_string<CharT>
7929 get_units(std::ratio<3600>)
7930 {
7931  return {'h'};
7932 }
7933 
7934 #endif // __cplusplus < 201402 || (defined(__EDG_VERSION__) && __EDG_VERSION__ <= 411)
7935 
7936 template <class CharT, class Traits = std::char_traits<CharT>>
7938 
7939 template <>
7940 struct make_string<char>
7941 {
7942  template <class Rep>
7943  static
7944  std::string
7945  from(Rep n)
7946  {
7947  return std::to_string(n);
7948  }
7949 };
7950 
7951 template <class Traits>
7952 struct make_string<char, Traits>
7953 {
7954  template <class Rep>
7955  static
7956  std::basic_string<char, Traits>
7957  from(Rep n)
7958  {
7959  auto s = std::to_string(n);
7960  return std::basic_string<char, Traits>(s.begin(), s.end());
7961  }
7962 };
7963 
7964 template <>
7965 struct make_string<wchar_t>
7966 {
7967  template <class Rep>
7968  static
7969  std::wstring
7970  from(Rep n)
7971  {
7972  return std::to_wstring(n);
7973  }
7974 };
7975 
7976 template <class Traits>
7977 struct make_string<wchar_t, Traits>
7978 {
7979  template <class Rep>
7980  static
7981  std::basic_string<wchar_t, Traits>
7982  from(Rep n)
7983  {
7984  auto s = std::to_wstring(n);
7985  return std::basic_string<wchar_t, Traits>(s.begin(), s.end());
7986  }
7987 };
7988 
7989 } // namespace detail
7990 
7991 template <class CharT, class Traits, class Rep, class Period>
7992 inline
7993 std::basic_ostream<CharT, Traits>&
7994 operator<<(std::basic_ostream<CharT, Traits>& os,
7995  const std::chrono::duration<Rep, Period>& d)
7996 {
7997  using namespace detail;
7998  return os << make_string<CharT, Traits>::from(d.count()) +
7999  get_units<CharT>(typename Period::type{});
8000 }
8001 
8002 } // namespace date
8003 
8004 
8005 #ifdef __GNUC__
8006 # pragma GCC diagnostic pop
8007 #endif
8008 
8009 
8010 #endif // DATE_H
constexpr decimal_format_seconds(const Duration &d) noexcept
Definition: date.h:3643
unsigned read_unsigned(std::basic_istream< CharT, Traits > &is, unsigned m=1, unsigned M=10)
Definition: date.h:5734
short y_
Definition: date.h:367
unsigned char index_
Definition: date.h:455
date::month m_
Definition: date.h:539
sys_time< days > sys_days
Definition: date.h:163
std::chrono::time_point< std::chrono::system_clock, Duration > sys_time
Definition: date.h:161
fields(weekday wd_)
Definition: date.h:4350
constexpr std::enable_if< std::numeric_limits< Rep >::is_signed, std::chrono::duration< Rep, Period > >::type abs(std::chrono::duration< Rep, Period > d)
Definition: date.h:3754
constexpr date::month month() const noexcept
Definition: date.h:2143
date::weekday_indexed wdi_
Definition: date.h:762
constexpr time_of_day_storage(std::chrono::hours h, std::chrono::minutes m, unsigned md) noexcept
Definition: date.h:3959
constexpr const date::month dec
Definition: date.h:1847
unsigned M
Definition: date.h:5826
unsigned m
Definition: date.h:5832
precision to_duration() const noexcept
Definition: date.h:3700
month & operator+=(const months &m) noexcept
Definition: date.h:1376
constexpr date::month month() const noexcept
Definition: date.h:2432
constexpr time_of_day_storage(std::chrono::hours h, std::chrono::minutes m, std::chrono::seconds s, precision sub_s, unsigned md) noexcept
Definition: date.h:4153
constexpr bool operator!=(const day &x, const day &y) noexcept
Definition: date.h:1282
constexpr const date::last_spec last
Definition: date.h:1834
constexpr time_of_day(Arg0 &&arg0, Arg1 &&arg1, Args &&...args) noexcept
Definition: date.h:4253
constexpr bool operator>=(const day &x, const day &y) noexcept
Definition: date.h:1314
constexpr bool operator==(const day &x, const day &y) noexcept
Definition: date.h:1274
constexpr unsigned index() const noexcept
Definition: date.h:2910
constexpr precision subseconds() const noexcept
Definition: date.h:3650
constexpr time_of_day< std::chrono::duration< Rep, Period > > make_time(const std::chrono::duration< Rep, Period > &d)
Definition: date.h:4264
year_month_weekday_last & operator+=(const months &m) noexcept
Definition: date.h:3060
static constexpr year min() noexcept
Definition: date.h:1560
constexpr day operator-(const day &x, const days &y) noexcept
Definition: date.h:1347
weekday & operator++() noexcept
Definition: date.h:1695
#define NOEXCEPT
Definition: date.h:124
std::ios::fmtflags flags_
Definition: date.h:949
constexpr weekday_indexed operator[](unsigned index) const noexcept
Definition: date.h:1908
constexpr date::month month() const noexcept
Definition: date.h:3094
constexpr const date::month may
Definition: date.h:1840
constexpr std::chrono::time_point< Clock, To > floor(const std::chrono::time_point< Clock, FromDuration > &tp)
Definition: date.h:1211
days to_days() const noexcept
Definition: date.h:2964
constexpr date::day day() const noexcept
Definition: date.h:2144
year_month_day & operator+=(const months &m) noexcept
Definition: date.h:2624
year_month_weekday & operator+=(const months &m) noexcept
Definition: date.h:2863
std::basic_istream< CharT, Traits > & operator>>(std::basic_istream< CharT, Traits > &is, const parse_manip< Parsable, CharT, Traits, Alloc > &x)
Definition: date.h:7230
constexpr bool ok() const noexcept
Definition: date.h:2475
std::ratio< mul< n1, d2, !value >::value, mul< n2, d1, !value >::value > type
Definition: date.h:1077
std::chrono::duration< Rep, std::micro > type
Definition: date.h:3618
constexpr bool in_conventional_range() const noexcept
Definition: date.h:3799
constexpr date::year year() const noexcept
Definition: date.h:2431
days to_days() const noexcept
Definition: date.h:3137
void read(std::basic_istream< CharT, Traits > &)
Definition: date.h:5845
constexpr bool ok() const noexcept
Definition: date.h:1392
constexpr const date::weekday mon
Definition: date.h:1850
year_month & operator-=(const months &dm) noexcept
Definition: date.h:1992
std::basic_istream< CharT, Traits > & from_stream(std::basic_istream< CharT, Traits > &is, const CharT *fmt, fields< Duration > &fds, std::basic_string< CharT, Traits, Alloc > *abbrev=nullptr, std::chrono::minutes *offset=nullptr)
Definition: date.h:5951
date::month m_
Definition: date.h:591
typename make_void< Ts... >::type void_t
A copy of std::void_t from C++17 - same reasoning as enable_if_t, it does not hurt to redefine...
Definition: CLI11.hpp:924
constexpr const date::weekday fri
Definition: date.h:1854
constexpr date::weekday weekday() const noexcept
Definition: date.h:2902
constexpr bool is_leap() const noexcept
Definition: date.h:1542
day & operator++() noexcept
Definition: date.h:1262
constexpr bool ok() const noexcept
Definition: date.h:1978
constexpr date::month month() const noexcept
Definition: date.h:2221
static std::basic_string< wchar_t, Traits > from(Rep n)
Definition: date.h:7982
constexpr std::chrono::seconds seconds() const noexcept
Definition: date.h:3699
typename std::common_type< typename std::common_type< Duration, std::chrono::seconds >::type, std::chrono::seconds >::type::rep rep
Definition: date.h:3629
year & operator-=(const years &y) noexcept
Definition: date.h:1535
date::year y_
Definition: date.h:497
unsigned m
Definition: date.h:5825
STL namespace.
std::chrono::hours h_
Definition: date.h:3775
std::chrono::minutes * offset_
Definition: date.h:7214
std::basic_string< CharT > get_units(std::ratio< 3600 >)
Definition: date.h:7929
Definition: date.h:79
constexpr date::weekday weekday() const noexcept
Definition: date.h:1866
fields(year_month_day ymd_)
Definition: date.h:4349
constexpr year operator-() const noexcept
Definition: date.h:1536
bool ok() const noexcept
Definition: date.h:2693
static year_month_weekday from_days(days dp) noexcept
Definition: date.h:2953
std::enable_if< detail::no_overflow< Period, typename To::period >::value, To >::type floor(const std::chrono::duration< Rep, Period > &d)
Definition: date.h:1134
constexpr const date::weekday tue
Definition: date.h:1851
constexpr date::year year() const noexcept
Definition: date.h:2617
std::string type(const x_type &a_param)
Definition: typename.hh:24
long double & i
Definition: date.h:5838
constexpr const date::month jul
Definition: date.h:1842
constexpr time_of_day_storage(std::chrono::hours h, std::chrono::minutes m, std::chrono::seconds s, unsigned md) noexcept
Definition: date.h:4045
auto format(const std::locale &loc, const CharT *fmt, const Streamable &tp) -> decltype(to_stream(std::declval< std::basic_ostream< CharT > &>(), fmt, tp), std::basic_string< CharT >
Definition: date.h:5663
std::basic_string< CharT, Traits, Alloc > * abbrev_
Definition: date.h:7213
date::month m_
Definition: date.h:614
constexpr bool ok() const noexcept
Definition: date.h:1725
To ceil(const std::chrono::duration< Rep, Period > &d)
Definition: date.h:1186
constexpr date::month month() const noexcept
Definition: date.h:2897
constexpr date::weekday_indexed weekday_indexed() const noexcept
Definition: date.h:2296
constexpr date::weekday weekday() const noexcept
Definition: date.h:1931
std::basic_string< CharT > msl(std::exa)
Definition: date.h:7901
std::chrono::duration< rep > precision
Definition: date.h:3686
constexpr bool ok() const noexcept
Definition: date.h:1876
month & operator--() noexcept
Definition: date.h:1370
constexpr year_month_day_last(const date::year &y, const date::month_day_last &mdl) noexcept
Definition: date.h:2389
constexpr const date::month apr
Definition: date.h:1839
constexpr bool operator>(const day &x, const day &y) noexcept
Definition: date.h:1298
year()=default
typename std::enable_if< B, T >::type enable_if_t
Definition: CLI11.hpp:918
constexpr const date::weekday thu
Definition: date.h:1853
weekday & operator-=(const days &d) noexcept
Definition: date.h:1712
year_month_day & operator-=(const months &m) noexcept
Definition: date.h:2633
std::chrono::duration< int, std::ratio_multiply< std::ratio< 24 >, std::chrono::hours::period > > days
Definition: date.h:147
typename std::conditional< digits< 32, std::int32_t, typename std::conditional< digits< 64, std::int64_t, std::int64_t >::type >::type type
Definition: date.h:989
int read_signed(std::basic_istream< CharT, Traits > &is, unsigned m=1, unsigned M=10)
Definition: date.h:5759
constexpr date::year year() const noexcept
Definition: date.h:1976
year_month_day ymd
Definition: date.h:4343
constexpr bool in_conventional_range() const noexcept
Definition: date.h:3702
constexpr date::month month() const noexcept
Definition: date.h:2343
month_day()=default
year & operator++() noexcept
Definition: date.h:1530
Parsable & tp_
Definition: date.h:7212
const std::basic_string< CharT, Traits, Alloc > format_
Definition: date.h:7211
unsigned char m_
Definition: date.h:329
bool ok() const noexcept
Definition: date.h:2940
fields(year_month_day ymd_, time_of_day< Duration > tod_)
Definition: date.h:4354
year_month_day()=default
constexpr month_weekday_last(const date::month &m, const date::weekday_last &wd) noexcept
Definition: date.h:2337
date::weekday_indexed wdi_
Definition: date.h:592
constexpr const date::month jun
Definition: date.h:1841
constexpr std::chrono::time_point< Clock, To > ceil(const std::chrono::time_point< Clock, FromDuration > &tp)
Definition: date.h:1233
#define CONSTDATA
Definition: date.h:121
date::month m_
Definition: date.h:761
void read(std::basic_istream< CharT, Traits > &is, rld a0, Args &&...args)
Definition: date.h:5938
constexpr date::month month() const noexcept
Definition: date.h:2618
constexpr bool ok() const noexcept
Definition: date.h:3129
year_month()=default
constexpr year operator+() const noexcept
Definition: date.h:1537
constexpr time_of_day(Duration since_midnight) noexcept
Definition: date.h:4247
constexpr unsigned index() const noexcept
Definition: date.h:1871
constexpr date::weekday_indexed weekday_indexed() const noexcept
Definition: date.h:2918
constexpr const date::weekday sun
Definition: date.h:1849
weekday & operator+=(const days &d) noexcept
Definition: date.h:1703
constexpr date::month_day_last month_day_last() const noexcept
Definition: date.h:2437
constexpr std::enable_if< detail::no_overflow< Period, typename To::period >::value, To >::type trunc(const std::chrono::duration< Rep, Period > &d)
Definition: date.h:1091
date::day d_
Definition: date.h:642
weekday()=default
constexpr date::weekday_last weekday_last() const noexcept
Definition: date.h:3107
constexpr const date::month feb
Definition: date.h:1837
date::weekday wd_
Definition: date.h:477
constexpr bool ok() const noexcept
Definition: date.h:2356
fields(year_month_day ymd_, weekday wd_)
Definition: date.h:4353
date::month m_
Definition: date.h:641
date::day d_
Definition: date.h:540
unsigned char wd_
Definition: date.h:454
static constexpr unsigned char weekday_from_days(int z) noexcept
Definition: date.h:1671
year_month_day_last & operator-=(const months &m) noexcept
Definition: date.h:2407
sys_time< std::chrono::seconds > sys_seconds
Definition: date.h:164
constexpr year_month operator/(const year &y, const month &m) noexcept
Definition: date.h:3221
year & operator+=(const years &y) noexcept
Definition: date.h:1534
static std::wstring from(Rep n)
Definition: date.h:7970
std::chrono::duration< int, std::ratio_multiply< std::ratio< 146097, 400 >, days::period > > years
Definition: date.h:153
#define CONSTCD14
Definition: date.h:123
month()=default
constexpr time_of_day_base(std::chrono::hours h, bool neg, unsigned m) noexcept
Definition: date.h:3788
std::basic_ostream< CharT, Traits > & os_
Definition: date.h:947
constexpr const date::weekday sat
Definition: date.h:1855
fields(weekday wd_, time_of_day< Duration > tod_)
Definition: date.h:4356
typename make_precision< rep, width< std::common_type< typename std::common_type< Duration, std::chrono::seconds >::type, std::chrono::seconds >::type::period::den >::value >::type precision
Definition: date.h:3630
constexpr std::chrono::duration< Rep, Period > abs(std::chrono::duration< Rep, Period > d)
Definition: date.h:1201
constexpr const date::month oct
Definition: date.h:1845
constexpr date::year year() const noexcept
Definition: date.h:2896
static constexpr year max() noexcept
Definition: date.h:1568
long double read_long_double(std::basic_istream< CharT, Traits > &is, unsigned m=1, unsigned M=10)
Definition: date.h:5785
constexpr date::month month() const noexcept
Definition: date.h:1977
constexpr const date::weekday wed
Definition: date.h:1852
unsigned m
Definition: date.h:5839
constexpr std::enable_if< !std::numeric_limits< Rep >::is_signed, std::chrono::duration< Rep, Period > >::type abs(std::chrono::duration< Rep, Period > d)
Definition: date.h:3767
std::chrono::seconds s_
Definition: date.h:3634
year_month_day_last & operator+=(const months &m) noexcept
Definition: date.h:2398
constexpr const date::month mar
Definition: date.h:1838
constexpr decimal_format_seconds(const precision &s) noexcept
Definition: date.h:3694
save_stream(std::basic_ostream< CharT, Traits > &os)
Definition: date.h:963
constexpr bool ok() const noexcept
Definition: date.h:1932
auto parse(const std::basic_string< CharT, Traits, Alloc > &format, Parsable &tp) -> decltype(from_stream(std::declval< std::basic_istream< CharT, Traits > &>(), format.c_str(), tp), parse_manip< Parsable, CharT, Traits, Alloc >
Definition: date.h:7239
day()=default
constexpr day operator+(const day &x, const days &y) noexcept
Definition: date.h:1331
days to_days() const noexcept
Definition: date.h:2660
precision to_duration() const noexcept
Definition: date.h:3652
std::chrono::seconds & seconds() noexcept
Definition: date.h:3648
constexpr std::chrono::time_point< Clock, To > round(const std::chrono::time_point< Clock, FromDuration > &tp)
Definition: date.h:1222
constexpr date::weekday_last weekday_last() const noexcept
Definition: date.h:2348
month & operator-=(const months &m) noexcept
Definition: date.h:1385
year_month_weekday_last & operator-=(const months &m) noexcept
Definition: date.h:3069
unsigned M
Definition: date.h:5840
fields(year_month_day ymd_, weekday wd_, time_of_day< Duration > tod_)
Definition: date.h:4358
std::chrono::duration< int, std::ratio_multiply< std::ratio< 7 >, days::period > > weeks
Definition: date.h:150
constexpr month_weekday(const date::month &m, const date::weekday_indexed &wdi) noexcept
Definition: date.h:2285
constexpr date::weekday weekday() const noexcept
Definition: date.h:3099
bool ok() const noexcept
Definition: date.h:2149
unsigned extract_month(std::basic_ostream< CharT, Traits > &os, const fields< Duration > &fds)
Definition: date.h:4396
std::string to_string(std::uint64_t x)
Definition: date.h:7722
day & operator+=(const days &d) noexcept
Definition: date.h:1266
date::weekday_last wdl_
Definition: date.h:830
std::basic_ostream< CharT, Traits > & to_stream(std::basic_ostream< CharT, Traits > &os, const CharT *fmt, const fields< Duration > &fds, const std::string *abbrev=nullptr, const std::chrono::seconds *offset_sec=nullptr)
Definition: date.h:4598
unsigned char d_
Definition: date.h:291
constexpr date::year year() const noexcept
Definition: date.h:3093
constexpr year_month_weekday_last(const date::year &y, const date::month &m, const date::weekday_last &wdl) noexcept
Definition: date.h:3049
date::month m_
Definition: date.h:498
constexpr std::chrono::seconds seconds() const noexcept
Definition: date.h:3649
constexpr bool ok() const noexcept
Definition: date.h:1552
month & operator++() noexcept
Definition: date.h:1368
static year_month_day from_days(days dp) noexcept
Definition: date.h:2770
constexpr bool ok() const noexcept
Definition: date.h:2222
parse_manip(std::basic_string< CharT, Traits, Alloc > format, Parsable &tp, std::basic_string< CharT, Traits, Alloc > *abbrev=nullptr, std::chrono::minutes *offset=nullptr)
Definition: date.h:7217
bool read_char(std::basic_istream< CharT, Traits > &is, CharT fmt, std::ios::iostate &err)
Definition: date.h:5719
std::chrono::duration< int, std::ratio_divide< years::period, std::ratio< 12 > >> months
Definition: date.h:156
time_of_day< Duration > tod
Definition: date.h:4345
unsigned extract_weekday(std::basic_ostream< CharT, Traits > &os, const fields< Duration > &fds)
Definition: date.h:4370
local_time< days > local_days
Definition: date.h:172
year_month_weekday & operator-=(const months &m) noexcept
Definition: date.h:2872
date::month m_
Definition: date.h:567
constexpr bool operator<(const day &x, const day &y) noexcept
Definition: date.h:1290
constexpr const date::month jan
Definition: date.h:1836
constexpr bool operator<=(const day &x, const day &y) noexcept
Definition: date.h:1306
constexpr bool in_conventional_range() const noexcept
Definition: date.h:3657
constexpr const date::month nov
Definition: date.h:1846
unsigned M
Definition: date.h:5833
static std::string from(Rep n)
Definition: date.h:7945
date::year y_
Definition: date.h:640
date::month_day_last mdl_
Definition: date.h:694
constexpr date::month month() const noexcept
Definition: date.h:2291
weekday wd
Definition: date.h:4344
constexpr std::enable_if< !std::chrono::treat_as_floating_point< T >::value, T >::type trunc(T t) noexcept
Definition: date.h:1000
date::day day() const noexcept
Definition: date.h:2445
static std::basic_string< char, Traits > from(Rep n)
Definition: date.h:7957
constexpr bool ok() const noexcept
Definition: date.h:2304
constexpr date::day day() const noexcept
Definition: date.h:2619
year_month & operator+=(const months &dm) noexcept
Definition: date.h:1983
std::chrono::time_point< local_t, Duration > local_time
Definition: date.h:169
constexpr month_day_last(const date::month &m) noexcept
Definition: date.h:2223
typename std::common_type< Duration, std::chrono::seconds >::type::rep rep
Definition: date.h:3685
weekday & operator--() noexcept
Definition: date.h:1697
year & operator--() noexcept
Definition: date.h:1532
To round(const std::chrono::duration< Rep, Period > &d)
Definition: date.h:1162
local_time< std::chrono::seconds > local_seconds
Definition: date.h:171
fields(time_of_day< Duration > tod_)
Definition: date.h:4351
constexpr weekday_last(const date::weekday &wd) noexcept
Definition: date.h:1933
constexpr const date::month sep
Definition: date.h:1844
day & operator--() noexcept
Definition: date.h:1264
std::locale loc_
Definition: date.h:950
date::weekday_last wdl_
Definition: date.h:615
constexpr time_of_day_base() noexcept
Definition: date.h:3781
std::chrono::seconds & seconds() noexcept
Definition: date.h:3698
constexpr bool ok() const noexcept
Definition: date.h:1269
unsigned char wd_
Definition: date.h:413
constexpr const date::month aug
Definition: date.h:1843
day & operator-=(const days &d) noexcept
Definition: date.h:1267
#define CONSTCD11
Definition: date.h:122