#pragma once
#include <cstring>
#include <panda/date/Date.h>
#include <panda/date/DateRel.h>
namespace panda { namespace date {
using panda::time::christ_days;
class DateInt {
public:
DateInt () {}
DateInt (const Date& from, const Date& till) : _from(from), _till(till) {}
DateInt (const DateInt& src) : _from(src.from()), _till(src.till()) {}
explicit DateInt (string_view str) { operator=(str); }
DateInt& operator= (const DateInt& oth) {
_from = oth.from();
_till = oth.till();
return *this;
}
DateInt& operator= (string_view str);
err_t error () const { return _from.error() == E_OK ? _till.error() : _from.error(); }
const Date& from () const { return _from; }
const Date& till () const { return _till; }
Date& from () { return _from; }
Date& till () { return _till; }
panda::string to_string() const;
ptime_t hms_diff () const {
return (_till.hour() - _from.hour())*3600 + (_till.min() - _from.min())*60 + _till.sec() - _from.sec();
}
ptime_t duration () const { return error() ? 0 : (_till.epoch() - _from.epoch()); }
ptime_t sec () const { return duration(); }
ptime_t imin () const { return duration()/60; }
double min () const { return (double) duration()/60; }
ptime_t ihour () const { return duration()/3600; }
double hour () const { return (double) duration()/3600; }
ptime_t iday () const { return (ptime_t) day(); }
double day () const { return christ_days(_till.year()) + _till.yday() - christ_days(_from.year()) - _from.yday() + (double) hms_diff() / 86400; }
ptime_t imonth () const { return (ptime_t) month(); }
double month () const {
return (_till.year() - _from.year())*12 + _till.month() - _from.month() +
(double) (_till.day() - _from.day() + (double) hms_diff() / 86400) / _from.days_in_month();
}
ptime_t iyear () const { return (ptime_t) year(); }
double year () const { return month() / 12; }
DateRel relative () const { return DateRel(_from, _till); }
DateInt& operator+= (const DateRel& op) {
_from += op;
_till += op;
return *this;
}
DateInt& operator-= (const DateRel& op) {
_from -= op;
_till -= op;
return *this;
}
ptime_t compare (const DateInt& operand) const { return duration() - operand.duration(); }
bool is_same (const DateInt& operand) const { return _from == operand._from && _till == operand._till; }
DateInt& negate () {
std::swap(_from, _till);
return *this;
}
DateInt negated () const { return DateInt(_till, _from); }
int includes (const Date& date) const {
if (_from > date) return 1;
if (_till < date) return -1;
return 0;
}
private:
Date _from;
Date _till;
};
inline bool operator== (const DateInt& lhs, const DateInt& rhs) { return !lhs.compare(rhs); }
inline bool operator< (const DateInt& lhs, const DateInt& rhs) { return !operator==(lhs, rhs); }
inline bool operator<= (const DateInt& lhs, const DateInt& rhs) { return lhs.compare(rhs) <= 0; }
inline bool operator> (const DateInt& lhs, const DateInt& rhs) { return lhs.compare(rhs) > 0; }
inline bool operator>= (const DateInt& lhs, const DateInt& rhs) { return lhs.compare(rhs) >= 0; }
inline DateInt operator+ (const DateInt& lhs, const DateRel& rhs) { return DateInt(lhs) += rhs; }
inline DateInt operator- (const DateInt& lhs, const DateRel& rhs) { return DateInt(lhs) -= rhs; }
}}