60 #else // !HAS_STRING_VIEW 64 #endif // !HAS_STRING_VIEW 81 unsigned short n_ : 14;
82 unsigned short mode_ : 2;
83 std::chrono::duration<std::int32_t> time_ = std::chrono::hours{2};
88 bool ok()
const {
return mode_ != off;}
100 using sec = std::chrono::seconds;
114 assert(!
"rule called with bad mode");
132 os << r.m_/r.wd_[r.n_];
148 std::string std_abbrev_;
149 std::string dst_abbrev_ = {};
150 std::chrono::seconds offset_;
151 std::chrono::seconds save_ = std::chrono::hours{1};
158 template <
class Duration>
160 template <
class Duration>
163 template <
class Duration>
167 template <
class Duration>
171 template <
class Duration>
183 using namespace detail;
197 throw_invalid(s, i,
"Expecting end of string or ',' to start rule");
200 if (i == s.size() || s[i] !=
',')
201 throw_invalid(s, i,
"Expecting ',' and then the ending rule");
211 template <
class Duration>
215 using namespace date;
219 if (start_rule_.ok())
222 auto start =
sys_seconds{(start_rule_(y) - offset_).time_since_epoch()};
223 auto end =
sys_seconds{(end_rule_(y) - (offset_ + save_)).time_since_epoch()};
224 if (start <= st && st < end)
229 r.save = ceil<minutes>(save_);
230 r.abbrev = dst_abbrev_;
235 (offset_ + save_)).time_since_epoch()};
237 r.abbrev = std_abbrev_;
242 r.end =
sys_seconds{(start_rule_(y+
years{1}) - offset_).time_since_epoch()};
243 r.abbrev = std_abbrev_;
250 r.abbrev = std_abbrev_;
255 template <
class Duration>
259 using namespace date;
262 if (start_rule_.ok())
265 auto start =
sys_seconds{(start_rule_(y) - offset_).time_since_epoch()};
266 auto end =
sys_seconds{(end_rule_(y) - (offset_ + save_)).time_since_epoch()};
267 auto utcs =
sys_seconds{floor<seconds>(tp - offset_).time_since_epoch()};
268 auto utcd =
sys_seconds{floor<seconds>(tp - (offset_ + save_)).time_since_epoch()};
269 if ((utcs < start) != (utcd < start))
272 (offset_ + save_)).time_since_epoch()};
274 r.first.offset = offset_;
275 r.first.abbrev = std_abbrev_;
276 r.second.begin = start;
278 r.second.abbrev = dst_abbrev_;
279 r.second.offset = offset_ + save_;
280 r.second.save = ceil<minutes>(save_);
281 r.result = save_ > seconds{0} ? local_info::nonexistent
282 : local_info::ambiguous;
284 else if ((utcs < end) != (utcd < end))
286 r.first.begin = start;
288 r.first.offset = offset_ + save_;
289 r.first.save = ceil<minutes>(save_);
290 r.first.abbrev = dst_abbrev_;
291 r.second.begin = end;
293 offset_).time_since_epoch()};
294 r.second.abbrev = std_abbrev_;
295 r.second.offset = offset_;
296 r.result = save_ > seconds{0} ? local_info::ambiguous
297 : local_info::nonexistent;
299 else if (utcs < start)
302 (offset_ + save_)).time_since_epoch()};
304 r.first.offset = offset_;
305 r.first.abbrev = std_abbrev_;
309 r.first.begin = start;
311 r.first.offset = offset_ + save_;
312 r.first.save = ceil<minutes>(save_);
313 r.first.abbrev = dst_abbrev_;
319 offset_).time_since_epoch()};
320 r.first.abbrev = std_abbrev_;
321 r.first.offset = offset_;
328 r.first.abbrev = std_abbrev_;
329 r.first.offset = offset_;
334 template <
class Duration>
338 using namespace date;
339 auto i = get_info(tp);
340 if (i.result == local_info::nonexistent)
342 else if (i.result == local_info::ambiguous)
347 template <
class Duration>
351 using namespace date;
352 auto i = get_info(tp);
353 if (i.result == local_info::nonexistent)
357 else if (i.result == local_info::ambiguous)
359 if (z == choose::latest)
365 template <
class Duration>
369 using namespace date;
372 auto i = get_info(tp);
373 return LT{(tp + i.offset).time_since_epoch()};
380 using date::operator<<;
382 os << z.std_abbrev_ <<
", " << z.dst_abbrev_ <<
date::format(
", %T, ", z.offset_)
383 <<
date::format(
"%T, [", z.save_) << z.start_rule_ <<
", " << z.end_rule_ <<
")}";
394 throw std::runtime_error(std::string(
"Invalid time_zone initializer.\n") +
395 std::string(message) +
":\n" +
398 std::string(i,
'~') +
'^' +
399 std::string(s.size()-i-1,
'~') +
407 using namespace date;
409 throw_invalid(s, i,
"Expected rule but found end of string");
418 else if (s[i] ==
'M')
423 if (i == s.size() || s[i] !=
'.')
428 if (i == s.size() || s[i] !=
'.')
438 else if (std::isdigit(s[i]))
446 throw_invalid(s, i,
"Expected 'J', 'M', or a digit to start rule");
447 if (i != s.size() && s[i] ==
'/')
450 std::chrono::seconds t;
462 throw_invalid(s, i,
"Expected a name but found end of string");
470 "Expected to find closing '>', but found end of string");
473 name.push_back(s[i]);
480 while (i != s.size() && std::isalpha(s[i]))
482 name.push_back(s[i]);
487 throw_invalid(s, i,
"Found name to be shorter than 3 characters");
494 std::chrono::seconds& t)
497 throw_invalid(s, i,
"Expected to read signed time, but found end of string");
498 bool negative =
false;
504 else if (s[i] ==
'+')
518 throw_invalid(s, i,
"Expected to read unsigned time, but found end of string");
522 if (i != s.size() && s[i] ==
':')
527 if (i != s.size() && s[i] ==
':')
541 if (i == s.size() || !std::isdigit(s[i]))
543 u =
static_cast<unsigned>(s[i] -
'0');
545 for (++i; count < limit && i != s.size() && std::isdigit(s[i]); ++i, ++count)
546 u = u * 10 + static_cast<unsigned>(s[i] -
'0');
570 #else // !HAS_STRING_VIEW 586 #endif // !HAS_STRING_VIEW
CONSTCD11 bool is_leap() const NOEXCEPT
Definition: date.h:1542
CONSTDATA date::month dec
Definition: date.h:1847
local_time< days > local_days
Definition: date.h:172
date::local_time< typename std::common_type< Duration, std::chrono::seconds >::type > to_local(date::sys_time< Duration > tp) const
Definition: ptz.h:367
static Posix::time_zone locate_zone(const std::string &name)
Definition: ptz.h:574
friend unsigned read_date(const string_t &s, unsigned i, rule &r)
Definition: ptz.h:405
rule()
Definition: ptz.h:86
sys_time< std::chrono::seconds > sys_seconds
Definition: date.h:164
unsigned read_signed_time(const string_t &s, unsigned i, std::chrono::seconds &t)
Definition: ptz.h:493
unsigned read_date(const string_t &s, unsigned i, rule &r)
Definition: ptz.h:405
std::chrono::duration< int, std::ratio_multiply< std::ratio< 146097, 400 >, days::period > > years
Definition: date.h:153
sys_time< days > sys_days
Definition: date.h:163
auto format(const std::locale &loc, const CharT *fmt, const Streamable &tp) -> decltype(to_stream(std::declval< std::basic_ostream< CharT > &>(), fmt, tp), std::basic_string< CharT >
Definition: date.h:5663
date::local_seconds operator()(date::year y) const
Definition: ptz.h:97
std::chrono::duration< int, std::ratio_multiply< std::ratio< 24 >, std::chrono::hours::period > > days
Definition: date.h:147
CONSTDATA date::month jan
Definition: date.h:1836
static Posix::time_zone locate_zone(const char *name)
Definition: ptz.h:581
bool ok() const
Definition: ptz.h:88
date::sys_time< typename std::common_type< Duration, std::chrono::seconds >::type > to_sys(date::local_time< Duration > tp) const
Definition: ptz.h:336
friend std::ostream & operator<<(std::ostream &os, const rule &r)
Definition: ptz.h:121
const time_zone * locate_zone(const std::string &tz_name)
Definition: tz.cpp:3532
std::chrono::time_point< std::chrono::system_clock, Duration > sys_time
Definition: date.h:161
CONSTDATA date::last_spec last
Definition: date.h:1834
unsigned read_unsigned(const string_t &s, unsigned i, unsigned limit, unsigned &u)
Definition: ptz.h:539
local_time< std::chrono::seconds > local_seconds
Definition: date.h:171
time_zone(const detail::string_t &name)
Definition: ptz.h:181
unsigned read_unsigned_time(const string_t &s, unsigned i, std::chrono::seconds &t)
Definition: ptz.h:514
date::sys_info get_info(date::sys_time< Duration > st) const
Definition: ptz.h:213
choose
Definition: tz.h:149
void throw_invalid(const string_t &s, unsigned i, const string_t &message)
Definition: ptz.h:392
std::chrono::time_point< local_t, Duration > local_time
Definition: date.h:169
unsigned read_name(const string_t &s, unsigned i, std::string &name)
Definition: ptz.h:459
std::chrono::seconds offset
Definition: tz.h:160
const time_zone * operator->() const
Definition: ptz.h:177
std::string string_t
Definition: ptz.h:62