mirror of
https://github.com/HowardHinnant/date.git
synced 2024-12-28 01:04:54 +08:00
Add support down to femtosecond precision
* Requires platform specific use of 128bit integral representation (e.g. std::chrono::duration<__int128_t, std::femto>).
This commit is contained in:
parent
5f01382e24
commit
481771ef5e
126
date.h
126
date.h
@ -1014,18 +1014,86 @@ trunc(T t) NOEXCEPT
|
|||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <std::intmax_t Xp, std::intmax_t Yp>
|
||||||
|
struct static_gcd
|
||||||
|
{
|
||||||
|
static const std::intmax_t value = static_gcd<Yp, Xp % Yp>::value;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <std::intmax_t Xp>
|
||||||
|
struct static_gcd<Xp, 0>
|
||||||
|
{
|
||||||
|
static const std::intmax_t value = Xp;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct static_gcd<0, 0>
|
||||||
|
{
|
||||||
|
static const std::intmax_t value = 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class R1, class R2>
|
||||||
|
struct no_overflow
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
static const std::intmax_t gcd_n1_n2 = static_gcd<R1::num, R2::num>::value;
|
||||||
|
static const std::intmax_t gcd_d1_d2 = static_gcd<R1::den, R2::den>::value;
|
||||||
|
static const std::intmax_t n1 = R1::num / gcd_n1_n2;
|
||||||
|
static const std::intmax_t d1 = R1::den / gcd_d1_d2;
|
||||||
|
static const std::intmax_t n2 = R2::num / gcd_n1_n2;
|
||||||
|
static const std::intmax_t d2 = R2::den / gcd_d1_d2;
|
||||||
|
static const std::intmax_t max = -((std::intmax_t(1) <<
|
||||||
|
(sizeof(std::intmax_t) * CHAR_BIT - 1)) + 1);
|
||||||
|
|
||||||
|
template <std::intmax_t Xp, std::intmax_t Yp, bool overflow>
|
||||||
|
struct mul // overflow == false
|
||||||
|
{
|
||||||
|
static const std::intmax_t value = Xp * Yp;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <std::intmax_t Xp, std::intmax_t Yp>
|
||||||
|
struct mul<Xp, Yp, true>
|
||||||
|
{
|
||||||
|
static const std::intmax_t value = 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
static const bool value = (n1 <= max / d2) && (n2 <= max / d1);
|
||||||
|
typedef std::ratio<mul<n1, d2, !value>::value,
|
||||||
|
mul<n2, d1, !value>::value> type;
|
||||||
|
};
|
||||||
|
|
||||||
} // detail
|
} // detail
|
||||||
|
|
||||||
// trunc towards zero
|
// trunc towards zero
|
||||||
template <class To, class Rep, class Period>
|
template <class To, class Rep, class Period>
|
||||||
CONSTCD11
|
CONSTCD11
|
||||||
inline
|
inline
|
||||||
|
typename std::enable_if
|
||||||
|
<
|
||||||
|
detail::no_overflow<Period, typename To::period>::value,
|
||||||
To
|
To
|
||||||
|
>::type
|
||||||
trunc(const std::chrono::duration<Rep, Period>& d)
|
trunc(const std::chrono::duration<Rep, Period>& d)
|
||||||
{
|
{
|
||||||
return To{detail::trunc(std::chrono::duration_cast<To>(d).count())};
|
return To{detail::trunc(std::chrono::duration_cast<To>(d).count())};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class To, class Rep, class Period>
|
||||||
|
CONSTCD11
|
||||||
|
inline
|
||||||
|
typename std::enable_if
|
||||||
|
<
|
||||||
|
!detail::no_overflow<Period, typename To::period>::value,
|
||||||
|
To
|
||||||
|
>::type
|
||||||
|
trunc(const std::chrono::duration<Rep, Period>& d)
|
||||||
|
{
|
||||||
|
using namespace std::chrono;
|
||||||
|
using rep = typename std::common_type<Rep, typename To::rep>::type;
|
||||||
|
return To{detail::trunc(duration_cast<To>(duration_cast<duration<rep>>(d)).count())};
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef HAS_CHRONO_ROUNDING
|
#ifndef HAS_CHRONO_ROUNDING
|
||||||
# if defined(_MSC_FULL_VER) && _MSC_FULL_VER >= 190023918
|
# if defined(_MSC_FULL_VER) && _MSC_FULL_VER >= 190023918
|
||||||
# define HAS_CHRONO_ROUNDING 1
|
# define HAS_CHRONO_ROUNDING 1
|
||||||
@ -1044,7 +1112,11 @@ trunc(const std::chrono::duration<Rep, Period>& d)
|
|||||||
template <class To, class Rep, class Period>
|
template <class To, class Rep, class Period>
|
||||||
CONSTCD14
|
CONSTCD14
|
||||||
inline
|
inline
|
||||||
|
typename std::enable_if
|
||||||
|
<
|
||||||
|
detail::no_overflow<Period, typename To::period>::value,
|
||||||
To
|
To
|
||||||
|
>::type
|
||||||
floor(const std::chrono::duration<Rep, Period>& d)
|
floor(const std::chrono::duration<Rep, Period>& d)
|
||||||
{
|
{
|
||||||
auto t = trunc<To>(d);
|
auto t = trunc<To>(d);
|
||||||
@ -1053,6 +1125,21 @@ floor(const std::chrono::duration<Rep, Period>& d)
|
|||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class To, class Rep, class Period>
|
||||||
|
CONSTCD14
|
||||||
|
inline
|
||||||
|
typename std::enable_if
|
||||||
|
<
|
||||||
|
!detail::no_overflow<Period, typename To::period>::value,
|
||||||
|
To
|
||||||
|
>::type
|
||||||
|
floor(const std::chrono::duration<Rep, Period>& d)
|
||||||
|
{
|
||||||
|
using namespace std::chrono;
|
||||||
|
using rep = typename std::common_type<Rep, typename To::rep>::type;
|
||||||
|
return floor<To>(floor<duration<rep>>(d));
|
||||||
|
}
|
||||||
|
|
||||||
// round to nearest, to even on tie
|
// round to nearest, to even on tie
|
||||||
template <class To, class Rep, class Period>
|
template <class To, class Rep, class Period>
|
||||||
CONSTCD14
|
CONSTCD14
|
||||||
@ -3494,18 +3581,18 @@ struct static_pow10<0>
|
|||||||
static CONSTDATA std::uint64_t value = 1;
|
static CONSTDATA std::uint64_t value = 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <unsigned w, bool in_range = (w < 19)>
|
template <class Rep, unsigned w, bool in_range = (w < 19)>
|
||||||
struct make_precision
|
struct make_precision
|
||||||
{
|
{
|
||||||
using type = std::chrono::duration<std::int64_t,
|
using type = std::chrono::duration<Rep,
|
||||||
std::ratio<1, static_pow10<w>::value>>;
|
std::ratio<1, static_pow10<w>::value>>;
|
||||||
static CONSTDATA unsigned width = w;
|
static CONSTDATA unsigned width = w;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <unsigned w>
|
template <class Rep, unsigned w>
|
||||||
struct make_precision<w, false>
|
struct make_precision<Rep, w, false>
|
||||||
{
|
{
|
||||||
using type = std::chrono::microseconds;
|
using type = std::chrono::duration<Rep, std::micro>;
|
||||||
static CONSTDATA unsigned width = 6;
|
static CONSTDATA unsigned width = 6;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -3516,8 +3603,9 @@ template <class Duration,
|
|||||||
class decimal_format_seconds
|
class decimal_format_seconds
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using precision = typename make_precision<w>::type;
|
using rep = typename std::common_type<Duration, std::chrono::seconds>::type::rep;
|
||||||
static auto CONSTDATA width = make_precision<w>::width;
|
using precision = typename make_precision<rep, w>::type;
|
||||||
|
static auto CONSTDATA width = make_precision<rep, w>::width;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::chrono::seconds s_;
|
std::chrono::seconds s_;
|
||||||
@ -3561,7 +3649,7 @@ public:
|
|||||||
os << x.s_.count() <<
|
os << x.s_.count() <<
|
||||||
std::use_facet<std::numpunct<char>>(os.getloc()).decimal_point();
|
std::use_facet<std::numpunct<char>>(os.getloc()).decimal_point();
|
||||||
os.width(width);
|
os.width(width);
|
||||||
os << x.sub_s_.count();
|
os << static_cast<std::int64_t>(x.sub_s_.count());
|
||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -3571,8 +3659,9 @@ class decimal_format_seconds<Duration, 0>
|
|||||||
{
|
{
|
||||||
static CONSTDATA unsigned w = 0;
|
static CONSTDATA unsigned w = 0;
|
||||||
public:
|
public:
|
||||||
using precision = std::chrono::seconds;
|
using rep = typename std::common_type<Duration, std::chrono::seconds>::type::rep;
|
||||||
static auto CONSTDATA width = make_precision<w>::width;
|
using precision = std::chrono::duration<rep>;
|
||||||
|
static auto CONSTDATA width = make_precision<rep, w>::width;
|
||||||
private:
|
private:
|
||||||
|
|
||||||
std::chrono::seconds s_;
|
std::chrono::seconds s_;
|
||||||
@ -4032,9 +4121,9 @@ public:
|
|||||||
{}
|
{}
|
||||||
|
|
||||||
CONSTCD11 explicit time_of_day_storage(Duration since_midnight) NOEXCEPT
|
CONSTCD11 explicit time_of_day_storage(Duration since_midnight) NOEXCEPT
|
||||||
: base(std::chrono::duration_cast<std::chrono::hours>(since_midnight),
|
: base(date::trunc<std::chrono::hours>(since_midnight),
|
||||||
since_midnight < Duration{0}, is24hr)
|
since_midnight < Duration{0}, is24hr)
|
||||||
, m_(std::chrono::duration_cast<std::chrono::minutes>(detail::abs(since_midnight) - h_))
|
, m_(date::trunc<std::chrono::minutes>(detail::abs(since_midnight) - h_))
|
||||||
, s_(detail::abs(since_midnight) - h_ - m_)
|
, s_(detail::abs(since_midnight) - h_ - m_)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
@ -5513,7 +5602,7 @@ to_stream(std::basic_ostream<CharT, Traits>& os, const CharT* fmt,
|
|||||||
{
|
{
|
||||||
using CT = typename std::common_type<Duration, std::chrono::seconds>::type;
|
using CT = typename std::common_type<Duration, std::chrono::seconds>::type;
|
||||||
auto ld = floor<days>(tp);
|
auto ld = floor<days>(tp);
|
||||||
fields<CT> fds{year_month_day{ld}, time_of_day<CT>{tp-ld}};
|
fields<CT> fds{year_month_day{ld}, time_of_day<CT>{tp-local_seconds{ld}}};
|
||||||
return to_stream(os, fmt, fds, abbrev, offset_sec);
|
return to_stream(os, fmt, fds, abbrev, offset_sec);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5522,11 +5611,12 @@ std::basic_ostream<CharT, Traits>&
|
|||||||
to_stream(std::basic_ostream<CharT, Traits>& os, const CharT* fmt,
|
to_stream(std::basic_ostream<CharT, Traits>& os, const CharT* fmt,
|
||||||
const sys_time<Duration>& tp)
|
const sys_time<Duration>& tp)
|
||||||
{
|
{
|
||||||
using CT = typename std::common_type<Duration, std::chrono::seconds>::type;
|
using namespace std::chrono;
|
||||||
|
using CT = typename std::common_type<Duration, seconds>::type;
|
||||||
const std::string abbrev("UTC");
|
const std::string abbrev("UTC");
|
||||||
CONSTDATA std::chrono::seconds offset{0};
|
CONSTDATA seconds offset{0};
|
||||||
auto sd = floor<days>(tp);
|
auto sd = floor<days>(tp);
|
||||||
fields<CT> fds{year_month_day{sd}, time_of_day<CT>{tp-sd}};
|
fields<CT> fds{year_month_day{sd}, time_of_day<CT>{tp-sys_seconds{sd}}};
|
||||||
return to_stream(os, fmt, fds, &abbrev, &offset);
|
return to_stream(os, fmt, fds, &abbrev, &offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -7033,7 +7123,7 @@ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
|
|||||||
if (!fds.ymd.ok() || !fds.tod.in_conventional_range())
|
if (!fds.ymd.ok() || !fds.tod.in_conventional_range())
|
||||||
is.setstate(ios::failbit);
|
is.setstate(ios::failbit);
|
||||||
if (!is.fail())
|
if (!is.fail())
|
||||||
tp = round<Duration>(sys_days(fds.ymd) + fds.tod.to_duration() - *offptr);
|
tp = round<Duration>(sys_days(fds.ymd) - *offptr + fds.tod.to_duration());
|
||||||
return is;
|
return is;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -7051,7 +7141,7 @@ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
|
|||||||
if (!fds.ymd.ok() || !fds.tod.in_conventional_range())
|
if (!fds.ymd.ok() || !fds.tod.in_conventional_range())
|
||||||
is.setstate(ios::failbit);
|
is.setstate(ios::failbit);
|
||||||
if (!is.fail())
|
if (!is.fail())
|
||||||
tp = round<Duration>(local_days(fds.ymd) + fds.tod.to_duration());
|
tp = round<Duration>(local_seconds{local_days(fds.ymd)} + fds.tod.to_duration());
|
||||||
return is;
|
return is;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,7 +94,7 @@ main()
|
|||||||
{
|
{
|
||||||
using D = decimal_format_seconds<milliseconds>;
|
using D = decimal_format_seconds<milliseconds>;
|
||||||
static_assert(D::width == 3, "");
|
static_assert(D::width == 3, "");
|
||||||
static_assert(is_same<D::precision, make_precision<D::width>::type>{}, "");
|
static_assert(is_same<D::precision, make_precision<D::rep, D::width>::type>{}, "");
|
||||||
D dfs{seconds{3}};
|
D dfs{seconds{3}};
|
||||||
assert(dfs.seconds() == seconds{3});
|
assert(dfs.seconds() == seconds{3});
|
||||||
assert(dfs.to_duration() == seconds{3});
|
assert(dfs.to_duration() == seconds{3});
|
||||||
@ -106,7 +106,7 @@ main()
|
|||||||
{
|
{
|
||||||
using D = decimal_format_seconds<milliseconds>;
|
using D = decimal_format_seconds<milliseconds>;
|
||||||
static_assert(D::width == 3, "");
|
static_assert(D::width == 3, "");
|
||||||
static_assert(is_same<D::precision, make_precision<D::width>::type>{}, "");
|
static_assert(is_same<D::precision, make_precision<D::rep, D::width>::type>{}, "");
|
||||||
D dfs{milliseconds{3}};
|
D dfs{milliseconds{3}};
|
||||||
assert(dfs.seconds() == seconds{0});
|
assert(dfs.seconds() == seconds{0});
|
||||||
assert(dfs.to_duration() == milliseconds{3});
|
assert(dfs.to_duration() == milliseconds{3});
|
||||||
@ -118,7 +118,7 @@ main()
|
|||||||
{
|
{
|
||||||
using D = decimal_format_seconds<microfortnights>;
|
using D = decimal_format_seconds<microfortnights>;
|
||||||
static_assert(D::width == 4, "");
|
static_assert(D::width == 4, "");
|
||||||
using S = make_precision<D::width>::type;
|
using S = make_precision<D::rep, D::width>::type;
|
||||||
static_assert(is_same<D::precision, S>{}, "");
|
static_assert(is_same<D::precision, S>{}, "");
|
||||||
D dfs{microfortnights{3}};
|
D dfs{microfortnights{3}};
|
||||||
assert(dfs.seconds() == seconds{3});
|
assert(dfs.seconds() == seconds{3});
|
||||||
@ -132,7 +132,7 @@ main()
|
|||||||
using CT = common_type<seconds, microfortnights>::type;
|
using CT = common_type<seconds, microfortnights>::type;
|
||||||
using D = decimal_format_seconds<CT>;
|
using D = decimal_format_seconds<CT>;
|
||||||
static_assert(D::width == 4, "");
|
static_assert(D::width == 4, "");
|
||||||
using S = make_precision<D::width>::type;
|
using S = make_precision<D::rep, D::width>::type;
|
||||||
static_assert(is_same<D::precision, S>{}, "");
|
static_assert(is_same<D::precision, S>{}, "");
|
||||||
D dfs{microfortnights{3}};
|
D dfs{microfortnights{3}};
|
||||||
assert(dfs.seconds() == seconds{3});
|
assert(dfs.seconds() == seconds{3});
|
||||||
|
@ -40,24 +40,24 @@ main()
|
|||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace std::chrono;
|
using namespace std::chrono;
|
||||||
|
|
||||||
static_assert(make_precision<0>::width == 0, "");
|
static_assert(make_precision<int64_t, 0>::width == 0, "");
|
||||||
static_assert(is_same<make_precision<0>::type, duration<int64_t, ratio<1, 1>>>{}, "");
|
static_assert(is_same<make_precision<int64_t, 0>::type, duration<int64_t, ratio<1, 1>>>{}, "");
|
||||||
|
|
||||||
static_assert(make_precision<1>::width == 1, "");
|
static_assert(make_precision<int64_t, 1>::width == 1, "");
|
||||||
static_assert(is_same<make_precision<1>::type, duration<int64_t, ratio<1, 10>>>{}, "");
|
static_assert(is_same<make_precision<int64_t, 1>::type, duration<int64_t, ratio<1, 10>>>{}, "");
|
||||||
|
|
||||||
static_assert(make_precision<2>::width == 2, "");
|
static_assert(make_precision<int64_t, 2>::width == 2, "");
|
||||||
static_assert(is_same<make_precision<2>::type, duration<int64_t, ratio<1, 100>>>{}, "");
|
static_assert(is_same<make_precision<int64_t, 2>::type, duration<int64_t, ratio<1, 100>>>{}, "");
|
||||||
|
|
||||||
static_assert(make_precision<3>::width == 3, "");
|
static_assert(make_precision<int64_t, 3>::width == 3, "");
|
||||||
static_assert(is_same<make_precision<3>::type, duration<int64_t, ratio<1, 1000>>>{}, "");
|
static_assert(is_same<make_precision<int64_t, 3>::type, duration<int64_t, ratio<1, 1000>>>{}, "");
|
||||||
|
|
||||||
static_assert(make_precision<18>::width == 18, "");
|
static_assert(make_precision<int64_t, 18>::width == 18, "");
|
||||||
static_assert(is_same<make_precision<18>::type, duration<int64_t, ratio<1, 1000000000000000000>>>{}, "");
|
static_assert(is_same<make_precision<int64_t, 18>::type, duration<int64_t, ratio<1, 1000000000000000000>>>{}, "");
|
||||||
|
|
||||||
static_assert(make_precision<19>::width == 6, "");
|
static_assert(make_precision<int64_t, 19>::width == 6, "");
|
||||||
static_assert(is_same<make_precision<19>::type, microseconds>{}, "");
|
static_assert(is_same<make_precision<int64_t, 19>::type, microseconds>{}, "");
|
||||||
|
|
||||||
static_assert(make_precision<20>::width == 6, "");
|
static_assert(make_precision<int64_t, 20>::width == 6, "");
|
||||||
static_assert(is_same<make_precision<20>::type, microseconds>{}, "");
|
static_assert(is_same<make_precision<int64_t, 20>::type, microseconds>{}, "");
|
||||||
}
|
}
|
||||||
|
23
tz.h
23
tz.h
@ -1913,7 +1913,7 @@ to_stream(std::basic_ostream<CharT, Traits>& os, const CharT* fmt,
|
|||||||
auto tp = sys_time<CT>{t.time_since_epoch() - ls.second};
|
auto tp = sys_time<CT>{t.time_since_epoch() - ls.second};
|
||||||
auto const sd = floor<days>(tp);
|
auto const sd = floor<days>(tp);
|
||||||
year_month_day ymd = sd;
|
year_month_day ymd = sd;
|
||||||
auto time = make_time(tp - sd);
|
auto time = make_time(tp - sys_seconds{sd});
|
||||||
time.seconds() += seconds{ls.first};
|
time.seconds() += seconds{ls.first};
|
||||||
fields<CT> fds{ymd, time};
|
fields<CT> fds{ymd, time};
|
||||||
return to_stream(os, fmt, fds, &abbrev, &offset);
|
return to_stream(os, fmt, fds, &abbrev, &offset);
|
||||||
@ -1947,7 +1947,7 @@ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
|
|||||||
bool is_60_sec = fds.tod.seconds() == seconds{60};
|
bool is_60_sec = fds.tod.seconds() == seconds{60};
|
||||||
if (is_60_sec)
|
if (is_60_sec)
|
||||||
fds.tod.seconds() -= seconds{1};
|
fds.tod.seconds() -= seconds{1};
|
||||||
auto tmp = to_utc_time(sys_days(fds.ymd) + (fds.tod.to_duration() - *offptr));
|
auto tmp = to_utc_time(sys_days(fds.ymd) - *offptr + fds.tod.to_duration());
|
||||||
if (is_60_sec)
|
if (is_60_sec)
|
||||||
tmp += seconds{1};
|
tmp += seconds{1};
|
||||||
if (is_60_sec != is_leap_second(tmp).first || !fds.tod.in_conventional_range())
|
if (is_60_sec != is_leap_second(tmp).first || !fds.tod.in_conventional_range())
|
||||||
@ -2028,10 +2028,10 @@ to_stream(std::basic_ostream<CharT, Traits>& os, const CharT* fmt,
|
|||||||
const string abbrev("TAI");
|
const string abbrev("TAI");
|
||||||
CONSTDATA seconds offset{0};
|
CONSTDATA seconds offset{0};
|
||||||
auto tp = sys_time<CT>{t.time_since_epoch()} -
|
auto tp = sys_time<CT>{t.time_since_epoch()} -
|
||||||
(sys_days(year{1970}/jan/1) - sys_days(year{1958}/jan/1));
|
seconds(sys_days(year{1970}/jan/1) - sys_days(year{1958}/jan/1));
|
||||||
auto const sd = floor<days>(tp);
|
auto const sd = floor<days>(tp);
|
||||||
year_month_day ymd = sd;
|
year_month_day ymd = sd;
|
||||||
auto time = make_time(tp - sd);
|
auto time = make_time(tp - sys_seconds{sd});
|
||||||
fields<CT> fds{ymd, time};
|
fields<CT> fds{ymd, time};
|
||||||
return to_stream(os, fmt, fds, &abbrev, &offset);
|
return to_stream(os, fmt, fds, &abbrev, &offset);
|
||||||
}
|
}
|
||||||
@ -2062,8 +2062,9 @@ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
|
|||||||
is.setstate(ios::failbit);
|
is.setstate(ios::failbit);
|
||||||
if (!is.fail())
|
if (!is.fail())
|
||||||
tp = tai_time<Duration>{duration_cast<Duration>(
|
tp = tai_time<Duration>{duration_cast<Duration>(
|
||||||
(sys_days(fds.ymd) + fds.tod.to_duration() + (sys_days(year{1970}/jan/1) -
|
(sys_days(fds.ymd) +
|
||||||
sys_days(year{1958}/jan/1)) - *offptr).time_since_epoch())};
|
(sys_days(year{1970}/jan/1) - sys_days(year{1958}/jan/1)) -
|
||||||
|
*offptr + fds.tod.to_duration()).time_since_epoch())};
|
||||||
return is;
|
return is;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2135,10 +2136,10 @@ to_stream(std::basic_ostream<CharT, Traits>& os, const CharT* fmt,
|
|||||||
const string abbrev("GPS");
|
const string abbrev("GPS");
|
||||||
CONSTDATA seconds offset{0};
|
CONSTDATA seconds offset{0};
|
||||||
auto tp = sys_time<CT>{t.time_since_epoch()} +
|
auto tp = sys_time<CT>{t.time_since_epoch()} +
|
||||||
(sys_days(year{1980}/jan/sun[1]) - sys_days(year{1970}/jan/1));
|
seconds(sys_days(year{1980}/jan/sun[1]) - sys_days(year{1970}/jan/1));
|
||||||
auto const sd = floor<days>(tp);
|
auto const sd = floor<days>(tp);
|
||||||
year_month_day ymd = sd;
|
year_month_day ymd = sd;
|
||||||
auto time = make_time(tp - sd);
|
auto time = make_time(tp - sys_seconds{sd});
|
||||||
fields<CT> fds{ymd, time};
|
fields<CT> fds{ymd, time};
|
||||||
return to_stream(os, fmt, fds, &abbrev, &offset);
|
return to_stream(os, fmt, fds, &abbrev, &offset);
|
||||||
}
|
}
|
||||||
@ -2169,9 +2170,9 @@ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
|
|||||||
is.setstate(ios::failbit);
|
is.setstate(ios::failbit);
|
||||||
if (!is.fail())
|
if (!is.fail())
|
||||||
tp = gps_time<Duration>{duration_cast<Duration>(
|
tp = gps_time<Duration>{duration_cast<Duration>(
|
||||||
(sys_days(fds.ymd) + fds.tod.to_duration() -
|
(sys_days(fds.ymd) -
|
||||||
(sys_days(year{1980}/jan/sun[1]) -
|
(sys_days(year{1980}/jan/sun[1]) - sys_days(year{1970}/jan/1)) -
|
||||||
sys_days(year{1970}/jan/1)) - *offptr).time_since_epoch())};
|
*offptr + fds.tod.to_duration()).time_since_epoch())};
|
||||||
return is;
|
return is;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user