85 unsigned short n_ : 14;
87 std::chrono::duration<std::int32_t>
time_ = std::chrono::hours{2};
134 using sec = std::chrono::seconds;
148 assert(!
"rule called with bad mode");
157 using namespace std::chrono;
158 auto print_offset = [](seconds
off)
165 nm += std::to_string(offset.hours().count());
166 if (offset.minutes() != minutes{0} || offset.seconds() != seconds{0})
169 if (offset.minutes() < minutes{10})
171 nm += std::to_string(offset.minutes().count());
172 if (offset.seconds() != seconds{0})
175 if (offset.seconds() < seconds{10})
177 nm += std::to_string(offset.seconds().count());
189 nm += std::to_string(
n_);
193 nm += std::to_string(
static_cast<unsigned>(
m_));
195 nm += std::to_string(
n_);
200 nm = std::to_string(
n_);
205 nm += print_offset(
time_);
241 std::chrono::seconds
save_ = std::chrono::hours{1};
248 template <
class Duration>
250 template <
class Duration>
253 template <
class Duration>
257 template <
class Duration>
261 template <
class Duration>
269 std::string
name()
const;
364 throw_invalid(s, i,
"Expecting end of string or ',' to start rule");
367 if (i == s.size() || s[i] !=
',')
368 throw_invalid(s, i,
"Expecting ',' and then the ending rule");
378template <
class Duration>
392 using std::chrono::minutes;
397 auto y = year_month_day{floor<days>(st)}.year();
402 if (start <= st && st < end)
407 r.save = ceil<minutes>(
save_);
425 if (end <= st && st < start)
436 r.save = ceil<minutes>(
save_);
444 r.save = ceil<minutes>(
save_);
454template <
class Duration>
468 using std::chrono::seconds;
469 using std::chrono::minutes;
474 auto y = year_month_day{floor<days>(tp)}.year();
479 auto northern = start <= end;
480 if ((utcs < start) != (utcd < start))
489 r.second.begin = start;
496 r.second.save = ceil<minutes>(
save_);
497 r.result =
save_ > seconds{0} ? local_info::nonexistent
498 : local_info::ambiguous;
500 else if ((utcs < end) != (utcd < end))
503 r.first.begin = start;
508 r.first.save = ceil<minutes>(
save_);
510 r.second.begin = end;
514 r.second.end = start;
517 r.result =
save_ > seconds{0} ? local_info::ambiguous
518 : local_info::nonexistent;
528template <
class Duration>
537 if (i.result == local_info::nonexistent)
538 throw nonexistent_local_time(tp, i);
539 else if (i.result == local_info::ambiguous)
540 throw ambiguous_local_time(tp, i);
541 return sys_time<Duration>{tp.time_since_epoch()} - i.first.offset;
544template <
class Duration>
552 if (i.result == local_info::nonexistent)
556 else if (i.result == local_info::ambiguous)
558 if (z == choose::latest)
559 return sys_time<Duration>{tp.time_since_epoch()} - i.second.offset;
561 return sys_time<Duration>{tp.time_since_epoch()} - i.first.offset;
564template <
class Duration>
569 using std::chrono::seconds;
570 using LT = local_time<typename std::common_type<Duration, seconds>::type>;
572 return LT{(tp + i.offset).time_since_epoch()};
579 using date::operator<<;
590 using namespace date;
591 using namespace std::chrono;
593 auto print_offset = [](seconds off)
597 if (offset.is_negative())
599 nm += std::to_string(offset.hours().count());
600 if (offset.minutes() != minutes{0} || offset.seconds() != seconds{0})
603 if (offset.minutes() < minutes{10})
605 nm += std::to_string(offset.minutes().count());
606 if (offset.seconds() != seconds{0})
609 if (offset.seconds() < seconds{10})
611 nm += std::to_string(offset.seconds().count());
620 if (
save_ != hours{1})
659 throw std::runtime_error(std::string(
"Invalid time_zone initializer.\n") +
660 std::string(message) +
":\n" +
661 std::string(s) +
'\n' +
663 std::string(i,
'~') +
'^' +
664 std::string(i < s.size() ? s.size()-i-1 : 0,
'~') +
675 throw_invalid(s, i,
"Expected rule but found end of string");
680 i =
read_unsigned(s, i, 3, n,
"Expected to find the Julian day [1, 365]");
684 else if (s[i] ==
'M')
688 i =
read_unsigned(s, i, 2, m,
"Expected to find month [1, 12]");
689 if (i == s.size() || s[i] !=
'.')
693 i =
read_unsigned(s, i, 1, n,
"Expected to find week number [1, 5]");
694 if (i == s.size() || s[i] !=
'.')
698 i =
read_unsigned(s, i, 1, wd,
"Expected to find day of week [0, 6]");
704 else if (std::isdigit(s[i]))
712 throw_invalid(s, i,
"Expected 'J', 'M', or a digit to start rule");
713 if (i != s.size() && s[i] ==
'/')
716 std::chrono::seconds t;
728 throw_invalid(s, i,
"Expected a name but found end of string");
736 "Expected to find closing '>', but found end of string");
739 name.push_back(s[i]);
746 while (i != s.size() && std::isalpha(s[i]))
748 name.push_back(s[i]);
753 throw_invalid(s, i,
"Found name to be shorter than 3 characters");
760 std::chrono::seconds& t)
763 throw_invalid(s, i,
"Expected to read signed time, but found end of string");
764 bool negative =
false;
770 else if (s[i] ==
'+')
782 using std::chrono::seconds;
783 using std::chrono::minutes;
784 using std::chrono::hours;
786 throw_invalid(s, i,
"Expected to read unsigned time, but found end of string");
788 i =
read_unsigned(s, i, 2, x,
"Expected to find hours [0, 24]");
790 if (i != s.size() && s[i] ==
':')
793 i =
read_unsigned(s, i, 2, x,
"Expected to find minutes [0, 59]");
795 if (i != s.size() && s[i] ==
':')
798 i =
read_unsigned(s, i, 2, x,
"Expected to find seconds [0, 59]");
810 if (i == s.size() || !std::isdigit(s[i]))
812 u =
static_cast<unsigned>(s[i] -
'0');
814 for (++i; count < limit && i != s.size() && std::isdigit(s[i]); ++i, ++count)
815 u = u * 10 +
static_cast<unsigned>(s[i] -
'0');
friend std::ostream & operator<<(std::ostream &os, const rule &r)
std::chrono::duration< std::int32_t > time_
date::local_seconds operator()(date::year y) const
friend bool operator==(const rule &x, const rule &y)
friend unsigned read_date(const string_t &s, unsigned i, rule &r)
std::string to_string() const
date::sys_time< typename std::common_type< Duration, std::chrono::seconds >::type > to_sys(date::local_time< Duration > tp) const
date::sys_info contant_offset() const
date::sys_seconds get_end(date::year y) const
date::sys_info get_info(date::sys_time< Duration > st) const
std::chrono::seconds save_
std::chrono::seconds offset_
date::sys_seconds get_next_end(date::year y) const
time_zone(const detail::string_t &name)
date::local_time< typename std::common_type< Duration, std::chrono::seconds >::type > to_local(date::sys_time< Duration > tp) const
friend std::ostream & operator<<(std::ostream &os, const time_zone &z)
const time_zone * operator->() const
date::sys_seconds get_start(date::year y) const
date::sys_seconds get_prev_start(date::year y) const
date::sys_seconds get_prev_end(date::year y) const
date::sys_seconds get_next_start(date::year y) const
friend bool operator==(const time_zone &x, const time_zone &y)
CONSTCD11 unsigned c_encoding() const NOEXCEPT
CONSTCD11 bool is_leap() const NOEXCEPT
bool operator==(const rule &x, const rule &y)
unsigned read_signed_time(const string_t &s, unsigned i, std::chrono::seconds &t)
unsigned read_unsigned(const string_t &s, unsigned i, unsigned limit, unsigned &u, const string_t &message=string_t{})
void throw_invalid(const string_t &s, unsigned i, const string_t &message)
unsigned read_date(const string_t &s, unsigned i, rule &r)
std::ostream & operator<<(std::ostream &os, const rule &r)
unsigned read_unsigned_time(const string_t &s, unsigned i, std::chrono::seconds &t)
unsigned read_name(const string_t &s, unsigned i, std::string &name)
bool operator!=(const rule &x, const rule &y)
bool operator!=(const time_zone &x, const time_zone &y)
bool operator==(const time_zone &x, const time_zone &y)
std::ostream & operator<<(std::ostream &os, const time_zone &z)
CONSTDATA date::last_spec last
local_time< std::chrono::seconds > local_seconds
local_time< days > local_days
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 >{})
CONSTDATA date::month January
std::chrono::time_point< std::chrono::system_clock, Duration > sys_time
CONSTCD14 std::enable_if< detail::no_overflow< Period, typenameTo::period >::value, To >::type floor(const std::chrono::duration< Rep, Period > &d)
CONSTDATA date::month December
const time_zone * locate_zone(const std::string &tz_name)
std::chrono::duration< int, detail::ratio_multiply< std::ratio< 24 >, std::chrono::hours::period > > days
std::chrono::time_point< local_t, Duration > local_time
sys_time< std::chrono::seconds > sys_seconds
sys_time< days > sys_days
CONSTCD14 To ceil(const std::chrono::duration< Rep, Period > &d)
static Posix::time_zone locate_zone(const char *name)
static Posix::time_zone locate_zone(const std::string &name)