For example i have ptime("2000-10-10 00:00:00"). How i can add to this ptime? For example "0001-00-01 00:00:00" - one year and one day, and i can use only this format cuz i get string like "yyyy-mm-dd hh:mm:ss" or in timestamp_t(uin64_t). In main func i write example how i see this.
constexpr const char format[] = "%Y-%m-%d %H:%M:%S";
bt::ptime from_string_dtime(const std::string& s);
class date_time
{
public:
date_time() = default;
date_time(const std::string& dtime);
date_time(const bt::ptime& ptime);
~date_time() = default;
api::timestamp_t to_timestamp();
public:
friend date_time operator (const date_time& lv, uint64_t rv);
private:
bt::ptime d_time;
};
bt::ptime from_string_dtime(const std::string& s)
{
bt::ptime pt;
std::istringstream is(s);
is.exceptions(std::ifstream::failbit | std::ifstream::badbit);
is.imbue(std::locale(std::locale::classic(), new bt::time_input_facet(format)));
is >> pt;
return pt;
}
date_time::date_time(const std::string& dtime)
: d_time(from_string_dtime(dtime))
{}
date_time::date_time(const bt::ptime& ptime)
: d_time(ptime)
{}
api::timestamp_t date_time::to_timestamp() {
const bt::ptime epoch = bt::from_time_t(0);
bt::time_duration duration = d_time - epoch;
return duration.total_seconds();
}
date_time operator (const date_time& lv, uint64_t rv)
{
return date_time(lv.d_time bt::milliseconds(rv));
}
int main()
{
nup::core::date_time dtime("0000-00-01 00:00:01"); // Exception here, i understand why, but idk how resolve
nup::core::date_time dtime2("2004-04-22 00:00:01");
nup::core::date_time dtime3("2004-04-23 00:00:02");
//i want smth like this
(dtime dtime2) == dtime(3)
}
CodePudding user response:
nup::core::date_time dtime("0000-00-01 00:00:01"); // Exception here, i understand why, but idk how resolve
The problem is that you're trying to treat something that is not a date-time as a... date_time
. Parse a duration instead!
struct duration {
unsigned y, m, d;
bt::time_duration tod;
};
duration parse_duration(std::string_view sv) {
namespace x3 = boost::spirit::x3;
static const x3::uint_parser<unsigned short, 10, 4, 4> u4{};
static const x3::uint_parser<unsigned short, 10, 2, 2> u2{};
duration result;
unsigned short H, M, S;
auto tied = std::tie(result.y, result.m, result.d, H, M, S);
if (!x3::parse(begin(sv), end(sv),
u4 >> '-' >> u2 >> '-' >> u2 >> ' ' >> //
u2 >> ':' >> u2 >> ':' >> u2 >> x3::eoi,
tied))
{
throw std::runtime_error("invalid time duration");
}
result.tod = bt::hours(H) bt::minutes(M) bt::seconds(S);
return result;
}
Now you can implement operator
:
friend date_time operator (const date_time& lv, duration const& rv) {
return lv.d_time //
bg::years(rv.y) bg::months(rv.m) bg::days(rv.d) rv.tod;
}
Live Demo
#include <boost/date_time/gregorian/gregorian_io.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/date_time/posix_time/posix_time_io.hpp>
#include <boost/fusion/adapted/std_tuple.hpp>
#include <boost/spirit/home/x3.hpp>
#include <sstream>
namespace bg = boost::gregorian;
namespace bt = boost::posix_time;
namespace nup::core {
constexpr const char format[] = "%Y-%m-%d %H:%M:%S";
bt::ptime from_string_dtime(const std::string& s);
struct duration {
unsigned y, m, d;
bt::time_duration tod;
};
duration parse_duration(std::string_view sv) {
namespace x3 = boost::spirit::x3;
static const x3::uint_parser<unsigned short, 10, 4, 4> u4{};
static const x3::uint_parser<unsigned short, 10, 2, 2> u2{};
duration result;
unsigned short H, M, S;
auto tied = std::tie(result.y, result.m, result.d, H, M, S);
if (!x3::parse(begin(sv), end(sv),
u4 >> '-' >> u2 >> '-' >> u2 >> ' ' >> //
u2 >> ':' >> u2 >> ':' >> u2 >> x3::eoi,
tied))
{
throw std::runtime_error("invalid time duration");
}
result.tod = bt::hours(H) bt::minutes(M) bt::seconds(S);
return result;
}
class date_time {
public:
date_time() = default;
~date_time() = default;
date_time(const std::string& dtime)
: d_time(from_string_dtime(dtime)) {}
date_time(const bt::ptime& ptime) : d_time(ptime) {}
auto to_timestamp() {
const bt::ptime epoch = bt::from_time_t(0);
bt::time_duration duration = d_time - epoch;
return duration.total_seconds();
}
public:
friend date_time operator (const date_time& lv, duration const& rv) {
return lv.d_time //
bg::years(rv.y) bg::months(rv.m) bg::days(rv.d) rv.tod;
}
friend std::ostream& operator<<(std::ostream& os, date_time const& dt) {
return os << dt.d_time;
}
private:
bt::ptime d_time;
};
bt::ptime from_string_dtime(const std::string& s) {
bt::ptime pt;
std::istringstream is(s);
is.exceptions(std::ios::failbit | std::ios::badbit);
is.imbue(std::locale(std::locale::classic(),
new bt::time_input_facet(format)));
is >> pt;
return pt;
}
} // namespace nup::core
int main()
{
auto dtime = nup::core::parse_duration("0000-00-01 00:00:01");
nup::core::date_time dtime2("2004-04-22 00:00:01");
nup::core::date_time dtime3("2004-04-23 00:00:02");
std::cout << "dtime: " << dtime.y << "-" << dtime.m << "-" << dtime.d << " " << dtime.tod << "\n";
std::cout << "dtime2: " << dtime2 << "\n";
std::cout << "(dtime2 dtime): " << (dtime2 dtime) << "\n";
std::cout << "dtime3: " << dtime3 << "\n";
}
Prints
dtime: 0-0-1 00:00:01
dtime2: 2004-Apr-22 00:00:01
(dtime2 dtime): 2004-Apr-23 00:00:02
dtime3: 2004-Apr-23 00:00:02