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