mirror of
https://github.com/HowardHinnant/date.git
synced 2024-12-27 08:31:03 +08:00
Specify exception constructors
* For nonexistent_local_time and ambiguous_local_time. * Simplify the constructors. * Make these exceptions usable for custom time zones.
This commit is contained in:
parent
5563d31b2e
commit
9381e894a5
@ -32,6 +32,7 @@ This is actually several separate C++11/C++14 libraries:
|
|||||||
`"date.h"` and `"tz.h"` are now being proposed for standardization:
|
`"date.h"` and `"tz.h"` are now being proposed for standardization:
|
||||||
|
|
||||||
* Current proposal: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0355r4.html
|
* Current proposal: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0355r4.html
|
||||||
|
* Draft revision: http://howardhinnant.github.io/date/d0355r5.html
|
||||||
|
|
||||||
List of projects using this library:
|
List of projects using this library:
|
||||||
|
|
||||||
|
@ -151,101 +151,6 @@ namespace detail
|
|||||||
struct undocumented;
|
struct undocumented;
|
||||||
}
|
}
|
||||||
|
|
||||||
class nonexistent_local_time
|
|
||||||
: public std::runtime_error
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
template <class Duration>
|
|
||||||
nonexistent_local_time(local_time<Duration> tp, local_seconds first,
|
|
||||||
const std::string& first_abbrev, local_seconds last,
|
|
||||||
const std::string& last_abbrev, sys_seconds time_sys);
|
|
||||||
|
|
||||||
private:
|
|
||||||
template <class Duration>
|
|
||||||
static
|
|
||||||
std::string
|
|
||||||
make_msg(local_time<Duration> tp,
|
|
||||||
local_seconds first, const std::string& first_abbrev,
|
|
||||||
local_seconds last, const std::string& last_abbrev,
|
|
||||||
sys_seconds time_sys);
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class Duration>
|
|
||||||
inline
|
|
||||||
nonexistent_local_time::nonexistent_local_time(local_time<Duration> tp,
|
|
||||||
local_seconds begin,
|
|
||||||
const std::string& first_abbrev,
|
|
||||||
local_seconds end,
|
|
||||||
const std::string& last_abbrev,
|
|
||||||
sys_seconds time_sys)
|
|
||||||
: std::runtime_error(make_msg(tp, begin, first_abbrev, end, last_abbrev, time_sys))
|
|
||||||
{}
|
|
||||||
|
|
||||||
template <class Duration>
|
|
||||||
std::string
|
|
||||||
nonexistent_local_time::make_msg(local_time<Duration> tp, local_seconds begin,
|
|
||||||
const std::string& first_abbrev, local_seconds end,
|
|
||||||
const std::string& last_abbrev, sys_seconds time_sys)
|
|
||||||
{
|
|
||||||
using namespace date;
|
|
||||||
std::ostringstream os;
|
|
||||||
os << tp << " is in a gap between\n"
|
|
||||||
<< begin << ' ' << first_abbrev << " and\n"
|
|
||||||
<< end << ' ' << last_abbrev
|
|
||||||
<< " which are both equivalent to\n"
|
|
||||||
<< time_sys << " UTC";
|
|
||||||
return os.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
class ambiguous_local_time
|
|
||||||
: public std::runtime_error
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
template <class Duration>
|
|
||||||
ambiguous_local_time(local_time<Duration> tp, std::chrono::seconds first_offset,
|
|
||||||
const std::string& first_abbrev,
|
|
||||||
std::chrono::seconds second_offset,
|
|
||||||
const std::string& second_abbrev);
|
|
||||||
|
|
||||||
private:
|
|
||||||
template <class Duration>
|
|
||||||
static
|
|
||||||
std::string
|
|
||||||
make_msg(local_time<Duration> tp,
|
|
||||||
std::chrono::seconds first_offset, const std::string& first_abbrev,
|
|
||||||
std::chrono::seconds second_offset, const std::string& second_abbrev);
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class Duration>
|
|
||||||
inline
|
|
||||||
ambiguous_local_time::ambiguous_local_time(
|
|
||||||
local_time<Duration> tp,
|
|
||||||
std::chrono::seconds first_offset,
|
|
||||||
const std::string& first_abbrev,
|
|
||||||
std::chrono::seconds second_offset,
|
|
||||||
const std::string& second_abbrev)
|
|
||||||
: std::runtime_error(make_msg(tp, first_offset, first_abbrev, second_offset,
|
|
||||||
second_abbrev))
|
|
||||||
{}
|
|
||||||
|
|
||||||
template <class Duration>
|
|
||||||
std::string
|
|
||||||
ambiguous_local_time::make_msg(local_time<Duration> tp,
|
|
||||||
std::chrono::seconds first_offset,
|
|
||||||
const std::string& first_abbrev,
|
|
||||||
std::chrono::seconds second_offset,
|
|
||||||
const std::string& second_abbrev)
|
|
||||||
{
|
|
||||||
using namespace date;
|
|
||||||
std::ostringstream os;
|
|
||||||
os << tp << " is ambiguous. It could be\n"
|
|
||||||
<< tp << ' ' << first_abbrev << " == "
|
|
||||||
<< tp - first_offset << " UTC or\n"
|
|
||||||
<< tp << ' ' << second_abbrev << " == "
|
|
||||||
<< tp - second_offset << " UTC";
|
|
||||||
return os.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
struct sys_info
|
struct sys_info
|
||||||
{
|
{
|
||||||
sys_seconds begin;
|
sys_seconds begin;
|
||||||
@ -291,6 +196,79 @@ operator<<(std::basic_ostream<CharT, Traits>& os, const local_info& r)
|
|||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class nonexistent_local_time
|
||||||
|
: public std::runtime_error
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
template <class Duration>
|
||||||
|
nonexistent_local_time(local_time<Duration> tp, const local_info& i);
|
||||||
|
|
||||||
|
private:
|
||||||
|
template <class Duration>
|
||||||
|
static
|
||||||
|
std::string
|
||||||
|
make_msg(local_time<Duration> tp, const local_info& i);
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class Duration>
|
||||||
|
inline
|
||||||
|
nonexistent_local_time::nonexistent_local_time(local_time<Duration> tp,
|
||||||
|
const local_info& i)
|
||||||
|
: std::runtime_error(make_msg(tp, i))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Duration>
|
||||||
|
std::string
|
||||||
|
nonexistent_local_time::make_msg(local_time<Duration> tp, const local_info& i)
|
||||||
|
{
|
||||||
|
assert(i.result == local_info::nonexistent);
|
||||||
|
std::ostringstream os;
|
||||||
|
os << tp << " is in a gap between\n"
|
||||||
|
<< local_seconds{i.first.end.time_since_epoch()} + i.first.offset << ' '
|
||||||
|
<< i.first.abbrev << " and\n"
|
||||||
|
<< local_seconds{i.second.begin.time_since_epoch()} + i.second.offset << ' '
|
||||||
|
<< i.second.abbrev
|
||||||
|
<< " which are both equivalent to\n"
|
||||||
|
<< i.first.end << " UTC";
|
||||||
|
return os.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
class ambiguous_local_time
|
||||||
|
: public std::runtime_error
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
template <class Duration>
|
||||||
|
ambiguous_local_time(local_time<Duration> tp, const local_info& i);
|
||||||
|
|
||||||
|
private:
|
||||||
|
template <class Duration>
|
||||||
|
static
|
||||||
|
std::string
|
||||||
|
make_msg(local_time<Duration> tp, const local_info& i);
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class Duration>
|
||||||
|
inline
|
||||||
|
ambiguous_local_time::ambiguous_local_time(local_time<Duration> tp, const local_info& i)
|
||||||
|
: std::runtime_error(make_msg(tp, i))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Duration>
|
||||||
|
std::string
|
||||||
|
ambiguous_local_time::make_msg(local_time<Duration> tp, const local_info& i)
|
||||||
|
{
|
||||||
|
assert(i.result == local_info::ambiguous);
|
||||||
|
std::ostringstream os;
|
||||||
|
os << tp << " is ambiguous. It could be\n"
|
||||||
|
<< tp << ' ' << i.first.abbrev << " == "
|
||||||
|
<< tp - i.first.offset << " UTC or\n"
|
||||||
|
<< tp << ' ' << i.second.abbrev << " == "
|
||||||
|
<< tp - i.second.offset << " UTC";
|
||||||
|
return os.str();
|
||||||
|
}
|
||||||
|
|
||||||
class time_zone;
|
class time_zone;
|
||||||
|
|
||||||
#if HAS_STRING_VIEW
|
#if HAS_STRING_VIEW
|
||||||
@ -958,19 +936,9 @@ time_zone::to_sys_impl(local_time<Duration> tp, choose, std::true_type) const
|
|||||||
using namespace std::chrono;
|
using namespace std::chrono;
|
||||||
auto i = get_info(tp);
|
auto i = get_info(tp);
|
||||||
if (i.result == local_info::nonexistent)
|
if (i.result == local_info::nonexistent)
|
||||||
{
|
throw nonexistent_local_time(tp, i);
|
||||||
auto prev_end = local_seconds{i.first.end.time_since_epoch()} +
|
|
||||||
i.first.offset;
|
|
||||||
auto next_begin = local_seconds{i.second.begin.time_since_epoch()} +
|
|
||||||
i.second.offset;
|
|
||||||
throw nonexistent_local_time(tp, prev_end, i.first.abbrev,
|
|
||||||
next_begin, i.second.abbrev, i.first.end);
|
|
||||||
}
|
|
||||||
else if (i.result == local_info::ambiguous)
|
else if (i.result == local_info::ambiguous)
|
||||||
{
|
throw ambiguous_local_time(tp, i);
|
||||||
throw ambiguous_local_time(tp, i.first.offset, i.first.abbrev,
|
|
||||||
i.second.offset, i.second.abbrev);
|
|
||||||
}
|
|
||||||
return sys_time<Duration>{tp.time_since_epoch()} - i.first.offset;
|
return sys_time<Duration>{tp.time_since_epoch()} - i.first.offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user