mirror of
https://github.com/HowardHinnant/date.git
synced 2024-12-27 00:14:07 +08:00
Rewrite format and parse in terms of detail::fields<Duration>
* Add format and parse to utc_time<Duration>. * Added more tests.
This commit is contained in:
parent
3233cbaf9a
commit
e9d36c6200
145
test/date_test/detail/decimal_format_seconds.pass.cpp
Normal file
145
test/date_test/detail/decimal_format_seconds.pass.cpp
Normal file
@ -0,0 +1,145 @@
|
||||
// The MIT License (MIT)
|
||||
//
|
||||
// Copyright (c) 2017 Howard Hinnant
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
// template <class Duration,
|
||||
// unsigned w = width<std::common_type<
|
||||
// Duration,
|
||||
// std::chrono::seconds>::type::period::den>::value>
|
||||
// class decimal_format_seconds
|
||||
// {
|
||||
// public:
|
||||
// using precision = typename make_precision<w>::type;
|
||||
// static auto constexpr width = make_precision<w>::width;
|
||||
//
|
||||
// private:
|
||||
// std::chrono::seconds s_;
|
||||
// precision sub_s_;
|
||||
//
|
||||
// public:
|
||||
// constexpr explicit decimal_format_seconds(const Duration& d) noexcept;
|
||||
//
|
||||
// constexpr std::chrono::seconds& seconds() noexcept;
|
||||
// constexpr std::chrono::seconds seconds() const noexcept;
|
||||
// constexpr precision subseconds() const noexcept;
|
||||
// constexpr precision to_duration() const noexcept;
|
||||
//
|
||||
// template <class CharT, class Traits>
|
||||
// friend
|
||||
// std::basic_ostream<CharT, Traits>&
|
||||
// operator<<(std::basic_ostream<CharT, Traits>& os, const decimal_format_seconds& x);
|
||||
// };
|
||||
|
||||
#include "date.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <sstream>
|
||||
#include <type_traits>
|
||||
|
||||
using fortnights = std::chrono::duration<date::weeks::rep,
|
||||
std::ratio_multiply<std::ratio<2>,
|
||||
date::weeks::period>>;
|
||||
|
||||
using microfortnights = std::chrono::duration<std::int64_t,
|
||||
std::ratio_multiply<fortnights::period,
|
||||
std::micro>>;
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
using namespace date::detail;
|
||||
using namespace std;
|
||||
using namespace std::chrono;
|
||||
|
||||
{
|
||||
using D = decimal_format_seconds<minutes>;
|
||||
static_assert(is_same<D::precision, seconds>{}, "");
|
||||
static_assert(D::width == 0, "");
|
||||
D dfs{minutes{3}};
|
||||
assert(dfs.seconds() == seconds{180});
|
||||
assert(dfs.to_duration() == seconds{180});
|
||||
ostringstream out;
|
||||
out << dfs;
|
||||
assert(out.str() == "180");
|
||||
}
|
||||
{
|
||||
using D = decimal_format_seconds<seconds>;
|
||||
static_assert(is_same<D::precision, seconds>{}, "");
|
||||
static_assert(D::width == 0, "");
|
||||
D dfs{seconds{3}};
|
||||
assert(dfs.seconds() == seconds{3});
|
||||
assert(dfs.to_duration() == seconds{3});
|
||||
ostringstream out;
|
||||
out << dfs;
|
||||
assert(out.str() == "03");
|
||||
}
|
||||
{
|
||||
using D = decimal_format_seconds<milliseconds>;
|
||||
static_assert(D::width == 3, "");
|
||||
static_assert(is_same<D::precision, make_precision<D::width>::type>{}, "");
|
||||
D dfs{seconds{3}};
|
||||
assert(dfs.seconds() == seconds{3});
|
||||
assert(dfs.to_duration() == seconds{3});
|
||||
assert(dfs.subseconds() == milliseconds{0});
|
||||
ostringstream out;
|
||||
out << dfs;
|
||||
assert(out.str() == "03.000");
|
||||
}
|
||||
{
|
||||
using D = decimal_format_seconds<milliseconds>;
|
||||
static_assert(D::width == 3, "");
|
||||
static_assert(is_same<D::precision, make_precision<D::width>::type>{}, "");
|
||||
D dfs{milliseconds{3}};
|
||||
assert(dfs.seconds() == seconds{0});
|
||||
assert(dfs.to_duration() == milliseconds{3});
|
||||
assert(dfs.subseconds() == milliseconds{3});
|
||||
ostringstream out;
|
||||
out << dfs;
|
||||
assert(out.str() == "00.003");
|
||||
}
|
||||
{
|
||||
using D = decimal_format_seconds<microfortnights>;
|
||||
static_assert(D::width == 4, "");
|
||||
using S = make_precision<D::width>::type;
|
||||
static_assert(is_same<D::precision, S>{}, "");
|
||||
D dfs{microfortnights{3}};
|
||||
assert(dfs.seconds() == seconds{3});
|
||||
assert(dfs.to_duration() == S{36288});
|
||||
assert(dfs.subseconds() == S{6288});
|
||||
ostringstream out;
|
||||
out << dfs;
|
||||
assert(out.str() == "03.6288");
|
||||
}
|
||||
{
|
||||
using CT = common_type<seconds, microfortnights>::type;
|
||||
using D = decimal_format_seconds<CT>;
|
||||
static_assert(D::width == 4, "");
|
||||
using S = make_precision<D::width>::type;
|
||||
static_assert(is_same<D::precision, S>{}, "");
|
||||
D dfs{microfortnights{3}};
|
||||
assert(dfs.seconds() == seconds{3});
|
||||
assert(dfs.to_duration() == S{36288});
|
||||
assert(dfs.subseconds() == S{6288});
|
||||
ostringstream out;
|
||||
out << dfs;
|
||||
assert(out.str() == "03.6288");
|
||||
}
|
||||
}
|
63
test/date_test/detail/make_precision.pass.cpp
Normal file
63
test/date_test/detail/make_precision.pass.cpp
Normal file
@ -0,0 +1,63 @@
|
||||
// The MIT License (MIT)
|
||||
//
|
||||
// Copyright (c) 2017 Howard Hinnant
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
// template <unsigned w>
|
||||
// struct make_precision
|
||||
// {
|
||||
// using type = std::chrono::duration<std::int64_t,
|
||||
// std::ratio<1, static_pow10<w>::value>>;
|
||||
// static constexpr unsigned width = w;
|
||||
// };
|
||||
|
||||
#include "date.h"
|
||||
|
||||
#include <cstdint>
|
||||
#include <type_traits>
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
using namespace date::detail;
|
||||
using namespace std;
|
||||
using namespace std::chrono;
|
||||
|
||||
static_assert(make_precision<0>::width == 0, "");
|
||||
static_assert(is_same<make_precision<0>::type, duration<int64_t, ratio<1, 1>>>{}, "");
|
||||
|
||||
static_assert(make_precision<1>::width == 1, "");
|
||||
static_assert(is_same<make_precision<1>::type, duration<int64_t, ratio<1, 10>>>{}, "");
|
||||
|
||||
static_assert(make_precision<2>::width == 2, "");
|
||||
static_assert(is_same<make_precision<2>::type, duration<int64_t, ratio<1, 100>>>{}, "");
|
||||
|
||||
static_assert(make_precision<3>::width == 3, "");
|
||||
static_assert(is_same<make_precision<3>::type, duration<int64_t, ratio<1, 1000>>>{}, "");
|
||||
|
||||
static_assert(make_precision<18>::width == 18, "");
|
||||
static_assert(is_same<make_precision<18>::type, duration<int64_t, ratio<1, 1000000000000000000>>>{}, "");
|
||||
|
||||
static_assert(make_precision<19>::width == 6, "");
|
||||
static_assert(is_same<make_precision<19>::type, microseconds>{}, "");
|
||||
|
||||
static_assert(make_precision<20>::width == 6, "");
|
||||
static_assert(is_same<make_precision<20>::type, microseconds>{}, "");
|
||||
}
|
50
test/date_test/detail/static_pow10.pass.cpp
Normal file
50
test/date_test/detail/static_pow10.pass.cpp
Normal file
@ -0,0 +1,50 @@
|
||||
// The MIT License (MIT)
|
||||
//
|
||||
// Copyright (c) 2017 Howard Hinnant
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
// template <unsigned exp>
|
||||
// struct static_pow10
|
||||
// {
|
||||
// static constepxr std::uint64_t value = ...;
|
||||
// };
|
||||
|
||||
#include "date.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <sstream>
|
||||
#include <type_traits>
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
using namespace date::detail;
|
||||
static_assert(static_pow10<0>::value == 1, "");
|
||||
static_assert(static_pow10<1>::value == 10, "");
|
||||
static_assert(static_pow10<2>::value == 100, "");
|
||||
static_assert(static_pow10<3>::value == 1000, "");
|
||||
static_assert(static_pow10<4>::value == 10000, "");
|
||||
static_assert(static_pow10<5>::value == 100000, "");
|
||||
static_assert(static_pow10<6>::value == 1000000, "");
|
||||
static_assert(static_pow10<7>::value == 10000000, "");
|
||||
static_assert(static_pow10<8>::value == 100000000, "");
|
||||
static_assert(static_pow10<9>::value == 1000000000, "");
|
||||
static_assert(static_pow10<10>::value == 10000000000, "");
|
||||
}
|
64
test/date_test/detail/width.pass.cpp
Normal file
64
test/date_test/detail/width.pass.cpp
Normal file
@ -0,0 +1,64 @@
|
||||
// The MIT License (MIT)
|
||||
//
|
||||
// Copyright (c) 2017 Howard Hinnant
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
// width<n>::value is the number of fractional decimal digits in 1/n
|
||||
// width<0>::value and width<1>::value are defined to be 0
|
||||
// If 1/n takes more than 18 fractional decimal digits,
|
||||
// the result is truncated to 19.
|
||||
// Example: width<2>::value == 1
|
||||
// Example: width<3>::value == 19
|
||||
// Example: width<4>::value == 2
|
||||
// Example: width<10>::value == 1
|
||||
// Example: width<1000>::value == 3
|
||||
// template <std::uint64_t n>
|
||||
//
|
||||
// struct width
|
||||
// {
|
||||
// static constexpr unsigned value = ...;
|
||||
// };
|
||||
|
||||
#include "date.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <sstream>
|
||||
#include <type_traits>
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
using namespace date::detail;
|
||||
static_assert(width<0>::value == 0, "");
|
||||
static_assert(width<1>::value == 0, "");
|
||||
static_assert(width<2>::value == 1, "");
|
||||
static_assert(width<3>::value == 19, "");
|
||||
static_assert(width<4>::value == 2, "");
|
||||
static_assert(width<5>::value == 1, "");
|
||||
static_assert(width<6>::value == 19, "");
|
||||
static_assert(width<7>::value == 19, "");
|
||||
static_assert(width<8>::value == 3, "");
|
||||
static_assert(width<9>::value == 19, "");
|
||||
static_assert(width<10>::value == 1, "");
|
||||
static_assert(width<100>::value == 2, "");
|
||||
static_assert(width<1000>::value == 3, "");
|
||||
static_assert(width<10000>::value == 4, "");
|
||||
static_assert(width<625>::value == 4, "");
|
||||
}
|
@ -34,7 +34,7 @@ test_a()
|
||||
// correct abbreviation
|
||||
std::istringstream in{"Sun 2016-12-11"};
|
||||
sys_days tp;
|
||||
parse(in, "%a %F", tp);
|
||||
in >> parse("%a %F", tp);
|
||||
assert(!in.fail());
|
||||
assert(!in.bad());
|
||||
assert(!in.eof());
|
||||
@ -44,7 +44,7 @@ test_a()
|
||||
// correct abbreviation
|
||||
std::istringstream in{"Sun 2016-12-11"};
|
||||
sys_days tp;
|
||||
parse(in, "%A %F", tp);
|
||||
in >> parse("%A %F", tp);
|
||||
assert(!in.fail());
|
||||
assert(!in.bad());
|
||||
assert(!in.eof());
|
||||
@ -54,7 +54,7 @@ test_a()
|
||||
// correct full name
|
||||
std::istringstream in{"Sunday 2016-12-11"};
|
||||
sys_days tp;
|
||||
parse(in, "%a %F", tp);
|
||||
in >> parse("%a %F", tp);
|
||||
assert(!in.fail());
|
||||
assert(!in.bad());
|
||||
assert(!in.eof());
|
||||
@ -64,7 +64,7 @@ test_a()
|
||||
// correct full name
|
||||
std::istringstream in{"Sunday 2016-12-11"};
|
||||
sys_days tp;
|
||||
parse(in, "%A %F", tp);
|
||||
in >> parse("%A %F", tp);
|
||||
assert(!in.fail());
|
||||
assert(!in.bad());
|
||||
assert(!in.eof());
|
||||
@ -74,7 +74,7 @@ test_a()
|
||||
// not a valid name
|
||||
std::istringstream in{"Dec 2016-12-11"};
|
||||
sys_days tp;
|
||||
parse(in, "%a %F", tp);
|
||||
in >> parse("%a %F", tp);
|
||||
assert( in.fail());
|
||||
assert(!in.bad());
|
||||
assert(!in.eof());
|
||||
@ -84,7 +84,7 @@ test_a()
|
||||
// wrong name
|
||||
std::istringstream in{"Sat 2016-12-11"};
|
||||
sys_days tp;
|
||||
parse(in, "%a %F", tp);
|
||||
in >> parse("%a %F", tp);
|
||||
assert( in.fail());
|
||||
assert(!in.bad());
|
||||
assert(!in.eof());
|
||||
@ -94,7 +94,7 @@ test_a()
|
||||
// extra ws in input
|
||||
std::istringstream in{"Sun 2016-12-11"};
|
||||
sys_days tp;
|
||||
parse(in, "%a %F", tp);
|
||||
in >> parse("%a %F", tp);
|
||||
assert(!in.fail());
|
||||
assert(!in.bad());
|
||||
assert(!in.eof());
|
||||
@ -104,7 +104,7 @@ test_a()
|
||||
// extra ws in format
|
||||
std::istringstream in{"Sun 2016-12-11"};
|
||||
sys_days tp;
|
||||
parse(in, "%a %F", tp);
|
||||
in >> parse("%a %F", tp);
|
||||
assert(!in.fail());
|
||||
assert(!in.bad());
|
||||
assert(!in.eof());
|
||||
@ -120,7 +120,7 @@ test_b()
|
||||
// correct abbreviation
|
||||
std::istringstream in{"Dec 11 2016"};
|
||||
sys_days tp;
|
||||
parse(in, "%b %d %Y", tp);
|
||||
in >> parse("%b %d %Y", tp);
|
||||
assert(!in.fail());
|
||||
assert(!in.bad());
|
||||
assert(!in.eof());
|
||||
@ -130,7 +130,7 @@ test_b()
|
||||
// correct abbreviation
|
||||
std::istringstream in{"Dec 11 2016"};
|
||||
sys_days tp;
|
||||
parse(in, "%B %d %Y", tp);
|
||||
in >> parse("%B %d %Y", tp);
|
||||
assert(!in.fail());
|
||||
assert(!in.bad());
|
||||
assert(!in.eof());
|
||||
@ -140,7 +140,7 @@ test_b()
|
||||
// correct abbreviation
|
||||
std::istringstream in{"Dec 11 2016"};
|
||||
sys_days tp;
|
||||
parse(in, "%h %d %Y", tp);
|
||||
in >> parse("%h %d %Y", tp);
|
||||
assert(!in.fail());
|
||||
assert(!in.bad());
|
||||
assert(!in.eof());
|
||||
@ -150,7 +150,7 @@ test_b()
|
||||
// correct full name
|
||||
std::istringstream in{"December 11 2016"};
|
||||
sys_days tp;
|
||||
parse(in, "%b %d %Y", tp);
|
||||
in >> parse("%b %d %Y", tp);
|
||||
assert(!in.fail());
|
||||
assert(!in.bad());
|
||||
assert(!in.eof());
|
||||
@ -160,7 +160,7 @@ test_b()
|
||||
// correct full name
|
||||
std::istringstream in{"December 11 2016"};
|
||||
sys_days tp;
|
||||
parse(in, "%B %d %Y", tp);
|
||||
in >> parse("%B %d %Y", tp);
|
||||
assert(!in.fail());
|
||||
assert(!in.bad());
|
||||
assert(!in.eof());
|
||||
@ -170,7 +170,7 @@ test_b()
|
||||
// correct full name
|
||||
std::istringstream in{"December 11 2016"};
|
||||
sys_days tp;
|
||||
parse(in, "%h %d %Y", tp);
|
||||
in >> parse("%h %d %Y", tp);
|
||||
assert(!in.fail());
|
||||
assert(!in.bad());
|
||||
assert(!in.eof());
|
||||
@ -180,7 +180,7 @@ test_b()
|
||||
// incorrect abbreviation
|
||||
std::istringstream in{"Dece 11 2016"};
|
||||
sys_days tp;
|
||||
parse(in, "%b %d %Y", tp);
|
||||
in >> parse("%b %d %Y", tp);
|
||||
assert( in.fail());
|
||||
assert(!in.bad());
|
||||
assert(!in.eof());
|
||||
@ -197,7 +197,7 @@ test_c()
|
||||
// correct abbreviation
|
||||
std::istringstream in{"Sun Dec 11 14:02:43 2016"};
|
||||
sys_seconds tp;
|
||||
parse(in, "%c", tp);
|
||||
in >> parse("%c", tp);
|
||||
assert(!in.fail());
|
||||
assert(!in.bad());
|
||||
assert(tp == sys_days{2016_y/12/11} + hours{14} + minutes{2} + seconds{43});
|
||||
@ -213,7 +213,7 @@ test_x()
|
||||
// correct abbreviation
|
||||
std::istringstream in{"12/11/16"};
|
||||
sys_seconds tp;
|
||||
parse(in, "%x", tp);
|
||||
in >> parse("%x", tp);
|
||||
assert(!in.fail());
|
||||
assert(!in.bad());
|
||||
assert(tp == sys_days{2016_y/12/11});
|
||||
@ -229,7 +229,7 @@ test_X()
|
||||
// correct abbreviation
|
||||
std::istringstream in{"2016-12-11 14:02:43"};
|
||||
sys_seconds tp;
|
||||
parse(in, "%F %X", tp);
|
||||
in >> parse("%F %X", tp);
|
||||
assert(!in.fail());
|
||||
assert(!in.bad());
|
||||
assert(tp == sys_days{2016_y/12/11} + hours{14} + minutes{2} + seconds{43});
|
||||
@ -244,7 +244,7 @@ test_C()
|
||||
{
|
||||
std::istringstream in{"20 16 12 11"};
|
||||
sys_days tp;
|
||||
parse(in, "%C %y %m %d", tp);
|
||||
in >> parse("%C %y %m %d", tp);
|
||||
assert(!in.fail());
|
||||
assert(!in.bad());
|
||||
assert(tp == 2016_y/12/11);
|
||||
@ -252,7 +252,7 @@ test_C()
|
||||
{
|
||||
std::istringstream in{"-2 1 12 11"};
|
||||
sys_days tp;
|
||||
parse(in, "%C %y %m %d", tp);
|
||||
in >> parse("%C %y %m %d", tp);
|
||||
assert(!in.fail());
|
||||
assert(!in.bad());
|
||||
assert(tp == -101_y/12/11);
|
||||
@ -260,7 +260,7 @@ test_C()
|
||||
{
|
||||
std::istringstream in{"-1 0 12 11"};
|
||||
sys_days tp;
|
||||
parse(in, "%C %y %m %d", tp);
|
||||
in >> parse("%C %y %m %d", tp);
|
||||
assert(!in.fail());
|
||||
assert(!in.bad());
|
||||
assert(tp == -100_y/12/11);
|
||||
@ -268,7 +268,7 @@ test_C()
|
||||
{
|
||||
std::istringstream in{"-1 99 12 11"};
|
||||
sys_days tp;
|
||||
parse(in, "%C %y %m %d", tp);
|
||||
in >> parse("%C %y %m %d", tp);
|
||||
assert(!in.fail());
|
||||
assert(!in.bad());
|
||||
assert(tp == -99_y/12/11);
|
||||
@ -276,7 +276,7 @@ test_C()
|
||||
{
|
||||
std::istringstream in{"-1 1 12 11"};
|
||||
sys_days tp;
|
||||
parse(in, "%C %y %m %d", tp);
|
||||
in >> parse("%C %y %m %d", tp);
|
||||
assert(!in.fail());
|
||||
assert(!in.bad());
|
||||
assert(tp == -1_y/12/11);
|
||||
@ -284,7 +284,7 @@ test_C()
|
||||
{
|
||||
std::istringstream in{"0 0 12 11"};
|
||||
sys_days tp;
|
||||
parse(in, "%C %y %m %d", tp);
|
||||
in >> parse("%C %y %m %d", tp);
|
||||
assert(!in.fail());
|
||||
assert(!in.bad());
|
||||
assert(tp == 0_y/12/11);
|
||||
@ -292,7 +292,7 @@ test_C()
|
||||
{
|
||||
std::istringstream in{"0 1 12 11"};
|
||||
sys_days tp;
|
||||
parse(in, "%C %y %m %d", tp);
|
||||
in >> parse("%C %y %m %d", tp);
|
||||
assert(!in.fail());
|
||||
assert(!in.bad());
|
||||
assert(tp == 1_y/12/11);
|
||||
@ -300,7 +300,7 @@ test_C()
|
||||
{
|
||||
std::istringstream in{"0 99 12 11"};
|
||||
sys_days tp;
|
||||
parse(in, "%C %y %m %d", tp);
|
||||
in >> parse("%C %y %m %d", tp);
|
||||
assert(!in.fail());
|
||||
assert(!in.bad());
|
||||
assert(tp == 99_y/12/11);
|
||||
@ -308,7 +308,7 @@ test_C()
|
||||
{
|
||||
std::istringstream in{"1 0 12 11"};
|
||||
sys_days tp;
|
||||
parse(in, "%C %y %m %d", tp);
|
||||
in >> parse("%C %y %m %d", tp);
|
||||
assert(!in.fail());
|
||||
assert(!in.bad());
|
||||
assert(tp == 100_y/12/11);
|
||||
@ -316,7 +316,7 @@ test_C()
|
||||
{
|
||||
std::istringstream in{"1 1 12 11"};
|
||||
sys_days tp;
|
||||
parse(in, "%C %y %m %d", tp);
|
||||
in >> parse("%C %y %m %d", tp);
|
||||
assert(!in.fail());
|
||||
assert(!in.bad());
|
||||
assert(tp == 101_y/12/11);
|
||||
@ -331,7 +331,7 @@ test_d()
|
||||
{
|
||||
std::istringstream in{"2016 09 12"};
|
||||
sys_days tp;
|
||||
parse(in, "%Y %d %m", tp);
|
||||
in >> parse("%Y %d %m", tp);
|
||||
assert(!in.fail());
|
||||
assert(!in.bad());
|
||||
assert(tp == 2016_y/12/9);
|
||||
@ -339,7 +339,7 @@ test_d()
|
||||
{
|
||||
std::istringstream in{"2016 09 12"};
|
||||
sys_days tp;
|
||||
parse(in, "%Y %e %m", tp);
|
||||
in >> parse("%Y %e %m", tp);
|
||||
assert(!in.fail());
|
||||
assert(!in.bad());
|
||||
assert(tp == 2016_y/12/9);
|
||||
@ -347,7 +347,7 @@ test_d()
|
||||
{
|
||||
std::istringstream in{"2016 9 12"};
|
||||
sys_days tp;
|
||||
parse(in, "%Y %d %m", tp);
|
||||
in >> parse("%Y %d %m", tp);
|
||||
assert(!in.fail());
|
||||
assert(!in.bad());
|
||||
assert(tp == 2016_y/12/9);
|
||||
@ -355,7 +355,7 @@ test_d()
|
||||
{
|
||||
std::istringstream in{"2016 9 12"};
|
||||
sys_days tp;
|
||||
parse(in, "%Y %e %m", tp);
|
||||
in >> parse("%Y %e %m", tp);
|
||||
assert(!in.fail());
|
||||
assert(!in.bad());
|
||||
assert(tp == 2016_y/12/9);
|
||||
@ -370,7 +370,7 @@ test_D()
|
||||
{
|
||||
std::istringstream in{"12/11/16"};
|
||||
sys_days tp;
|
||||
parse(in, "%D", tp);
|
||||
in >> parse("%D", tp);
|
||||
assert(!in.fail());
|
||||
assert(!in.bad());
|
||||
assert(tp == 2016_y/12/11);
|
||||
@ -385,7 +385,7 @@ test_F()
|
||||
{
|
||||
std::istringstream in{"2016-12-13"};
|
||||
sys_days tp;
|
||||
parse(in, "%F", tp);
|
||||
in >> parse("%F", tp);
|
||||
assert(!in.fail());
|
||||
assert(!in.bad());
|
||||
assert(tp == 2016_y/12/13);
|
||||
@ -400,7 +400,7 @@ test_H()
|
||||
{
|
||||
std::istringstream in{"2016-12-11 15"};
|
||||
sys_time<hours> tp;
|
||||
parse(in, "%F %H", tp);
|
||||
in >> parse("%F %H", tp);
|
||||
assert(!in.fail());
|
||||
assert(!in.bad());
|
||||
assert(tp == sys_days{2016_y/12/11} + hours{15});
|
||||
@ -415,7 +415,7 @@ test_Ip()
|
||||
{
|
||||
std::istringstream in{"2016-12-11 1 pm"};
|
||||
sys_time<hours> tp;
|
||||
parse(in, "%F %I %p", tp);
|
||||
in >> parse("%F %I %p", tp);
|
||||
assert(!in.fail());
|
||||
assert(!in.bad());
|
||||
assert(tp == sys_days{2016_y/12/11} + hours{13});
|
||||
@ -423,7 +423,7 @@ test_Ip()
|
||||
{
|
||||
std::istringstream in{"2016-12-11 1 am"};
|
||||
sys_time<hours> tp;
|
||||
parse(in, "%F %I %p", tp);
|
||||
in >> parse("%F %I %p", tp);
|
||||
assert(!in.fail());
|
||||
assert(!in.bad());
|
||||
assert(tp == sys_days{2016_y/12/11} + hours{1});
|
||||
@ -438,7 +438,7 @@ test_j()
|
||||
{
|
||||
std::istringstream in{"2016 361"};
|
||||
sys_days tp;
|
||||
parse(in, "%Y %j", tp);
|
||||
in >> parse("%Y %j", tp);
|
||||
assert(!in.fail());
|
||||
assert(!in.bad());
|
||||
assert(tp == sys_days{2016_y/12/26});
|
||||
@ -453,7 +453,7 @@ test_m()
|
||||
{
|
||||
std::istringstream in{"2016 12 09"};
|
||||
sys_days tp;
|
||||
parse(in, "%Y %d %m", tp);
|
||||
in >> parse("%Y %d %m", tp);
|
||||
assert(!in.fail());
|
||||
assert(!in.bad());
|
||||
assert(tp == 2016_y/9/12);
|
||||
@ -461,7 +461,7 @@ test_m()
|
||||
{
|
||||
std::istringstream in{"2016 12 9"};
|
||||
sys_days tp;
|
||||
parse(in, "%Y %d %m", tp);
|
||||
in >> parse("%Y %d %m", tp);
|
||||
assert(!in.fail());
|
||||
assert(!in.bad());
|
||||
assert(tp == 2016_y/9/12);
|
||||
@ -476,7 +476,7 @@ test_M()
|
||||
{
|
||||
std::istringstream in{"2016-12-11 15"};
|
||||
sys_time<minutes> tp;
|
||||
parse(in, "%F %M", tp);
|
||||
in >> parse("%F %M", tp);
|
||||
assert(!in.fail());
|
||||
assert(!in.bad());
|
||||
assert(tp == sys_days{2016_y/12/11} + minutes{15});
|
||||
@ -491,7 +491,7 @@ test_S()
|
||||
{
|
||||
std::istringstream in{"2016-12-11 15"};
|
||||
sys_seconds tp;
|
||||
parse(in, "%F %S", tp);
|
||||
in >> parse("%F %S", tp);
|
||||
assert(!in.fail());
|
||||
assert(!in.bad());
|
||||
assert(tp == sys_days{2016_y/12/11} + seconds{15});
|
||||
@ -499,7 +499,7 @@ test_S()
|
||||
{
|
||||
std::istringstream in{"2016-12-11 15.001"};
|
||||
sys_time<milliseconds> tp;
|
||||
parse(in, "%F %S", tp);
|
||||
in >> parse("%F %S", tp);
|
||||
assert(!in.fail());
|
||||
assert(!in.bad());
|
||||
assert(tp == sys_days{2016_y/12/11} + seconds{15} + milliseconds{1});
|
||||
@ -514,7 +514,7 @@ test_T()
|
||||
{
|
||||
std::istringstream in{"2016-12-11 15:43:22"};
|
||||
sys_seconds tp;
|
||||
parse(in, "%F %T", tp);
|
||||
in >> parse("%F %T", tp);
|
||||
assert(!in.fail());
|
||||
assert(!in.bad());
|
||||
assert(tp == sys_days{2016_y/12/11} + hours{15} + minutes{43} + seconds{22});
|
||||
@ -522,7 +522,7 @@ test_T()
|
||||
{
|
||||
std::istringstream in{"2016-12-11 15:43:22.001"};
|
||||
sys_time<milliseconds> tp;
|
||||
parse(in, "%F %T", tp);
|
||||
in >> parse("%F %T", tp);
|
||||
assert(!in.fail());
|
||||
assert(!in.bad());
|
||||
assert(tp == sys_days{2016_y/12/11} + hours{15} + minutes{43} + seconds{22} +
|
||||
@ -531,11 +531,19 @@ test_T()
|
||||
{
|
||||
std::istringstream in{"2016-12-11 15:43:22"};
|
||||
sys_time<milliseconds> tp;
|
||||
parse(in, "%F %T", tp);
|
||||
in >> parse("%F %T", tp);
|
||||
assert(!in.fail());
|
||||
assert(!in.bad());
|
||||
assert(tp == sys_days{2016_y/12/11} + hours{15} + minutes{43} + seconds{22});
|
||||
}
|
||||
{
|
||||
std::istringstream in{"15:43:22.001"};
|
||||
milliseconds d;
|
||||
in >> parse("%T", d);
|
||||
assert(!in.fail());
|
||||
assert(!in.bad());
|
||||
assert(d == hours{15} + minutes{43} + seconds{22} + milliseconds{1});
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@ -546,7 +554,7 @@ test_p()
|
||||
{
|
||||
std::istringstream in{"2016-12-11 11pm"};
|
||||
sys_time<hours> tp;
|
||||
parse(in, "%F %I%p", tp);
|
||||
in >> parse("%F %I%p", tp);
|
||||
assert(!in.fail());
|
||||
assert(!in.bad());
|
||||
assert(tp == sys_days{2016_y/12/11} + hours{23});
|
||||
@ -561,7 +569,7 @@ test_r()
|
||||
{
|
||||
std::istringstream in{"2016-12-26 1:36:57 pm"};
|
||||
sys_seconds tp;
|
||||
parse(in, "%F %r", tp);
|
||||
in >> parse("%F %r", tp);
|
||||
assert(!in.fail());
|
||||
assert(!in.bad());
|
||||
assert(tp == sys_days{2016_y/12/26} + hours{13} + minutes{36} + seconds{57});
|
||||
@ -576,7 +584,7 @@ test_R()
|
||||
{
|
||||
std::istringstream in{"2016-12-26 13:36"};
|
||||
sys_seconds tp;
|
||||
parse(in, "%F %R", tp);
|
||||
in >> parse("%F %R", tp);
|
||||
assert(!in.fail());
|
||||
assert(!in.bad());
|
||||
assert(tp == sys_days{2016_y/12/26} + hours{13} + minutes{36});
|
||||
@ -591,7 +599,7 @@ test_U()
|
||||
{
|
||||
std::istringstream in{"2016-52-1"};
|
||||
sys_days tp;
|
||||
parse(in, "%Y-%U-%w", tp);
|
||||
in >> parse("%Y-%U-%w", tp);
|
||||
assert(!in.fail());
|
||||
assert(!in.bad());
|
||||
assert(tp == sys_days{2016_y/12/26});
|
||||
@ -606,7 +614,7 @@ test_W()
|
||||
{
|
||||
std::istringstream in{"2016-52-1"};
|
||||
sys_days tp;
|
||||
parse(in, "%Y-%W-%w", tp);
|
||||
in >> parse("%Y-%W-%w", tp);
|
||||
assert(!in.fail());
|
||||
assert(!in.bad());
|
||||
assert(tp == sys_days{2016_y/12/26});
|
||||
@ -621,7 +629,7 @@ test_GV()
|
||||
{
|
||||
std::istringstream in{"2016-52-1"};
|
||||
sys_days tp;
|
||||
parse(in, "%G-%V-%w", tp);
|
||||
in >> parse("%G-%V-%w", tp);
|
||||
assert(!in.fail());
|
||||
assert(!in.bad());
|
||||
assert(tp == sys_days{2016_y/12/26});
|
||||
@ -629,7 +637,7 @@ test_GV()
|
||||
{
|
||||
std::istringstream in{"2016-52-1"};
|
||||
sys_days tp;
|
||||
parse(in, "%G-%V-%w", tp);
|
||||
in >> parse("%G-%V-%w", tp);
|
||||
assert(!in.fail());
|
||||
assert(!in.bad());
|
||||
assert(tp == sys_days{2016_y/12/26});
|
||||
@ -637,7 +645,7 @@ test_GV()
|
||||
{
|
||||
std::istringstream in{"20 16-52-1"};
|
||||
sys_days tp;
|
||||
parse(in, "%C %g-%V-%w", tp);
|
||||
in >> parse("%C %g-%V-%w", tp);
|
||||
assert(!in.fail());
|
||||
assert(!in.bad());
|
||||
assert(tp == sys_days{2016_y/12/26});
|
||||
@ -645,7 +653,7 @@ test_GV()
|
||||
{
|
||||
std::istringstream in{"20 16-52-1"};
|
||||
sys_days tp;
|
||||
parse(in, "%C %g-%V-%u", tp);
|
||||
in >> parse("%C %g-%V-%u", tp);
|
||||
assert(!in.fail());
|
||||
assert(!in.bad());
|
||||
assert(tp == sys_days{2016_y/12/26});
|
||||
@ -660,7 +668,7 @@ test_z()
|
||||
{
|
||||
std::istringstream in{"2016-12-26 15:53:22 -0500"};
|
||||
sys_seconds tp;
|
||||
parse(in, "%F %T %z", tp);
|
||||
in >> parse("%F %T %z", tp);
|
||||
assert(!in.fail());
|
||||
assert(!in.bad());
|
||||
assert(tp == sys_days{2016_y/12/26} + hours{20} + minutes{53} + seconds{22});
|
||||
@ -668,7 +676,7 @@ test_z()
|
||||
{
|
||||
std::istringstream in{"2016-12-26 15:53:22 -0500"};
|
||||
local_seconds tp;
|
||||
parse(in, "%F %T %z", tp);
|
||||
in >> parse("%F %T %z", tp);
|
||||
assert(!in.fail());
|
||||
assert(!in.bad());
|
||||
assert(tp == local_days{2016_y/12/26} + hours{15} + minutes{53} + seconds{22});
|
||||
@ -676,7 +684,7 @@ test_z()
|
||||
{
|
||||
std::istringstream in{"2016-12-26 15:53:22 -05:00"};
|
||||
sys_seconds tp;
|
||||
parse(in, "%F %T %Ez", tp);
|
||||
in >> parse("%F %T %Ez", tp);
|
||||
assert(!in.fail());
|
||||
assert(!in.bad());
|
||||
assert(tp == sys_days{2016_y/12/26} + hours{20} + minutes{53} + seconds{22});
|
||||
@ -692,7 +700,7 @@ test_Z()
|
||||
std::string a;
|
||||
std::istringstream in{"2016-12-26 15:53:22 word"};
|
||||
local_seconds tp;
|
||||
parse(in, "%F %T %Z", tp, a);
|
||||
in >> parse("%F %T %Z", tp, a);
|
||||
assert(!in.fail());
|
||||
assert(!in.bad());
|
||||
assert(tp == local_days{2016_y/12/26} + hours{15} + minutes{53} + seconds{22});
|
||||
|
@ -60,7 +60,7 @@ main()
|
||||
static_assert(is_same<tod::precision, hours>{}, "");
|
||||
|
||||
static_assert( is_trivially_destructible<tod>{}, "");
|
||||
static_assert(!is_default_constructible<tod>{}, "");
|
||||
static_assert( is_default_constructible<tod>{}, "");
|
||||
static_assert( is_trivially_copy_constructible<tod>{}, "");
|
||||
static_assert( is_trivially_copy_assignable<tod>{}, "");
|
||||
static_assert( is_trivially_move_constructible<tod>{}, "");
|
||||
|
119
test/date_test/time_of_day_microfortnights.pass.cpp
Normal file
119
test/date_test/time_of_day_microfortnights.pass.cpp
Normal file
@ -0,0 +1,119 @@
|
||||
// The MIT License (MIT)
|
||||
//
|
||||
// Copyright (c) 2015, 2016 Howard Hinnant
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
// enum {am = 1, pm};
|
||||
|
||||
// template <class Rep, class Period>
|
||||
// class time_of_day<std::chrono::duration<Rep, Period>>
|
||||
// {
|
||||
// public:
|
||||
// using precision = std::chrono::std::chrono::duration<Rep, Period>;
|
||||
//
|
||||
// constexpr explicit time_of_day(precision since_midnight) noexcept;
|
||||
// constexpr time_of_day(std::chrono::hours h, std::chrono::minutes m,
|
||||
// std::chrono::seconds s, precision sub_s,
|
||||
// unsigned md) noexcept;
|
||||
//
|
||||
// constexpr std::chrono::hours hours() const noexcept;
|
||||
// constexpr std::chrono::minutes minutes() const noexcept;
|
||||
// constexpr std::chrono::seconds seconds() const noexcept;
|
||||
// constexpr precision subseconds() const noexcept;
|
||||
// constexpr unsigned mode() const noexcept;
|
||||
//
|
||||
// constexpr explicit operator precision() const noexcept;
|
||||
// constexpr precision to_duration() const noexcept;
|
||||
//
|
||||
// void make24() noexcept;
|
||||
// void make12() noexcept;
|
||||
// };
|
||||
|
||||
// template <class Rep, class Period>
|
||||
// std::ostream&
|
||||
// operator<<(std::ostream& os, const time_of_day<std::chrono::duration<Rep, Period>>& t);
|
||||
|
||||
#include "date.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <sstream>
|
||||
#include <type_traits>
|
||||
|
||||
using fortnights = std::chrono::duration<date::weeks::rep,
|
||||
std::ratio_multiply<std::ratio<2>,
|
||||
date::weeks::period>>;
|
||||
|
||||
using microfortnights = std::chrono::duration<std::int64_t,
|
||||
std::ratio_multiply<fortnights::period,
|
||||
std::micro>>;
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
using namespace date;
|
||||
using namespace std;
|
||||
using namespace std::chrono;
|
||||
|
||||
using tod = time_of_day<typename common_type<hours, minutes, microfortnights>::type>;
|
||||
|
||||
static_assert(is_same<tod::precision::period, ratio<1, 10000>>{}, "");
|
||||
|
||||
static_assert( is_trivially_destructible<tod>{}, "");
|
||||
static_assert( is_default_constructible<tod>{}, "");
|
||||
static_assert( is_trivially_copy_constructible<tod>{}, "");
|
||||
static_assert( is_trivially_copy_assignable<tod>{}, "");
|
||||
static_assert( is_trivially_move_constructible<tod>{}, "");
|
||||
static_assert( is_trivially_move_assignable<tod>{}, "");
|
||||
|
||||
static_assert(is_constructible<tod, microfortnights>{}, "");
|
||||
static_assert(!is_convertible<microfortnights, tod>{}, "");
|
||||
|
||||
static_assert(is_nothrow_constructible<tod::precision, tod>{}, "");
|
||||
static_assert(!is_convertible<tod, tod::precision>{}, "");
|
||||
|
||||
constexpr tod t1 = tod{hours{13} + minutes{7} + microfortnights{5}};
|
||||
static_assert(t1.hours() == hours{13}, "");
|
||||
static_assert(t1.minutes() == minutes{7}, "");
|
||||
static_assert(t1.seconds() == seconds{6}, "");
|
||||
static_assert(t1.subseconds() == tod::precision{480}, "");
|
||||
#if __cplusplus >= 201402
|
||||
static_assert(static_cast<tod::precision>(t1) == hours{13} + minutes{7}
|
||||
+ microfortnights{5}, "");
|
||||
static_assert(t1.to_duration() == hours{13} + minutes{7} + microfortnights{5}, "");
|
||||
#endif
|
||||
|
||||
auto t2 = t1;
|
||||
assert(t2.hours() == t1.hours());
|
||||
assert(t2.minutes() == t1.minutes());
|
||||
assert(t2.seconds() == t1.seconds());
|
||||
assert(t2.subseconds() == t1.subseconds());
|
||||
assert(t2.to_duration() == t1.to_duration());
|
||||
ostringstream os;
|
||||
os << t2;
|
||||
assert(os.str() == "13:07:06.0480");
|
||||
t2.make12();
|
||||
os.str("");
|
||||
os << t2;
|
||||
assert(os.str() == "1:07:06.0480pm");
|
||||
t2.make24();
|
||||
os.str("");
|
||||
os << t2;
|
||||
assert(os.str() == "13:07:06.0480");
|
||||
}
|
@ -68,7 +68,7 @@ main()
|
||||
static_assert(is_same<tod::precision, milliseconds>{}, "");
|
||||
|
||||
static_assert( is_trivially_destructible<tod>{}, "");
|
||||
static_assert(!is_default_constructible<tod>{}, "");
|
||||
static_assert( is_default_constructible<tod>{}, "");
|
||||
static_assert( is_trivially_copy_constructible<tod>{}, "");
|
||||
static_assert( is_trivially_copy_assignable<tod>{}, "");
|
||||
static_assert( is_trivially_move_constructible<tod>{}, "");
|
||||
|
@ -62,7 +62,7 @@ main()
|
||||
static_assert(is_same<tod::precision, minutes>{}, "");
|
||||
|
||||
static_assert( is_trivially_destructible<tod>{}, "");
|
||||
static_assert(!is_default_constructible<tod>{}, "");
|
||||
static_assert( is_default_constructible<tod>{}, "");
|
||||
static_assert( is_trivially_copy_constructible<tod>{}, "");
|
||||
static_assert( is_trivially_copy_assignable<tod>{}, "");
|
||||
static_assert( is_trivially_move_constructible<tod>{}, "");
|
||||
|
@ -68,7 +68,7 @@ main()
|
||||
static_assert(is_same<tod::precision, nanoseconds>{}, "");
|
||||
|
||||
static_assert( is_trivially_destructible<tod>{}, "");
|
||||
static_assert(!is_default_constructible<tod>{}, "");
|
||||
static_assert( is_default_constructible<tod>{}, "");
|
||||
static_assert( is_trivially_copy_constructible<tod>{}, "");
|
||||
static_assert( is_trivially_copy_assignable<tod>{}, "");
|
||||
static_assert( is_trivially_move_constructible<tod>{}, "");
|
||||
|
@ -63,7 +63,7 @@ main()
|
||||
static_assert(is_same<tod::precision, seconds>{}, "");
|
||||
|
||||
static_assert( is_trivially_destructible<tod>{}, "");
|
||||
static_assert(!is_default_constructible<tod>{}, "");
|
||||
static_assert( is_default_constructible<tod>{}, "");
|
||||
static_assert( is_trivially_copy_constructible<tod>{}, "");
|
||||
static_assert( is_trivially_copy_assignable<tod>{}, "");
|
||||
static_assert( is_trivially_move_constructible<tod>{}, "");
|
||||
|
217
tz.h
217
tz.h
@ -1108,13 +1108,20 @@ utc_clock::now()
|
||||
}
|
||||
|
||||
template <class CharT, class Traits, class Duration>
|
||||
std::basic_ostream<CharT, Traits>&
|
||||
operator<<(std::basic_ostream<CharT, Traits>& os, const utc_time<Duration>& t)
|
||||
void
|
||||
to_stream(std::basic_ostream<CharT, Traits>& os, const CharT* fmt,
|
||||
const utc_time<Duration>& t)
|
||||
{
|
||||
using namespace std;
|
||||
using namespace std::chrono;
|
||||
using duration = typename std::common_type<Duration, seconds>::type;
|
||||
using CT = typename common_type<Duration, seconds>::type;
|
||||
const string abbrev("UTC");
|
||||
CONSTDATA seconds offset{0};
|
||||
auto const& leaps = get_tzdb().leaps;
|
||||
auto tp = sys_time<duration>{t.time_since_epoch()};
|
||||
auto tp = sys_time<CT>{t.time_since_epoch()};
|
||||
year_month_day ymd;
|
||||
time_of_day<CT> time;
|
||||
seconds ls{0};
|
||||
if (tp >= leaps.front())
|
||||
{
|
||||
auto const lt = std::upper_bound(leaps.begin(), leaps.end(), tp);
|
||||
@ -1122,17 +1129,205 @@ operator<<(std::basic_ostream<CharT, Traits>& os, const utc_time<Duration>& t)
|
||||
if (tp < lt[-1])
|
||||
{
|
||||
if (tp >= lt[-1].date() - seconds{1})
|
||||
{
|
||||
auto const dp = floor<days>(tp);
|
||||
auto time = make_time(tp-dp);
|
||||
time.seconds() += seconds{1};
|
||||
return os << year_month_day(dp) << ' ' << time;
|
||||
}
|
||||
ls = seconds{1};
|
||||
else
|
||||
tp += seconds{1};
|
||||
}
|
||||
}
|
||||
return os << tp;
|
||||
auto const sd = floor<days>(tp);
|
||||
ymd = sd;
|
||||
time = make_time(tp - sd);
|
||||
time.seconds() += ls;
|
||||
detail::fields<CT> fds{ymd, time};
|
||||
detail::to_stream(os, fmt, fds, &abbrev, &offset);
|
||||
}
|
||||
|
||||
template <class CharT, class Traits, class Duration>
|
||||
std::basic_ostream<CharT, Traits>&
|
||||
operator<<(std::basic_ostream<CharT, Traits>& os, const utc_time<Duration>& t)
|
||||
{
|
||||
to_stream(os, "%F %T", t);
|
||||
return os;
|
||||
}
|
||||
|
||||
template <class CharT, class Duration>
|
||||
std::basic_string<CharT>
|
||||
format(const std::locale& loc, const CharT* fmt, const utc_time<Duration>& tp)
|
||||
{
|
||||
std::basic_ostringstream<CharT> os;
|
||||
os.imbue(loc);
|
||||
to_stream(os, fmt, tp);
|
||||
return os.str();
|
||||
}
|
||||
|
||||
template <class CharT, class Duration>
|
||||
std::basic_string<CharT>
|
||||
format(const CharT* fmt, const utc_time<Duration>& tp)
|
||||
{
|
||||
std::basic_ostringstream<CharT> os;
|
||||
to_stream(os, fmt, tp);
|
||||
return os.str();
|
||||
}
|
||||
|
||||
template <class CharT, class Traits, class Duration>
|
||||
std::basic_string<CharT, Traits>
|
||||
format(const std::locale& loc, const std::basic_string<CharT, Traits>& fmt,
|
||||
const utc_time<Duration>& tp)
|
||||
{
|
||||
std::basic_ostringstream<CharT, Traits> os;
|
||||
os.imbue(loc);
|
||||
to_stream(os, fmt.c_str(), tp);
|
||||
return os.str();
|
||||
}
|
||||
|
||||
template <class CharT, class Traits, class Duration>
|
||||
std::basic_string<CharT, Traits>
|
||||
format(const std::basic_string<CharT, Traits>& fmt, const utc_time<Duration>& tp)
|
||||
{
|
||||
std::basic_ostringstream<CharT, Traits> os;
|
||||
to_stream(os, fmt.c_str(), tp);
|
||||
return os.str();
|
||||
}
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template <class Duration, class CharT, class Traits = std::char_traits<CharT>>
|
||||
struct parse_utc_manip
|
||||
{
|
||||
const std::basic_string<CharT, Traits> format_;
|
||||
utc_time<Duration>& tp_;
|
||||
std::basic_string<CharT, Traits>* abbrev_;
|
||||
std::chrono::minutes* offset_;
|
||||
|
||||
public:
|
||||
parse_utc_manip(std::basic_string<CharT, Traits> format,
|
||||
utc_time<Duration>& tp, std::basic_string<CharT, Traits>* abbrev = nullptr,
|
||||
std::chrono::minutes* offset = nullptr)
|
||||
: format_(std::move(format))
|
||||
, tp_(tp)
|
||||
, abbrev_(abbrev)
|
||||
, offset_(offset)
|
||||
{}
|
||||
|
||||
};
|
||||
|
||||
template <class Duration, class CharT, class Traits>
|
||||
std::basic_istream<CharT, Traits>&
|
||||
operator>>(std::basic_istream<CharT, Traits>& is,
|
||||
const parse_utc_manip<Duration, CharT, Traits>& x)
|
||||
{
|
||||
using namespace std;
|
||||
using namespace std::chrono;
|
||||
using CT = typename common_type<Duration, seconds>::type;
|
||||
minutes offset{};
|
||||
auto offptr = x.offset_ ? x.offset_ : &offset;
|
||||
fields<CT> fds{};
|
||||
parse(is, x.format_.c_str(), fds, x.abbrev_, offptr);
|
||||
if (!fds.ymd.ok())
|
||||
is.setstate(ios::failbit);
|
||||
if (!is.fail())
|
||||
{
|
||||
bool is_leap_second = fds.tod.seconds() == seconds{60};
|
||||
if (is_leap_second)
|
||||
fds.tod.seconds() -= seconds{1};
|
||||
x.tp_ = to_utc_time(sys_days(fds.ymd) +
|
||||
duration_cast<Duration>(fds.tod.to_duration() - *offptr));
|
||||
if (is_leap_second)
|
||||
x.tp_ += seconds{1};
|
||||
}
|
||||
return is;
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <class Duration, class CharT, class Traits>
|
||||
inline
|
||||
detail::parse_utc_manip<Duration, CharT, Traits>
|
||||
parse(const std::basic_string<CharT, Traits>& format, utc_time<Duration>& tp)
|
||||
{
|
||||
return {format, tp};
|
||||
}
|
||||
|
||||
template <class Duration, class CharT, class Traits>
|
||||
inline
|
||||
detail::parse_utc_manip<Duration, CharT, Traits>
|
||||
parse(const std::basic_string<CharT, Traits>& format, utc_time<Duration>& tp,
|
||||
std::basic_string<CharT, Traits>& abbrev)
|
||||
{
|
||||
return {format, tp, &abbrev};
|
||||
}
|
||||
|
||||
template <class Duration, class CharT, class Traits>
|
||||
inline
|
||||
detail::parse_utc_manip<Duration, CharT, Traits>
|
||||
parse(const std::basic_string<CharT, Traits>& format, utc_time<Duration>& tp,
|
||||
std::chrono::minutes& offset)
|
||||
{
|
||||
return {format, tp, nullptr, &offset};
|
||||
}
|
||||
|
||||
template <class Duration, class CharT, class Traits>
|
||||
inline
|
||||
detail::parse_utc_manip<Duration, CharT, Traits>
|
||||
parse(const std::basic_string<CharT, Traits>& format, utc_time<Duration>& tp,
|
||||
std::basic_string<CharT, Traits>& abbrev, std::chrono::minutes& offset)
|
||||
{
|
||||
return {format, tp, &abbrev, &offset};
|
||||
}
|
||||
|
||||
template <class Duration, class CharT, class Traits>
|
||||
inline
|
||||
detail::parse_utc_manip<Duration, CharT, Traits>
|
||||
parse(const std::basic_string<CharT, Traits>& format, utc_time<Duration>& tp,
|
||||
std::chrono::minutes& offset, std::basic_string<CharT, Traits>& abbrev)
|
||||
{
|
||||
return {format, tp, &abbrev, &offset};
|
||||
}
|
||||
|
||||
// const CharT* formats
|
||||
|
||||
template <class Duration, class CharT>
|
||||
inline
|
||||
detail::parse_utc_manip<Duration, CharT>
|
||||
parse(const CharT* format, utc_time<Duration>& tp)
|
||||
{
|
||||
return {format, tp};
|
||||
}
|
||||
|
||||
template <class Duration, class CharT, class Traits>
|
||||
inline
|
||||
detail::parse_utc_manip<Duration, CharT, Traits>
|
||||
parse(const CharT* format, utc_time<Duration>& tp,
|
||||
std::basic_string<CharT, Traits>& abbrev)
|
||||
{
|
||||
return {format, tp, &abbrev};
|
||||
}
|
||||
|
||||
template <class Duration, class CharT>
|
||||
inline
|
||||
detail::parse_utc_manip<Duration, CharT>
|
||||
parse(const CharT* format, utc_time<Duration>& tp, std::chrono::minutes& offset)
|
||||
{
|
||||
return {format, tp, nullptr, &offset};
|
||||
}
|
||||
|
||||
template <class Duration, class CharT, class Traits>
|
||||
inline
|
||||
detail::parse_utc_manip<Duration, CharT, Traits>
|
||||
parse(const CharT* format, utc_time<Duration>& tp,
|
||||
std::basic_string<CharT, Traits>& abbrev, std::chrono::minutes& offset)
|
||||
{
|
||||
return {format, tp, &abbrev, &offset};
|
||||
}
|
||||
|
||||
template <class Duration, class CharT, class Traits>
|
||||
inline
|
||||
detail::parse_utc_manip<Duration, CharT, Traits>
|
||||
parse(const CharT* format, utc_time<Duration>& tp,
|
||||
std::chrono::minutes& offset, std::basic_string<CharT, Traits>& abbrev)
|
||||
{
|
||||
return {format, tp, &abbrev, &offset};
|
||||
}
|
||||
|
||||
// tai_clock
|
||||
|
Loading…
x
Reference in New Issue
Block a user