diff --git a/date.h b/date.h index 3bdf0b2..cf1e907 100644 --- a/date.h +++ b/date.h @@ -3919,6 +3919,604 @@ operator<<(std::basic_ostream& os, const local_time& ut return os << sys_time{ut.time_since_epoch()}; } +// format + +namespace detail +{ + +template +std::basic_string +format(const std::locale& loc, std::basic_string fmt, + local_time tp, const std::string* abbrev = nullptr, + const std::chrono::seconds* offset_sec = nullptr) +{ + // Handle these specially + // %S append fractional seconds if tp has precision finer than seconds + // %T append fractional seconds if tp has precision finer than seconds + // %z replace with offset from zone on +/-hhmm format + // %Ez, %Oz replace with offset from zone on +/-hh:mm format + // %Z replace with abbreviation from zone + + using namespace std; + using namespace std::chrono; + auto command = false; + auto modified = false; + for (std::size_t i = 0; i < fmt.size(); ++i) + { + switch (fmt[i]) + { + case '%': + command = true; + modified = false; + break; + case 'O': + case 'E': + modified = true; + break; + case 'S': + case 'T': + if (command && !modified && ratio_less>::value) + { + basic_ostringstream os; + os.imbue(loc); + os << make_time(tp - floor(tp)); + auto s = os.str(); + s.erase(0, 8); + fmt.insert(i+1, s); + i += s.size() - 1; + } + command = false; + modified = false; + break; + case 'z': + if (command) + { + if (offset_sec == nullptr) + throw std::runtime_error("Can not format local_time with %z"); + else + { + auto offset = duration_cast(*offset_sec); + basic_ostringstream os; + if (offset >= minutes{0}) + os << '+'; + os << make_time(offset); + auto s = os.str(); + if (!modified) + s.erase(s.find(':'), 1); + fmt.replace(i - 1 - modified, 2 + modified, s); + i += s.size() - 1; + } + } + command = false; + modified = false; + break; + case 'Z': + if (command && !modified) + { + if (abbrev == nullptr) + throw std::runtime_error("Can not format local_time with %Z"); + else + { + fmt.replace(i - 1, 2, + std::basic_string(abbrev->begin(), abbrev->end())); + i += abbrev->size() - 1; + } + } + command = false; + modified = false; + break; + default: + command = false; + modified = false; + break; + } + } + auto& f = use_facet>(loc); + basic_ostringstream os; + auto tt = system_clock::to_time_t(sys_time{tp.time_since_epoch()}); + std::tm tm{}; +#ifndef _MSC_VER + gmtime_r(&tt, &tm); +#else + gmtime_s(&tm, &tt); +#endif + f.put(os, os, os.fill(), &tm, fmt.data(), fmt.data() + fmt.size()); + return os.str(); +} + +} // namespace detail + +template +inline +std::basic_string +format(const std::locale& loc, std::basic_string fmt, + local_time tp) +{ + return detail::format(loc, std::move(fmt), tp); +} + +template +inline +std::basic_string +format(std::basic_string fmt, local_time tp) +{ + return detail::format(std::locale{}, std::move(fmt), tp); +} + +template +inline +std::basic_string +format(const std::locale& loc, std::basic_string fmt, + sys_time tp) +{ + const std::string abbrev("UTC"); + CONSTDATA std::chrono::seconds offset{0}; + return detail::format(loc, std::move(fmt), + local_time{tp.time_since_epoch()}, &abbrev, &offset); +} + +template +inline +std::basic_string +format(std::basic_string fmt, sys_time tp) +{ + const std::string abbrev("UTC"); + CONSTDATA std::chrono::seconds offset{0}; + return detail::format(std::move(fmt), local_time{tp.time_since_epoch()}, + &abbrev, &offset); +} + +// const CharT* formats + +template +inline +std::basic_string +format(const std::locale& loc, const CharT* fmt, local_time tp) +{ + return detail::format(loc, std::basic_string(fmt), tp); +} + +template +inline +std::basic_string +format(const CharT* fmt, local_time tp) +{ + return detail::format(std::locale{}, std::basic_string(fmt), tp); +} + +template +inline +std::basic_string +format(const std::locale& loc, const CharT* fmt, sys_time tp) +{ + const std::string abbrev("UTC"); + CONSTDATA std::chrono::seconds offset{0}; + return detail::format(loc, std::basic_string(fmt), + local_time{tp.time_since_epoch()}, + &abbrev, &offset); +} + +template +inline +std::basic_string +format(const CharT* fmt, sys_time tp) +{ + const std::string abbrev("UTC"); + CONSTDATA std::chrono::seconds offset{0}; + return detail::format(std::locale{}, std::basic_string(fmt), + local_time{tp.time_since_epoch()}, + &abbrev, &offset); +} + +// parse + +namespace detail +{ + +template +void +parse(std::basic_istream& is, + const std::basic_string& format, sys_time& tp, + std::basic_string& abbrev, std::chrono::minutes& offset) +{ + using namespace std; + using namespace std::chrono; + typename basic_istream::sentry ok{is}; + if (ok) + { + auto& f = use_facet>(is.getloc()); + ios_base::iostate err = ios_base::goodbit; + std::tm tm{}; + Duration subseconds{}; + std::basic_string temp_abbrev; + minutes temp_offset{}; + + auto b = format.data(); + auto i = b; + auto e = b + format.size(); + auto command = false; + auto modified = false; + for (; i < e; ++i) + { + switch (*i) + { + case '%': + command = true; + modified = false; + break; + case 'O': + case 'E': + modified = true; + break; + case 'T': + case 'S': + if (command && !modified) + { + f.get(is, 0, is, err, &tm, b, i-1); + b = i+1; + if (*i == 'T') + { + const CharT hm[] = {'%', 'H', ':', '%', 'M', ':'}; + f.get(is, 0, is, err, &tm, hm, hm+6); + } + if (ratio_less>::value) + { + auto decimal_point = Traits::to_int_type( + use_facet>(is.getloc()).decimal_point()); + string buf; + while (true) + { + auto k = is.peek(); + if (Traits::eq_int_type(k, Traits::eof())) + break; + if (Traits::eq_int_type(k, decimal_point)) + { + buf += '.'; + decimal_point = Traits::eof(); + is.get(); + } + else + { + auto c = static_cast(Traits::to_char_type(k)); + if (isdigit(c)) + { + buf += c; + is.get(); + } + else + { + break; + } + } + }; + if (!buf.empty()) + subseconds = round(duration{stod(buf)}); + else + err |= ios_base::failbit; + } + else + { + const CharT hm[] = {'%', 'S'}; + f.get(is, 0, is, err, &tm, hm, hm+2); + } + } + command = false; + modified = false; + break; + case 'z': + if (command) + { + f.get(is, 0, is, err, &tm, b, i-1-modified); + b = i+1; + if ((err & ios_base::failbit) == 0) + { + CharT sign{}; + is >> sign; + if (!is.fail() && (sign == '+' || sign == '-')) + { + char h1, h0, m1, m0; + char colon = ':'; + h1 = static_cast(is.get()); + h0 = static_cast(is.get()); + if (modified) + { + if (h0 == ':') + { + colon = h0; + h0 = h1; + h1 = '0'; + } + else + colon = static_cast(is.get()); + } + m1 = static_cast(is.get()); + m0 = static_cast(is.get()); + if (!is.fail() && std::isdigit(h1) && std::isdigit(h0) + && std::isdigit(m1) && std::isdigit(m0) + && colon == ':') + { + temp_offset = 10*hours{h1 - '0'} + hours{h0 - '0'} + + 10*minutes{m1 - '0'} + minutes{m0 - '0'}; + if (sign == '-') + temp_offset = -temp_offset; + } + else + err |= ios_base::failbit; + } + else + err |= ios_base::failbit; + } + } + command = false; + modified = false; + break; + case 'Z': + if (command && !modified) + { + f.get(is, 0, is, err, &tm, b, i-1); + b = i+1; + if ((err & ios_base::failbit) == 0) + { + is >> temp_abbrev; + if (is.fail()) + err |= ios_base::failbit; + } + } + command = false; + modified = false; + break; + default: + command = false; + modified = false; + break; + } + } + if ((err & ios_base::failbit) == 0) + { + if (b < e) + f.get(is, 0, is, err, &tm, b, e); + if ((err & ios_base::failbit) == 0) + { +#ifdef _WIN32 + auto tt = _mkgmtime(&tm); +#else + auto tt = timegm(&tm); +#endif + tp = floor(system_clock::from_time_t(tt) + subseconds); + abbrev = std::move(temp_abbrev); + offset = temp_offset; + } + } + is.setstate(err); + } +} + +} // namespace detail + +template +inline +void +parse(std::basic_istream& is, + const std::basic_string& format, sys_time& tp) +{ + std::basic_string abbrev; + std::chrono::minutes offset{}; + detail::parse(is, format, tp, abbrev, offset); + if (!is.fail()) + tp = floor(tp - offset); +} + +template +inline +void +parse(std::basic_istream& is, + const std::basic_string& format, sys_time& tp, + std::basic_string& abbrev) +{ + std::chrono::minutes offset{}; + detail::parse(is, format, tp, abbrev, offset); + if (!is.fail()) + tp = floor(tp - offset); +} + +template +inline +void +parse(std::basic_istream& is, + const std::basic_string& format, sys_time& tp, + std::chrono::minutes& offset) +{ + std::basic_string abbrev; + detail::parse(is, format, tp, abbrev, offset); + if (!is.fail()) + tp = floor(tp - offset); +} + +template +inline +void +parse(std::basic_istream& is, + const std::basic_string& format, sys_time& tp, + std::basic_string& abbrev, std::chrono::minutes& offset) +{ + detail::parse(is, format, tp, abbrev, offset); + if (!is.fail()) + tp = floor(tp - offset); +} + +template +inline +void +parse(std::basic_istream& is, + const std::basic_string& format, sys_time& tp, + std::chrono::minutes& offset, std::basic_string& abbrev) +{ + detail::parse(is, format, tp, abbrev, offset); + if (!is.fail()) + tp = floor(tp - offset); +} + +template +inline +void +parse(std::basic_istream& is, + const std::basic_string& format, local_time& tp) +{ + sys_time st; + std::basic_string abbrev; + std::chrono::minutes offset{}; + detail::parse(is, format, st, abbrev, offset); + if (!is.fail()) + tp = local_time{st.time_since_epoch()}; +} + +template +inline +void +parse(std::basic_istream& is, + const std::basic_string& format, local_time& tp, + std::basic_string& abbrev) +{ + sys_time st; + std::chrono::minutes offset{}; + detail::parse(is, format, st, abbrev, offset); + if (!is.fail()) + tp = local_time{st.time_since_epoch()}; +} + +template +inline +void +parse(std::basic_istream& is, + const std::basic_string& format, local_time& tp, + std::chrono::minutes& offset) +{ + sys_time st; + std::basic_string abbrev; + detail::parse(is, format, st, abbrev, offset); + if (!is.fail()) + tp = local_time{st.time_since_epoch()}; +} + +template +inline +void +parse(std::basic_istream& is, + const std::basic_string& format, local_time& tp, + std::basic_string& abbrev, std::chrono::minutes& offset) +{ + sys_time st; + detail::parse(is, format, st, abbrev, offset); + if (!is.fail()) + tp = local_time{st.time_since_epoch()}; +} + +template +inline +void +parse(std::basic_istream& is, + const std::basic_string& format, local_time& tp, + std::chrono::minutes& offset, std::basic_string& abbrev) +{ + sys_time st; + detail::parse(is, format, st, abbrev, offset); + if (!is.fail()) + tp = local_time{st.time_since_epoch()}; +} + +// const CharT* formats + +template +inline +void +parse(std::basic_istream& is, const CharT* format, sys_time& tp) +{ + parse(is, std::basic_string(format), tp); +} + +template +inline +void +parse(std::basic_istream& is, const CharT* format, sys_time& tp, + std::basic_string& abbrev) +{ + parse(is, std::basic_string(format), tp, abbrev); +} + +template +inline +void +parse(std::basic_istream& is, const CharT* format, sys_time& tp, + std::chrono::minutes& offset) +{ + parse(is, std::basic_string(format), tp, offset); +} + +template +inline +void +parse(std::basic_istream& is, const CharT* format, sys_time& tp, + std::basic_string& abbrev, std::chrono::minutes& offset) +{ + parse(is, std::basic_string(format), tp, abbrev, offset); +} + +template +inline +void +parse(std::basic_istream& is, const CharT* format, sys_time& tp, + std::chrono::minutes& offset, std::basic_string& abbrev) +{ + parse(is, std::basic_string(format), tp, abbrev, offset); +} + +template +inline +void +parse(std::basic_istream& is, const CharT* format, + local_time& tp) +{ + parse(is, std::basic_string(format), tp); +} + +template +inline +void +parse(std::basic_istream& is, const CharT* format, + local_time& tp, std::basic_string& abbrev) +{ + parse(is, std::basic_string(format), tp, abbrev); +} + +template +inline +void +parse(std::basic_istream& is, const CharT* format, + local_time& tp, std::chrono::minutes& offset) +{ + parse(is, std::basic_string(format), tp, offset); +} + +template +inline +void +parse(std::basic_istream& is, const CharT* format, + local_time& tp, std::basic_string& abbrev, + std::chrono::minutes& offset) +{ + parse(is, std::basic_string(format), tp, abbrev, offset); +} + +template +inline +void +parse(std::basic_istream& is, const CharT* format, + local_time& tp, std::chrono::minutes& offset, + std::basic_string& abbrev) +{ + parse(is, std::basic_string(format), tp, abbrev, offset); +} + } // namespace date #endif // DATE_H diff --git a/tz.h b/tz.h index 5196517..6941491 100644 --- a/tz.h +++ b/tz.h @@ -1336,127 +1336,6 @@ to_gps_time(tai_time t) // format -namespace detail -{ - -template -std::basic_string -format(const std::locale& loc, std::basic_string fmt, - local_time tp, const sys_info* info = nullptr) -{ - // Handle these specially - // %S append fractional seconds if tp has precision finer than seconds - // %T append fractional seconds if tp has precision finer than seconds - // %z replace with offset from zone on +/-hhmm format - // %Ez, %Oz replace with offset from zone on +/-hh:mm format - // %Z replace with abbreviation from zone - - using namespace std; - using namespace std::chrono; - auto command = false; - auto modified = false; - for (std::size_t i = 0; i < fmt.size(); ++i) - { - switch (fmt[i]) - { - case '%': - command = true; - modified = false; - break; - case 'O': - case 'E': - modified = true; - break; - case 'S': - case 'T': - if (command && !modified && ratio_less>::value) - { - basic_ostringstream os; - os.imbue(loc); - os << make_time(tp - floor(tp)); - auto s = os.str(); - s.erase(0, 8); - fmt.insert(i+1, s); - i += s.size() - 1; - } - command = false; - modified = false; - break; - case 'z': - if (command) - { - if (info == nullptr) - throw std::runtime_error("Can not format local_time with %z"); - else - { - auto offset = duration_cast(info->offset); - basic_ostringstream os; - if (offset >= minutes{0}) - os << '+'; - os << make_time(offset); - auto s = os.str(); - if (!modified) - s.erase(s.find(':'), 1); - fmt.replace(i - 1 - modified, 2 + modified, s); - i += s.size() - 1; - } - } - command = false; - modified = false; - break; - case 'Z': - if (command && !modified) - { - if (info == nullptr) - throw std::runtime_error("Can not format local_time with %Z"); - else - { - fmt.replace(i - 1, 2, std::basic_string - (info->abbrev.begin(), info->abbrev.end())); - i += info->abbrev.size() - 1; - } - } - command = false; - modified = false; - break; - default: - command = false; - modified = false; - break; - } - } - auto& f = use_facet>(loc); - basic_ostringstream os; - auto tt = system_clock::to_time_t(sys_time{tp.time_since_epoch()}); - std::tm tm{}; -#ifndef _MSC_VER - gmtime_r(&tt, &tm); -#else - gmtime_s(&tm, &tt); -#endif - f.put(os, os, os.fill(), &tm, fmt.data(), fmt.data() + fmt.size()); - return os.str(); -} - -} // namespace detail - -template -inline -std::basic_string -format(const std::locale& loc, std::basic_string fmt, - local_time tp) -{ - return detail::format(loc, std::move(fmt), tp); -} - -template -inline -std::basic_string -format(std::basic_string fmt, local_time tp) -{ - return detail::format(std::locale{}, std::move(fmt), tp); -} - template inline std::basic_string @@ -1464,7 +1343,8 @@ format(const std::locale& loc, std::basic_string fmt, const zoned_time& tp) { auto const info = tp.get_info(); - return detail::format(loc, std::move(fmt), tp.get_local_time(), &info); + return detail::format(loc, std::move(fmt), tp.get_local_time(), + &info.abbrev, &info.offset); } template @@ -1473,44 +1353,12 @@ std::basic_string format(std::basic_string fmt, const zoned_time& tp) { auto const info = tp.get_info(); - return detail::format(std::locale{}, std::move(fmt), tp.get_local_time(), &info); -} - -template -inline -std::basic_string -format(const std::locale& loc, std::basic_string fmt, - sys_time tp) -{ - return format(loc, std::move(fmt), make_zoned(locate_zone("UTC"), tp)); -} - -template -inline -std::basic_string -format(std::basic_string fmt, sys_time tp) -{ - return format(std::move(fmt), make_zoned(locate_zone("UTC"), tp)); + return detail::format(std::locale{}, std::move(fmt), tp.get_local_time(), + &info.abbrev, &info.offset); } // const CharT* formats -template -inline -std::basic_string -format(const std::locale& loc, const CharT* fmt, local_time tp) -{ - return detail::format(loc, std::basic_string(fmt), tp); -} - -template -inline -std::basic_string -format(const CharT* fmt, local_time tp) -{ - return detail::format(std::locale{}, std::basic_string(fmt), tp); -} - template inline std::basic_string @@ -1518,7 +1366,7 @@ format(const std::locale& loc, const CharT* fmt, const zoned_time& tp) { auto const info = tp.get_info(); return detail::format(loc, std::basic_string(fmt), tp.get_local_time(), - &info); + &info.abbrev, &info.offset); } template @@ -1528,432 +1376,7 @@ format(const CharT* fmt, const zoned_time& tp) { auto const info = tp.get_info(); return detail::format(std::locale{}, std::basic_string(fmt), - tp.get_local_time(), &info); -} - -template -inline -std::basic_string -format(const std::locale& loc, const CharT* fmt, sys_time tp) -{ - return format(loc, fmt, make_zoned(locate_zone("UTC"), tp)); -} - -template -inline -std::basic_string -format(const CharT* fmt, sys_time tp) -{ - return format(fmt, make_zoned(locate_zone("UTC"), tp)); -} - -// parse - -namespace detail -{ - -template -void -parse(std::basic_istream& is, - const std::basic_string& format, sys_time& tp, - std::basic_string& abbrev, std::chrono::minutes& offset) -{ - using namespace std; - using namespace std::chrono; - typename basic_istream::sentry ok{is}; - if (ok) - { - auto& f = use_facet>(is.getloc()); - ios_base::iostate err = ios_base::goodbit; - std::tm tm{}; - Duration subseconds{}; - std::basic_string temp_abbrev; - minutes temp_offset{}; - - auto b = format.data(); - auto i = b; - auto e = b + format.size(); - auto command = false; - auto modified = false; - for (; i < e; ++i) - { - switch (*i) - { - case '%': - command = true; - modified = false; - break; - case 'O': - case 'E': - modified = true; - break; - case 'T': - case 'S': - if (command && !modified) - { - f.get(is, 0, is, err, &tm, b, i-1); - b = i+1; - if (*i == 'T') - { - const CharT hm[] = {'%', 'H', ':', '%', 'M', ':'}; - f.get(is, 0, is, err, &tm, hm, hm+6); - } - if (ratio_less>::value) - { - auto decimal_point = Traits::to_int_type( - use_facet>(is.getloc()).decimal_point()); - string buf; - while (true) - { - auto k = is.peek(); - if (Traits::eq_int_type(k, Traits::eof())) - break; - if (Traits::eq_int_type(k, decimal_point)) - { - buf += '.'; - decimal_point = Traits::eof(); - is.get(); - } - else - { - auto c = static_cast(Traits::to_char_type(k)); - if (isdigit(c)) - { - buf += c; - is.get(); - } - else - { - break; - } - } - }; - if (!buf.empty()) - subseconds = round(duration{stod(buf)}); - else - err |= ios_base::failbit; - } - else - { - const CharT hm[] = {'%', 'S'}; - f.get(is, 0, is, err, &tm, hm, hm+2); - } - } - command = false; - modified = false; - break; - case 'z': - if (command) - { - f.get(is, 0, is, err, &tm, b, i-1-modified); - b = i+1; - if ((err & ios_base::failbit) == 0) - { - CharT sign{}; - is >> sign; - if (!is.fail() && (sign == '+' || sign == '-')) - { - char h1, h0, m1, m0; - char colon = ':'; - h1 = static_cast(is.get()); - h0 = static_cast(is.get()); - if (modified) - { - if (h0 == ':') - { - colon = h0; - h0 = h1; - h1 = '0'; - } - else - colon = static_cast(is.get()); - } - m1 = static_cast(is.get()); - m0 = static_cast(is.get()); - if (!is.fail() && std::isdigit(h1) && std::isdigit(h0) - && std::isdigit(m1) && std::isdigit(m0) - && colon == ':') - { - temp_offset = 10*hours{h1 - '0'} + hours{h0 - '0'} + - 10*minutes{m1 - '0'} + minutes{m0 - '0'}; - if (sign == '-') - temp_offset = -temp_offset; - } - else - err |= ios_base::failbit; - } - else - err |= ios_base::failbit; - } - } - command = false; - modified = false; - break; - case 'Z': - if (command && !modified) - { - f.get(is, 0, is, err, &tm, b, i-1); - b = i+1; - if ((err & ios_base::failbit) == 0) - { - is >> temp_abbrev; - if (is.fail()) - err |= ios_base::failbit; - } - } - command = false; - modified = false; - break; - default: - command = false; - modified = false; - break; - } - } - if ((err & ios_base::failbit) == 0) - { - if (b < e) - f.get(is, 0, is, err, &tm, b, e); - if ((err & ios_base::failbit) == 0) - { -#ifdef _WIN32 - auto tt = _mkgmtime(&tm); -#else - auto tt = timegm(&tm); -#endif - tp = floor(system_clock::from_time_t(tt) + subseconds); - abbrev = std::move(temp_abbrev); - offset = temp_offset; - } - } - is.setstate(err); - } -} - -} // namespace detail - -template -inline -void -parse(std::basic_istream& is, - const std::basic_string& format, sys_time& tp) -{ - std::basic_string abbrev; - std::chrono::minutes offset{}; - detail::parse(is, format, tp, abbrev, offset); - if (!is.fail()) - tp = floor(tp - offset); -} - -template -inline -void -parse(std::basic_istream& is, - const std::basic_string& format, sys_time& tp, - std::basic_string& abbrev) -{ - std::chrono::minutes offset{}; - detail::parse(is, format, tp, abbrev, offset); - if (!is.fail()) - tp = floor(tp - offset); -} - -template -inline -void -parse(std::basic_istream& is, - const std::basic_string& format, sys_time& tp, - std::chrono::minutes& offset) -{ - std::basic_string abbrev; - detail::parse(is, format, tp, abbrev, offset); - if (!is.fail()) - tp = floor(tp - offset); -} - -template -inline -void -parse(std::basic_istream& is, - const std::basic_string& format, sys_time& tp, - std::basic_string& abbrev, std::chrono::minutes& offset) -{ - detail::parse(is, format, tp, abbrev, offset); - if (!is.fail()) - tp = floor(tp - offset); -} - -template -inline -void -parse(std::basic_istream& is, - const std::basic_string& format, sys_time& tp, - std::chrono::minutes& offset, std::basic_string& abbrev) -{ - detail::parse(is, format, tp, abbrev, offset); - if (!is.fail()) - tp = floor(tp - offset); -} - -template -inline -void -parse(std::basic_istream& is, - const std::basic_string& format, local_time& tp) -{ - sys_time st; - std::basic_string abbrev; - std::chrono::minutes offset{}; - detail::parse(is, format, st, abbrev, offset); - if (!is.fail()) - tp = local_time{st.time_since_epoch()}; -} - -template -inline -void -parse(std::basic_istream& is, - const std::basic_string& format, local_time& tp, - std::basic_string& abbrev) -{ - sys_time st; - std::chrono::minutes offset{}; - detail::parse(is, format, st, abbrev, offset); - if (!is.fail()) - tp = local_time{st.time_since_epoch()}; -} - -template -inline -void -parse(std::basic_istream& is, - const std::basic_string& format, local_time& tp, - std::chrono::minutes& offset) -{ - sys_time st; - std::basic_string abbrev; - detail::parse(is, format, st, abbrev, offset); - if (!is.fail()) - tp = local_time{st.time_since_epoch()}; -} - -template -inline -void -parse(std::basic_istream& is, - const std::basic_string& format, local_time& tp, - std::basic_string& abbrev, std::chrono::minutes& offset) -{ - sys_time st; - detail::parse(is, format, st, abbrev, offset); - if (!is.fail()) - tp = local_time{st.time_since_epoch()}; -} - -template -inline -void -parse(std::basic_istream& is, - const std::basic_string& format, local_time& tp, - std::chrono::minutes& offset, std::basic_string& abbrev) -{ - sys_time st; - detail::parse(is, format, st, abbrev, offset); - if (!is.fail()) - tp = local_time{st.time_since_epoch()}; -} - -// const CharT* formats - -template -inline -void -parse(std::basic_istream& is, const CharT* format, sys_time& tp) -{ - parse(is, std::basic_string(format), tp); -} - -template -inline -void -parse(std::basic_istream& is, const CharT* format, sys_time& tp, - std::basic_string& abbrev) -{ - parse(is, std::basic_string(format), tp, abbrev); -} - -template -inline -void -parse(std::basic_istream& is, const CharT* format, sys_time& tp, - std::chrono::minutes& offset) -{ - parse(is, std::basic_string(format), tp, offset); -} - -template -inline -void -parse(std::basic_istream& is, const CharT* format, sys_time& tp, - std::basic_string& abbrev, std::chrono::minutes& offset) -{ - parse(is, std::basic_string(format), tp, abbrev, offset); -} - -template -inline -void -parse(std::basic_istream& is, const CharT* format, sys_time& tp, - std::chrono::minutes& offset, std::basic_string& abbrev) -{ - parse(is, std::basic_string(format), tp, abbrev, offset); -} - -template -inline -void -parse(std::basic_istream& is, const CharT* format, - local_time& tp) -{ - parse(is, std::basic_string(format), tp); -} - -template -inline -void -parse(std::basic_istream& is, const CharT* format, - local_time& tp, std::basic_string& abbrev) -{ - parse(is, std::basic_string(format), tp, abbrev); -} - -template -inline -void -parse(std::basic_istream& is, const CharT* format, - local_time& tp, std::chrono::minutes& offset) -{ - parse(is, std::basic_string(format), tp, offset); -} - -template -inline -void -parse(std::basic_istream& is, const CharT* format, - local_time& tp, std::basic_string& abbrev, - std::chrono::minutes& offset) -{ - parse(is, std::basic_string(format), tp, abbrev, offset); -} - -template -inline -void -parse(std::basic_istream& is, const CharT* format, - local_time& tp, std::chrono::minutes& offset, - std::basic_string& abbrev) -{ - parse(is, std::basic_string(format), tp, abbrev, offset); + tp.get_local_time(), &info.abbrev, &info.offset); } } // namespace date