Get rid of tz. Hide unnecessary API. Clean up get_info

This commit is contained in:
Howard Hinnant
2016-05-08 22:59:39 -04:00
parent 183b7a82f2
commit f5f0f80778
4 changed files with 172 additions and 97 deletions

View File

@@ -103,7 +103,7 @@ main()
auto z = locate_zone(name); auto z = locate_zone(name);
auto begin = sys_days(jan/1/year::min()) + 0s; auto begin = sys_days(jan/1/year::min()) + 0s;
auto end = sys_days(jan/1/2035) + 0s; auto end = sys_days(jan/1/2035) + 0s;
auto info = z->get_info(begin, tz::utc); auto info = z->get_info(begin);
std::cout << "Initially: "; std::cout << "Initially: ";
if (info.offset >= 0s) if (info.offset >= 0s)
std::cout << '+'; std::cout << '+';
@@ -119,7 +119,7 @@ main()
auto prev_save = info.save; auto prev_save = info.save;
for (begin = info.end; begin < end; begin = info.end) for (begin = info.end; begin < end; begin = info.end)
{ {
info = z->get_info(begin, tz::utc); info = z->get_info(begin);
test_info(z, info); test_info(z, info);
if (info.offset == prev_offset && info.abbrev == prev_abbrev && if (info.offset == prev_offset && info.abbrev == prev_abbrev &&
info.save == prev_save) info.save == prev_save)

85
tz.cpp
View File

@@ -119,9 +119,6 @@ static const std::vector<std::string> files =
CONSTDATA auto min_year = date::year::min(); CONSTDATA auto min_year = date::year::min();
CONSTDATA auto max_year = date::year::max(); CONSTDATA auto max_year = date::year::max();
// Arbitrary day of the year that will be away from any limits.
// Used with year::min() and year::max().
CONSTDATA auto boring_day = date::aug/18;
CONSTDATA auto min_day = date::jan/1; CONSTDATA auto min_day = date::jan/1;
CONSTDATA auto max_day = date::dec/31; CONSTDATA auto max_day = date::dec/31;
@@ -129,16 +126,9 @@ CONSTDATA auto max_day = date::dec/31;
// | End Configuration | // | End Configuration |
// +-------------------+ // +-------------------+
#if _MSC_VER && ! defined(__clang__) && ! defined( __GNUG__) #ifndef _MSC_VER
// We can't use static_assert here for MSVC (yet) because
// the expression isn't constexpr in MSVC yet.
// FIXME! Remove this when MSVC's constexpr support improves.
#else
static_assert(min_year <= max_year, "Configuration error"); static_assert(min_year <= max_year, "Configuration error");
#endif #endif
#if __cplusplus >= 201402
static_assert(boring_day.ok(), "Configuration error");
#endif
// Until filesystem arrives. // Until filesystem arrives.
static CONSTDATA char folder_delimiter = static CONSTDATA char folder_delimiter =
@@ -290,7 +280,7 @@ static inline size_t countof(T(&arr)[N])
// The routine tries to load as many time zone entries as possible despite errors. // The routine tries to load as many time zone entries as possible despite errors.
// We don't want to fail to load the whole database just because one record can't be read. // We don't want to fail to load the whole database just because one record can't be read.
static void get_windows_timezone_info(std::vector<timezone_info>& tz_list) static void get_windows_timezone_info(std::vector<detail::timezone_info>& tz_list)
{ {
tz_list.clear(); tz_list.clear();
LONG result; LONG result;
@@ -315,7 +305,7 @@ static void get_windows_timezone_info(std::vector<timezone_info>& tz_list)
std::wstring full_zone_key_name; std::wstring full_zone_key_name;
for (DWORD zone_index = 0; ; ++zone_index) for (DWORD zone_index = 0; ; ++zone_index)
{ {
timezone_info tz; detail::timezone_info tz;
size = (DWORD) sizeof(zone_key_name)/sizeof(zone_key_name[0]); size = (DWORD) sizeof(zone_key_name)/sizeof(zone_key_name[0]);
auto status = RegEnumKeyExW(zones_key.handle(), zone_index, zone_key_name, &size, auto status = RegEnumKeyExW(zones_key.handle(), zone_index, zone_key_name, &size,
@@ -366,7 +356,7 @@ static void get_windows_timezone_info(std::vector<timezone_info>& tz_list)
// under the windows registry key Time Zones. // under the windows registry key Time Zones.
// To be clear, standard_name does NOT represent a windows timezone id // To be clear, standard_name does NOT represent a windows timezone id
// or an IANA tzid // or an IANA tzid
static const timezone_info* find_native_timezone_by_standard_name( static const detail::timezone_info* find_native_timezone_by_standard_name(
const std::string& standard_name) const std::string& standard_name)
{ {
// TODO! we can improve on linear search. // TODO! we can improve on linear search.
@@ -383,11 +373,11 @@ static const timezone_info* find_native_timezone_by_standard_name(
// Read CSV file of "other","territory","type". // Read CSV file of "other","territory","type".
// See timezone_mapping structure for more info. // See timezone_mapping structure for more info.
// This function should be kept in sync with the code that writes this file. // This function should be kept in sync with the code that writes this file.
static std::vector<timezone_mapping> static std::vector<detail::timezone_mapping>
load_timezone_mappings_from_csv_file(const std::string& input_path) load_timezone_mappings_from_csv_file(const std::string& input_path)
{ {
size_t line = 1; size_t line = 1;
std::vector<timezone_mapping> mappings; std::vector<detail::timezone_mapping> mappings;
std::ifstream is(input_path, std::ios_base::in | std::ios_base::binary); std::ifstream is(input_path, std::ios_base::in | std::ios_base::binary);
if (!is.is_open()) if (!is.is_open())
{ {
@@ -418,7 +408,7 @@ load_timezone_mappings_from_csv_file(const std::string& input_path)
for (;;) for (;;)
{ {
timezone_mapping zm{}; detail::timezone_mapping zm{};
char ch; char ch;
is.read(&ch, 1); is.read(&ch, 1);
@@ -1532,7 +1522,7 @@ find_rule_for_zone(const std::pair<const Rule*, const Rule*>& eqr,
} }
static static
Info sys_info
find_rule(const std::pair<const Rule*, date::year>& first_rule, find_rule(const std::pair<const Rule*, date::year>& first_rule,
const std::pair<const Rule*, date::year>& last_rule, const std::pair<const Rule*, date::year>& last_rule,
const date::year& y, const std::chrono::seconds& offset, const date::year& y, const std::chrono::seconds& offset,
@@ -1543,7 +1533,7 @@ find_rule(const std::pair<const Rule*, date::year>& first_rule,
using namespace date; using namespace date;
auto r = first_rule.first; auto r = first_rule.first;
auto ry = first_rule.second; auto ry = first_rule.second;
Info x{sys_days(year::min()/min_day), sys_days(year::max()/max_day), sys_info x{sys_days(year::min()/min_day), sys_days(year::max()/max_day),
seconds{0}, initial_save, initial_abbrev}; seconds{0}, initial_save, initial_abbrev};
while (r != nullptr) while (r != nullptr)
{ {
@@ -1757,11 +1747,43 @@ format_abbrev(std::string format, const std::string& variable, std::chrono::seco
return format; return format;
} }
Info sys_info
time_zone::get_info_impl(sys_seconds tp, tz timezone) const time_zone::get_info_impl(sys_seconds tp) const
{
return get_info_impl(tp, static_cast<int>(tz::utc));
}
local_info
time_zone::get_info_impl(local_seconds tp) const
{
using namespace std::chrono;
local_info i{};
i.first = get_info_impl(sys_seconds{tp.time_since_epoch()}, static_cast<int>(tz::local));
auto tps = sys_seconds{(tp - i.first.offset).time_since_epoch()};
if (tps < i.first.begin)
{
i.second = std::move(i.first);
i.first = get_info_impl(i.second.begin - seconds{1}, static_cast<int>(tz::utc));
i.result = local_info::nonexistent;
}
else if (i.first.end - tps <= days{1})
{
i.second = get_info_impl(i.first.end, static_cast<int>(tz::utc));
tps = sys_seconds{(tp - i.second.offset).time_since_epoch()};
if (tps >= i.second.begin)
i.result = local_info::ambiguous;
else
i.second = {};
}
return i;
}
sys_info
time_zone::get_info_impl(sys_seconds tp, int tz_int) const
{ {
using namespace std::chrono; using namespace std::chrono;
using namespace date; using namespace date;
tz timezone = static_cast<tz>(tz_int);
assert(timezone != tz::standard); assert(timezone != tz::standard);
auto y = year_month_day(floor<days>(tp)).year(); auto y = year_month_day(floor<days>(tp)).year();
if (y < min_year || y > max_year) if (y < min_year || y > max_year)
@@ -1782,7 +1804,7 @@ time_zone::get_info_impl(sys_seconds tp, tz timezone) const
t < sys_seconds{zl.until_loc_.time_since_epoch()}; t < sys_seconds{zl.until_loc_.time_since_epoch()};
}); });
Info r{}; sys_info r{};
if (i != zonelets_.end()) if (i != zonelets_.end())
{ {
if (i->tag_ == zonelet::has_save) if (i->tag_ == zonelet::has_save)
@@ -2301,9 +2323,8 @@ operator<<(std::ostream& os, const TZ_DB& db)
// ----------------------- // -----------------------
std::ostream& std::ostream&
operator<<(std::ostream& os, const Info& r) operator<<(std::ostream& os, const sys_info& r)
{ {
using namespace date;
os << r.begin << '\n'; os << r.begin << '\n';
os << r.end << '\n'; os << r.end << '\n';
os << make_time(r.offset) << "\n"; os << make_time(r.offset) << "\n";
@@ -2312,6 +2333,22 @@ operator<<(std::ostream& os, const Info& r)
return os; return os;
} }
std::ostream&
operator<<(std::ostream& os, const local_info& r)
{
if (r.result == local_info::nonexistent)
os << "nonexistent between\n";
else if (r.result == local_info::ambiguous)
os << "ambiguous between\n";
os << r.first;
if (r.result != local_info::unique)
{
os << "and\n";
os << r.second;
}
return os;
}
#ifdef _WIN32 #ifdef _WIN32
const time_zone* const time_zone*

172
tz.h
View File

@@ -97,7 +97,6 @@ static_assert(HAS_REMOTE_API == 0 ? AUTO_DOWNLOAD == 0 : true,
namespace date namespace date
{ {
enum class tz {utc, local, standard};
enum class choose {earliest, latest}; enum class choose {earliest, latest};
class nonexistent_local_time class nonexistent_local_time
@@ -197,7 +196,7 @@ ambiguous_local_time::make_msg(local_time<Duration> tp,
class Rule; class Rule;
struct Info struct sys_info
{ {
sys_seconds begin; sys_seconds begin;
sys_seconds end; sys_seconds end;
@@ -207,7 +206,21 @@ struct Info
}; };
std::ostream& std::ostream&
operator<<(std::ostream& os, const Info& r); operator<<(std::ostream& os, const sys_info& r);
struct local_info
{
enum {unique, nonexistent, ambiguous} result;
sys_info first;
sys_info second;
};
std::ostream&
operator<<(std::ostream& os, const local_info& r);
// deprecated:
using Info = sys_info;
class time_zone; class time_zone;
// deprecated: // deprecated:
@@ -253,12 +266,12 @@ public:
explicit zoned_time(const std::string& name); explicit zoned_time(const std::string& name);
template <class Duration2, template <class Duration2,
class = std::enable_if class = typename std::enable_if
< <
std::is_convertible<sys_time<Duration2>, std::is_convertible<sys_time<Duration2>,
sys_time<Duration>>::value sys_time<Duration>>::value
>> >::type>
zoned_time(const zoned_time<Duration2>& zt); zoned_time(const zoned_time<Duration2>& zt) NOEXCEPT;
zoned_time(const time_zone* z, local_time<Duration> tp); zoned_time(const time_zone* z, local_time<Duration> tp);
zoned_time(const std::string& name, local_time<Duration> tp); zoned_time(const std::string& name, local_time<Duration> tp);
@@ -267,8 +280,8 @@ public:
zoned_time(const time_zone* z, const zoned_time<Duration>& zt); zoned_time(const time_zone* z, const zoned_time<Duration>& zt);
zoned_time(const std::string& name, const zoned_time<Duration>& zt); zoned_time(const std::string& name, const zoned_time<Duration>& zt);
zoned_time(const time_zone* z, const zoned_time<Duration>& zt, choose c); zoned_time(const time_zone* z, const zoned_time<Duration>& zt, choose);
zoned_time(const std::string& name, const zoned_time<Duration>& zt, choose c); zoned_time(const std::string& name, const zoned_time<Duration>& zt, choose);
zoned_time(const time_zone* z, const sys_time<Duration>& st); zoned_time(const time_zone* z, const sys_time<Duration>& st);
zoned_time(const std::string& name, const sys_time<Duration>& st); zoned_time(const std::string& name, const sys_time<Duration>& st);
@@ -276,12 +289,13 @@ public:
zoned_time& operator=(sys_time<Duration> st); zoned_time& operator=(sys_time<Duration> st);
zoned_time& operator=(local_time<Duration> ut); zoned_time& operator=(local_time<Duration> ut);
explicit operator local_time<Duration>() const;
operator sys_time<Duration>() const; operator sys_time<Duration>() const;
explicit operator local_time<Duration>() const;
const time_zone* get_time_zone() const; const time_zone* get_time_zone() const;
local_time<Duration> get_local_time() const; local_time<Duration> get_local_time() const;
sys_time<Duration> get_sys_time() const; sys_time<Duration> get_sys_time() const;
sys_info get_info() const;
template <class Duration1, class Duration2> template <class Duration1, class Duration2>
friend friend
@@ -295,21 +309,18 @@ public:
private: private:
static_assert(std::ratio_less_equal<typename Duration::period, static_assert(std::is_convertible<std::chrono::seconds, Duration>::value,
std::chrono::seconds::period>::value,
"zoned_time must have a precision of seconds or finer"); "zoned_time must have a precision of seconds or finer");
}; };
using zoned_seconds = zoned_time<std::chrono::seconds>; using zoned_seconds = zoned_time<std::chrono::seconds>;
// Should equality bother with comparing zones?
// If zones don't matter, add operator< ?
template <class Duration1, class Duration2> template <class Duration1, class Duration2>
inline inline
bool bool
operator==(const zoned_time<Duration1>& x, const zoned_time<Duration2>& y) operator==(const zoned_time<Duration1>& x, const zoned_time<Duration2>& y)
{ {
return x.zone == y.zone && x.tp == y.tp; return x.zone_ == y.zone_ && x.tp_ == y.tp_;
} }
template <class Duration1, class Duration2> template <class Duration1, class Duration2>
@@ -344,10 +355,9 @@ public:
const std::string& name() const; const std::string& name() const;
template <class Duration> Info get_info(sys_time<Duration> st) const; template <class Duration> sys_info get_info(sys_time<Duration> st) const;
template <class Duration> Info get_info(local_time<Duration> tp) const; template <class Duration> local_info get_info(local_time<Duration> tp) const;
private:
template <class Duration> template <class Duration>
sys_time<typename std::common_type<Duration, std::chrono::seconds>::type> sys_time<typename std::common_type<Duration, std::chrono::seconds>::type>
to_sys(local_time<Duration> tp) const; to_sys(local_time<Duration> tp) const;
@@ -360,7 +370,6 @@ private:
local_time<typename std::common_type<Duration, std::chrono::seconds>::type> local_time<typename std::common_type<Duration, std::chrono::seconds>::type>
to_local(sys_time<Duration> tp) const; to_local(sys_time<Duration> tp) const;
public:
friend bool operator==(const time_zone& x, const time_zone& y); friend bool operator==(const time_zone& x, const time_zone& y);
friend bool operator< (const time_zone& x, const time_zone& y); friend bool operator< (const time_zone& x, const time_zone& y);
friend std::ostream& operator<<(std::ostream& os, const time_zone& z); friend std::ostream& operator<<(std::ostream& os, const time_zone& z);
@@ -369,16 +378,18 @@ public:
void adjust_infos(const std::vector<Rule>& rules); void adjust_infos(const std::vector<Rule>& rules);
private: private:
Info get_info_impl(sys_seconds tp, tz timezone) const; sys_info get_info_impl(sys_seconds tp) const;
local_info get_info_impl(local_seconds tp) const;
sys_info get_info_impl(sys_seconds tp, int timezone) const;
void parse_info(std::istream& in); void parse_info(std::istream& in);
template <class Duration, bool b> template <class Duration>
sys_time<typename std::common_type<Duration, std::chrono::seconds>::type> sys_time<typename std::common_type<Duration, std::chrono::seconds>::type>
to_sys_impl(local_time<Duration> tp, choose z, to_sys_impl(local_time<Duration> tp, choose z, std::false_type) const;
std::integral_constant<bool, b> do_throw) const; template <class Duration>
sys_time<typename std::common_type<Duration, std::chrono::seconds>::type>
template <class Duration2> friend class zoned_time; to_sys_impl(local_time<Duration> tp, choose, std::true_type) const;
}; };
#if defined(_MSC_VER) && (_MSC_VER < 1900) #if defined(_MSC_VER) && (_MSC_VER < 1900)
@@ -415,21 +426,20 @@ time_zone::name() const
template <class Duration> template <class Duration>
inline inline
Info sys_info
time_zone::get_info(sys_time<Duration> st) const time_zone::get_info(sys_time<Duration> st) const
{ {
using namespace std::chrono; using namespace std::chrono;
return get_info_impl(floor<seconds>(st), tz::utc); return get_info_impl(floor<seconds>(st));
} }
template <class Duration> template <class Duration>
inline inline
Info local_info
time_zone::get_info(local_time<Duration> tp) const time_zone::get_info(local_time<Duration> tp) const
{ {
using namespace std::chrono; using namespace std::chrono;
return get_info_impl(floor<seconds>(sys_time<Duration>{tp.time_since_epoch()}), return get_info_impl(floor<seconds>(tp));
tz::local);
} }
template <class Duration> template <class Duration>
@@ -466,48 +476,47 @@ inline bool operator> (const time_zone& x, const time_zone& y) {return y < x;}
inline bool operator<=(const time_zone& x, const time_zone& y) {return !(y < x);} inline bool operator<=(const time_zone& x, const time_zone& y) {return !(y < x);}
inline bool operator>=(const time_zone& x, const time_zone& y) {return !(x < y);} inline bool operator>=(const time_zone& x, const time_zone& y) {return !(x < y);}
template <class Duration, bool b> template <class Duration>
sys_time<typename std::common_type<Duration, std::chrono::seconds>::type> sys_time<typename std::common_type<Duration, std::chrono::seconds>::type>
time_zone::to_sys_impl(local_time<Duration> tp, choose z, time_zone::to_sys_impl(local_time<Duration> tp, choose z, std::false_type) const
std::integral_constant<bool, b> do_throw) const
{ {
using namespace date; using namespace date;
using namespace std::chrono; using namespace std::chrono;
auto i = get_info(tp); auto i = get_info(tp);
auto tp_sys = sys_time<Duration>{tp.time_since_epoch()} - i.offset; if (i.result == local_info::nonexistent)
if (floor<seconds>(tp_sys) - i.begin <= days{1})
{ {
auto ut_begin = local_seconds{i.begin.time_since_epoch()} + i.offset; return i.first.end;
if (floor<seconds>(tp) < ut_begin)
{
if (do_throw)
{
auto prev = get_info(i.begin - seconds{1});
auto ut_prev_begin = local_seconds{i.begin.time_since_epoch()} + prev.offset;
throw nonexistent_local_time(tp, ut_prev_begin, prev.abbrev,
ut_begin, i.abbrev, i.begin);
} }
return i.begin; else if (i.result == local_info::ambiguous)
}
assert(floor<seconds>(tp) >=
local_seconds{i.begin.time_since_epoch()} +
get_info(i.begin - seconds{1}).offset);
}
if (i.end - floor<seconds>(tp_sys) <= days{1})
{ {
assert(floor<seconds>(tp) < local_seconds{i.end.time_since_epoch()} + i.offset);
auto next = get_info(i.end);
if (floor<seconds>(tp) >= local_seconds{i.end.time_since_epoch()} + next.offset)
{
if (do_throw)
throw ambiguous_local_time(tp, i.offset, i.abbrev,
next.offset, next.abbrev);
if (z == choose::earliest) if (z == choose::earliest)
return tp_sys; return sys_time<Duration>{tp.time_since_epoch()} - i.second.offset;
return sys_time<Duration>{tp.time_since_epoch()} - next.offset;
} }
return sys_time<Duration>{tp.time_since_epoch()} - i.first.offset;
} }
return tp_sys;
template <class Duration>
sys_time<typename std::common_type<Duration, std::chrono::seconds>::type>
time_zone::to_sys_impl(local_time<Duration> tp, choose, std::true_type) const
{
using namespace date;
using namespace std::chrono;
auto i = get_info(tp);
if (i.result == local_info::nonexistent)
{
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)
{
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;
} }
class Link class Link
@@ -651,7 +660,8 @@ operator>=(const sys_time<Duration>& x, const Leap& y)
#if TIMEZONE_MAPPING #if TIMEZONE_MAPPING
// TODO! Ensure all these types aren't exposed. namespace detail
{
// The time zone mapping is modelled after this data file: // The time zone mapping is modelled after this data file:
// http://unicode.org/repos/cldr/trunk/common/supplemental/windowsZones.xml // http://unicode.org/repos/cldr/trunk/common/supplemental/windowsZones.xml
@@ -689,6 +699,8 @@ struct timezone_info
std::string standard_name; std::string standard_name;
}; };
} // detail
#endif // TIMEZONE_MAPPING #endif // TIMEZONE_MAPPING
struct TZ_DB struct TZ_DB
@@ -700,8 +712,8 @@ struct TZ_DB
std::vector<Rule> rules; std::vector<Rule> rules;
#if TIMEZONE_MAPPING #if TIMEZONE_MAPPING
// TODO! These need some protection. // TODO! These need some protection.
std::vector<timezone_mapping> mappings; std::vector<detail::timezone_mapping> mappings;
std::vector<timezone_info> native_zones; std::vector<detail::timezone_info> native_zones;
#endif #endif
TZ_DB() = default; TZ_DB() = default;
@@ -783,7 +795,7 @@ template <class Duration>
inline inline
zoned_time<Duration>::zoned_time(const time_zone* z, local_time<Duration> t) zoned_time<Duration>::zoned_time(const time_zone* z, local_time<Duration> t)
: zone_(z) : zone_(z)
, tp_(floor<Duration>(z->to_sys(t))) , tp_(z->to_sys(t))
{} {}
template <class Duration> template <class Duration>
@@ -796,7 +808,7 @@ template <class Duration>
inline inline
zoned_time<Duration>::zoned_time(const time_zone* z, local_time<Duration> t, choose c) zoned_time<Duration>::zoned_time(const time_zone* z, local_time<Duration> t, choose c)
: zone_(z) : zone_(z)
, tp_(floor<Duration>(z->to_sys(t, c))) , tp_(z->to_sys(t, c))
{} {}
template <class Duration> template <class Duration>
@@ -809,7 +821,7 @@ zoned_time<Duration>::zoned_time(const std::string& name, local_time<Duration> t
template <class Duration> template <class Duration>
template <class Duration2, class> template <class Duration2, class>
inline inline
zoned_time<Duration>::zoned_time(const zoned_time<Duration2>& zt) zoned_time<Duration>::zoned_time(const zoned_time<Duration2>& zt) NOEXCEPT
: zone_(zt.zone_) : zone_(zt.zone_)
, tp_(zt.tp_) , tp_(zt.tp_)
{} {}
@@ -868,7 +880,7 @@ inline
zoned_time<Duration>& zoned_time<Duration>&
zoned_time<Duration>::operator=(local_time<Duration> ut) zoned_time<Duration>::operator=(local_time<Duration> ut)
{ {
tp_ = floor<Duration>(zone_->to_sys(ut)); tp_ = zone_->to_sys(ut);
return *this; return *this;
} }
@@ -899,7 +911,7 @@ inline
local_time<Duration> local_time<Duration>
zoned_time<Duration>::get_local_time() const zoned_time<Duration>::get_local_time() const
{ {
return floor<Duration>(zone_->to_local(tp_)); return zone_->to_local(tp_);
} }
template <class Duration> template <class Duration>
@@ -910,6 +922,14 @@ zoned_time<Duration>::get_sys_time() const
return tp_; return tp_;
} }
template <class Duration>
inline
sys_info
zoned_time<Duration>::get_info() const
{
return zone_->get_info(tp_);
}
// make_zoned_time // make_zoned_time
template <class Duration> template <class Duration>
@@ -936,6 +956,22 @@ make_zoned(const std::string& name, local_time<Duration> tp)
return {name, tp}; return {name, tp};
} }
template <class Duration>
inline
zoned_time<typename std::common_type<Duration, std::chrono::seconds>::type>
make_zoned(const time_zone* zone, local_time<Duration> tp, choose c)
{
return {zone, tp, c};
}
template <class Duration>
inline
zoned_time<typename std::common_type<Duration, std::chrono::seconds>::type>
make_zoned(const std::string& name, local_time<Duration> tp, choose c)
{
return {name, tp, c};
}
template <class Duration> template <class Duration>
inline inline
zoned_time<typename std::common_type<Duration, std::chrono::seconds>::type> zoned_time<typename std::common_type<Duration, std::chrono::seconds>::type>

View File

@@ -32,6 +32,8 @@
namespace date namespace date
{ {
enum class tz {utc, local, standard};
class MonthDayTime class MonthDayTime
{ {
private: private: