| line | stmt | bran | cond | sub | pod | time | code | 
| 1 |  |  |  |  |  |  | #pragma once | 
| 2 |  |  |  |  |  |  | #include "Date.h" | 
| 3 |  |  |  |  |  |  | #include | 
| 4 |  |  |  |  |  |  |  | 
| 5 |  |  |  |  |  |  | namespace panda { namespace date { | 
| 6 |  |  |  |  |  |  |  | 
| 7 | 0 |  |  |  |  |  | struct DateRel { | 
| 8 |  |  |  |  |  |  | enum class Format { simple, iso8601d, iso8601i }; | 
| 9 |  |  |  |  |  |  |  | 
| 10 |  |  |  |  |  |  | struct InputFormat { | 
| 11 |  |  |  |  |  |  | static const int simple   = 1; | 
| 12 |  |  |  |  |  |  | static const int iso8601d = 2; | 
| 13 |  |  |  |  |  |  | static const int iso8601i = 4; | 
| 14 |  |  |  |  |  |  | static const int iso8601  = iso8601d + iso8601i; | 
| 15 |  |  |  |  |  |  | static const int all      = ~0; | 
| 16 |  |  |  |  |  |  | }; | 
| 17 |  |  |  |  |  |  |  | 
| 18 |  |  |  |  |  |  | DateRel () : _sec(0), _min(0), _hour(0), _day(0), _month(0), _year(0) {} | 
| 19 |  |  |  |  |  |  |  | 
| 20 | 0 |  |  |  |  |  | DateRel (ptime_t year, ptime_t mon = 0, ptime_t day=0, ptime_t hour=0, ptime_t min=0, ptime_t sec=0) | 
| 21 | 0 |  |  |  |  |  | : _sec(sec), _min(min), _hour(hour), _day(day), _month(mon), _year(year) {} | 
| 22 |  |  |  |  |  |  |  | 
| 23 | 0 | 0 |  |  |  |  | explicit DateRel (string_view str, int fmt = InputFormat::all) { _error = parse(str, fmt); } | 
| 24 |  |  |  |  |  |  |  | 
| 25 | 0 | 0 |  |  |  |  | DateRel (const Date& from, const Date& till)               { set(from, till); } | 
| 26 |  |  |  |  |  |  | DateRel (const string_view& from, const string_view& till) { set(Date(from), Date(till)); } | 
| 27 | 0 | 0 |  |  |  |  | DateRel (const DateRel& source)                            { operator=(source); } | 
| 28 |  |  |  |  |  |  |  | 
| 29 |  |  |  |  |  |  | void set (const Date&, const Date&); | 
| 30 |  |  |  |  |  |  | void set (const string_view& from, const string_view& till) { set(Date(from), Date(till)); } | 
| 31 |  |  |  |  |  |  |  | 
| 32 |  |  |  |  |  |  | DateRel& operator= (string_view str) { _error = parse(str, InputFormat::all); return *this; } | 
| 33 |  |  |  |  |  |  |  | 
| 34 | 0 |  |  |  |  |  | DateRel& operator= (const DateRel& source) { | 
| 35 | 0 |  |  |  |  |  | _sec   = source._sec; | 
| 36 | 0 |  |  |  |  |  | _min   = source._min; | 
| 37 | 0 |  |  |  |  |  | _hour  = source._hour; | 
| 38 | 0 |  |  |  |  |  | _day   = source._day; | 
| 39 | 0 |  |  |  |  |  | _month = source._month; | 
| 40 | 0 |  |  |  |  |  | _year  = source._year; | 
| 41 | 0 |  |  |  |  |  | _from  = source._from; | 
| 42 | 0 |  |  |  |  |  | _error = source._error; | 
| 43 | 0 |  |  |  |  |  | return *this; | 
| 44 |  |  |  |  |  |  | } | 
| 45 |  |  |  |  |  |  |  | 
| 46 | 0 |  |  |  |  |  | std::error_code error () const { return _error; } | 
| 47 |  |  |  |  |  |  |  | 
| 48 | 46 |  |  |  |  |  | ptime_t sec   () const { return _sec; } | 
| 49 | 46 |  |  |  |  |  | ptime_t min   () const { return _min; } | 
| 50 | 46 |  |  |  |  |  | ptime_t hour  () const { return _hour; } | 
| 51 | 34 |  |  |  |  |  | ptime_t day   () const { return _day; } | 
| 52 | 38 |  |  |  |  |  | ptime_t month () const { return _month; } | 
| 53 | 40 |  |  |  |  |  | ptime_t year  () const { return _year; } | 
| 54 |  |  |  |  |  |  |  | 
| 55 |  |  |  |  |  |  | const optional& from  () const { return _from; } | 
| 56 | 32 |  |  |  |  |  | optional& from  ()       { return _from; } | 
| 57 | 4 | 50 |  |  |  |  | optional  till  () const { return _from ? (*_from + *this) : optional(); } | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
| 58 |  |  |  |  |  |  |  | 
| 59 | 0 |  |  |  |  |  | DateRel& sec   (ptime_t val)   { _sec = val; return *this; } | 
| 60 | 0 |  |  |  |  |  | DateRel& min   (ptime_t val)   { _min = val; return *this; } | 
| 61 | 0 |  |  |  |  |  | DateRel& hour  (ptime_t val)   { _hour = val; return *this; } | 
| 62 | 0 |  |  |  |  |  | DateRel& day   (ptime_t val)   { _day = val; return *this; } | 
| 63 | 0 |  |  |  |  |  | DateRel& month (ptime_t val)   { _month = val; return *this; } | 
| 64 | 4 |  |  |  |  |  | DateRel& year  (ptime_t val)   { _year = val; return *this; } | 
| 65 | 8 |  |  |  |  |  | DateRel& from  (const Date& v) { _from = v; return *this; } | 
| 66 |  |  |  |  |  |  |  | 
| 67 |  |  |  |  |  |  | bool empty () const { return (_sec | _min | _hour | _day | _month | _year) == 0; } | 
| 68 |  |  |  |  |  |  |  | 
| 69 | 208 |  |  |  |  |  | ptime_t duration () const { | 
| 70 | 208 | 100 |  |  |  |  | if (_from) return (*_from + *this).epoch() - _from->epoch(); | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
| 71 | 208 |  |  |  |  |  | else       return _sec + _min*60 + _hour*3600 + _day * 86400 + (_month + 12*_year) * 2629744; | 
| 72 |  |  |  |  |  |  | } | 
| 73 |  |  |  |  |  |  |  | 
| 74 | 64 |  |  |  |  |  | ptime_t to_secs  () const { return duration(); } | 
| 75 | 16 |  |  |  |  |  | double  to_mins  () const { return double(duration()) / 60; } | 
| 76 | 8 |  |  |  |  |  | double  to_hours () const { return double(duration()) / 3600; } | 
| 77 |  |  |  |  |  |  |  | 
| 78 | 4 |  |  |  |  |  | double to_days () const { | 
| 79 | 4 | 100 |  |  |  |  | if (_from) { | 
| 80 | 4 | 50 |  |  |  |  | auto till = *_from + *this; | 
| 81 | 2 | 50 |  |  |  |  | return panda::time::christ_days(till.year()) - panda::time::christ_days(_from->year()) + | 
|  |  | 50 |  |  |  |  |  | 
| 82 | 2 | 50 |  |  |  |  | till.yday()  - _from->yday() + double(hms_diff(till)) / 86400; | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
| 83 |  |  |  |  |  |  | } | 
| 84 | 4 |  |  |  |  |  | else return double(duration()) / 86400; | 
| 85 |  |  |  |  |  |  | } | 
| 86 |  |  |  |  |  |  |  | 
| 87 | 8 |  |  |  |  |  | double to_months () const { | 
| 88 | 8 | 100 |  |  |  |  | if (_from) { | 
| 89 | 8 | 50 |  |  |  |  | auto till = *_from + *this; | 
| 90 | 4 | 50 |  |  |  |  | return (till.year() - _from->year())*12 + till.month() - _from->month() + | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
| 91 | 4 | 50 |  |  |  |  | double(till.day() - _from->day() + double(hms_diff(till)) / 86400) / _from->days_in_month(); | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
| 92 |  |  |  |  |  |  | } | 
| 93 | 8 |  |  |  |  |  | else return double(duration()) / 2629744; | 
| 94 |  |  |  |  |  |  | } | 
| 95 |  |  |  |  |  |  |  | 
| 96 | 8 |  |  |  |  |  | double to_years () const { return to_months() / 12; } | 
| 97 |  |  |  |  |  |  |  | 
| 98 |  |  |  |  |  |  | string to_string (Format fmt = Format::simple) const; | 
| 99 |  |  |  |  |  |  |  | 
| 100 |  |  |  |  |  |  | DateRel& operator+= (const DateRel&); | 
| 101 |  |  |  |  |  |  | DateRel& operator-= (const DateRel&); | 
| 102 |  |  |  |  |  |  | DateRel& operator*= (double koef); | 
| 103 |  |  |  |  |  |  | DateRel& operator/= (double koef); | 
| 104 |  |  |  |  |  |  | DateRel  operator-  () const { return negated(); } | 
| 105 |  |  |  |  |  |  | DateRel& negate     (); | 
| 106 |  |  |  |  |  |  |  | 
| 107 | 4 | 50 |  |  |  |  | DateRel negated () const { return DateRel(*this).negate(); } | 
|  |  | 50 |  |  |  |  |  | 
| 108 |  |  |  |  |  |  |  | 
| 109 | 146 |  |  |  |  |  | ptime_t compare (const DateRel& operand) const { return duration() - operand.duration(); } | 
| 110 |  |  |  |  |  |  |  | 
| 111 | 92 |  |  |  |  |  | bool is_same (const DateRel& operand) const { | 
| 112 | 92 | 50 |  |  |  |  | return _sec == operand._sec && _min == operand._min && _hour == operand._hour && | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
| 113 | 184 | 50 |  |  |  |  | _day == operand._day && _month == operand._month && _year == operand._year && _from == operand._from; | 
|  |  | 100 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
| 114 |  |  |  |  |  |  | } | 
| 115 |  |  |  |  |  |  |  | 
| 116 | 12 |  |  |  |  |  | int includes (const Date& date) const { | 
| 117 | 12 | 100 |  |  |  |  | if (!_from) return 0; | 
| 118 | 10 | 100 |  |  |  |  | if (*_from > date) return 1; | 
| 119 | 8 | 50 |  |  |  |  | if ((*_from + *this) < date) return -1; | 
|  |  | 100 |  |  |  |  |  | 
| 120 | 12 |  |  |  |  |  | return 0; | 
| 121 |  |  |  |  |  |  | } | 
| 122 |  |  |  |  |  |  |  | 
| 123 |  |  |  |  |  |  | private: | 
| 124 |  |  |  |  |  |  | ptime_t        _sec; | 
| 125 |  |  |  |  |  |  | ptime_t        _min; | 
| 126 |  |  |  |  |  |  | ptime_t        _hour; | 
| 127 |  |  |  |  |  |  | ptime_t        _day; | 
| 128 |  |  |  |  |  |  | ptime_t        _month; | 
| 129 |  |  |  |  |  |  | ptime_t        _year; | 
| 130 |  |  |  |  |  |  | optional _from; | 
| 131 |  |  |  |  |  |  | errc           _error = errc::ok; | 
| 132 |  |  |  |  |  |  |  | 
| 133 |  |  |  |  |  |  | errc parse (string_view, int); | 
| 134 |  |  |  |  |  |  |  | 
| 135 | 6 |  |  |  |  |  | ptime_t hms_diff (const Date& till) const { | 
| 136 | 6 |  |  |  |  |  | return (till.hour() - _from->hour())*3600 + (till.min() - _from->min())*60 + till.sec() - _from->sec(); | 
| 137 |  |  |  |  |  |  | } | 
| 138 |  |  |  |  |  |  | }; | 
| 139 |  |  |  |  |  |  |  | 
| 140 |  |  |  |  |  |  | #undef SEC // fuck solaris | 
| 141 |  |  |  |  |  |  |  | 
| 142 |  |  |  |  |  |  | extern const DateRel YEAR; | 
| 143 |  |  |  |  |  |  | extern const DateRel MONTH; | 
| 144 |  |  |  |  |  |  | extern const DateRel WEEK; | 
| 145 |  |  |  |  |  |  | extern const DateRel DAY; | 
| 146 |  |  |  |  |  |  | extern const DateRel HOUR; | 
| 147 |  |  |  |  |  |  | extern const DateRel MIN; | 
| 148 |  |  |  |  |  |  | extern const DateRel SEC; | 
| 149 |  |  |  |  |  |  |  | 
| 150 |  |  |  |  |  |  | std::ostream& operator<< (std::ostream&, const DateRel&); | 
| 151 |  |  |  |  |  |  |  | 
| 152 |  |  |  |  |  |  | inline bool operator== (const DateRel& lhs, const DateRel& rhs) { return !lhs.compare(rhs); } | 
| 153 |  |  |  |  |  |  | inline bool operator!= (const DateRel& lhs, const DateRel& rhs) { return !operator==(lhs, rhs); } | 
| 154 |  |  |  |  |  |  | inline bool operator<  (const DateRel& lhs, const DateRel& rhs) { return lhs.compare(rhs) < 0; } | 
| 155 |  |  |  |  |  |  | inline bool operator<= (const DateRel& lhs, const DateRel& rhs) { return lhs.compare(rhs) <= 0; } | 
| 156 |  |  |  |  |  |  | inline bool operator>  (const DateRel& lhs, const DateRel& rhs) { return lhs.compare(rhs) > 0; } | 
| 157 |  |  |  |  |  |  | inline bool operator>= (const DateRel& lhs, const DateRel& rhs) { return lhs.compare(rhs) >= 0; } | 
| 158 |  |  |  |  |  |  |  | 
| 159 | 31 | 50 |  |  |  |  | inline DateRel operator+ (const DateRel& lhs, const DateRel& rhs) { return DateRel(lhs) += rhs; } | 
|  |  | 50 |  |  |  |  |  | 
| 160 | 12 | 50 |  |  |  |  | inline DateRel operator- (const DateRel& lhs, const DateRel& rhs) { return DateRel(lhs) -= rhs; } | 
|  |  | 50 |  |  |  |  |  | 
| 161 | 33 | 50 |  |  |  |  | inline DateRel operator* (const DateRel& dr, double koef)         { return DateRel(dr) *= koef; } | 
|  |  | 50 |  |  |  |  |  | 
| 162 |  |  |  |  |  |  | inline DateRel operator* (double koef, const DateRel& dr)         { return DateRel(dr) *= koef; } | 
| 163 | 17 | 50 |  |  |  |  | inline DateRel operator/ (const DateRel& dr, double koef)         { return DateRel(dr) /= koef; } | 
|  |  | 50 |  |  |  |  |  | 
| 164 |  |  |  |  |  |  |  | 
| 165 |  |  |  |  |  |  | inline DateRel operator- (const Date& lhs, const Date& rhs)       { return DateRel(rhs, lhs); } | 
| 166 |  |  |  |  |  |  |  | 
| 167 |  |  |  |  |  |  | }} |