forked from HowardHinnant/date
Move formatting and parsing
Moved formatting and parsing of sys_time and local_time from tz.h to date.h in order to make this functionality available to a wider audience. Existing code does not need to change. But future code can #include "date.h" instead of "tz.h" and need not compile tz.cpp nor link to curl. Formatting zoned_time remains in tz.h.
This commit is contained in:
598
date.h
598
date.h
@@ -3919,6 +3919,604 @@ operator<<(std::basic_ostream<CharT, Traits>& os, const local_time<Duration>& ut
|
|||||||
return os << sys_time<Duration>{ut.time_since_epoch()};
|
return os << sys_time<Duration>{ut.time_since_epoch()};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// format
|
||||||
|
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
template <class CharT, class Traits, class Duration>
|
||||||
|
std::basic_string<CharT, Traits>
|
||||||
|
format(const std::locale& loc, std::basic_string<CharT, Traits> fmt,
|
||||||
|
local_time<Duration> 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<typename Duration::period, ratio<1>>::value)
|
||||||
|
{
|
||||||
|
basic_ostringstream<CharT, Traits> os;
|
||||||
|
os.imbue(loc);
|
||||||
|
os << make_time(tp - floor<seconds>(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<minutes>(*offset_sec);
|
||||||
|
basic_ostringstream<CharT, Traits> 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<CharT, Traits>(abbrev->begin(), abbrev->end()));
|
||||||
|
i += abbrev->size() - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
command = false;
|
||||||
|
modified = false;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
command = false;
|
||||||
|
modified = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
auto& f = use_facet<time_put<CharT>>(loc);
|
||||||
|
basic_ostringstream<CharT, Traits> os;
|
||||||
|
auto tt = system_clock::to_time_t(sys_time<Duration>{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 <class CharT, class Traits, class Duration>
|
||||||
|
inline
|
||||||
|
std::basic_string<CharT, Traits>
|
||||||
|
format(const std::locale& loc, std::basic_string<CharT, Traits> fmt,
|
||||||
|
local_time<Duration> tp)
|
||||||
|
{
|
||||||
|
return detail::format(loc, std::move(fmt), tp);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class CharT, class Traits, class Duration>
|
||||||
|
inline
|
||||||
|
std::basic_string<CharT, Traits>
|
||||||
|
format(std::basic_string<CharT, Traits> fmt, local_time<Duration> tp)
|
||||||
|
{
|
||||||
|
return detail::format(std::locale{}, std::move(fmt), tp);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class CharT, class Traits, class Duration>
|
||||||
|
inline
|
||||||
|
std::basic_string<CharT, Traits>
|
||||||
|
format(const std::locale& loc, std::basic_string<CharT, Traits> fmt,
|
||||||
|
sys_time<Duration> tp)
|
||||||
|
{
|
||||||
|
const std::string abbrev("UTC");
|
||||||
|
CONSTDATA std::chrono::seconds offset{0};
|
||||||
|
return detail::format(loc, std::move(fmt),
|
||||||
|
local_time<Duration>{tp.time_since_epoch()}, &abbrev, &offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class CharT, class Traits, class Duration>
|
||||||
|
inline
|
||||||
|
std::basic_string<CharT, Traits>
|
||||||
|
format(std::basic_string<CharT, Traits> fmt, sys_time<Duration> tp)
|
||||||
|
{
|
||||||
|
const std::string abbrev("UTC");
|
||||||
|
CONSTDATA std::chrono::seconds offset{0};
|
||||||
|
return detail::format(std::move(fmt), local_time<Duration>{tp.time_since_epoch()},
|
||||||
|
&abbrev, &offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
// const CharT* formats
|
||||||
|
|
||||||
|
template <class CharT, class Duration>
|
||||||
|
inline
|
||||||
|
std::basic_string<CharT>
|
||||||
|
format(const std::locale& loc, const CharT* fmt, local_time<Duration> tp)
|
||||||
|
{
|
||||||
|
return detail::format(loc, std::basic_string<CharT>(fmt), tp);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class CharT, class Duration>
|
||||||
|
inline
|
||||||
|
std::basic_string<CharT>
|
||||||
|
format(const CharT* fmt, local_time<Duration> tp)
|
||||||
|
{
|
||||||
|
return detail::format(std::locale{}, std::basic_string<CharT>(fmt), tp);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class CharT, class Duration>
|
||||||
|
inline
|
||||||
|
std::basic_string<CharT>
|
||||||
|
format(const std::locale& loc, const CharT* fmt, sys_time<Duration> tp)
|
||||||
|
{
|
||||||
|
const std::string abbrev("UTC");
|
||||||
|
CONSTDATA std::chrono::seconds offset{0};
|
||||||
|
return detail::format(loc, std::basic_string<CharT>(fmt),
|
||||||
|
local_time<Duration>{tp.time_since_epoch()},
|
||||||
|
&abbrev, &offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class CharT, class Duration>
|
||||||
|
inline
|
||||||
|
std::basic_string<CharT>
|
||||||
|
format(const CharT* fmt, sys_time<Duration> tp)
|
||||||
|
{
|
||||||
|
const std::string abbrev("UTC");
|
||||||
|
CONSTDATA std::chrono::seconds offset{0};
|
||||||
|
return detail::format(std::locale{}, std::basic_string<CharT>(fmt),
|
||||||
|
local_time<Duration>{tp.time_since_epoch()},
|
||||||
|
&abbrev, &offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
// parse
|
||||||
|
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
template <class CharT, class Traits, class Duration>
|
||||||
|
void
|
||||||
|
parse(std::basic_istream<CharT, Traits>& is,
|
||||||
|
const std::basic_string<CharT, Traits>& format, sys_time<Duration>& tp,
|
||||||
|
std::basic_string<CharT, Traits>& abbrev, std::chrono::minutes& offset)
|
||||||
|
{
|
||||||
|
using namespace std;
|
||||||
|
using namespace std::chrono;
|
||||||
|
typename basic_istream<CharT, Traits>::sentry ok{is};
|
||||||
|
if (ok)
|
||||||
|
{
|
||||||
|
auto& f = use_facet<time_get<CharT>>(is.getloc());
|
||||||
|
ios_base::iostate err = ios_base::goodbit;
|
||||||
|
std::tm tm{};
|
||||||
|
Duration subseconds{};
|
||||||
|
std::basic_string<CharT, Traits> 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<typename Duration::period, ratio<1>>::value)
|
||||||
|
{
|
||||||
|
auto decimal_point = Traits::to_int_type(
|
||||||
|
use_facet<numpunct<CharT>>(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<char>(Traits::to_char_type(k));
|
||||||
|
if (isdigit(c))
|
||||||
|
{
|
||||||
|
buf += c;
|
||||||
|
is.get();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if (!buf.empty())
|
||||||
|
subseconds = round<Duration>(duration<double>{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<char>(is.get());
|
||||||
|
h0 = static_cast<char>(is.get());
|
||||||
|
if (modified)
|
||||||
|
{
|
||||||
|
if (h0 == ':')
|
||||||
|
{
|
||||||
|
colon = h0;
|
||||||
|
h0 = h1;
|
||||||
|
h1 = '0';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
colon = static_cast<char>(is.get());
|
||||||
|
}
|
||||||
|
m1 = static_cast<char>(is.get());
|
||||||
|
m0 = static_cast<char>(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<Duration>(system_clock::from_time_t(tt) + subseconds);
|
||||||
|
abbrev = std::move(temp_abbrev);
|
||||||
|
offset = temp_offset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
is.setstate(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
template <class CharT, class Traits, class Duration>
|
||||||
|
inline
|
||||||
|
void
|
||||||
|
parse(std::basic_istream<CharT, Traits>& is,
|
||||||
|
const std::basic_string<CharT, Traits>& format, sys_time<Duration>& tp)
|
||||||
|
{
|
||||||
|
std::basic_string<CharT, Traits> abbrev;
|
||||||
|
std::chrono::minutes offset{};
|
||||||
|
detail::parse(is, format, tp, abbrev, offset);
|
||||||
|
if (!is.fail())
|
||||||
|
tp = floor<Duration>(tp - offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class CharT, class Traits, class Duration>
|
||||||
|
inline
|
||||||
|
void
|
||||||
|
parse(std::basic_istream<CharT, Traits>& is,
|
||||||
|
const std::basic_string<CharT, Traits>& format, sys_time<Duration>& tp,
|
||||||
|
std::basic_string<CharT, Traits>& abbrev)
|
||||||
|
{
|
||||||
|
std::chrono::minutes offset{};
|
||||||
|
detail::parse(is, format, tp, abbrev, offset);
|
||||||
|
if (!is.fail())
|
||||||
|
tp = floor<Duration>(tp - offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class CharT, class Traits, class Duration>
|
||||||
|
inline
|
||||||
|
void
|
||||||
|
parse(std::basic_istream<CharT, Traits>& is,
|
||||||
|
const std::basic_string<CharT, Traits>& format, sys_time<Duration>& tp,
|
||||||
|
std::chrono::minutes& offset)
|
||||||
|
{
|
||||||
|
std::basic_string<CharT, Traits> abbrev;
|
||||||
|
detail::parse(is, format, tp, abbrev, offset);
|
||||||
|
if (!is.fail())
|
||||||
|
tp = floor<Duration>(tp - offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class CharT, class Traits, class Duration>
|
||||||
|
inline
|
||||||
|
void
|
||||||
|
parse(std::basic_istream<CharT, Traits>& is,
|
||||||
|
const std::basic_string<CharT, Traits>& format, sys_time<Duration>& tp,
|
||||||
|
std::basic_string<CharT, Traits>& abbrev, std::chrono::minutes& offset)
|
||||||
|
{
|
||||||
|
detail::parse(is, format, tp, abbrev, offset);
|
||||||
|
if (!is.fail())
|
||||||
|
tp = floor<Duration>(tp - offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class CharT, class Traits, class Duration>
|
||||||
|
inline
|
||||||
|
void
|
||||||
|
parse(std::basic_istream<CharT, Traits>& is,
|
||||||
|
const std::basic_string<CharT, Traits>& format, sys_time<Duration>& tp,
|
||||||
|
std::chrono::minutes& offset, std::basic_string<CharT, Traits>& abbrev)
|
||||||
|
{
|
||||||
|
detail::parse(is, format, tp, abbrev, offset);
|
||||||
|
if (!is.fail())
|
||||||
|
tp = floor<Duration>(tp - offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class CharT, class Traits, class Duration>
|
||||||
|
inline
|
||||||
|
void
|
||||||
|
parse(std::basic_istream<CharT, Traits>& is,
|
||||||
|
const std::basic_string<CharT, Traits>& format, local_time<Duration>& tp)
|
||||||
|
{
|
||||||
|
sys_time<Duration> st;
|
||||||
|
std::basic_string<CharT, Traits> abbrev;
|
||||||
|
std::chrono::minutes offset{};
|
||||||
|
detail::parse(is, format, st, abbrev, offset);
|
||||||
|
if (!is.fail())
|
||||||
|
tp = local_time<Duration>{st.time_since_epoch()};
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class CharT, class Traits, class Duration>
|
||||||
|
inline
|
||||||
|
void
|
||||||
|
parse(std::basic_istream<CharT, Traits>& is,
|
||||||
|
const std::basic_string<CharT, Traits>& format, local_time<Duration>& tp,
|
||||||
|
std::basic_string<CharT, Traits>& abbrev)
|
||||||
|
{
|
||||||
|
sys_time<Duration> st;
|
||||||
|
std::chrono::minutes offset{};
|
||||||
|
detail::parse(is, format, st, abbrev, offset);
|
||||||
|
if (!is.fail())
|
||||||
|
tp = local_time<Duration>{st.time_since_epoch()};
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class CharT, class Traits, class Duration>
|
||||||
|
inline
|
||||||
|
void
|
||||||
|
parse(std::basic_istream<CharT, Traits>& is,
|
||||||
|
const std::basic_string<CharT, Traits>& format, local_time<Duration>& tp,
|
||||||
|
std::chrono::minutes& offset)
|
||||||
|
{
|
||||||
|
sys_time<Duration> st;
|
||||||
|
std::basic_string<CharT, Traits> abbrev;
|
||||||
|
detail::parse(is, format, st, abbrev, offset);
|
||||||
|
if (!is.fail())
|
||||||
|
tp = local_time<Duration>{st.time_since_epoch()};
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class CharT, class Traits, class Duration>
|
||||||
|
inline
|
||||||
|
void
|
||||||
|
parse(std::basic_istream<CharT, Traits>& is,
|
||||||
|
const std::basic_string<CharT, Traits>& format, local_time<Duration>& tp,
|
||||||
|
std::basic_string<CharT, Traits>& abbrev, std::chrono::minutes& offset)
|
||||||
|
{
|
||||||
|
sys_time<Duration> st;
|
||||||
|
detail::parse(is, format, st, abbrev, offset);
|
||||||
|
if (!is.fail())
|
||||||
|
tp = local_time<Duration>{st.time_since_epoch()};
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class CharT, class Traits, class Duration>
|
||||||
|
inline
|
||||||
|
void
|
||||||
|
parse(std::basic_istream<CharT, Traits>& is,
|
||||||
|
const std::basic_string<CharT, Traits>& format, local_time<Duration>& tp,
|
||||||
|
std::chrono::minutes& offset, std::basic_string<CharT, Traits>& abbrev)
|
||||||
|
{
|
||||||
|
sys_time<Duration> st;
|
||||||
|
detail::parse(is, format, st, abbrev, offset);
|
||||||
|
if (!is.fail())
|
||||||
|
tp = local_time<Duration>{st.time_since_epoch()};
|
||||||
|
}
|
||||||
|
|
||||||
|
// const CharT* formats
|
||||||
|
|
||||||
|
template <class CharT, class Traits, class Duration>
|
||||||
|
inline
|
||||||
|
void
|
||||||
|
parse(std::basic_istream<CharT, Traits>& is, const CharT* format, sys_time<Duration>& tp)
|
||||||
|
{
|
||||||
|
parse(is, std::basic_string<CharT, Traits>(format), tp);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class CharT, class Traits, class Duration>
|
||||||
|
inline
|
||||||
|
void
|
||||||
|
parse(std::basic_istream<CharT, Traits>& is, const CharT* format, sys_time<Duration>& tp,
|
||||||
|
std::basic_string<CharT, Traits>& abbrev)
|
||||||
|
{
|
||||||
|
parse(is, std::basic_string<CharT, Traits>(format), tp, abbrev);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class CharT, class Traits, class Duration>
|
||||||
|
inline
|
||||||
|
void
|
||||||
|
parse(std::basic_istream<CharT, Traits>& is, const CharT* format, sys_time<Duration>& tp,
|
||||||
|
std::chrono::minutes& offset)
|
||||||
|
{
|
||||||
|
parse(is, std::basic_string<CharT, Traits>(format), tp, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class CharT, class Traits, class Duration>
|
||||||
|
inline
|
||||||
|
void
|
||||||
|
parse(std::basic_istream<CharT, Traits>& is, const CharT* format, sys_time<Duration>& tp,
|
||||||
|
std::basic_string<CharT, Traits>& abbrev, std::chrono::minutes& offset)
|
||||||
|
{
|
||||||
|
parse(is, std::basic_string<CharT, Traits>(format), tp, abbrev, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class CharT, class Traits, class Duration>
|
||||||
|
inline
|
||||||
|
void
|
||||||
|
parse(std::basic_istream<CharT, Traits>& is, const CharT* format, sys_time<Duration>& tp,
|
||||||
|
std::chrono::minutes& offset, std::basic_string<CharT, Traits>& abbrev)
|
||||||
|
{
|
||||||
|
parse(is, std::basic_string<CharT, Traits>(format), tp, abbrev, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class CharT, class Traits, class Duration>
|
||||||
|
inline
|
||||||
|
void
|
||||||
|
parse(std::basic_istream<CharT, Traits>& is, const CharT* format,
|
||||||
|
local_time<Duration>& tp)
|
||||||
|
{
|
||||||
|
parse(is, std::basic_string<CharT, Traits>(format), tp);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class CharT, class Traits, class Duration>
|
||||||
|
inline
|
||||||
|
void
|
||||||
|
parse(std::basic_istream<CharT, Traits>& is, const CharT* format,
|
||||||
|
local_time<Duration>& tp, std::basic_string<CharT, Traits>& abbrev)
|
||||||
|
{
|
||||||
|
parse(is, std::basic_string<CharT, Traits>(format), tp, abbrev);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class CharT, class Traits, class Duration>
|
||||||
|
inline
|
||||||
|
void
|
||||||
|
parse(std::basic_istream<CharT, Traits>& is, const CharT* format,
|
||||||
|
local_time<Duration>& tp, std::chrono::minutes& offset)
|
||||||
|
{
|
||||||
|
parse(is, std::basic_string<CharT, Traits>(format), tp, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class CharT, class Traits, class Duration>
|
||||||
|
inline
|
||||||
|
void
|
||||||
|
parse(std::basic_istream<CharT, Traits>& is, const CharT* format,
|
||||||
|
local_time<Duration>& tp, std::basic_string<CharT, Traits>& abbrev,
|
||||||
|
std::chrono::minutes& offset)
|
||||||
|
{
|
||||||
|
parse(is, std::basic_string<CharT, Traits>(format), tp, abbrev, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class CharT, class Traits, class Duration>
|
||||||
|
inline
|
||||||
|
void
|
||||||
|
parse(std::basic_istream<CharT, Traits>& is, const CharT* format,
|
||||||
|
local_time<Duration>& tp, std::chrono::minutes& offset,
|
||||||
|
std::basic_string<CharT, Traits>& abbrev)
|
||||||
|
{
|
||||||
|
parse(is, std::basic_string<CharT, Traits>(format), tp, abbrev, offset);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace date
|
} // namespace date
|
||||||
|
|
||||||
#endif // DATE_H
|
#endif // DATE_H
|
||||||
|
589
tz.h
589
tz.h
@@ -1336,127 +1336,6 @@ to_gps_time(tai_time<Duration> t)
|
|||||||
|
|
||||||
// format
|
// format
|
||||||
|
|
||||||
namespace detail
|
|
||||||
{
|
|
||||||
|
|
||||||
template <class CharT, class Traits, class Duration>
|
|
||||||
std::basic_string<CharT, Traits>
|
|
||||||
format(const std::locale& loc, std::basic_string<CharT, Traits> fmt,
|
|
||||||
local_time<Duration> 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<typename Duration::period, ratio<1>>::value)
|
|
||||||
{
|
|
||||||
basic_ostringstream<CharT, Traits> os;
|
|
||||||
os.imbue(loc);
|
|
||||||
os << make_time(tp - floor<seconds>(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<minutes>(info->offset);
|
|
||||||
basic_ostringstream<CharT, Traits> 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<CharT, Traits>
|
|
||||||
(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<time_put<CharT>>(loc);
|
|
||||||
basic_ostringstream<CharT, Traits> os;
|
|
||||||
auto tt = system_clock::to_time_t(sys_time<Duration>{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 <class CharT, class Traits, class Duration>
|
|
||||||
inline
|
|
||||||
std::basic_string<CharT, Traits>
|
|
||||||
format(const std::locale& loc, std::basic_string<CharT, Traits> fmt,
|
|
||||||
local_time<Duration> tp)
|
|
||||||
{
|
|
||||||
return detail::format(loc, std::move(fmt), tp);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class CharT, class Traits, class Duration>
|
|
||||||
inline
|
|
||||||
std::basic_string<CharT, Traits>
|
|
||||||
format(std::basic_string<CharT, Traits> fmt, local_time<Duration> tp)
|
|
||||||
{
|
|
||||||
return detail::format(std::locale{}, std::move(fmt), tp);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class CharT, class Traits, class Duration>
|
template <class CharT, class Traits, class Duration>
|
||||||
inline
|
inline
|
||||||
std::basic_string<CharT, Traits>
|
std::basic_string<CharT, Traits>
|
||||||
@@ -1464,7 +1343,8 @@ format(const std::locale& loc, std::basic_string<CharT, Traits> fmt,
|
|||||||
const zoned_time<Duration>& tp)
|
const zoned_time<Duration>& tp)
|
||||||
{
|
{
|
||||||
auto const info = tp.get_info();
|
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 <class CharT, class Traits, class Duration>
|
template <class CharT, class Traits, class Duration>
|
||||||
@@ -1473,44 +1353,12 @@ std::basic_string<CharT, Traits>
|
|||||||
format(std::basic_string<CharT, Traits> fmt, const zoned_time<Duration>& tp)
|
format(std::basic_string<CharT, Traits> fmt, const zoned_time<Duration>& tp)
|
||||||
{
|
{
|
||||||
auto const info = tp.get_info();
|
auto const info = tp.get_info();
|
||||||
return detail::format(std::locale{}, std::move(fmt), tp.get_local_time(), &info);
|
return detail::format(std::locale{}, std::move(fmt), tp.get_local_time(),
|
||||||
}
|
&info.abbrev, &info.offset);
|
||||||
|
|
||||||
template <class CharT, class Traits, class Duration>
|
|
||||||
inline
|
|
||||||
std::basic_string<CharT, Traits>
|
|
||||||
format(const std::locale& loc, std::basic_string<CharT, Traits> fmt,
|
|
||||||
sys_time<Duration> tp)
|
|
||||||
{
|
|
||||||
return format(loc, std::move(fmt), make_zoned(locate_zone("UTC"), tp));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class CharT, class Traits, class Duration>
|
|
||||||
inline
|
|
||||||
std::basic_string<CharT, Traits>
|
|
||||||
format(std::basic_string<CharT, Traits> fmt, sys_time<Duration> tp)
|
|
||||||
{
|
|
||||||
return format(std::move(fmt), make_zoned(locate_zone("UTC"), tp));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// const CharT* formats
|
// const CharT* formats
|
||||||
|
|
||||||
template <class CharT, class Duration>
|
|
||||||
inline
|
|
||||||
std::basic_string<CharT>
|
|
||||||
format(const std::locale& loc, const CharT* fmt, local_time<Duration> tp)
|
|
||||||
{
|
|
||||||
return detail::format(loc, std::basic_string<CharT>(fmt), tp);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class CharT, class Duration>
|
|
||||||
inline
|
|
||||||
std::basic_string<CharT>
|
|
||||||
format(const CharT* fmt, local_time<Duration> tp)
|
|
||||||
{
|
|
||||||
return detail::format(std::locale{}, std::basic_string<CharT>(fmt), tp);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class CharT, class Duration>
|
template <class CharT, class Duration>
|
||||||
inline
|
inline
|
||||||
std::basic_string<CharT>
|
std::basic_string<CharT>
|
||||||
@@ -1518,7 +1366,7 @@ format(const std::locale& loc, const CharT* fmt, const zoned_time<Duration>& tp)
|
|||||||
{
|
{
|
||||||
auto const info = tp.get_info();
|
auto const info = tp.get_info();
|
||||||
return detail::format(loc, std::basic_string<CharT>(fmt), tp.get_local_time(),
|
return detail::format(loc, std::basic_string<CharT>(fmt), tp.get_local_time(),
|
||||||
&info);
|
&info.abbrev, &info.offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class CharT, class Duration>
|
template <class CharT, class Duration>
|
||||||
@@ -1528,432 +1376,7 @@ format(const CharT* fmt, const zoned_time<Duration>& tp)
|
|||||||
{
|
{
|
||||||
auto const info = tp.get_info();
|
auto const info = tp.get_info();
|
||||||
return detail::format(std::locale{}, std::basic_string<CharT>(fmt),
|
return detail::format(std::locale{}, std::basic_string<CharT>(fmt),
|
||||||
tp.get_local_time(), &info);
|
tp.get_local_time(), &info.abbrev, &info.offset);
|
||||||
}
|
|
||||||
|
|
||||||
template <class CharT, class Duration>
|
|
||||||
inline
|
|
||||||
std::basic_string<CharT>
|
|
||||||
format(const std::locale& loc, const CharT* fmt, sys_time<Duration> tp)
|
|
||||||
{
|
|
||||||
return format(loc, fmt, make_zoned(locate_zone("UTC"), tp));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class CharT, class Duration>
|
|
||||||
inline
|
|
||||||
std::basic_string<CharT>
|
|
||||||
format(const CharT* fmt, sys_time<Duration> tp)
|
|
||||||
{
|
|
||||||
return format(fmt, make_zoned(locate_zone("UTC"), tp));
|
|
||||||
}
|
|
||||||
|
|
||||||
// parse
|
|
||||||
|
|
||||||
namespace detail
|
|
||||||
{
|
|
||||||
|
|
||||||
template <class CharT, class Traits, class Duration>
|
|
||||||
void
|
|
||||||
parse(std::basic_istream<CharT, Traits>& is,
|
|
||||||
const std::basic_string<CharT, Traits>& format, sys_time<Duration>& tp,
|
|
||||||
std::basic_string<CharT, Traits>& abbrev, std::chrono::minutes& offset)
|
|
||||||
{
|
|
||||||
using namespace std;
|
|
||||||
using namespace std::chrono;
|
|
||||||
typename basic_istream<CharT, Traits>::sentry ok{is};
|
|
||||||
if (ok)
|
|
||||||
{
|
|
||||||
auto& f = use_facet<time_get<CharT>>(is.getloc());
|
|
||||||
ios_base::iostate err = ios_base::goodbit;
|
|
||||||
std::tm tm{};
|
|
||||||
Duration subseconds{};
|
|
||||||
std::basic_string<CharT, Traits> 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<typename Duration::period, ratio<1>>::value)
|
|
||||||
{
|
|
||||||
auto decimal_point = Traits::to_int_type(
|
|
||||||
use_facet<numpunct<CharT>>(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<char>(Traits::to_char_type(k));
|
|
||||||
if (isdigit(c))
|
|
||||||
{
|
|
||||||
buf += c;
|
|
||||||
is.get();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if (!buf.empty())
|
|
||||||
subseconds = round<Duration>(duration<double>{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<char>(is.get());
|
|
||||||
h0 = static_cast<char>(is.get());
|
|
||||||
if (modified)
|
|
||||||
{
|
|
||||||
if (h0 == ':')
|
|
||||||
{
|
|
||||||
colon = h0;
|
|
||||||
h0 = h1;
|
|
||||||
h1 = '0';
|
|
||||||
}
|
|
||||||
else
|
|
||||||
colon = static_cast<char>(is.get());
|
|
||||||
}
|
|
||||||
m1 = static_cast<char>(is.get());
|
|
||||||
m0 = static_cast<char>(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<Duration>(system_clock::from_time_t(tt) + subseconds);
|
|
||||||
abbrev = std::move(temp_abbrev);
|
|
||||||
offset = temp_offset;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
is.setstate(err);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace detail
|
|
||||||
|
|
||||||
template <class CharT, class Traits, class Duration>
|
|
||||||
inline
|
|
||||||
void
|
|
||||||
parse(std::basic_istream<CharT, Traits>& is,
|
|
||||||
const std::basic_string<CharT, Traits>& format, sys_time<Duration>& tp)
|
|
||||||
{
|
|
||||||
std::basic_string<CharT, Traits> abbrev;
|
|
||||||
std::chrono::minutes offset{};
|
|
||||||
detail::parse(is, format, tp, abbrev, offset);
|
|
||||||
if (!is.fail())
|
|
||||||
tp = floor<Duration>(tp - offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class CharT, class Traits, class Duration>
|
|
||||||
inline
|
|
||||||
void
|
|
||||||
parse(std::basic_istream<CharT, Traits>& is,
|
|
||||||
const std::basic_string<CharT, Traits>& format, sys_time<Duration>& tp,
|
|
||||||
std::basic_string<CharT, Traits>& abbrev)
|
|
||||||
{
|
|
||||||
std::chrono::minutes offset{};
|
|
||||||
detail::parse(is, format, tp, abbrev, offset);
|
|
||||||
if (!is.fail())
|
|
||||||
tp = floor<Duration>(tp - offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class CharT, class Traits, class Duration>
|
|
||||||
inline
|
|
||||||
void
|
|
||||||
parse(std::basic_istream<CharT, Traits>& is,
|
|
||||||
const std::basic_string<CharT, Traits>& format, sys_time<Duration>& tp,
|
|
||||||
std::chrono::minutes& offset)
|
|
||||||
{
|
|
||||||
std::basic_string<CharT, Traits> abbrev;
|
|
||||||
detail::parse(is, format, tp, abbrev, offset);
|
|
||||||
if (!is.fail())
|
|
||||||
tp = floor<Duration>(tp - offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class CharT, class Traits, class Duration>
|
|
||||||
inline
|
|
||||||
void
|
|
||||||
parse(std::basic_istream<CharT, Traits>& is,
|
|
||||||
const std::basic_string<CharT, Traits>& format, sys_time<Duration>& tp,
|
|
||||||
std::basic_string<CharT, Traits>& abbrev, std::chrono::minutes& offset)
|
|
||||||
{
|
|
||||||
detail::parse(is, format, tp, abbrev, offset);
|
|
||||||
if (!is.fail())
|
|
||||||
tp = floor<Duration>(tp - offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class CharT, class Traits, class Duration>
|
|
||||||
inline
|
|
||||||
void
|
|
||||||
parse(std::basic_istream<CharT, Traits>& is,
|
|
||||||
const std::basic_string<CharT, Traits>& format, sys_time<Duration>& tp,
|
|
||||||
std::chrono::minutes& offset, std::basic_string<CharT, Traits>& abbrev)
|
|
||||||
{
|
|
||||||
detail::parse(is, format, tp, abbrev, offset);
|
|
||||||
if (!is.fail())
|
|
||||||
tp = floor<Duration>(tp - offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class CharT, class Traits, class Duration>
|
|
||||||
inline
|
|
||||||
void
|
|
||||||
parse(std::basic_istream<CharT, Traits>& is,
|
|
||||||
const std::basic_string<CharT, Traits>& format, local_time<Duration>& tp)
|
|
||||||
{
|
|
||||||
sys_time<Duration> st;
|
|
||||||
std::basic_string<CharT, Traits> abbrev;
|
|
||||||
std::chrono::minutes offset{};
|
|
||||||
detail::parse(is, format, st, abbrev, offset);
|
|
||||||
if (!is.fail())
|
|
||||||
tp = local_time<Duration>{st.time_since_epoch()};
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class CharT, class Traits, class Duration>
|
|
||||||
inline
|
|
||||||
void
|
|
||||||
parse(std::basic_istream<CharT, Traits>& is,
|
|
||||||
const std::basic_string<CharT, Traits>& format, local_time<Duration>& tp,
|
|
||||||
std::basic_string<CharT, Traits>& abbrev)
|
|
||||||
{
|
|
||||||
sys_time<Duration> st;
|
|
||||||
std::chrono::minutes offset{};
|
|
||||||
detail::parse(is, format, st, abbrev, offset);
|
|
||||||
if (!is.fail())
|
|
||||||
tp = local_time<Duration>{st.time_since_epoch()};
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class CharT, class Traits, class Duration>
|
|
||||||
inline
|
|
||||||
void
|
|
||||||
parse(std::basic_istream<CharT, Traits>& is,
|
|
||||||
const std::basic_string<CharT, Traits>& format, local_time<Duration>& tp,
|
|
||||||
std::chrono::minutes& offset)
|
|
||||||
{
|
|
||||||
sys_time<Duration> st;
|
|
||||||
std::basic_string<CharT, Traits> abbrev;
|
|
||||||
detail::parse(is, format, st, abbrev, offset);
|
|
||||||
if (!is.fail())
|
|
||||||
tp = local_time<Duration>{st.time_since_epoch()};
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class CharT, class Traits, class Duration>
|
|
||||||
inline
|
|
||||||
void
|
|
||||||
parse(std::basic_istream<CharT, Traits>& is,
|
|
||||||
const std::basic_string<CharT, Traits>& format, local_time<Duration>& tp,
|
|
||||||
std::basic_string<CharT, Traits>& abbrev, std::chrono::minutes& offset)
|
|
||||||
{
|
|
||||||
sys_time<Duration> st;
|
|
||||||
detail::parse(is, format, st, abbrev, offset);
|
|
||||||
if (!is.fail())
|
|
||||||
tp = local_time<Duration>{st.time_since_epoch()};
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class CharT, class Traits, class Duration>
|
|
||||||
inline
|
|
||||||
void
|
|
||||||
parse(std::basic_istream<CharT, Traits>& is,
|
|
||||||
const std::basic_string<CharT, Traits>& format, local_time<Duration>& tp,
|
|
||||||
std::chrono::minutes& offset, std::basic_string<CharT, Traits>& abbrev)
|
|
||||||
{
|
|
||||||
sys_time<Duration> st;
|
|
||||||
detail::parse(is, format, st, abbrev, offset);
|
|
||||||
if (!is.fail())
|
|
||||||
tp = local_time<Duration>{st.time_since_epoch()};
|
|
||||||
}
|
|
||||||
|
|
||||||
// const CharT* formats
|
|
||||||
|
|
||||||
template <class CharT, class Traits, class Duration>
|
|
||||||
inline
|
|
||||||
void
|
|
||||||
parse(std::basic_istream<CharT, Traits>& is, const CharT* format, sys_time<Duration>& tp)
|
|
||||||
{
|
|
||||||
parse(is, std::basic_string<CharT, Traits>(format), tp);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class CharT, class Traits, class Duration>
|
|
||||||
inline
|
|
||||||
void
|
|
||||||
parse(std::basic_istream<CharT, Traits>& is, const CharT* format, sys_time<Duration>& tp,
|
|
||||||
std::basic_string<CharT, Traits>& abbrev)
|
|
||||||
{
|
|
||||||
parse(is, std::basic_string<CharT, Traits>(format), tp, abbrev);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class CharT, class Traits, class Duration>
|
|
||||||
inline
|
|
||||||
void
|
|
||||||
parse(std::basic_istream<CharT, Traits>& is, const CharT* format, sys_time<Duration>& tp,
|
|
||||||
std::chrono::minutes& offset)
|
|
||||||
{
|
|
||||||
parse(is, std::basic_string<CharT, Traits>(format), tp, offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class CharT, class Traits, class Duration>
|
|
||||||
inline
|
|
||||||
void
|
|
||||||
parse(std::basic_istream<CharT, Traits>& is, const CharT* format, sys_time<Duration>& tp,
|
|
||||||
std::basic_string<CharT, Traits>& abbrev, std::chrono::minutes& offset)
|
|
||||||
{
|
|
||||||
parse(is, std::basic_string<CharT, Traits>(format), tp, abbrev, offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class CharT, class Traits, class Duration>
|
|
||||||
inline
|
|
||||||
void
|
|
||||||
parse(std::basic_istream<CharT, Traits>& is, const CharT* format, sys_time<Duration>& tp,
|
|
||||||
std::chrono::minutes& offset, std::basic_string<CharT, Traits>& abbrev)
|
|
||||||
{
|
|
||||||
parse(is, std::basic_string<CharT, Traits>(format), tp, abbrev, offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class CharT, class Traits, class Duration>
|
|
||||||
inline
|
|
||||||
void
|
|
||||||
parse(std::basic_istream<CharT, Traits>& is, const CharT* format,
|
|
||||||
local_time<Duration>& tp)
|
|
||||||
{
|
|
||||||
parse(is, std::basic_string<CharT, Traits>(format), tp);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class CharT, class Traits, class Duration>
|
|
||||||
inline
|
|
||||||
void
|
|
||||||
parse(std::basic_istream<CharT, Traits>& is, const CharT* format,
|
|
||||||
local_time<Duration>& tp, std::basic_string<CharT, Traits>& abbrev)
|
|
||||||
{
|
|
||||||
parse(is, std::basic_string<CharT, Traits>(format), tp, abbrev);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class CharT, class Traits, class Duration>
|
|
||||||
inline
|
|
||||||
void
|
|
||||||
parse(std::basic_istream<CharT, Traits>& is, const CharT* format,
|
|
||||||
local_time<Duration>& tp, std::chrono::minutes& offset)
|
|
||||||
{
|
|
||||||
parse(is, std::basic_string<CharT, Traits>(format), tp, offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class CharT, class Traits, class Duration>
|
|
||||||
inline
|
|
||||||
void
|
|
||||||
parse(std::basic_istream<CharT, Traits>& is, const CharT* format,
|
|
||||||
local_time<Duration>& tp, std::basic_string<CharT, Traits>& abbrev,
|
|
||||||
std::chrono::minutes& offset)
|
|
||||||
{
|
|
||||||
parse(is, std::basic_string<CharT, Traits>(format), tp, abbrev, offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class CharT, class Traits, class Duration>
|
|
||||||
inline
|
|
||||||
void
|
|
||||||
parse(std::basic_istream<CharT, Traits>& is, const CharT* format,
|
|
||||||
local_time<Duration>& tp, std::chrono::minutes& offset,
|
|
||||||
std::basic_string<CharT, Traits>& abbrev)
|
|
||||||
{
|
|
||||||
parse(is, std::basic_string<CharT, Traits>(format), tp, abbrev, offset);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace date
|
} // namespace date
|
||||||
|
Reference in New Issue
Block a user