From 2b3691508f70040393f2f4169e0c245b5ac14672 Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sat, 26 Sep 2015 11:39:45 -0400 Subject: [PATCH 001/117] ISO8601: Prepared ::parse method for its new role of parsing all dates --- src/ISO8601.cpp | 5 ++++- src/ISO8601.h | 3 ++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/ISO8601.cpp b/src/ISO8601.cpp index 6b4b16559..d5d9a6dbf 100644 --- a/src/ISO8601.cpp +++ b/src/ISO8601.cpp @@ -167,7 +167,10 @@ ISO8601d::operator time_t () const // | 'R' [n] '/' datetime '/' datetime # start end // ; // -bool ISO8601d::parse (const std::string& input, std::string::size_type& start) +bool ISO8601d::parse ( + const std::string& input, + std::string::size_type& start, + const std::string& format /* = "" */) { auto i = start; Nibbler n (input.substr (i)); diff --git a/src/ISO8601.h b/src/ISO8601.h index 9a6b60e79..9c41c81e1 100644 --- a/src/ISO8601.h +++ b/src/ISO8601.h @@ -23,6 +23,7 @@ // http://www.opensource.org/licenses/mit-license.php // //////////////////////////////////////////////////////////////////////////////// + #ifndef INCLUDED_ISO8601 #define INCLUDED_ISO8601 @@ -38,7 +39,7 @@ public: ISO8601d (const ISO8601d&); // Unimplemented ISO8601d& operator= (const ISO8601d&); // Unimplemented operator time_t () const; - bool parse (const std::string&, std::string::size_type&); + bool parse (const std::string&, std::string::size_type&, const std::string& format = ""); void clear (); private: From 1efc1f2531accdd97b9a993791fd602d56b274f2 Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sat, 26 Sep 2015 11:45:00 -0400 Subject: [PATCH 002/117] ISO8601: ::clear is now a private method --- src/ISO8601.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ISO8601.h b/src/ISO8601.h index 9c41c81e1..1d3c54f1e 100644 --- a/src/ISO8601.h +++ b/src/ISO8601.h @@ -40,9 +40,9 @@ public: ISO8601d& operator= (const ISO8601d&); // Unimplemented operator time_t () const; bool parse (const std::string&, std::string::size_type&, const std::string& format = ""); - void clear (); private: + void clear (); bool parse_date_time (Nibbler&); bool parse_date_time_ext (Nibbler&); bool parse_date_ext (Nibbler&); @@ -82,11 +82,11 @@ public: operator std::string () const; operator time_t () const; bool parse (const std::string&, std::string::size_type&); - void clear (); const std::string format () const; const std::string formatVague () const; private: + void clear (); bool parse_designated (Nibbler&); bool validate (); void resolve (); From 219f23de33b512ed999f027e9e2d7b483edb80d8 Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sat, 26 Sep 2015 11:55:29 -0400 Subject: [PATCH 003/117] ISO8601: Default ctor implies 'now' --- src/ISO8601.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ISO8601.cpp b/src/ISO8601.cpp index d5d9a6dbf..9ce967adb 100644 --- a/src/ISO8601.cpp +++ b/src/ISO8601.cpp @@ -109,6 +109,7 @@ static struct ISO8601d::ISO8601d () { clear (); + _value = time (NULL); } //////////////////////////////////////////////////////////////////////////////// From bb53ae17ae392a7d728b4824e01092fb4de7a3d1 Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sat, 26 Sep 2015 12:11:49 -0400 Subject: [PATCH 004/117] ISO8601p: Renamed ::_value to ::_period --- src/DOM.cpp | 2 +- src/ISO8601.cpp | 52 ++++++++++++++++++++-------------------- src/ISO8601.h | 2 +- src/commands/CmdInfo.cpp | 2 +- test/iso8601p.t.cpp | 24 +++++++++---------- 5 files changed, 41 insertions(+), 41 deletions(-) diff --git a/src/DOM.cpp b/src/DOM.cpp index 929f40823..a7f760a14 100644 --- a/src/DOM.cpp +++ b/src/DOM.cpp @@ -300,7 +300,7 @@ bool DOM::get (const std::string& name, const Task& task, Variant& value) ISO8601p iso; std::string::size_type cursor = 0; if (iso.parse (period, cursor)) - value = Variant ((time_t) iso._value, Variant::type_duration); + value = Variant ((time_t) iso, Variant::type_duration); else value = Variant ((time_t) ISO8601p (ref.get (canonical)), Variant::type_duration); } diff --git a/src/ISO8601.cpp b/src/ISO8601.cpp index 9ce967adb..00212db5d 100644 --- a/src/ISO8601.cpp +++ b/src/ISO8601.cpp @@ -592,7 +592,7 @@ ISO8601p::ISO8601p () ISO8601p::ISO8601p (time_t input) { clear (); - _value = input; + _period = input; } //////////////////////////////////////////////////////////////////////////////// @@ -605,7 +605,7 @@ ISO8601p::ISO8601p (const std::string& input) time_t value = (time_t) strtol (input.c_str (), NULL, 10); if (value == 0 || value > 60) { - _value = value; + _period = value; return; } } @@ -630,7 +630,7 @@ ISO8601p& ISO8601p::operator= (const ISO8601p& other) _hours = other._hours; _minutes = other._minutes; _seconds = other._seconds; - _value = other._value; + _period = other._period; } return *this; @@ -639,27 +639,27 @@ ISO8601p& ISO8601p::operator= (const ISO8601p& other) //////////////////////////////////////////////////////////////////////////////// bool ISO8601p::operator< (const ISO8601p& other) { - return _value < other._value; + return _period < other._period; } //////////////////////////////////////////////////////////////////////////////// bool ISO8601p::operator> (const ISO8601p& other) { - return _value > other._value; + return _period > other._period; } //////////////////////////////////////////////////////////////////////////////// ISO8601p::operator std::string () const { std::stringstream s; - s << _value; + s << _period; return s.str (); } //////////////////////////////////////////////////////////////////////////////// ISO8601p::operator time_t () const { - return _value; + return _period; } //////////////////////////////////////////////////////////////////////////////// @@ -732,7 +732,7 @@ bool ISO8601p::parse (const std::string& input, std::string::size_type& start) if (durations[i].unit == unit && durations[i].standalone == true) { - _value = static_cast (durations[i].seconds); + _period = static_cast (durations[i].seconds); return true; } } @@ -781,7 +781,7 @@ bool ISO8601p::parse (const std::string& input, std::string::size_type& start) if (durations[i].unit == unit) { seconds = durations[i].seconds; - _value = static_cast (quantity * static_cast (seconds)); + _period = static_cast (quantity * static_cast (seconds)); return true; } } @@ -801,15 +801,15 @@ void ISO8601p::clear () _hours = 0; _minutes = 0; _seconds = 0; - _value = 0; + _period = 0; } //////////////////////////////////////////////////////////////////////////////// const std::string ISO8601p::format () const { - if (_value) + if (_period) { - time_t t = _value; + time_t t = _period; int seconds = t % 60; t /= 60; int minutes = t % 60; t /= 60; int hours = t % 24; t /= 24; @@ -839,15 +839,15 @@ const std::string ISO8601p::format () const const std::string ISO8601p::formatVague () const { char formatted[24]; - float days = (float) _value / 86400.0; + float days = (float) _period / 86400.0; - if (_value >= 86400 * 365) sprintf (formatted, "%.1fy", (days / 365.0)); - else if (_value >= 86400 * 84) sprintf (formatted, "%1dmo", (int) (days / 30)); - else if (_value >= 86400 * 13) sprintf (formatted, "%dw", (int) (float) (days / 7.0)); - else if (_value >= 86400) sprintf (formatted, "%dd", (int) days); - else if (_value >= 3600) sprintf (formatted, "%dh", (int) (_value / 3600)); - else if (_value >= 60) sprintf (formatted, "%dmin", (int) (_value / 60)); - else if (_value >= 1) sprintf (formatted, "%ds", (int) _value); + if (_period >= 86400 * 365) sprintf (formatted, "%.1fy", (days / 365.0)); + else if (_period >= 86400 * 84) sprintf (formatted, "%1dmo", (int) (days / 30)); + else if (_period >= 86400 * 13) sprintf (formatted, "%dw", (int) (float) (days / 7.0)); + else if (_period >= 86400) sprintf (formatted, "%dd", (int) days); + else if (_period >= 3600) sprintf (formatted, "%dh", (int) (_period / 3600)); + else if (_period >= 60) sprintf (formatted, "%dmin", (int) (_period / 60)); + else if (_period >= 1) sprintf (formatted, "%ds", (int) _period); else formatted[0] = '\0'; return std::string (formatted); @@ -923,12 +923,12 @@ bool ISO8601p::validate () // Allow un-normalized values. void ISO8601p::resolve () { - _value = (_year * 365 * 86400) + - (_month * 30 * 86400) + - (_day * 86400) + - (_hours * 3600) + - (_minutes * 60) + - _seconds; + _period = (_year * 365 * 86400) + + (_month * 30 * 86400) + + (_day * 86400) + + (_hours * 3600) + + (_minutes * 60) + + _seconds; } //////////////////////////////////////////////////////////////////////////////// diff --git a/src/ISO8601.h b/src/ISO8601.h index 1d3c54f1e..9b6af4eb0 100644 --- a/src/ISO8601.h +++ b/src/ISO8601.h @@ -98,7 +98,7 @@ public: int _hours; int _minutes; int _seconds; - time_t _value; + time_t _period; }; // TODO Recurrence diff --git a/src/commands/CmdInfo.cpp b/src/commands/CmdInfo.cpp index 3066ac563..e6521b438 100644 --- a/src/commands/CmdInfo.cpp +++ b/src/commands/CmdInfo.cpp @@ -379,7 +379,7 @@ int CmdInfo::execute (std::string& output) ISO8601p iso; std::string::size_type cursor = 0; if (iso.parse (value, cursor)) - value = (std::string) Variant ((time_t) iso._value, Variant::type_duration); + value = (std::string) Variant ((time_t) iso, Variant::type_duration); else value = "PT0S"; } diff --git a/test/iso8601p.t.cpp b/test/iso8601p.t.cpp index b8d0186da..8c0d646bf 100644 --- a/test/iso8601p.t.cpp +++ b/test/iso8601p.t.cpp @@ -44,7 +44,7 @@ void testParse ( int in_hours, int in_minutes, int in_seconds, - time_t in_value, + time_t in_period, const std::string& output, const std::string& vague) { @@ -53,17 +53,17 @@ void testParse ( ISO8601p iso; std::string::size_type start = 0; - t.ok (iso.parse (input, start), label + "true"); - t.is ((int) start, in_start, label + "[]"); - t.is (iso._year, in_year, label + "_year"); - t.is (iso._month, in_month, label + "_month"); - t.is (iso._day, in_day, label + "_day"); - t.is (iso._hours, in_hours, label + "_hours"); - t.is (iso._minutes, in_minutes, label + "_minutes"); - t.is (iso._seconds, in_seconds, label + "_seconds"); - t.is ((size_t) iso._value, (size_t) in_value, label + "_value"); - t.is (iso.format (), output, label + " format"); - t.is (iso.formatVague (), vague, label + " formatVague"); + t.ok (iso.parse (input, start), label + "true"); + t.is ((int) start, in_start, label + "[]"); + t.is (iso._year, in_year, label + "_year"); + t.is (iso._month, in_month, label + "_month"); + t.is (iso._day, in_day, label + "_day"); + t.is (iso._hours, in_hours, label + "_hours"); + t.is (iso._minutes, in_minutes, label + "_minutes"); + t.is (iso._seconds, in_seconds, label + "_seconds"); + t.is ((size_t) iso._period, (size_t) in_period, label + "_period"); + t.is (iso.format (), output, label + " format"); + t.is (iso.formatVague (), vague, label + " formatVague"); } //////////////////////////////////////////////////////////////////////////////// From 5eb994823514527314285697fb936ac92424c829 Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sat, 26 Sep 2015 12:20:14 -0400 Subject: [PATCH 005/117] CmdExport: Measures JSON composition time under context.timer_render --- src/commands/CmdExport.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/commands/CmdExport.cpp b/src/commands/CmdExport.cpp index eebd3bf74..78682ffad 100644 --- a/src/commands/CmdExport.cpp +++ b/src/commands/CmdExport.cpp @@ -62,6 +62,9 @@ int CmdExport::execute (std::string& output) std::vector filtered; filter.subset (filtered); + // Export == render. + context.timer_render.start (); + // Obey 'limit:N'. int rows = 0; int lines = 0; @@ -97,6 +100,7 @@ int CmdExport::execute (std::string& output) if (json_array) output += "]\n"; + context.timer_render.stop (); return rc; } From eeb592d032e86018ae819af5c7658b79c6b5e54b Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sat, 26 Sep 2015 12:26:09 -0400 Subject: [PATCH 006/117] ISO8601d: Renamed ::_value to ::_date --- src/ISO8601.cpp | 8 ++++---- src/ISO8601.h | 2 +- test/iso8601d.t.cpp | 26 +++++++++++++------------- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/ISO8601.cpp b/src/ISO8601.cpp index 00212db5d..1a78f218e 100644 --- a/src/ISO8601.cpp +++ b/src/ISO8601.cpp @@ -109,7 +109,7 @@ static struct ISO8601d::ISO8601d () { clear (); - _value = time (NULL); + _date = time (NULL); } //////////////////////////////////////////////////////////////////////////////// @@ -120,7 +120,7 @@ ISO8601d::~ISO8601d () //////////////////////////////////////////////////////////////////////////////// ISO8601d::operator time_t () const { - return _value; + return _date; } //////////////////////////////////////////////////////////////////////////////// @@ -209,7 +209,7 @@ void ISO8601d::clear () _seconds = 0; _offset = 0; _utc = false; - _value = 0; + _date = 0; } //////////////////////////////////////////////////////////////////////////////// @@ -579,7 +579,7 @@ void ISO8601d::resolve () t.tm_min = (seconds % 3600) / 60; t.tm_sec = seconds % 60; - _value = utc ? timegm (&t) : mktime (&t); + _date = utc ? timegm (&t) : mktime (&t); } //////////////////////////////////////////////////////////////////////////////// diff --git a/src/ISO8601.h b/src/ISO8601.h index 9b6af4eb0..cb30a2d7a 100644 --- a/src/ISO8601.h +++ b/src/ISO8601.h @@ -64,7 +64,7 @@ public: int _seconds; int _offset; bool _utc; - time_t _value; + time_t _date; }; // Period diff --git a/test/iso8601d.t.cpp b/test/iso8601d.t.cpp index dd169d33c..0238a2ac8 100644 --- a/test/iso8601d.t.cpp +++ b/test/iso8601d.t.cpp @@ -47,25 +47,25 @@ void testParse ( int in_seconds, int in_offset, bool in_utc, - time_t in_value) + time_t in_date) { std::string label = std::string ("parse (\"") + input + "\") --> "; ISO8601d iso; std::string::size_type start = 0; - t.ok (iso.parse (input, start), label + "true"); - t.is ((int) start, in_start, label + "[]"); - t.is (iso._year, in_year, label + "_year"); - t.is (iso._month, in_month, label + "_month"); - t.is (iso._week, in_week, label + "_week"); - t.is (iso._weekday, in_weekday, label + "_weekday"); - t.is (iso._julian, in_julian, label + "_julian"); - t.is (iso._day, in_day, label + "_day"); - t.is (iso._seconds, in_seconds, label + "_seconds"); - t.is (iso._offset, in_offset, label + "_offset"); - t.is (iso._utc, in_utc, label + "_utc"); - t.is ((size_t) iso._value, (size_t) in_value, label + "_value"); + t.ok (iso.parse (input, start), label + "true"); + t.is ((int) start, in_start, label + "[]"); + t.is (iso._year, in_year, label + "_year"); + t.is (iso._month, in_month, label + "_month"); + t.is (iso._week, in_week, label + "_week"); + t.is (iso._weekday, in_weekday, label + "_weekday"); + t.is (iso._julian, in_julian, label + "_julian"); + t.is (iso._day, in_day, label + "_day"); + t.is (iso._seconds, in_seconds, label + "_seconds"); + t.is (iso._offset, in_offset, label + "_offset"); + t.is (iso._utc, in_utc, label + "_utc"); + t.is ((size_t) iso._date, (size_t) in_date, label + "_date"); } //////////////////////////////////////////////////////////////////////////////// From 12aeecc73fd287d4b61469ec020ad1fc2d89ed52 Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sat, 26 Sep 2015 12:27:23 -0400 Subject: [PATCH 007/117] ISO8601: Removed useless comment --- src/ISO8601.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/ISO8601.h b/src/ISO8601.h index cb30a2d7a..c55abe634 100644 --- a/src/ISO8601.h +++ b/src/ISO8601.h @@ -101,8 +101,6 @@ public: time_t _period; }; -// TODO Recurrence - #endif //////////////////////////////////////////////////////////////////////////////// From 541e9eec302bce6aaa167c9604634b2e789a9785 Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sat, 26 Sep 2015 12:40:56 -0400 Subject: [PATCH 008/117] Context: Initialize ISO8601::weekstart --- src/Context.cpp | 3 +++ src/ISO8601.cpp | 3 +++ src/ISO8601.h | 2 ++ 3 files changed, 8 insertions(+) diff --git a/src/Context.cpp b/src/Context.cpp index 62d879f73..140b04657 100644 --- a/src/Context.cpp +++ b/src/Context.cpp @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -634,6 +635,8 @@ void Context::staticInitialization () TDB2::debug_mode = config.getBoolean ("debug"); + ISO8601d::weekstart = config.get ("weekstart"); + for (auto& rc : config) { if (rc.first.substr (0, 4) == "uda." && diff --git a/src/ISO8601.cpp b/src/ISO8601.cpp index 1a78f218e..998dee123 100644 --- a/src/ISO8601.cpp +++ b/src/ISO8601.cpp @@ -30,6 +30,7 @@ #include #include #include +#include #define DAY 86400 #define HOUR 3600 @@ -105,6 +106,8 @@ static struct #define NUM_DURATIONS (sizeof (durations) / sizeof (durations[0])) +std::string ISO8601d::weekstart = STRING_DATE_SUNDAY; + //////////////////////////////////////////////////////////////////////////////// ISO8601d::ISO8601d () { diff --git a/src/ISO8601.h b/src/ISO8601.h index c55abe634..690bfc16c 100644 --- a/src/ISO8601.h +++ b/src/ISO8601.h @@ -34,6 +34,8 @@ class ISO8601d { public: + static std::string weekstart; + ISO8601d (); ~ISO8601d (); ISO8601d (const ISO8601d&); // Unimplemented From 6f726bf1cf895ddb8a92735f97d5b084905fd237 Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sat, 26 Sep 2015 12:57:57 -0400 Subject: [PATCH 009/117] ISO8601d: Added ::minimumMatchLength --- src/Context.cpp | 5 +++-- src/ISO8601.cpp | 3 ++- src/ISO8601.h | 1 + 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/Context.cpp b/src/Context.cpp index 140b04657..f01dffb92 100644 --- a/src/Context.cpp +++ b/src/Context.cpp @@ -622,8 +622,9 @@ void Context::getLimits (int& rows, int& lines) // easier, it has been decoupled from Context. void Context::staticInitialization () { - CLI2::minimumMatchLength = config.getInteger ("abbreviation.minimum"); - Lexer::minimumMatchLength = config.getInteger ("abbreviation.minimum"); + CLI2::minimumMatchLength = config.getInteger ("abbreviation.minimum"); + Lexer::minimumMatchLength = config.getInteger ("abbreviation.minimum"); + ISO8601d::minimumMatchLength = config.getInteger ("abbreviation.minimum"); Task::defaultProject = config.get ("default.project"); Task::defaultDue = config.get ("default.due"); diff --git a/src/ISO8601.cpp b/src/ISO8601.cpp index 998dee123..0179b2789 100644 --- a/src/ISO8601.cpp +++ b/src/ISO8601.cpp @@ -106,7 +106,8 @@ static struct #define NUM_DURATIONS (sizeof (durations) / sizeof (durations[0])) -std::string ISO8601d::weekstart = STRING_DATE_SUNDAY; +std::string ISO8601d::weekstart = STRING_DATE_SUNDAY; +int ISO8601d::minimumMatchLength = 3; //////////////////////////////////////////////////////////////////////////////// ISO8601d::ISO8601d () diff --git a/src/ISO8601.h b/src/ISO8601.h index 690bfc16c..80aeabc8f 100644 --- a/src/ISO8601.h +++ b/src/ISO8601.h @@ -35,6 +35,7 @@ class ISO8601d { public: static std::string weekstart; + static int minimumMatchLength; ISO8601d (); ~ISO8601d (); From 227163a4a16c1cbc6ee672a5aa8f49f7c7e7cb95 Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sat, 26 Sep 2015 13:07:13 -0400 Subject: [PATCH 010/117] Date: Removed method signature that doesn't even exist --- src/Date.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Date.h b/src/Date.h index 89a0c5f30..d8291f25a 100644 --- a/src/Date.h +++ b/src/Date.h @@ -77,7 +77,6 @@ public: static std::string monthName (int); static void dayName (int, std::string&); static std::string dayName (int); - static int weekOfYear (const std::string&); static int dayOfWeek (const std::string&); static int monthOfYear (const std::string&); static int length (const std::string&); From 71e2f1bf2f7a0b6e18f45ae91e18c3610f2a3626 Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sat, 26 Sep 2015 13:19:20 -0400 Subject: [PATCH 011/117] Date: Removed unused ::easter method - It is duplicated in Dates.cpp. --- src/Date.cpp | 26 -------------------------- src/Date.h | 1 - test/date.t.cpp | 20 +------------------- 3 files changed, 1 insertion(+), 46 deletions(-) diff --git a/src/Date.cpp b/src/Date.cpp index 6f39d6272..4e38b5d0c 100644 --- a/src/Date.cpp +++ b/src/Date.cpp @@ -573,32 +573,6 @@ int Date::length (const std::string& format) return total; } -//////////////////////////////////////////////////////////////////////////////// -time_t Date::easter (int year) -{ - int Y = year; - int a = Y % 19; - int b = Y / 100; - int c = Y % 100; - int d = b / 4; - int e = b % 4; - int f = (b + 8) / 25; - int g = (b - f + 1) / 3; - int h = (19 * a + b - d - g + 15) % 30; - int i = c / 4; - int k = c % 4; - int L = (32 + 2 * e + 2 * i - h - k) % 7; - int m = (a + 11 * h + 22 * L) / 451; - int month = (h + L - 7 * m + 114) / 31; - int day = ((h + L - 7 * m + 114) % 31) + 1; - struct tm t = {0}; - t.tm_isdst = -1; // Requests that mktime determine summer time effect. - t.tm_mday = day; - t.tm_mon = month - 1; - t.tm_year = year - 1900; - return mktime (&t); -} - //////////////////////////////////////////////////////////////////////////////// int Date::month () const { diff --git a/src/Date.h b/src/Date.h index d8291f25a..8553b0850 100644 --- a/src/Date.h +++ b/src/Date.h @@ -70,7 +70,6 @@ public: static bool valid (const int, const int, const int); static bool valid (const int, const int); - static time_t easter (int year); static bool leapYear (int); static int daysInMonth (int, int); static int daysInYear (int); diff --git a/test/date.t.cpp b/test/date.t.cpp index bf1809b0c..76e1d1010 100644 --- a/test/date.t.cpp +++ b/test/date.t.cpp @@ -36,7 +36,7 @@ Context context; //////////////////////////////////////////////////////////////////////////////// int main (int argc, char** argv) { - UnitTest t (211); + UnitTest t (203); // Ensure environment has no influence. unsetenv ("TASKDATA"); @@ -268,24 +268,6 @@ int main (int argc, char** argv) t.is (Date ("5/1/2011", "m/d/Y").dayOfYear (), 121, "dayOfYear (5/1/2011) -> 121"); t.is (Date ("12/31/2011", "m/d/Y").dayOfYear (), 365, "dayOfYear (12/31/2011) -> 365"); - // Easter - Date e1 (Date::easter(1980)); - t.is (e1.toString (), "4/6/1980", "Easter 4/6/1980"); - Date e2 (Date::easter(1995)); - t.is (e2.toString (), "4/16/1995", "Easter 4/16/1995"); - Date e3 (Date::easter(2000)); - t.is (e3.toString (), "4/23/2000", "Easter 4/23/2000"); - Date e4 (Date::easter(2009)); - t.is (e4.toString (), "4/12/2009", "Easter 4/12/2009"); - Date e5 (Date::easter(2010)); - t.is (e5.toString (), "4/4/2010", "Easter 4/4/2010"); - Date e6 (Date::easter(2011)); - t.is (e6.toString (), "4/24/2011", "Easter 4/24/2011"); - Date e7 (Date::easter(2012)); - t.is (e7.toString (), "4/8/2012", "Easter 4/8/2012"); - Date e8 (Date::easter(2020)); - t.is (e8.toString (), "4/12/2020", "Easter 4/12/2020"); - // Relative dates. Date r1 ("today"); t.ok (r1.sameDay (now), "today = now"); From 91588c7e96913629cd0e8560438c7ed440e59c8a Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sat, 26 Sep 2015 13:29:31 -0400 Subject: [PATCH 012/117] ISO8601: Added static ::dayOfWeek --- src/ISO8601.cpp | 19 +++++++++++++++++++ src/ISO8601.h | 2 ++ 2 files changed, 21 insertions(+) diff --git a/src/ISO8601.cpp b/src/ISO8601.cpp index 0179b2789..014d579ca 100644 --- a/src/ISO8601.cpp +++ b/src/ISO8601.cpp @@ -30,6 +30,7 @@ #include #include #include +#include #include #define DAY 86400 @@ -796,6 +797,24 @@ bool ISO8601p::parse (const std::string& input, std::string::size_type& start) return false; } +//////////////////////////////////////////////////////////////////////////////// +// Static +int ISO8601d::dayOfWeek (const std::string& input) +{ + if (ISO8601d::minimumMatchLength== 0) + minimumMatchLength= 3; + + if (closeEnough (STRING_DATE_SUNDAY, input, minimumMatchLength)) return 0; + else if (closeEnough (STRING_DATE_MONDAY, input, minimumMatchLength)) return 1; + else if (closeEnough (STRING_DATE_TUESDAY, input, minimumMatchLength)) return 2; + else if (closeEnough (STRING_DATE_WEDNESDAY, input, minimumMatchLength)) return 3; + else if (closeEnough (STRING_DATE_THURSDAY, input, minimumMatchLength)) return 4; + else if (closeEnough (STRING_DATE_FRIDAY, input, minimumMatchLength)) return 5; + else if (closeEnough (STRING_DATE_SATURDAY, input, minimumMatchLength)) return 6; + + return -1; +} + //////////////////////////////////////////////////////////////////////////////// void ISO8601p::clear () { diff --git a/src/ISO8601.h b/src/ISO8601.h index 80aeabc8f..b6df2aed4 100644 --- a/src/ISO8601.h +++ b/src/ISO8601.h @@ -44,6 +44,8 @@ public: operator time_t () const; bool parse (const std::string&, std::string::size_type&, const std::string& format = ""); + static int dayOfWeek (const std::string&); + private: void clear (); bool parse_date_time (Nibbler&); From 9962c14de2c6757a06375cd33644c33abc0ce9eb Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sat, 26 Sep 2015 13:33:41 -0400 Subject: [PATCH 013/117] Test: Added test for ISO8601d::dayOfWeek --- test/iso8601d.t.cpp | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/test/iso8601d.t.cpp b/test/iso8601d.t.cpp index 0238a2ac8..8baab02a5 100644 --- a/test/iso8601d.t.cpp +++ b/test/iso8601d.t.cpp @@ -71,7 +71,7 @@ void testParse ( //////////////////////////////////////////////////////////////////////////////// int main (int argc, char** argv) { - UnitTest t (758); + UnitTest t (767); ISO8601d iso; std::string::size_type start = 0; @@ -216,6 +216,25 @@ int main (int argc, char** argv) testParse (t, "20131206T123456Z", 16, 2013, 12, 0, 0, 0, 6, hms, 0, true, utc6+hms ); testParse (t, "20131206T123456", 15, 2013, 12, 0, 0, 0, 6, hms, 0, false, local6+hms); + try + { + t.is (ISO8601d::dayOfWeek ("SUNDAY"), 0, "SUNDAY == 0"); + t.is (ISO8601d::dayOfWeek ("sunday"), 0, "sunday == 0"); + t.is (ISO8601d::dayOfWeek ("Sunday"), 0, "Sunday == 0"); + t.is (ISO8601d::dayOfWeek ("Monday"), 1, "Monday == 1"); + t.is (ISO8601d::dayOfWeek ("Tuesday"), 2, "Tuesday == 2"); + t.is (ISO8601d::dayOfWeek ("Wednesday"), 3, "Wednesday == 3"); + t.is (ISO8601d::dayOfWeek ("Thursday"), 4, "Thursday == 4"); + t.is (ISO8601d::dayOfWeek ("Friday"), 5, "Friday == 5"); + t.is (ISO8601d::dayOfWeek ("Saturday"), 6, "Saturday == 6"); + } + + catch (const std::string& e) + { + t.fail ("Exception thrown."); + t.diag (e); + } + return 0; } From f615db8a4cd75c4081faecba85ad963e9dc8eafd Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sat, 26 Sep 2015 13:38:32 -0400 Subject: [PATCH 014/117] ISO8601d: Added ::length and tests --- src/ISO8601.cpp | 38 ++++++++++++++++++++++++++++++++++++++ src/ISO8601.h | 2 ++ test/iso8601d.t.cpp | 26 +++++++++++++++++++++++++- 3 files changed, 65 insertions(+), 1 deletion(-) diff --git a/src/ISO8601.cpp b/src/ISO8601.cpp index 014d579ca..d6d16b203 100644 --- a/src/ISO8601.cpp +++ b/src/ISO8601.cpp @@ -31,6 +31,7 @@ #include #include #include +#include #include #define DAY 86400 @@ -815,6 +816,43 @@ int ISO8601d::dayOfWeek (const std::string& input) return -1; } +//////////////////////////////////////////////////////////////////////////////// +int ISO8601d::length (const std::string& format) +{ + int len = 0; + for (auto& i : format) + { + switch (i) + { + case 'm': + case 'M': + case 'd': + case 'D': + case 'y': + case 'v': + case 'V': + case 'h': + case 'H': + case 'n': + case 'N': + case 's': + case 'S': len += 2; break; + case 'b': + case 'j': + case 'J': + case 'a': len += 3; break; + case 'Y': len += 4; break; + case 'A': + case 'B': len += 10; break; + + // Calculate the width, don't assume a single character width. + default: len += mk_wcwidth (i); break; + } + } + + return len; +} + //////////////////////////////////////////////////////////////////////////////// void ISO8601p::clear () { diff --git a/src/ISO8601.h b/src/ISO8601.h index b6df2aed4..0038b2552 100644 --- a/src/ISO8601.h +++ b/src/ISO8601.h @@ -46,6 +46,8 @@ public: static int dayOfWeek (const std::string&); + static int length (const std::string&); + private: void clear (); bool parse_date_time (Nibbler&); diff --git a/test/iso8601d.t.cpp b/test/iso8601d.t.cpp index 8baab02a5..dbd1f2712 100644 --- a/test/iso8601d.t.cpp +++ b/test/iso8601d.t.cpp @@ -71,7 +71,7 @@ void testParse ( //////////////////////////////////////////////////////////////////////////////// int main (int argc, char** argv) { - UnitTest t (767); + UnitTest t (788); ISO8601d iso; std::string::size_type start = 0; @@ -227,6 +227,30 @@ int main (int argc, char** argv) t.is (ISO8601d::dayOfWeek ("Thursday"), 4, "Thursday == 4"); t.is (ISO8601d::dayOfWeek ("Friday"), 5, "Friday == 5"); t.is (ISO8601d::dayOfWeek ("Saturday"), 6, "Saturday == 6"); + + // int ISO8601d::length (const std::string&); + t.is (ISO8601d::length ("m"), 2, "length 'm' --> 2"); + t.is (ISO8601d::length ("M"), 2, "length 'M' --> 2"); + t.is (ISO8601d::length ("d"), 2, "length 'd' --> 2"); + t.is (ISO8601d::length ("D"), 2, "length 'D' --> 2"); + t.is (ISO8601d::length ("y"), 2, "length 'y' --> 2"); + t.is (ISO8601d::length ("Y"), 4, "length 'Y' --> 4"); + t.is (ISO8601d::length ("a"), 3, "length 'a' --> 3"); + t.is (ISO8601d::length ("A"), 10, "length 'A' --> 10"); + t.is (ISO8601d::length ("b"), 3, "length 'b' --> 3"); + t.is (ISO8601d::length ("B"), 10, "length 'B' --> 10"); + t.is (ISO8601d::length ("v"), 2, "length 'v' --> 2"); + t.is (ISO8601d::length ("V"), 2, "length 'V' --> 2"); + t.is (ISO8601d::length ("h"), 2, "length 'h' --> 2"); + t.is (ISO8601d::length ("H"), 2, "length 'H' --> 2"); + t.is (ISO8601d::length ("n"), 2, "length 'n' --> 2"); + t.is (ISO8601d::length ("N"), 2, "length 'N' --> 2"); + t.is (ISO8601d::length ("s"), 2, "length 's' --> 2"); + t.is (ISO8601d::length ("S"), 2, "length 'S' --> 2"); + t.is (ISO8601d::length ("j"), 3, "length 'j' --> 3"); + t.is (ISO8601d::length ("J"), 3, "length 'J' --> 3"); + + t.is (ISO8601d::length (" "), 1, "length ' ' --> 1"); } catch (const std::string& e) From 6f5d07dcd4ce070cfc295c90808d3fedfaec9d92 Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sat, 26 Sep 2015 13:47:27 -0400 Subject: [PATCH 015/117] ISO8601d: Added ::leapYear and tests --- src/ISO8601.cpp | 9 +++++++++ src/ISO8601.h | 2 ++ test/iso8601d.t.cpp | 8 +++++++- 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/ISO8601.cpp b/src/ISO8601.cpp index d6d16b203..71671072c 100644 --- a/src/ISO8601.cpp +++ b/src/ISO8601.cpp @@ -798,6 +798,14 @@ bool ISO8601p::parse (const std::string& input, std::string::size_type& start) return false; } +//////////////////////////////////////////////////////////////////////////////// +// Static +bool ISO8601d::leapYear (int year) +{ + return ((! (year % 4)) && (year % 100)) || + ! (year % 400); +} + //////////////////////////////////////////////////////////////////////////////// // Static int ISO8601d::dayOfWeek (const std::string& input) @@ -817,6 +825,7 @@ int ISO8601d::dayOfWeek (const std::string& input) } //////////////////////////////////////////////////////////////////////////////// +// Static int ISO8601d::length (const std::string& format) { int len = 0; diff --git a/src/ISO8601.h b/src/ISO8601.h index 0038b2552..2ee9b0432 100644 --- a/src/ISO8601.h +++ b/src/ISO8601.h @@ -44,6 +44,8 @@ public: operator time_t () const; bool parse (const std::string&, std::string::size_type&, const std::string& format = ""); + static bool leapYear (int); + static int dayOfWeek (const std::string&); static int length (const std::string&); diff --git a/test/iso8601d.t.cpp b/test/iso8601d.t.cpp index dbd1f2712..bdf3682f0 100644 --- a/test/iso8601d.t.cpp +++ b/test/iso8601d.t.cpp @@ -71,7 +71,7 @@ void testParse ( //////////////////////////////////////////////////////////////////////////////// int main (int argc, char** argv) { - UnitTest t (788); + UnitTest t (792); ISO8601d iso; std::string::size_type start = 0; @@ -218,6 +218,12 @@ int main (int argc, char** argv) try { + // Leap year. + t.ok (ISO8601d::leapYear (2008), "2008 is a leap year"); + t.notok (ISO8601d::leapYear (2007), "2007 is not a leap year"); + t.ok (ISO8601d::leapYear (2000), "2000 is a leap year"); + t.notok (ISO8601d::leapYear (1900), "1900 is not a leap year"); + t.is (ISO8601d::dayOfWeek ("SUNDAY"), 0, "SUNDAY == 0"); t.is (ISO8601d::dayOfWeek ("sunday"), 0, "sunday == 0"); t.is (ISO8601d::dayOfWeek ("Sunday"), 0, "Sunday == 0"); From d8eb0ac0da4e40a34ed600b84b426bfb9e680505 Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sat, 26 Sep 2015 13:52:43 -0400 Subject: [PATCH 016/117] ISO8601d: Added ::daysInMonth and tests --- src/ISO8601.cpp | 12 ++++++++++++ src/ISO8601.h | 1 + test/iso8601d.t.cpp | 6 +++++- 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/ISO8601.cpp b/src/ISO8601.cpp index 71671072c..2a6ef6ddc 100644 --- a/src/ISO8601.cpp +++ b/src/ISO8601.cpp @@ -806,6 +806,18 @@ bool ISO8601d::leapYear (int year) ! (year % 400); } +//////////////////////////////////////////////////////////////////////////////// +// Static +int ISO8601d::daysInMonth (int month, int year) +{ + static int days[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; + + if (month == 2 && ISO8601d::leapYear (year)) + return 29; + + return days[month - 1]; +} + //////////////////////////////////////////////////////////////////////////////// // Static int ISO8601d::dayOfWeek (const std::string& input) diff --git a/src/ISO8601.h b/src/ISO8601.h index 2ee9b0432..34669e9af 100644 --- a/src/ISO8601.h +++ b/src/ISO8601.h @@ -45,6 +45,7 @@ public: bool parse (const std::string&, std::string::size_type&, const std::string& format = ""); static bool leapYear (int); + static int daysInMonth (int, int); static int dayOfWeek (const std::string&); diff --git a/test/iso8601d.t.cpp b/test/iso8601d.t.cpp index bdf3682f0..b3a5bd60d 100644 --- a/test/iso8601d.t.cpp +++ b/test/iso8601d.t.cpp @@ -71,7 +71,7 @@ void testParse ( //////////////////////////////////////////////////////////////////////////////// int main (int argc, char** argv) { - UnitTest t (792); + UnitTest t (794); ISO8601d iso; std::string::size_type start = 0; @@ -224,6 +224,10 @@ int main (int argc, char** argv) t.ok (ISO8601d::leapYear (2000), "2000 is a leap year"); t.notok (ISO8601d::leapYear (1900), "1900 is not a leap year"); + // Days in month. + t.is (ISO8601d::daysInMonth (2, 2008), 29, "29 days in February 2008"); + t.is (ISO8601d::daysInMonth (2, 2007), 28, "28 days in February 2007"); + t.is (ISO8601d::dayOfWeek ("SUNDAY"), 0, "SUNDAY == 0"); t.is (ISO8601d::dayOfWeek ("sunday"), 0, "sunday == 0"); t.is (ISO8601d::dayOfWeek ("Sunday"), 0, "Sunday == 0"); From 965415d7a48373be672e96d696538198bb840b76 Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sat, 26 Sep 2015 13:57:10 -0400 Subject: [PATCH 017/117] ISO8601d: Added ::daysInYear and tests --- src/ISO8601.cpp | 7 +++++++ src/ISO8601.h | 1 + test/iso8601d.t.cpp | 6 +++++- 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/ISO8601.cpp b/src/ISO8601.cpp index 2a6ef6ddc..a8ef2e6e6 100644 --- a/src/ISO8601.cpp +++ b/src/ISO8601.cpp @@ -818,6 +818,13 @@ int ISO8601d::daysInMonth (int month, int year) return days[month - 1]; } +//////////////////////////////////////////////////////////////////////////////// +// Static +int ISO8601d::daysInYear (int year) +{ + return ISO8601d::leapYear (year) ? 366 : 365; +} + //////////////////////////////////////////////////////////////////////////////// // Static int ISO8601d::dayOfWeek (const std::string& input) diff --git a/src/ISO8601.h b/src/ISO8601.h index 34669e9af..ff083ce05 100644 --- a/src/ISO8601.h +++ b/src/ISO8601.h @@ -46,6 +46,7 @@ public: static bool leapYear (int); static int daysInMonth (int, int); + static int daysInYear (int); static int dayOfWeek (const std::string&); diff --git a/test/iso8601d.t.cpp b/test/iso8601d.t.cpp index b3a5bd60d..98f2433e0 100644 --- a/test/iso8601d.t.cpp +++ b/test/iso8601d.t.cpp @@ -71,7 +71,7 @@ void testParse ( //////////////////////////////////////////////////////////////////////////////// int main (int argc, char** argv) { - UnitTest t (794); + UnitTest t (796); ISO8601d iso; std::string::size_type start = 0; @@ -224,6 +224,10 @@ int main (int argc, char** argv) t.ok (ISO8601d::leapYear (2000), "2000 is a leap year"); t.notok (ISO8601d::leapYear (1900), "1900 is not a leap year"); + // Days in year. + t.is (ISO8601d::daysInYear (2016), 366, "366 days in 2016"); + t.is (ISO8601d::daysInYear (2015), 365, "365 days in 2015"); + // Days in month. t.is (ISO8601d::daysInMonth (2, 2008), 29, "29 days in February 2008"); t.is (ISO8601d::daysInMonth (2, 2007), 28, "28 days in February 2007"); From 0d6788635ec21c7c46b872e47010a9fc4f9c61a2 Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sat, 26 Sep 2015 14:02:26 -0400 Subject: [PATCH 018/117] ISO8601d: Added ::monthName and tests --- src/ISO8601.cpp | 25 +++++++++++++++++++++++++ src/ISO8601.h | 1 + test/iso8601d.t.cpp | 16 +++++++++++++++- 3 files changed, 41 insertions(+), 1 deletion(-) diff --git a/src/ISO8601.cpp b/src/ISO8601.cpp index a8ef2e6e6..df30ac7e7 100644 --- a/src/ISO8601.cpp +++ b/src/ISO8601.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -825,6 +826,30 @@ int ISO8601d::daysInYear (int year) return ISO8601d::leapYear (year) ? 366 : 365; } +//////////////////////////////////////////////////////////////////////////////// +std::string ISO8601d::monthName (int month) +{ + static const char* months[12] = + { + STRING_DATE_JANUARY, + STRING_DATE_FEBRUARY, + STRING_DATE_MARCH, + STRING_DATE_APRIL, + STRING_DATE_MAY, + STRING_DATE_JUNE, + STRING_DATE_JULY, + STRING_DATE_AUGUST, + STRING_DATE_SEPTEMBER, + STRING_DATE_OCTOBER, + STRING_DATE_NOVEMBER, + STRING_DATE_DECEMBER, + }; + + assert (month > 0); + assert (month <= 12); + return ucFirst (months[month - 1]); +} + //////////////////////////////////////////////////////////////////////////////// // Static int ISO8601d::dayOfWeek (const std::string& input) diff --git a/src/ISO8601.h b/src/ISO8601.h index ff083ce05..d82a9895b 100644 --- a/src/ISO8601.h +++ b/src/ISO8601.h @@ -47,6 +47,7 @@ public: static bool leapYear (int); static int daysInMonth (int, int); static int daysInYear (int); + static std::string monthName (int); static int dayOfWeek (const std::string&); diff --git a/test/iso8601d.t.cpp b/test/iso8601d.t.cpp index 98f2433e0..61aaad248 100644 --- a/test/iso8601d.t.cpp +++ b/test/iso8601d.t.cpp @@ -71,7 +71,7 @@ void testParse ( //////////////////////////////////////////////////////////////////////////////// int main (int argc, char** argv) { - UnitTest t (796); + UnitTest t (808); ISO8601d iso; std::string::size_type start = 0; @@ -232,6 +232,20 @@ int main (int argc, char** argv) t.is (ISO8601d::daysInMonth (2, 2008), 29, "29 days in February 2008"); t.is (ISO8601d::daysInMonth (2, 2007), 28, "28 days in February 2007"); + // Names. + t.is (ISO8601d::monthName (1), "January", "1 = January"); + t.is (ISO8601d::monthName (2), "February", "2 = February"); + t.is (ISO8601d::monthName (3), "March", "3 = March"); + t.is (ISO8601d::monthName (4), "April", "4 = April"); + t.is (ISO8601d::monthName (5), "May", "5 = May"); + t.is (ISO8601d::monthName (6), "June", "6 = June"); + t.is (ISO8601d::monthName (7), "July", "7 = July"); + t.is (ISO8601d::monthName (8), "August", "8 = August"); + t.is (ISO8601d::monthName (9), "September", "9 = September"); + t.is (ISO8601d::monthName (10), "October", "10 = October"); + t.is (ISO8601d::monthName (11), "November", "11 = November"); + t.is (ISO8601d::monthName (12), "December", "12 = December"); + t.is (ISO8601d::dayOfWeek ("SUNDAY"), 0, "SUNDAY == 0"); t.is (ISO8601d::dayOfWeek ("sunday"), 0, "sunday == 0"); t.is (ISO8601d::dayOfWeek ("Sunday"), 0, "Sunday == 0"); From 86df4385792725f6f9e1240d3bf276a3064829be Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sat, 26 Sep 2015 14:08:50 -0400 Subject: [PATCH 019/117] CmdBurndown: Converted from Date::daysInMonth to ISO8601d::daysInMonth --- src/commands/CmdBurndown.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/commands/CmdBurndown.cpp b/src/commands/CmdBurndown.cpp index 54c51194c..9ea606b5c 100644 --- a/src/commands/CmdBurndown.cpp +++ b/src/commands/CmdBurndown.cpp @@ -630,7 +630,7 @@ Date Chart::increment (const Date& input) switch (_period) { case 'D': - if (++d > Date::daysInMonth (m, y)) + if (++d > ISO8601d::daysInMonth (m, y)) { d = 1; @@ -644,7 +644,7 @@ Date Chart::increment (const Date& input) case 'W': d += 7; - days = Date::daysInMonth (m, y); + days = ISO8601d::daysInMonth (m, y); if (d > days) { d -= days; @@ -689,7 +689,7 @@ Date Chart::decrement (const Date& input) --y; } - d = Date::daysInMonth (m, y); + d = ISO8601d::daysInMonth (m, y); } break; @@ -703,7 +703,7 @@ Date Chart::decrement (const Date& input) y--; } - d += Date::daysInMonth (m, y); + d += ISO8601d::daysInMonth (m, y); } break; From 18804a743c1418dfa4dc90c8a55d1c909cacd7bb Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sat, 26 Sep 2015 14:09:51 -0400 Subject: [PATCH 020/117] CmdCalendar: Converted from Date::daysInMonth to ISO8601d::daysInMonth --- src/commands/CmdCalendar.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/commands/CmdCalendar.cpp b/src/commands/CmdCalendar.cpp index 8b47fd193..d137daa3a 100644 --- a/src/commands/CmdCalendar.cpp +++ b/src/commands/CmdCalendar.cpp @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -317,7 +318,7 @@ int CmdCalendar::execute (std::string& output) details_mFrom = 12; --details_yFrom; } - int details_dFrom = Date::daysInMonth (details_mFrom, details_yFrom); + int details_dFrom = ISO8601d::daysInMonth (details_mFrom, details_yFrom); ++mTo; if (mTo == 13) @@ -487,7 +488,7 @@ std::string CmdCalendar::renderMonths ( years.push_back (++thisYear); } months.push_back (thisMonth); - daysInMonth.push_back (Date::daysInMonth (thisMonth++, thisYear)); + daysInMonth.push_back (ISO8601d::daysInMonth (thisMonth++, thisYear)); } int row = 0; From d351c9faf24166edfa957cafe2a807b9bc0f35e4 Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sat, 26 Sep 2015 14:12:23 -0400 Subject: [PATCH 021/117] Dates: Converted from Date::daysInMonth to ISO8601d::daysInMonth --- src/Dates.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Dates.cpp b/src/Dates.cpp index a4bb15228..14a8b0b7c 100644 --- a/src/Dates.cpp +++ b/src/Dates.cpp @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -302,7 +303,7 @@ bool namedDates (const std::string& name, Variant& value) t->tm_hour = 24; t->tm_min = 0; t->tm_sec = -1; - t->tm_mday = Date::daysInMonth (t->tm_mon + 1, t->tm_year + 1900); + t->tm_mday = ISO8601d::daysInMonth (t->tm_mon + 1, t->tm_year + 1900); t->tm_isdst = -1; value = Variant (mktime (t), Variant::type_date); } @@ -414,7 +415,7 @@ bool namedDates (const std::string& name, Variant& value) // If it is this month. if (d < number && - number <= Date::daysInMonth (m, y)) + number <= ISO8601d::daysInMonth (m, y)) { t->tm_hour = t->tm_min = t->tm_sec = 0; t->tm_mon = m - 1; From 24ff570427f10f194862a8694208c4e5ab18870d Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sat, 26 Sep 2015 14:16:38 -0400 Subject: [PATCH 022/117] ISO8601d: Added ::month --- src/ISO8601.cpp | 7 +++++++ src/ISO8601.h | 2 ++ 2 files changed, 9 insertions(+) diff --git a/src/ISO8601.cpp b/src/ISO8601.cpp index df30ac7e7..c8c1631cb 100644 --- a/src/ISO8601.cpp +++ b/src/ISO8601.cpp @@ -906,6 +906,13 @@ int ISO8601d::length (const std::string& format) return len; } +//////////////////////////////////////////////////////////////////////////////// +int ISO8601d::month () const +{ + struct tm* t = localtime (&_date); + return t->tm_mon + 1; +} + //////////////////////////////////////////////////////////////////////////////// void ISO8601p::clear () { diff --git a/src/ISO8601.h b/src/ISO8601.h index d82a9895b..466e40d7e 100644 --- a/src/ISO8601.h +++ b/src/ISO8601.h @@ -53,6 +53,8 @@ public: static int length (const std::string&); + int month () const; + private: void clear (); bool parse_date_time (Nibbler&); From 17185c79117b5e34b564c340236eda0caa2ddb28 Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sat, 26 Sep 2015 14:18:54 -0400 Subject: [PATCH 023/117] ISO8601d: Added ::week --- src/ISO8601.cpp | 6 ++++++ src/ISO8601.h | 1 + 2 files changed, 7 insertions(+) diff --git a/src/ISO8601.cpp b/src/ISO8601.cpp index c8c1631cb..881ca3849 100644 --- a/src/ISO8601.cpp +++ b/src/ISO8601.cpp @@ -913,6 +913,12 @@ int ISO8601d::month () const return t->tm_mon + 1; } +//////////////////////////////////////////////////////////////////////////////// +int ISO8601d::week () const +{ + return ISO8601d::weekOfYear (ISO8601d::dayOfWeek (ISO8601d::weekstart)); +} + //////////////////////////////////////////////////////////////////////////////// void ISO8601p::clear () { diff --git a/src/ISO8601.h b/src/ISO8601.h index 466e40d7e..9889da8fd 100644 --- a/src/ISO8601.h +++ b/src/ISO8601.h @@ -54,6 +54,7 @@ public: static int length (const std::string&); int month () const; + int week () const; private: void clear (); From eeac423fd6fd7428275279c6689a76388fcb8818 Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sat, 26 Sep 2015 14:20:32 -0400 Subject: [PATCH 024/117] ISO8601d: Added ::day --- src/ISO8601.cpp | 7 +++++++ src/ISO8601.h | 1 + 2 files changed, 8 insertions(+) diff --git a/src/ISO8601.cpp b/src/ISO8601.cpp index 881ca3849..e01df077b 100644 --- a/src/ISO8601.cpp +++ b/src/ISO8601.cpp @@ -919,6 +919,13 @@ int ISO8601d::week () const return ISO8601d::weekOfYear (ISO8601d::dayOfWeek (ISO8601d::weekstart)); } +//////////////////////////////////////////////////////////////////////////////// +int ISO8601d::day () const +{ + struct tm* t = localtime (&_date); + return t->tm_mday; +} + //////////////////////////////////////////////////////////////////////////////// void ISO8601p::clear () { diff --git a/src/ISO8601.h b/src/ISO8601.h index 9889da8fd..4e6e9a72d 100644 --- a/src/ISO8601.h +++ b/src/ISO8601.h @@ -55,6 +55,7 @@ public: int month () const; int week () const; + int day () const; private: void clear (); From af81b24d9252da76b33988f310146b99ca814b6d Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sat, 26 Sep 2015 14:21:42 -0400 Subject: [PATCH 025/117] ISO8601d: Added ::year --- src/ISO8601.cpp | 7 +++++++ src/ISO8601.h | 1 + 2 files changed, 8 insertions(+) diff --git a/src/ISO8601.cpp b/src/ISO8601.cpp index e01df077b..b1ca9eedf 100644 --- a/src/ISO8601.cpp +++ b/src/ISO8601.cpp @@ -926,6 +926,13 @@ int ISO8601d::day () const return t->tm_mday; } +//////////////////////////////////////////////////////////////////////////////// +int ISO8601d::year () const +{ + struct tm* t = localtime (&_date); + return t->tm_year + 1900; +} + //////////////////////////////////////////////////////////////////////////////// void ISO8601p::clear () { diff --git a/src/ISO8601.h b/src/ISO8601.h index 4e6e9a72d..3563bd5b8 100644 --- a/src/ISO8601.h +++ b/src/ISO8601.h @@ -56,6 +56,7 @@ public: int month () const; int week () const; int day () const; + int year () const; private: void clear (); From 66dc016ce6658d51443b094fbff60bbf3370dddb Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sat, 26 Sep 2015 14:22:37 -0400 Subject: [PATCH 026/117] ISO8601d: Added ::weekOfYear --- src/ISO8601.cpp | 21 +++++++++++++++++++++ src/ISO8601.h | 1 + 2 files changed, 22 insertions(+) diff --git a/src/ISO8601.cpp b/src/ISO8601.cpp index b1ca9eedf..d9ef406f3 100644 --- a/src/ISO8601.cpp +++ b/src/ISO8601.cpp @@ -933,6 +933,27 @@ int ISO8601d::year () const return t->tm_year + 1900; } +//////////////////////////////////////////////////////////////////////////////// +int ISO8601d::weekOfYear (int weekStart) const +{ + struct tm* t = localtime (&_date); + char weekStr[3]; + + if (weekStart == 0) + strftime(weekStr, sizeof(weekStr), "%U", t); + else if (weekStart == 1) + strftime(weekStr, sizeof(weekStr), "%V", t); + else + throw std::string (STRING_DATE_BAD_WEEKSTART); + + int weekNumber = atoi (weekStr); + + if (weekStart == 0) + weekNumber += 1; + + return weekNumber; +} + //////////////////////////////////////////////////////////////////////////////// void ISO8601p::clear () { diff --git a/src/ISO8601.h b/src/ISO8601.h index 3563bd5b8..db35dff1d 100644 --- a/src/ISO8601.h +++ b/src/ISO8601.h @@ -57,6 +57,7 @@ public: int week () const; int day () const; int year () const; + int weekOfYear (int) const; private: void clear (); From ac428e1f1a3ee6b4cfa5eba887322083b2b08330 Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sat, 26 Sep 2015 14:23:41 -0400 Subject: [PATCH 027/117] ISO8601d: Added ::dayOfWeek --- src/ISO8601.cpp | 7 +++++++ src/ISO8601.h | 1 + 2 files changed, 8 insertions(+) diff --git a/src/ISO8601.cpp b/src/ISO8601.cpp index d9ef406f3..3985b34a7 100644 --- a/src/ISO8601.cpp +++ b/src/ISO8601.cpp @@ -954,6 +954,13 @@ int ISO8601d::weekOfYear (int weekStart) const return weekNumber; } +//////////////////////////////////////////////////////////////////////////////// +int ISO8601d::dayOfWeek () const +{ + struct tm* t = localtime (&_date); + return t->tm_wday; +} + //////////////////////////////////////////////////////////////////////////////// void ISO8601p::clear () { diff --git a/src/ISO8601.h b/src/ISO8601.h index db35dff1d..9830c7177 100644 --- a/src/ISO8601.h +++ b/src/ISO8601.h @@ -58,6 +58,7 @@ public: int day () const; int year () const; int weekOfYear (int) const; + int dayOfWeek () const; private: void clear (); From 5ed0d131946d5d2b857e23b0e663538354b4632d Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sat, 26 Sep 2015 14:24:33 -0400 Subject: [PATCH 028/117] ISO8601d: Added ::dayOfYear --- src/ISO8601.cpp | 7 +++++++ src/ISO8601.h | 1 + 2 files changed, 8 insertions(+) diff --git a/src/ISO8601.cpp b/src/ISO8601.cpp index 3985b34a7..ad98d530d 100644 --- a/src/ISO8601.cpp +++ b/src/ISO8601.cpp @@ -961,6 +961,13 @@ int ISO8601d::dayOfWeek () const return t->tm_wday; } +//////////////////////////////////////////////////////////////////////////////// +int ISO8601d::dayOfYear () const +{ + struct tm* t = localtime (&_date); + return t->tm_yday + 1; +} + //////////////////////////////////////////////////////////////////////////////// void ISO8601p::clear () { diff --git a/src/ISO8601.h b/src/ISO8601.h index 9830c7177..8e585a2ed 100644 --- a/src/ISO8601.h +++ b/src/ISO8601.h @@ -59,6 +59,7 @@ public: int year () const; int weekOfYear (int) const; int dayOfWeek () const; + int dayOfYear () const; private: void clear (); From 7164215146642506df11a6bdf3153d5cd96acc2d Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sat, 26 Sep 2015 14:25:19 -0400 Subject: [PATCH 029/117] ISO8601d: Added ::hour, ::minute, ::second --- src/ISO8601.cpp | 21 +++++++++++++++++++++ src/ISO8601.h | 3 +++ 2 files changed, 24 insertions(+) diff --git a/src/ISO8601.cpp b/src/ISO8601.cpp index ad98d530d..8c18568c3 100644 --- a/src/ISO8601.cpp +++ b/src/ISO8601.cpp @@ -968,6 +968,27 @@ int ISO8601d::dayOfYear () const return t->tm_yday + 1; } +//////////////////////////////////////////////////////////////////////////////// +int ISO8601d::hour () const +{ + struct tm* t = localtime (&_date); + return t->tm_hour; +} + +//////////////////////////////////////////////////////////////////////////////// +int ISO8601d::minute () const +{ + struct tm* t = localtime (&_date); + return t->tm_min; +} + +//////////////////////////////////////////////////////////////////////////////// +int ISO8601d::second () const +{ + struct tm* t = localtime (&_date); + return t->tm_sec; +} + //////////////////////////////////////////////////////////////////////////////// void ISO8601p::clear () { diff --git a/src/ISO8601.h b/src/ISO8601.h index 8e585a2ed..9c489f54a 100644 --- a/src/ISO8601.h +++ b/src/ISO8601.h @@ -60,6 +60,9 @@ public: int weekOfYear (int) const; int dayOfWeek () const; int dayOfYear () const; + int hour () const; + int minute () const; + int second () const; private: void clear (); From f26cff9a4a8bcd0dbb3937ea7c45ce385bb4797a Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sat, 26 Sep 2015 14:32:14 -0400 Subject: [PATCH 030/117] ISO8601d: Added :dayName methods and tests --- src/ISO8601.cpp | 34 ++++++++++++++++++++++++++++++++++ src/ISO8601.h | 2 ++ test/iso8601d.t.cpp | 10 +++++++++- 3 files changed, 45 insertions(+), 1 deletion(-) diff --git a/src/ISO8601.cpp b/src/ISO8601.cpp index 8c18568c3..a3e2cbd3d 100644 --- a/src/ISO8601.cpp +++ b/src/ISO8601.cpp @@ -850,6 +850,40 @@ std::string ISO8601d::monthName (int month) return ucFirst (months[month - 1]); } +//////////////////////////////////////////////////////////////////////////////// +void ISO8601d::dayName (int dow, std::string& name) +{ + static const char* days[7] = + { + STRING_DATE_SUNDAY, + STRING_DATE_MONDAY, + STRING_DATE_TUESDAY, + STRING_DATE_WEDNESDAY, + STRING_DATE_THURSDAY, + STRING_DATE_FRIDAY, + STRING_DATE_SATURDAY, + }; + + name = ucFirst (days[dow]); +} + +//////////////////////////////////////////////////////////////////////////////// +std::string ISO8601d::dayName (int dow) +{ + static const char* days[7] = + { + STRING_DATE_SUNDAY, + STRING_DATE_MONDAY, + STRING_DATE_TUESDAY, + STRING_DATE_WEDNESDAY, + STRING_DATE_THURSDAY, + STRING_DATE_FRIDAY, + STRING_DATE_SATURDAY, + }; + + return ucFirst (days[dow]); +} + //////////////////////////////////////////////////////////////////////////////// // Static int ISO8601d::dayOfWeek (const std::string& input) diff --git a/src/ISO8601.h b/src/ISO8601.h index 9c489f54a..45027d06d 100644 --- a/src/ISO8601.h +++ b/src/ISO8601.h @@ -48,6 +48,8 @@ public: static int daysInMonth (int, int); static int daysInYear (int); static std::string monthName (int); + static void dayName (int, std::string&); + static std::string dayName (int); static int dayOfWeek (const std::string&); diff --git a/test/iso8601d.t.cpp b/test/iso8601d.t.cpp index 61aaad248..b3023af7e 100644 --- a/test/iso8601d.t.cpp +++ b/test/iso8601d.t.cpp @@ -71,7 +71,7 @@ void testParse ( //////////////////////////////////////////////////////////////////////////////// int main (int argc, char** argv) { - UnitTest t (808); + UnitTest t (815); ISO8601d iso; std::string::size_type start = 0; @@ -246,6 +246,14 @@ int main (int argc, char** argv) t.is (ISO8601d::monthName (11), "November", "11 = November"); t.is (ISO8601d::monthName (12), "December", "12 = December"); + t.is (ISO8601d::dayName (0), "Sunday", "0 == Sunday"); + t.is (ISO8601d::dayName (1), "Monday", "1 == Monday"); + t.is (ISO8601d::dayName (2), "Tuesday", "2 == Tuesday"); + t.is (ISO8601d::dayName (3), "Wednesday", "3 == Wednesday"); + t.is (ISO8601d::dayName (4), "Thursday", "4 == Thursday"); + t.is (ISO8601d::dayName (5), "Friday", "5 == Friday"); + t.is (ISO8601d::dayName (6), "Saturday", "6 == Saturday"); + t.is (ISO8601d::dayOfWeek ("SUNDAY"), 0, "SUNDAY == 0"); t.is (ISO8601d::dayOfWeek ("sunday"), 0, "sunday == 0"); t.is (ISO8601d::dayOfWeek ("Sunday"), 0, "Sunday == 0"); From ff320345e93505b7c5854f5bd6f15f234dfa02d1 Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sat, 26 Sep 2015 14:47:08 -0400 Subject: [PATCH 031/117] ISO8601: Added ::monthOfYear and tests --- src/ISO8601.cpp | 42 ++++++++++++++++++++++++++++++++++-------- src/ISO8601.h | 3 +-- test/iso8601d.t.cpp | 16 +++++++++++++++- 3 files changed, 50 insertions(+), 11 deletions(-) diff --git a/src/ISO8601.cpp b/src/ISO8601.cpp index a3e2cbd3d..ee7da3b87 100644 --- a/src/ISO8601.cpp +++ b/src/ISO8601.cpp @@ -827,6 +827,7 @@ int ISO8601d::daysInYear (int year) } //////////////////////////////////////////////////////////////////////////////// +// Static std::string ISO8601d::monthName (int month) { static const char* months[12] = @@ -851,6 +852,7 @@ std::string ISO8601d::monthName (int month) } //////////////////////////////////////////////////////////////////////////////// +// Static void ISO8601d::dayName (int dow, std::string& name) { static const char* days[7] = @@ -868,6 +870,7 @@ void ISO8601d::dayName (int dow, std::string& name) } //////////////////////////////////////////////////////////////////////////////// +// Static std::string ISO8601d::dayName (int dow) { static const char* days[7] = @@ -889,15 +892,38 @@ std::string ISO8601d::dayName (int dow) int ISO8601d::dayOfWeek (const std::string& input) { if (ISO8601d::minimumMatchLength== 0) - minimumMatchLength= 3; + ISO8601d::minimumMatchLength= 3; - if (closeEnough (STRING_DATE_SUNDAY, input, minimumMatchLength)) return 0; - else if (closeEnough (STRING_DATE_MONDAY, input, minimumMatchLength)) return 1; - else if (closeEnough (STRING_DATE_TUESDAY, input, minimumMatchLength)) return 2; - else if (closeEnough (STRING_DATE_WEDNESDAY, input, minimumMatchLength)) return 3; - else if (closeEnough (STRING_DATE_THURSDAY, input, minimumMatchLength)) return 4; - else if (closeEnough (STRING_DATE_FRIDAY, input, minimumMatchLength)) return 5; - else if (closeEnough (STRING_DATE_SATURDAY, input, minimumMatchLength)) return 6; + if (closeEnough (STRING_DATE_SUNDAY, input, ISO8601d::minimumMatchLength)) return 0; + else if (closeEnough (STRING_DATE_MONDAY, input, ISO8601d::minimumMatchLength)) return 1; + else if (closeEnough (STRING_DATE_TUESDAY, input, ISO8601d::minimumMatchLength)) return 2; + else if (closeEnough (STRING_DATE_WEDNESDAY, input, ISO8601d::minimumMatchLength)) return 3; + else if (closeEnough (STRING_DATE_THURSDAY, input, ISO8601d::minimumMatchLength)) return 4; + else if (closeEnough (STRING_DATE_FRIDAY, input, ISO8601d::minimumMatchLength)) return 5; + else if (closeEnough (STRING_DATE_SATURDAY, input, ISO8601d::minimumMatchLength)) return 6; + + return -1; +} + +//////////////////////////////////////////////////////////////////////////////// +// Static +int ISO8601d::monthOfYear (const std::string& input) +{ + if (ISO8601d::minimumMatchLength== 0) + ISO8601d::minimumMatchLength= 3; + + if (closeEnough (STRING_DATE_JANUARY, input, ISO8601d::minimumMatchLength)) return 1; + else if (closeEnough (STRING_DATE_FEBRUARY, input, ISO8601d::minimumMatchLength)) return 2; + else if (closeEnough (STRING_DATE_MARCH, input, ISO8601d::minimumMatchLength)) return 3; + else if (closeEnough (STRING_DATE_APRIL, input, ISO8601d::minimumMatchLength)) return 4; + else if (closeEnough (STRING_DATE_MAY, input, ISO8601d::minimumMatchLength)) return 5; + else if (closeEnough (STRING_DATE_JUNE, input, ISO8601d::minimumMatchLength)) return 6; + else if (closeEnough (STRING_DATE_JULY, input, ISO8601d::minimumMatchLength)) return 7; + else if (closeEnough (STRING_DATE_AUGUST, input, ISO8601d::minimumMatchLength)) return 8; + else if (closeEnough (STRING_DATE_SEPTEMBER, input, ISO8601d::minimumMatchLength)) return 9; + else if (closeEnough (STRING_DATE_OCTOBER, input, ISO8601d::minimumMatchLength)) return 10; + else if (closeEnough (STRING_DATE_NOVEMBER, input, ISO8601d::minimumMatchLength)) return 11; + else if (closeEnough (STRING_DATE_DECEMBER, input, ISO8601d::minimumMatchLength)) return 12; return -1; } diff --git a/src/ISO8601.h b/src/ISO8601.h index 45027d06d..e407e5603 100644 --- a/src/ISO8601.h +++ b/src/ISO8601.h @@ -50,9 +50,8 @@ public: static std::string monthName (int); static void dayName (int, std::string&); static std::string dayName (int); - static int dayOfWeek (const std::string&); - + static int monthOfYear (const std::string&); static int length (const std::string&); int month () const; diff --git a/test/iso8601d.t.cpp b/test/iso8601d.t.cpp index b3023af7e..1211fb5f9 100644 --- a/test/iso8601d.t.cpp +++ b/test/iso8601d.t.cpp @@ -71,7 +71,7 @@ void testParse ( //////////////////////////////////////////////////////////////////////////////// int main (int argc, char** argv) { - UnitTest t (815); + UnitTest t (827); ISO8601d iso; std::string::size_type start = 0; @@ -246,6 +246,20 @@ int main (int argc, char** argv) t.is (ISO8601d::monthName (11), "November", "11 = November"); t.is (ISO8601d::monthName (12), "December", "12 = December"); + // Names. + t.is (ISO8601d::monthOfYear ("January"), 1, "January = 1"); + t.is (ISO8601d::monthOfYear ("February"), 2, "February = 2"); + t.is (ISO8601d::monthOfYear ("March"), 3, "March = 3"); + t.is (ISO8601d::monthOfYear ("April"), 4, "April = 4"); + t.is (ISO8601d::monthOfYear ("May"), 5, "May = 5"); + t.is (ISO8601d::monthOfYear ("June"), 6, "June = 6"); + t.is (ISO8601d::monthOfYear ("July"), 7, "July = 7"); + t.is (ISO8601d::monthOfYear ("August"), 8, "August = 8"); + t.is (ISO8601d::monthOfYear ("September"), 9, "September = 9"); + t.is (ISO8601d::monthOfYear ("October"), 10, "October = 10"); + t.is (ISO8601d::monthOfYear ("November"), 11, "November = 11"); + t.is (ISO8601d::monthOfYear ("December"), 12, "December = 12"); + t.is (ISO8601d::dayName (0), "Sunday", "0 == Sunday"); t.is (ISO8601d::dayName (1), "Monday", "1 == Monday"); t.is (ISO8601d::dayName (2), "Tuesday", "2 == Tuesday"); From 90ac0e2b17c83e722f11378253b05f90263f443c Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sat, 26 Sep 2015 14:51:46 -0400 Subject: [PATCH 032/117] ISO8601d: Added ::operator== --- src/ISO8601.cpp | 6 ++++++ src/ISO8601.h | 2 ++ 2 files changed, 8 insertions(+) diff --git a/src/ISO8601.cpp b/src/ISO8601.cpp index ee7da3b87..b9c10bdf0 100644 --- a/src/ISO8601.cpp +++ b/src/ISO8601.cpp @@ -1049,6 +1049,12 @@ int ISO8601d::second () const return t->tm_sec; } +//////////////////////////////////////////////////////////////////////////////// +bool ISO8601d::operator== (const ISO8601d& rhs) const +{ + return rhs._date == _date; +} + //////////////////////////////////////////////////////////////////////////////// void ISO8601p::clear () { diff --git a/src/ISO8601.h b/src/ISO8601.h index e407e5603..c5d25f504 100644 --- a/src/ISO8601.h +++ b/src/ISO8601.h @@ -65,6 +65,8 @@ public: int minute () const; int second () const; + bool operator== (const ISO8601d&) const; + private: void clear (); bool parse_date_time (Nibbler&); From 7a996dfadf81d2e6e38e13f8888bd884a2cab1f2 Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sat, 26 Sep 2015 14:54:34 -0400 Subject: [PATCH 033/117] ISO8601d: Added ::operator!= --- src/ISO8601.cpp | 6 ++++++ src/ISO8601.h | 1 + 2 files changed, 7 insertions(+) diff --git a/src/ISO8601.cpp b/src/ISO8601.cpp index b9c10bdf0..89d29a489 100644 --- a/src/ISO8601.cpp +++ b/src/ISO8601.cpp @@ -1055,6 +1055,12 @@ bool ISO8601d::operator== (const ISO8601d& rhs) const return rhs._date == _date; } +//////////////////////////////////////////////////////////////////////////////// +bool ISO8601d::operator!= (const ISO8601d& rhs) const +{ + return rhs._date != _date; +} + //////////////////////////////////////////////////////////////////////////////// void ISO8601p::clear () { diff --git a/src/ISO8601.h b/src/ISO8601.h index c5d25f504..b78087817 100644 --- a/src/ISO8601.h +++ b/src/ISO8601.h @@ -66,6 +66,7 @@ public: int second () const; bool operator== (const ISO8601d&) const; + bool operator!= (const ISO8601d&) const; private: void clear (); From 9f8ea49446ef106385ea5345f0f9fbf08383db45 Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sat, 26 Sep 2015 14:56:36 -0400 Subject: [PATCH 034/117] ISO8601d: Added ::operator< --- src/ISO8601.cpp | 6 ++++++ src/ISO8601.h | 1 + 2 files changed, 7 insertions(+) diff --git a/src/ISO8601.cpp b/src/ISO8601.cpp index 89d29a489..c1fa548ce 100644 --- a/src/ISO8601.cpp +++ b/src/ISO8601.cpp @@ -1061,6 +1061,12 @@ bool ISO8601d::operator!= (const ISO8601d& rhs) const return rhs._date != _date; } +//////////////////////////////////////////////////////////////////////////////// +bool ISO8601d::operator< (const ISO8601d& rhs) const +{ + return _date < rhs._date; +} + //////////////////////////////////////////////////////////////////////////////// void ISO8601p::clear () { diff --git a/src/ISO8601.h b/src/ISO8601.h index b78087817..36f871774 100644 --- a/src/ISO8601.h +++ b/src/ISO8601.h @@ -67,6 +67,7 @@ public: bool operator== (const ISO8601d&) const; bool operator!= (const ISO8601d&) const; + bool operator< (const ISO8601d&) const; private: void clear (); From e09eee1a592b91909d329def269a6aa44fd60cee Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sat, 26 Sep 2015 14:58:24 -0400 Subject: [PATCH 035/117] ISO8601d: Added ::operator> --- src/ISO8601.cpp | 6 ++++++ src/ISO8601.h | 1 + 2 files changed, 7 insertions(+) diff --git a/src/ISO8601.cpp b/src/ISO8601.cpp index c1fa548ce..480297148 100644 --- a/src/ISO8601.cpp +++ b/src/ISO8601.cpp @@ -1067,6 +1067,12 @@ bool ISO8601d::operator< (const ISO8601d& rhs) const return _date < rhs._date; } +//////////////////////////////////////////////////////////////////////////////// +bool ISO8601d::operator> (const ISO8601d& rhs) const +{ + return _date > rhs._date; +} + //////////////////////////////////////////////////////////////////////////////// void ISO8601p::clear () { diff --git a/src/ISO8601.h b/src/ISO8601.h index 36f871774..ca10bd9cc 100644 --- a/src/ISO8601.h +++ b/src/ISO8601.h @@ -68,6 +68,7 @@ public: bool operator== (const ISO8601d&) const; bool operator!= (const ISO8601d&) const; bool operator< (const ISO8601d&) const; + bool operator> (const ISO8601d&) const; private: void clear (); From b7afcb97236d68a7b33e0d9a4dddd9712bd80d99 Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sat, 26 Sep 2015 14:59:47 -0400 Subject: [PATCH 036/117] ISO8601d: Added ::opreator<= --- src/ISO8601.cpp | 6 ++++++ src/ISO8601.h | 1 + 2 files changed, 7 insertions(+) diff --git a/src/ISO8601.cpp b/src/ISO8601.cpp index 480297148..e5920f304 100644 --- a/src/ISO8601.cpp +++ b/src/ISO8601.cpp @@ -1073,6 +1073,12 @@ bool ISO8601d::operator> (const ISO8601d& rhs) const return _date > rhs._date; } +//////////////////////////////////////////////////////////////////////////////// +bool ISO8601d::operator<= (const ISO8601d& rhs) const +{ + return _date <= rhs._date; +} + //////////////////////////////////////////////////////////////////////////////// void ISO8601p::clear () { diff --git a/src/ISO8601.h b/src/ISO8601.h index ca10bd9cc..b04fb4de2 100644 --- a/src/ISO8601.h +++ b/src/ISO8601.h @@ -69,6 +69,7 @@ public: bool operator!= (const ISO8601d&) const; bool operator< (const ISO8601d&) const; bool operator> (const ISO8601d&) const; + bool operator<= (const ISO8601d&) const; private: void clear (); From fe509cd3dd4301411797155e385e6003e02b735c Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sat, 26 Sep 2015 15:01:29 -0400 Subject: [PATCH 037/117] ISO8601d: Added ::operator>= --- src/ISO8601.cpp | 6 ++++++ src/ISO8601.h | 1 + 2 files changed, 7 insertions(+) diff --git a/src/ISO8601.cpp b/src/ISO8601.cpp index e5920f304..f899f481e 100644 --- a/src/ISO8601.cpp +++ b/src/ISO8601.cpp @@ -1079,6 +1079,12 @@ bool ISO8601d::operator<= (const ISO8601d& rhs) const return _date <= rhs._date; } +//////////////////////////////////////////////////////////////////////////////// +bool ISO8601d::operator>= (const ISO8601d& rhs) const +{ + return _date >= rhs._date; +} + //////////////////////////////////////////////////////////////////////////////// void ISO8601p::clear () { diff --git a/src/ISO8601.h b/src/ISO8601.h index b04fb4de2..625d6dce2 100644 --- a/src/ISO8601.h +++ b/src/ISO8601.h @@ -70,6 +70,7 @@ public: bool operator< (const ISO8601d&) const; bool operator> (const ISO8601d&) const; bool operator<= (const ISO8601d&) const; + bool operator>= (const ISO8601d&) const; private: void clear (); From ec66bc73d31787c86c448d9e7c36d4735fbcc23e Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sat, 26 Sep 2015 15:04:01 -0400 Subject: [PATCH 038/117] ISO8601d: Added ::sameHour --- src/ISO8601.cpp | 9 +++++++++ src/ISO8601.h | 1 + 2 files changed, 10 insertions(+) diff --git a/src/ISO8601.cpp b/src/ISO8601.cpp index f899f481e..d8e3b4a97 100644 --- a/src/ISO8601.cpp +++ b/src/ISO8601.cpp @@ -1085,6 +1085,15 @@ bool ISO8601d::operator>= (const ISO8601d& rhs) const return _date >= rhs._date; } +//////////////////////////////////////////////////////////////////////////////// +bool ISO8601d::sameHour (const ISO8601d& rhs) const +{ + return this->year () == rhs.year () && + this->month () == rhs.month () && + this->day () == rhs.day () && + this->hour () == rhs.hour (); +} + //////////////////////////////////////////////////////////////////////////////// void ISO8601p::clear () { diff --git a/src/ISO8601.h b/src/ISO8601.h index 625d6dce2..951a9ae36 100644 --- a/src/ISO8601.h +++ b/src/ISO8601.h @@ -71,6 +71,7 @@ public: bool operator> (const ISO8601d&) const; bool operator<= (const ISO8601d&) const; bool operator>= (const ISO8601d&) const; + bool sameHour (const ISO8601d&) const; private: void clear (); From 2c449583ef0a20e045cb80591e3a5f3083557b3b Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sat, 26 Sep 2015 15:05:58 -0400 Subject: [PATCH 039/117] ISO8601d: Added ::sameDay --- src/ISO8601.cpp | 8 ++++++++ src/ISO8601.h | 1 + 2 files changed, 9 insertions(+) diff --git a/src/ISO8601.cpp b/src/ISO8601.cpp index d8e3b4a97..896026ae1 100644 --- a/src/ISO8601.cpp +++ b/src/ISO8601.cpp @@ -1094,6 +1094,14 @@ bool ISO8601d::sameHour (const ISO8601d& rhs) const this->hour () == rhs.hour (); } +//////////////////////////////////////////////////////////////////////////////// +bool ISO8601d::sameDay (const ISO8601d& rhs) const +{ + return this->year () == rhs.year () && + this->month () == rhs.month () && + this->day () == rhs.day (); +} + //////////////////////////////////////////////////////////////////////////////// void ISO8601p::clear () { diff --git a/src/ISO8601.h b/src/ISO8601.h index 951a9ae36..9d9898bf7 100644 --- a/src/ISO8601.h +++ b/src/ISO8601.h @@ -72,6 +72,7 @@ public: bool operator<= (const ISO8601d&) const; bool operator>= (const ISO8601d&) const; bool sameHour (const ISO8601d&) const; + bool sameDay (const ISO8601d&) const; private: void clear (); From aa90fdbe1c4d0a10f875e96f0312b38bf3fc8d2c Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sat, 26 Sep 2015 15:07:48 -0400 Subject: [PATCH 040/117] ISO8601d: Added ::sameWeek --- src/ISO8601.cpp | 7 +++++++ src/ISO8601.h | 1 + 2 files changed, 8 insertions(+) diff --git a/src/ISO8601.cpp b/src/ISO8601.cpp index 896026ae1..ff1cee3a2 100644 --- a/src/ISO8601.cpp +++ b/src/ISO8601.cpp @@ -1102,6 +1102,13 @@ bool ISO8601d::sameDay (const ISO8601d& rhs) const this->day () == rhs.day (); } +//////////////////////////////////////////////////////////////////////////////// +bool ISO8601d::sameWeek (const ISO8601d& rhs) const +{ + return this->year () == rhs.year () && + this->week () == rhs.week (); +} + //////////////////////////////////////////////////////////////////////////////// void ISO8601p::clear () { diff --git a/src/ISO8601.h b/src/ISO8601.h index 9d9898bf7..14090f4f5 100644 --- a/src/ISO8601.h +++ b/src/ISO8601.h @@ -73,6 +73,7 @@ public: bool operator>= (const ISO8601d&) const; bool sameHour (const ISO8601d&) const; bool sameDay (const ISO8601d&) const; + bool sameWeek (const ISO8601d&) const; private: void clear (); From 04836c2cececb8ab1fb44060d5c9f6e28ae99507 Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sat, 26 Sep 2015 15:10:04 -0400 Subject: [PATCH 041/117] ISO8601d: Added ::sameMonth --- src/ISO8601.cpp | 7 +++++++ src/ISO8601.h | 1 + 2 files changed, 8 insertions(+) diff --git a/src/ISO8601.cpp b/src/ISO8601.cpp index ff1cee3a2..df284d816 100644 --- a/src/ISO8601.cpp +++ b/src/ISO8601.cpp @@ -1109,6 +1109,13 @@ bool ISO8601d::sameWeek (const ISO8601d& rhs) const this->week () == rhs.week (); } +//////////////////////////////////////////////////////////////////////////////// +bool ISO8601d::sameMonth (const ISO8601d& rhs) const +{ + return this->year () == rhs.year () && + this->month () == rhs.month (); +} + //////////////////////////////////////////////////////////////////////////////// void ISO8601p::clear () { diff --git a/src/ISO8601.h b/src/ISO8601.h index 14090f4f5..0f1ec163c 100644 --- a/src/ISO8601.h +++ b/src/ISO8601.h @@ -74,6 +74,7 @@ public: bool sameHour (const ISO8601d&) const; bool sameDay (const ISO8601d&) const; bool sameWeek (const ISO8601d&) const; + bool sameMonth (const ISO8601d&) const; private: void clear (); From 79f030b199a79bf2c65c16e2d35d34ac34aa4d70 Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sat, 26 Sep 2015 15:11:58 -0400 Subject: [PATCH 042/117] ISO8601d: Added ::sameYear --- src/ISO8601.cpp | 6 ++++++ src/ISO8601.h | 1 + 2 files changed, 7 insertions(+) diff --git a/src/ISO8601.cpp b/src/ISO8601.cpp index df284d816..65712d75a 100644 --- a/src/ISO8601.cpp +++ b/src/ISO8601.cpp @@ -1116,6 +1116,12 @@ bool ISO8601d::sameMonth (const ISO8601d& rhs) const this->month () == rhs.month (); } +//////////////////////////////////////////////////////////////////////////////// +bool ISO8601d::sameYear (const ISO8601d& rhs) const +{ + return this->year () == rhs.year (); +} + //////////////////////////////////////////////////////////////////////////////// void ISO8601p::clear () { diff --git a/src/ISO8601.h b/src/ISO8601.h index 0f1ec163c..3378fb647 100644 --- a/src/ISO8601.h +++ b/src/ISO8601.h @@ -75,6 +75,7 @@ public: bool sameDay (const ISO8601d&) const; bool sameWeek (const ISO8601d&) const; bool sameMonth (const ISO8601d&) const; + bool sameYear (const ISO8601d&) const; private: void clear (); From 957c8b7e7b25ea877c7d34bc078748aacda78df3 Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sat, 26 Sep 2015 15:18:29 -0400 Subject: [PATCH 043/117] ISO8601d: Added ::ISO8601 (time_t) --- src/ISO8601.cpp | 7 +++++++ src/ISO8601.h | 1 + 2 files changed, 8 insertions(+) diff --git a/src/ISO8601.cpp b/src/ISO8601.cpp index 65712d75a..c118ec65a 100644 --- a/src/ISO8601.cpp +++ b/src/ISO8601.cpp @@ -119,6 +119,13 @@ ISO8601d::ISO8601d () _date = time (NULL); } +//////////////////////////////////////////////////////////////////////////////// +ISO8601d::ISO8601d (const time_t t) +{ + clear (); + _date = t; +} + //////////////////////////////////////////////////////////////////////////////// ISO8601d::~ISO8601d () { diff --git a/src/ISO8601.h b/src/ISO8601.h index 3378fb647..98ecb94db 100644 --- a/src/ISO8601.h +++ b/src/ISO8601.h @@ -38,6 +38,7 @@ public: static int minimumMatchLength; ISO8601d (); + ISO8601d (time_t); ~ISO8601d (); ISO8601d (const ISO8601d&); // Unimplemented ISO8601d& operator= (const ISO8601d&); // Unimplemented From c0952892087b4bfe9dfc562082ccf8eea8312548 Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sat, 26 Sep 2015 15:33:45 -0400 Subject: [PATCH 044/117] ISO8601d: Added ::operator+ --- src/ISO8601.cpp | 6 ++++++ src/ISO8601.h | 2 ++ 2 files changed, 8 insertions(+) diff --git a/src/ISO8601.cpp b/src/ISO8601.cpp index c118ec65a..8a4db0462 100644 --- a/src/ISO8601.cpp +++ b/src/ISO8601.cpp @@ -1129,6 +1129,12 @@ bool ISO8601d::sameYear (const ISO8601d& rhs) const return this->year () == rhs.year (); } +//////////////////////////////////////////////////////////////////////////////// +ISO8601d ISO8601d::operator+ (const int delta) +{ + return ISO8601d (_date + delta); +} + //////////////////////////////////////////////////////////////////////////////// void ISO8601p::clear () { diff --git a/src/ISO8601.h b/src/ISO8601.h index 98ecb94db..d9dd25462 100644 --- a/src/ISO8601.h +++ b/src/ISO8601.h @@ -78,6 +78,8 @@ public: bool sameMonth (const ISO8601d&) const; bool sameYear (const ISO8601d&) const; + ISO8601d operator+ (const int); + private: void clear (); bool parse_date_time (Nibbler&); From ed2cf991f36e25b26f46eaf17a83e565b8a739d1 Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sat, 26 Sep 2015 15:38:25 -0400 Subject: [PATCH 045/117] ISO8601d: Added ::operator- --- src/ISO8601.cpp | 6 ++++++ src/ISO8601.h | 1 + 2 files changed, 7 insertions(+) diff --git a/src/ISO8601.cpp b/src/ISO8601.cpp index 8a4db0462..eed021304 100644 --- a/src/ISO8601.cpp +++ b/src/ISO8601.cpp @@ -1135,6 +1135,12 @@ ISO8601d ISO8601d::operator+ (const int delta) return ISO8601d (_date + delta); } +//////////////////////////////////////////////////////////////////////////////// +ISO8601d ISO8601d::operator- (const int delta) +{ + return ISO8601d (_date - delta); +} + //////////////////////////////////////////////////////////////////////////////// void ISO8601p::clear () { diff --git a/src/ISO8601.h b/src/ISO8601.h index d9dd25462..224cf9659 100644 --- a/src/ISO8601.h +++ b/src/ISO8601.h @@ -79,6 +79,7 @@ public: bool sameYear (const ISO8601d&) const; ISO8601d operator+ (const int); + ISO8601d operator- (const int); private: void clear (); From 984b12c0d2fc4a5dd551b7b596c122afaeeb66f9 Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sat, 26 Sep 2015 15:39:03 -0400 Subject: [PATCH 046/117] ISO8601d: Added ::operator+= --- src/ISO8601.cpp | 7 +++++++ src/ISO8601.h | 1 + 2 files changed, 8 insertions(+) diff --git a/src/ISO8601.cpp b/src/ISO8601.cpp index eed021304..302904cd6 100644 --- a/src/ISO8601.cpp +++ b/src/ISO8601.cpp @@ -1141,6 +1141,13 @@ ISO8601d ISO8601d::operator- (const int delta) return ISO8601d (_date - delta); } +//////////////////////////////////////////////////////////////////////////////// +ISO8601d& ISO8601d::operator+= (const int delta) +{ + _date += (time_t) delta; + return *this; +} + //////////////////////////////////////////////////////////////////////////////// void ISO8601p::clear () { diff --git a/src/ISO8601.h b/src/ISO8601.h index 224cf9659..c7550478c 100644 --- a/src/ISO8601.h +++ b/src/ISO8601.h @@ -80,6 +80,7 @@ public: ISO8601d operator+ (const int); ISO8601d operator- (const int); + ISO8601d& operator+= (const int); private: void clear (); From 16818c0b9313ae7e45ec5ffdde2c99f8bb402ef1 Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sat, 26 Sep 2015 15:40:40 -0400 Subject: [PATCH 047/117] ISO8601d: Added ::operator-= --- src/ISO8601.cpp | 7 +++++++ src/ISO8601.h | 1 + 2 files changed, 8 insertions(+) diff --git a/src/ISO8601.cpp b/src/ISO8601.cpp index 302904cd6..68ae4fec8 100644 --- a/src/ISO8601.cpp +++ b/src/ISO8601.cpp @@ -1148,6 +1148,13 @@ ISO8601d& ISO8601d::operator+= (const int delta) return *this; } +//////////////////////////////////////////////////////////////////////////////// +ISO8601d& ISO8601d::operator-= (const int delta) +{ + _date -= (time_t) delta; + return *this; +} + //////////////////////////////////////////////////////////////////////////////// void ISO8601p::clear () { diff --git a/src/ISO8601.h b/src/ISO8601.h index c7550478c..aaebf84c3 100644 --- a/src/ISO8601.h +++ b/src/ISO8601.h @@ -81,6 +81,7 @@ public: ISO8601d operator+ (const int); ISO8601d operator- (const int); ISO8601d& operator+= (const int); + ISO8601d& operator-= (const int); private: void clear (); From 860a1de034863455c0e039279009e50517338b15 Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sat, 26 Sep 2015 15:43:07 -0400 Subject: [PATCH 048/117] ISO8601d: Added ::operator- --- src/ISO8601.cpp | 6 ++++++ src/ISO8601.h | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/ISO8601.cpp b/src/ISO8601.cpp index 68ae4fec8..4148fca26 100644 --- a/src/ISO8601.cpp +++ b/src/ISO8601.cpp @@ -1155,6 +1155,12 @@ ISO8601d& ISO8601d::operator-= (const int delta) return *this; } +//////////////////////////////////////////////////////////////////////////////// +time_t ISO8601d::operator- (const ISO8601d& rhs) +{ + return _date - rhs._date; +} + //////////////////////////////////////////////////////////////////////////////// void ISO8601p::clear () { diff --git a/src/ISO8601.h b/src/ISO8601.h index aaebf84c3..6e7dd7cca 100644 --- a/src/ISO8601.h +++ b/src/ISO8601.h @@ -77,11 +77,11 @@ public: bool sameWeek (const ISO8601d&) const; bool sameMonth (const ISO8601d&) const; bool sameYear (const ISO8601d&) const; - ISO8601d operator+ (const int); ISO8601d operator- (const int); ISO8601d& operator+= (const int); ISO8601d& operator-= (const int); + time_t operator- (const ISO8601d&); private: void clear (); From 5073921707f1f71ca1967c0d9eb8c9053608c935 Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sat, 26 Sep 2015 15:58:25 -0400 Subject: [PATCH 049/117] ISO8601d: Added (m,d,y) ctor --- src/ISO8601.cpp | 15 +++++++++++++++ src/ISO8601.h | 1 + 2 files changed, 16 insertions(+) diff --git a/src/ISO8601.cpp b/src/ISO8601.cpp index 4148fca26..ef7a62026 100644 --- a/src/ISO8601.cpp +++ b/src/ISO8601.cpp @@ -126,6 +126,21 @@ ISO8601d::ISO8601d (const time_t t) _date = t; } +//////////////////////////////////////////////////////////////////////////////// +ISO8601d::ISO8601d (const int m, const int d, const int y) +{ + clear (); + + // Error if not valid. + struct tm t = {0}; + t.tm_isdst = -1; // Requests that mktime determine summer time effect. + t.tm_mday = d; + t.tm_mon = m - 1; + t.tm_year = y - 1900; + + _date = mktime (&t); +} + //////////////////////////////////////////////////////////////////////////////// ISO8601d::~ISO8601d () { diff --git a/src/ISO8601.h b/src/ISO8601.h index 6e7dd7cca..a102534f1 100644 --- a/src/ISO8601.h +++ b/src/ISO8601.h @@ -39,6 +39,7 @@ public: ISO8601d (); ISO8601d (time_t); + ISO8601d (const int, const int, const int); ~ISO8601d (); ISO8601d (const ISO8601d&); // Unimplemented ISO8601d& operator= (const ISO8601d&); // Unimplemented From 2242cb2a8bf09cbb7daeb794b07d44cab6f939c2 Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sat, 26 Sep 2015 15:59:41 -0400 Subject: [PATCH 050/117] ISO8601d: Added (m,d,y,h,m,s) ctor --- src/ISO8601.cpp | 19 +++++++++++++++++++ src/ISO8601.h | 1 + 2 files changed, 20 insertions(+) diff --git a/src/ISO8601.cpp b/src/ISO8601.cpp index ef7a62026..d6c0e73e7 100644 --- a/src/ISO8601.cpp +++ b/src/ISO8601.cpp @@ -141,6 +141,25 @@ ISO8601d::ISO8601d (const int m, const int d, const int y) _date = mktime (&t); } +//////////////////////////////////////////////////////////////////////////////// +ISO8601d::ISO8601d (const int m, const int d, const int y, + const int hr, const int mi, const int se) +{ + clear (); + + // Error if not valid. + struct tm t = {0}; + t.tm_isdst = -1; // Requests that mktime determine summer time effect. + t.tm_mday = d; + t.tm_mon = m - 1; + t.tm_year = y - 1900; + t.tm_hour = hr; + t.tm_min = mi; + t.tm_sec = se; + + _date = mktime (&t); +} + //////////////////////////////////////////////////////////////////////////////// ISO8601d::~ISO8601d () { diff --git a/src/ISO8601.h b/src/ISO8601.h index a102534f1..559794f4e 100644 --- a/src/ISO8601.h +++ b/src/ISO8601.h @@ -40,6 +40,7 @@ public: ISO8601d (); ISO8601d (time_t); ISO8601d (const int, const int, const int); + ISO8601d (const int, const int, const int, const int, const int, const int); ~ISO8601d (); ISO8601d (const ISO8601d&); // Unimplemented ISO8601d& operator= (const ISO8601d&); // Unimplemented From 9c9216acbf6b4daefd16a249cab9aec565fc2ab1 Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sat, 26 Sep 2015 16:01:30 -0400 Subject: [PATCH 051/117] ISO8601d: Added ::startOfDay --- src/ISO8601.cpp | 6 ++++++ src/ISO8601.h | 3 ++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/ISO8601.cpp b/src/ISO8601.cpp index d6c0e73e7..6fa9df6c1 100644 --- a/src/ISO8601.cpp +++ b/src/ISO8601.cpp @@ -840,6 +840,12 @@ bool ISO8601p::parse (const std::string& input, std::string::size_type& start) return false; } +//////////////////////////////////////////////////////////////////////////////// +ISO8601d ISO8601d::startOfDay () const +{ + return ISO8601d (month (), day (), year ()); +} + //////////////////////////////////////////////////////////////////////////////// // Static bool ISO8601d::leapYear (int year) diff --git a/src/ISO8601.h b/src/ISO8601.h index 559794f4e..d4cd49768 100644 --- a/src/ISO8601.h +++ b/src/ISO8601.h @@ -43,10 +43,11 @@ public: ISO8601d (const int, const int, const int, const int, const int, const int); ~ISO8601d (); ISO8601d (const ISO8601d&); // Unimplemented - ISO8601d& operator= (const ISO8601d&); // Unimplemented operator time_t () const; bool parse (const std::string&, std::string::size_type&, const std::string& format = ""); + ISO8601d startOfDay () const; + static bool leapYear (int); static int daysInMonth (int, int); static int daysInYear (int); From ef6d0a8f9a26c845fd9536819d03c78bdb57dfd4 Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sat, 26 Sep 2015 16:02:41 -0400 Subject: [PATCH 052/117] ISO8601d: Added ::operator-- (prefix) --- src/ISO8601.cpp | 14 ++++++++++++++ src/ISO8601.h | 1 + 2 files changed, 15 insertions(+) diff --git a/src/ISO8601.cpp b/src/ISO8601.cpp index 6fa9df6c1..0295a96b6 100644 --- a/src/ISO8601.cpp +++ b/src/ISO8601.cpp @@ -1201,6 +1201,20 @@ time_t ISO8601d::operator- (const ISO8601d& rhs) return _date - rhs._date; } +//////////////////////////////////////////////////////////////////////////////// +// Prefix decrement by one day. +void ISO8601d::operator-- () +{ + ISO8601d yesterday = startOfDay () - 1; + yesterday = ISO8601d (yesterday.month (), + yesterday.day (), + yesterday.year (), + hour (), + minute (), + second ()); + _date = yesterday._date; +} + //////////////////////////////////////////////////////////////////////////////// void ISO8601p::clear () { diff --git a/src/ISO8601.h b/src/ISO8601.h index d4cd49768..85833640d 100644 --- a/src/ISO8601.h +++ b/src/ISO8601.h @@ -85,6 +85,7 @@ public: ISO8601d& operator+= (const int); ISO8601d& operator-= (const int); time_t operator- (const ISO8601d&); + void operator-- (); // Prefix private: void clear (); From e96eaaac38c619d1867420a3417980cee11d4780 Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sat, 26 Sep 2015 16:05:47 -0400 Subject: [PATCH 053/117] ISO8601d: Added ::operator-- (postfix) --- src/ISO8601.cpp | 14 ++++++++++++++ src/ISO8601.h | 1 + 2 files changed, 15 insertions(+) diff --git a/src/ISO8601.cpp b/src/ISO8601.cpp index 0295a96b6..ba2d68d7e 100644 --- a/src/ISO8601.cpp +++ b/src/ISO8601.cpp @@ -1215,6 +1215,20 @@ void ISO8601d::operator-- () _date = yesterday._date; } +//////////////////////////////////////////////////////////////////////////////// +// Postfix decrement by one day. +void ISO8601d::operator-- (int) +{ + ISO8601d yesterday = startOfDay () - 1; + yesterday = ISO8601d (yesterday.month (), + yesterday.day (), + yesterday.year (), + hour (), + minute (), + second ()); + _date = yesterday._date; +} + //////////////////////////////////////////////////////////////////////////////// void ISO8601p::clear () { diff --git a/src/ISO8601.h b/src/ISO8601.h index 85833640d..c3a24ab61 100644 --- a/src/ISO8601.h +++ b/src/ISO8601.h @@ -86,6 +86,7 @@ public: ISO8601d& operator-= (const int); time_t operator- (const ISO8601d&); void operator-- (); // Prefix + void operator-- (int); // Postfix private: void clear (); From 98dbfb01b4110042b520e5a79a43f9937ef6d2ca Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sat, 26 Sep 2015 16:08:11 -0400 Subject: [PATCH 054/117] ISO8601d: ::operator++ (prefix) --- src/ISO8601.cpp | 14 ++++++++++++++ src/ISO8601.h | 1 + 2 files changed, 15 insertions(+) diff --git a/src/ISO8601.cpp b/src/ISO8601.cpp index ba2d68d7e..85813a4d3 100644 --- a/src/ISO8601.cpp +++ b/src/ISO8601.cpp @@ -1229,6 +1229,20 @@ void ISO8601d::operator-- (int) _date = yesterday._date; } +//////////////////////////////////////////////////////////////////////////////// +// Prefix increment by one day. +void ISO8601d::operator++ () +{ + ISO8601d tomorrow = (startOfDay () + 90001).startOfDay (); + tomorrow = ISO8601d (tomorrow.month (), + tomorrow.day (), + tomorrow.year (), + hour (), + minute (), + second ()); + _date = tomorrow._date; +} + //////////////////////////////////////////////////////////////////////////////// void ISO8601p::clear () { diff --git a/src/ISO8601.h b/src/ISO8601.h index c3a24ab61..0694a149c 100644 --- a/src/ISO8601.h +++ b/src/ISO8601.h @@ -87,6 +87,7 @@ public: time_t operator- (const ISO8601d&); void operator-- (); // Prefix void operator-- (int); // Postfix + void operator++ (); // Prefix private: void clear (); From a6331747d2ee5703bf318d3842db66afd25cd880 Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sat, 26 Sep 2015 16:09:56 -0400 Subject: [PATCH 055/117] ISO8601d: Added ::oprator++ (postfix) --- src/ISO8601.cpp | 14 ++++++++++++++ src/ISO8601.h | 1 + 2 files changed, 15 insertions(+) diff --git a/src/ISO8601.cpp b/src/ISO8601.cpp index 85813a4d3..797828ab8 100644 --- a/src/ISO8601.cpp +++ b/src/ISO8601.cpp @@ -1243,6 +1243,20 @@ void ISO8601d::operator++ () _date = tomorrow._date; } +//////////////////////////////////////////////////////////////////////////////// +// Postfix increment by one day. +void ISO8601d::operator++ (int) +{ + ISO8601d tomorrow = (startOfDay () + 90001).startOfDay (); + tomorrow = ISO8601d (tomorrow.month (), + tomorrow.day (), + tomorrow.year (), + hour (), + minute (), + second ()); + _date = tomorrow._date; +} + //////////////////////////////////////////////////////////////////////////////// void ISO8601p::clear () { diff --git a/src/ISO8601.h b/src/ISO8601.h index 0694a149c..f5fbc1e9c 100644 --- a/src/ISO8601.h +++ b/src/ISO8601.h @@ -88,6 +88,7 @@ public: void operator-- (); // Prefix void operator-- (int); // Postfix void operator++ (); // Prefix + void operator++ (int); // Postfix private: void clear (); From 25c4f8871e688717aa8d8e0e7a3121d3c1371763 Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sat, 26 Sep 2015 16:12:48 -0400 Subject: [PATCH 056/117] ISO8601d: Added ::startOfWeek --- src/ISO8601.cpp | 8 ++++++++ src/ISO8601.h | 1 + 2 files changed, 9 insertions(+) diff --git a/src/ISO8601.cpp b/src/ISO8601.cpp index 797828ab8..3e740296f 100644 --- a/src/ISO8601.cpp +++ b/src/ISO8601.cpp @@ -846,6 +846,14 @@ ISO8601d ISO8601d::startOfDay () const return ISO8601d (month (), day (), year ()); } +//////////////////////////////////////////////////////////////////////////////// +ISO8601d ISO8601d::startOfWeek () const +{ + ISO8601d sow (_date); + sow -= (dayOfWeek () * 86400); + return ISO8601d (sow.month (), sow.day (), sow.year ()); +} + //////////////////////////////////////////////////////////////////////////////// // Static bool ISO8601d::leapYear (int year) diff --git a/src/ISO8601.h b/src/ISO8601.h index f5fbc1e9c..97f9d6f39 100644 --- a/src/ISO8601.h +++ b/src/ISO8601.h @@ -47,6 +47,7 @@ public: bool parse (const std::string&, std::string::size_type&, const std::string& format = ""); ISO8601d startOfDay () const; + ISO8601d startOfWeek () const; static bool leapYear (int); static int daysInMonth (int, int); From b6aced87269cd2755b16638faf75a3e2af8acc46 Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sat, 26 Sep 2015 16:14:12 -0400 Subject: [PATCH 057/117] ISO8601d: Added ::startOfMonth --- src/ISO8601.cpp | 6 ++++++ src/ISO8601.h | 1 + 2 files changed, 7 insertions(+) diff --git a/src/ISO8601.cpp b/src/ISO8601.cpp index 3e740296f..444907c3b 100644 --- a/src/ISO8601.cpp +++ b/src/ISO8601.cpp @@ -854,6 +854,12 @@ ISO8601d ISO8601d::startOfWeek () const return ISO8601d (sow.month (), sow.day (), sow.year ()); } +//////////////////////////////////////////////////////////////////////////////// +ISO8601d ISO8601d::startOfMonth () const +{ + return ISO8601d (month (), 1, year ()); +} + //////////////////////////////////////////////////////////////////////////////// // Static bool ISO8601d::leapYear (int year) diff --git a/src/ISO8601.h b/src/ISO8601.h index 97f9d6f39..062a0c961 100644 --- a/src/ISO8601.h +++ b/src/ISO8601.h @@ -48,6 +48,7 @@ public: ISO8601d startOfDay () const; ISO8601d startOfWeek () const; + ISO8601d startOfMonth () const; static bool leapYear (int); static int daysInMonth (int, int); From da88eefe2bc40e987ee23b8512a2322a86bae4cf Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sat, 26 Sep 2015 16:15:39 -0400 Subject: [PATCH 058/117] ISO8601d: Added ::startOfYear --- src/ISO8601.cpp | 6 ++++++ src/ISO8601.h | 1 + 2 files changed, 7 insertions(+) diff --git a/src/ISO8601.cpp b/src/ISO8601.cpp index 444907c3b..7abb1b79d 100644 --- a/src/ISO8601.cpp +++ b/src/ISO8601.cpp @@ -860,6 +860,12 @@ ISO8601d ISO8601d::startOfMonth () const return ISO8601d (month (), 1, year ()); } +//////////////////////////////////////////////////////////////////////////////// +ISO8601d ISO8601d::startOfYear () const +{ + return ISO8601d (1, 1, year ()); +} + //////////////////////////////////////////////////////////////////////////////// // Static bool ISO8601d::leapYear (int year) diff --git a/src/ISO8601.h b/src/ISO8601.h index 062a0c961..44373f220 100644 --- a/src/ISO8601.h +++ b/src/ISO8601.h @@ -49,6 +49,7 @@ public: ISO8601d startOfDay () const; ISO8601d startOfWeek () const; ISO8601d startOfMonth () const; + ISO8601d startOfYear () const; static bool leapYear (int); static int daysInMonth (int, int); From 7a5025e64d4531f0e84cbd634be5c8f37fa9aa99 Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sat, 26 Sep 2015 16:18:00 -0400 Subject: [PATCH 059/117] ISO8601d: Added ::toMDY --- src/ISO8601.cpp | 10 ++++++++++ src/ISO8601.h | 2 ++ 2 files changed, 12 insertions(+) diff --git a/src/ISO8601.cpp b/src/ISO8601.cpp index 7abb1b79d..b7f00aec2 100644 --- a/src/ISO8601.cpp +++ b/src/ISO8601.cpp @@ -840,6 +840,16 @@ bool ISO8601p::parse (const std::string& input, std::string::size_type& start) return false; } +//////////////////////////////////////////////////////////////////////////////// +void ISO8601d::toMDY (int& m, int& d, int& y) +{ + struct tm* t = localtime (&_date); + + m = t->tm_mon + 1; + d = t->tm_mday; + y = t->tm_year + 1900; +} + //////////////////////////////////////////////////////////////////////////////// ISO8601d ISO8601d::startOfDay () const { diff --git a/src/ISO8601.h b/src/ISO8601.h index 44373f220..ef55eafa5 100644 --- a/src/ISO8601.h +++ b/src/ISO8601.h @@ -46,6 +46,8 @@ public: operator time_t () const; bool parse (const std::string&, std::string::size_type&, const std::string& format = ""); + void toMDY (int&, int&, int&); + ISO8601d startOfDay () const; ISO8601d startOfWeek () const; ISO8601d startOfMonth () const; From c0bc6059ca9ac7256c06deb5db0e8c3edf7a5b9f Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sat, 26 Sep 2015 16:19:56 -0400 Subject: [PATCH 060/117] ISO8601d: Added ::toJulian --- src/ISO8601.cpp | 6 ++++++ src/ISO8601.h | 1 + 2 files changed, 7 insertions(+) diff --git a/src/ISO8601.cpp b/src/ISO8601.cpp index b7f00aec2..a3eccc6fe 100644 --- a/src/ISO8601.cpp +++ b/src/ISO8601.cpp @@ -840,6 +840,12 @@ bool ISO8601p::parse (const std::string& input, std::string::size_type& start) return false; } +//////////////////////////////////////////////////////////////////////////////// +double ISO8601d::toJulian () +{ + return (_date / 86400.0) + 2440587.5; +} + //////////////////////////////////////////////////////////////////////////////// void ISO8601d::toMDY (int& m, int& d, int& y) { diff --git a/src/ISO8601.h b/src/ISO8601.h index ef55eafa5..b0aec7e6f 100644 --- a/src/ISO8601.h +++ b/src/ISO8601.h @@ -46,6 +46,7 @@ public: operator time_t () const; bool parse (const std::string&, std::string::size_type&, const std::string& format = ""); + double toJulian (); void toMDY (int&, int&, int&); ISO8601d startOfDay () const; From 4a33f3e0933916c7741961fae14865e84c898d48 Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sat, 26 Sep 2015 18:35:47 -0400 Subject: [PATCH 061/117] ISO8601d: Added ::toEpochString --- src/ISO8601.cpp | 8 ++++++++ src/ISO8601.h | 1 + 2 files changed, 9 insertions(+) diff --git a/src/ISO8601.cpp b/src/ISO8601.cpp index a3eccc6fe..f75939878 100644 --- a/src/ISO8601.cpp +++ b/src/ISO8601.cpp @@ -840,6 +840,14 @@ bool ISO8601p::parse (const std::string& input, std::string::size_type& start) return false; } +//////////////////////////////////////////////////////////////////////////////// +std::string ISO8601d::toEpochString () +{ + std::stringstream epoch; + epoch << _date; + return epoch.str (); +} + //////////////////////////////////////////////////////////////////////////////// double ISO8601d::toJulian () { diff --git a/src/ISO8601.h b/src/ISO8601.h index b0aec7e6f..45e4796b3 100644 --- a/src/ISO8601.h +++ b/src/ISO8601.h @@ -46,6 +46,7 @@ public: operator time_t () const; bool parse (const std::string&, std::string::size_type&, const std::string& format = ""); + std::string toEpochString (); double toJulian (); void toMDY (int&, int&, int&); From cc8a305b37f5044da8d958702cb886f84bb4d5e9 Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sat, 26 Sep 2015 18:39:33 -0400 Subject: [PATCH 062/117] ISO8601d: Added ::toEpoch --- src/ISO8601.cpp | 6 ++++++ src/ISO8601.h | 1 + 2 files changed, 7 insertions(+) diff --git a/src/ISO8601.cpp b/src/ISO8601.cpp index f75939878..fb1332f56 100644 --- a/src/ISO8601.cpp +++ b/src/ISO8601.cpp @@ -840,6 +840,12 @@ bool ISO8601p::parse (const std::string& input, std::string::size_type& start) return false; } +//////////////////////////////////////////////////////////////////////////////// +time_t ISO8601d::toEpoch () +{ + return _date; +} + //////////////////////////////////////////////////////////////////////////////// std::string ISO8601d::toEpochString () { diff --git a/src/ISO8601.h b/src/ISO8601.h index 45e4796b3..87730df8c 100644 --- a/src/ISO8601.h +++ b/src/ISO8601.h @@ -46,6 +46,7 @@ public: operator time_t () const; bool parse (const std::string&, std::string::size_type&, const std::string& format = ""); + time_t toEpoch (); std::string toEpochString (); double toJulian (); void toMDY (int&, int&, int&); From 2414f6b3d4f655f765d3831679bc9bfe21f9fc84 Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sat, 26 Sep 2015 18:42:32 -0400 Subject: [PATCH 063/117] ISO8601d: Added ::toISO --- src/ISO8601.cpp | 20 ++++++++++++++++++++ src/ISO8601.h | 1 + 2 files changed, 21 insertions(+) diff --git a/src/ISO8601.cpp b/src/ISO8601.cpp index fb1332f56..1f2765f38 100644 --- a/src/ISO8601.cpp +++ b/src/ISO8601.cpp @@ -26,6 +26,7 @@ #include #include +#include #include #include #include @@ -854,6 +855,25 @@ std::string ISO8601d::toEpochString () return epoch.str (); } +//////////////////////////////////////////////////////////////////////////////// +// 19980119T070000Z = YYYYMMDDThhmmssZ +std::string ISO8601d::toISO () +{ + struct tm* t = gmtime (&_date); + + std::stringstream iso; + iso << std::setw (4) << std::setfill ('0') << t->tm_year + 1900 + << std::setw (2) << std::setfill ('0') << t->tm_mon + 1 + << std::setw (2) << std::setfill ('0') << t->tm_mday + << "T" + << std::setw (2) << std::setfill ('0') << t->tm_hour + << std::setw (2) << std::setfill ('0') << t->tm_min + << std::setw (2) << std::setfill ('0') << t->tm_sec + << "Z"; + + return iso.str (); +} + //////////////////////////////////////////////////////////////////////////////// double ISO8601d::toJulian () { diff --git a/src/ISO8601.h b/src/ISO8601.h index 87730df8c..cf4824f23 100644 --- a/src/ISO8601.h +++ b/src/ISO8601.h @@ -48,6 +48,7 @@ public: time_t toEpoch (); std::string toEpochString (); + std::string toISO (); double toJulian (); void toMDY (int&, int&, int&); From 85703803c8f7d475144eabf723f5ef7e74fc1309 Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sat, 26 Sep 2015 18:43:11 -0400 Subject: [PATCH 064/117] ISO8601d: Added ::toEpoch --- src/ISO8601.cpp | 13 +++++++++++++ src/ISO8601.h | 1 + 2 files changed, 14 insertions(+) diff --git a/src/ISO8601.cpp b/src/ISO8601.cpp index 1f2765f38..453db43dc 100644 --- a/src/ISO8601.cpp +++ b/src/ISO8601.cpp @@ -631,6 +631,19 @@ void ISO8601d::resolve () _date = utc ? timegm (&t) : mktime (&t); } +//////////////////////////////////////////////////////////////////////////////// +bool ISO8601d::isEpoch (const std::string& input) +{ + if (Lexer::isAllDigits (input) && + input.length () <= 10 ) + { + _date = (time_t) strtol (input.c_str (), NULL, 10); + return true; + } + + return false; +} + //////////////////////////////////////////////////////////////////////////////// ISO8601p::ISO8601p () { diff --git a/src/ISO8601.h b/src/ISO8601.h index cf4824f23..54ce7332d 100644 --- a/src/ISO8601.h +++ b/src/ISO8601.h @@ -111,6 +111,7 @@ private: int dayOfWeek (int, int, int); bool validate (); void resolve (); + bool isEpoch (const std::string&); public: int _year; From d25113e65301b330b5ba8d5d4efeef167efff2a6 Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sat, 26 Sep 2015 20:35:04 -0400 Subject: [PATCH 065/117] ISO8601d: Added ::toString --- src/ISO8601.cpp | 61 +++++++++++++++++++++++++++++++++++++++++-------- src/ISO8601.h | 1 + 2 files changed, 53 insertions(+), 9 deletions(-) diff --git a/src/ISO8601.cpp b/src/ISO8601.cpp index 453db43dc..38e5ea59b 100644 --- a/src/ISO8601.cpp +++ b/src/ISO8601.cpp @@ -31,7 +31,6 @@ #include #include #include -#include #include #include #include @@ -502,14 +501,14 @@ int ISO8601d::dayOfWeek (int year, int month, int day) bool ISO8601d::validate () { // _year; - if ((_year && (_year < 1900 || _year > 2200)) || - (_month && (_month < 1 || _month > 12)) || - (_week && (_week < 1 || _week > 53)) || - (_weekday && (_weekday < 0 || _weekday > 6)) || - (_julian && (_julian < 1 || _julian > Date::daysInYear (_year))) || - (_day && (_day < 1 || _day > Date::daysInMonth (_month, _year))) || - (_seconds && (_seconds < 1 || _seconds > 86400)) || - (_offset && (_offset < -86400 || _offset > 86400))) + if ((_year && (_year < 1900 || _year > 2200)) || + (_month && (_month < 1 || _month > 12)) || + (_week && (_week < 1 || _week > 53)) || + (_weekday && (_weekday < 0 || _weekday > 6)) || + (_julian && (_julian < 1 || _julian > ISO8601d::daysInYear (_year))) || + (_day && (_day < 1 || _day > ISO8601d::daysInMonth (_month, _year))) || + (_seconds && (_seconds < 1 || _seconds > 86400)) || + (_offset && (_offset < -86400 || _offset > 86400))) return false; return true; @@ -903,6 +902,50 @@ void ISO8601d::toMDY (int& m, int& d, int& y) y = t->tm_year + 1900; } +//////////////////////////////////////////////////////////////////////////////// +const std::string ISO8601d::toString ( + const std::string& format /*= "m/d/Y" */) const +{ + // Making this local copy seems to fix a bug. Remove the local copy and + // you'll see segmentation faults and all kinds of gibberish. + std::string localFormat = format; + + char buffer[12]; + std::string formatted; + for (unsigned int i = 0; i < localFormat.length (); ++i) + { + int c = localFormat[i]; + switch (c) + { + case 'm': sprintf (buffer, "%d", this->month ()); break; + case 'M': sprintf (buffer, "%02d", this->month ()); break; + case 'd': sprintf (buffer, "%d", this->day ()); break; + case 'D': sprintf (buffer, "%02d", this->day ()); break; + case 'y': sprintf (buffer, "%02d", this->year () % 100); break; + case 'Y': sprintf (buffer, "%d", this->year ()); break; + case 'a': sprintf (buffer, "%.3s", ISO8601d::dayName (dayOfWeek ()).c_str ()); break; + case 'A': sprintf (buffer, "%.10s", ISO8601d::dayName (dayOfWeek ()).c_str ()); break; + case 'b': sprintf (buffer, "%.3s", ISO8601d::monthName (month ()).c_str ()); break; + case 'B': sprintf (buffer, "%.10s", ISO8601d::monthName (month ()).c_str ()); break; + case 'v': sprintf (buffer, "%d", ISO8601d::weekOfYear (ISO8601d::dayOfWeek (ISO8601d::weekstart))); break; + case 'V': sprintf (buffer, "%02d", ISO8601d::weekOfYear (ISO8601d::dayOfWeek (ISO8601d::weekstart))); break; + case 'h': sprintf (buffer, "%d", this->hour ()); break; + case 'H': sprintf (buffer, "%02d", this->hour ()); break; + case 'n': sprintf (buffer, "%d", this->minute ()); break; + case 'N': sprintf (buffer, "%02d", this->minute ()); break; + case 's': sprintf (buffer, "%d", this->second ()); break; + case 'S': sprintf (buffer, "%02d", this->second ()); break; + case 'j': sprintf (buffer, "%d", this->dayOfYear ()); break; + case 'J': sprintf (buffer, "%03d", this->dayOfYear ()); break; + default: sprintf (buffer, "%c", c); break; + } + + formatted += buffer; + } + + return formatted; +} + //////////////////////////////////////////////////////////////////////////////// ISO8601d ISO8601d::startOfDay () const { diff --git a/src/ISO8601.h b/src/ISO8601.h index 54ce7332d..bb7c8e8af 100644 --- a/src/ISO8601.h +++ b/src/ISO8601.h @@ -51,6 +51,7 @@ public: std::string toISO (); double toJulian (); void toMDY (int&, int&, int&); + const std::string toString (const std::string& format = "m/d/Y") const; ISO8601d startOfDay () const; ISO8601d startOfWeek () const; From 6c02c03674e0d3157b2fc121a7f7b6eb979b2f65 Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sat, 26 Sep 2015 20:51:04 -0400 Subject: [PATCH 066/117] ISO8601d: Added various ::valid methods --- src/ISO8601.cpp | 67 +++++++++++++++++++++++++++++++++++++++++++++++++ src/ISO8601.h | 4 +++ 2 files changed, 71 insertions(+) diff --git a/src/ISO8601.cpp b/src/ISO8601.cpp index 38e5ea59b..7c99ed86b 100644 --- a/src/ISO8601.cpp +++ b/src/ISO8601.cpp @@ -972,6 +972,73 @@ ISO8601d ISO8601d::startOfYear () const return ISO8601d (1, 1, year ()); } +//////////////////////////////////////////////////////////////////////////////// +/* +bool ISO8601d::valid (const std::string& input, const std::string& format) +{ + try + { + ISO8601d test (input, format); + } + + catch (...) + { + return false; + } + + return true; +} +*/ + +//////////////////////////////////////////////////////////////////////////////// +bool ISO8601d::valid (const int m, const int d, const int y, const int hr, + const int mi, const int se) +{ + if (hr < 0 || hr > 23) + return false; + + if (mi < 0 || mi > 59) + return false; + + if (se < 0 || se > 59) + return false; + + return ISO8601d::valid (m, d, y); +} + +//////////////////////////////////////////////////////////////////////////////// +bool ISO8601d::valid (const int m, const int d, const int y) +{ + // Check that the year is valid. + if (y < 0) + return false; + + // Check that the month is valid. + if (m < 1 || m > 12) + return false; + + // Finally check that the days fall within the acceptable range for this + // month, and whether or not this is a leap year. + if (d < 1 || d > ISO8601d::daysInMonth (m, y)) + return false; + + return true; +} + +//////////////////////////////////////////////////////////////////////////////// +// Julian +bool ISO8601d::valid (const int d, const int y) +{ + // Check that the year is valid. + if (y < 0) + return false; + + if (d < 1 || d > ISO8601d::daysInYear (y)) + return false; + + return true; +} + //////////////////////////////////////////////////////////////////////////////// // Static bool ISO8601d::leapYear (int year) diff --git a/src/ISO8601.h b/src/ISO8601.h index bb7c8e8af..94dc69427 100644 --- a/src/ISO8601.h +++ b/src/ISO8601.h @@ -58,6 +58,10 @@ public: ISO8601d startOfMonth () const; ISO8601d startOfYear () const; +// static bool valid (const std::string&, const std::string& format = "m/d/Y"); + static bool valid (const int, const int, const int, const int, const int, const int); + static bool valid (const int, const int, const int); + static bool valid (const int, const int); static bool leapYear (int); static int daysInMonth (int, int); static int daysInYear (int); From 23c2958f44bcc97a75f80a3baa40e144efb8854f Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sat, 26 Sep 2015 21:16:11 -0400 Subject: [PATCH 067/117] Dates: Converted from Date to ISO8601d --- src/Dates.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Dates.cpp b/src/Dates.cpp index 14a8b0b7c..e4238c7bb 100644 --- a/src/Dates.cpp +++ b/src/Dates.cpp @@ -31,7 +31,6 @@ #include #include #include -#include #include #include #include @@ -39,14 +38,14 @@ //////////////////////////////////////////////////////////////////////////////// static bool isMonth (const std::string& name, int& i) { - i = Date::monthOfYear (name) - 1; + i = ISO8601d::monthOfYear (name) - 1; return i != -2 ? true : false; } //////////////////////////////////////////////////////////////////////////////// static bool isDay (const std::string& name, int& i) { - i = Date::dayOfWeek (name); + i = ISO8601d::dayOfWeek (name); return i != -1 ? true : false; } From 2b31994ce0c628e6026dae0796750b900bf3e974 Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sat, 26 Sep 2015 21:41:50 -0400 Subject: [PATCH 068/117] Test: Added more ISO601d tests --- test/iso8601d.t.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/test/iso8601d.t.cpp b/test/iso8601d.t.cpp index 1211fb5f9..b19bff0d8 100644 --- a/test/iso8601d.t.cpp +++ b/test/iso8601d.t.cpp @@ -71,7 +71,7 @@ void testParse ( //////////////////////////////////////////////////////////////////////////////// int main (int argc, char** argv) { - UnitTest t (827); + UnitTest t (828); ISO8601d iso; std::string::size_type start = 0; @@ -218,6 +218,9 @@ int main (int argc, char** argv) try { + ISO8601d now; + t.ok (now.toISO ().find ("1969") == std::string::npos, "'now' != 1969"); + // Leap year. t.ok (ISO8601d::leapYear (2008), "2008 is a leap year"); t.notok (ISO8601d::leapYear (2007), "2007 is not a leap year"); From 843e49e2bc8748d4c22160746b6328f7860cf3ac Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sat, 26 Sep 2015 21:43:58 -0400 Subject: [PATCH 069/117] Test: Added more ISO8601d tests --- test/iso8601d.t.cpp | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/test/iso8601d.t.cpp b/test/iso8601d.t.cpp index b19bff0d8..f250ee870 100644 --- a/test/iso8601d.t.cpp +++ b/test/iso8601d.t.cpp @@ -71,7 +71,7 @@ void testParse ( //////////////////////////////////////////////////////////////////////////////// int main (int argc, char** argv) { - UnitTest t (828); + UnitTest t (840); ISO8601d iso; std::string::size_type start = 0; @@ -221,6 +221,25 @@ int main (int argc, char** argv) ISO8601d now; t.ok (now.toISO ().find ("1969") == std::string::npos, "'now' != 1969"); + ISO8601d yesterday; + yesterday -= 86400; + ISO8601d tomorrow; + tomorrow += 86400; + + t.ok (yesterday <= now, "yesterday <= now"); + t.ok (yesterday < now, "yesterday < now"); + t.notok (yesterday == now, "!(yesterday == now)"); + t.ok (yesterday != now, "yesterday != now"); + t.ok (now >= yesterday, "now >= yesterday"); + t.ok (now > yesterday, "now > yesterday"); + + t.ok (tomorrow >= now, "tomorrow >= now"); + t.ok (tomorrow > now, "tomorrow > now"); + t.notok (tomorrow == now, "!(tomorrow == now)"); + t.ok (tomorrow != now, "tomorrow != now"); + t.ok (now <= tomorrow, "now <= tomorrow"); + t.ok (now < tomorrow, "now < tomorrow"); + // Leap year. t.ok (ISO8601d::leapYear (2008), "2008 is a leap year"); t.notok (ISO8601d::leapYear (2007), "2007 is not a leap year"); From 76db26e3d7ff840660a07625192812246d465964 Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sat, 26 Sep 2015 21:47:23 -0400 Subject: [PATCH 070/117] Test: Added more ISO8601d tests --- test/iso8601d.t.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/test/iso8601d.t.cpp b/test/iso8601d.t.cpp index f250ee870..cc67d4ed9 100644 --- a/test/iso8601d.t.cpp +++ b/test/iso8601d.t.cpp @@ -71,7 +71,7 @@ void testParse ( //////////////////////////////////////////////////////////////////////////////// int main (int argc, char** argv) { - UnitTest t (840); + UnitTest t (845); ISO8601d iso; std::string::size_type start = 0; @@ -300,6 +300,14 @@ int main (int argc, char** argv) t.is (ISO8601d::dayOfWeek ("Friday"), 5, "Friday == 5"); t.is (ISO8601d::dayOfWeek ("Saturday"), 6, "Saturday == 6"); + ISO8601d happyNewYear (1, 1, 2008); + t.is (happyNewYear.dayOfWeek (), 2, "1/1/2008 == Tuesday"); + t.is (happyNewYear.month (), 1, "1/1/2008 == January"); + t.is (happyNewYear.day (), 1, "1/1/2008 == 1"); + t.is (happyNewYear.year (), 2008, "1/1/2008 == 2008"); + + t.is (happyNewYear.toString (), "1/1/2008", "toString 1/1/2008"); + // int ISO8601d::length (const std::string&); t.is (ISO8601d::length ("m"), 2, "length 'm' --> 2"); t.is (ISO8601d::length ("M"), 2, "length 'M' --> 2"); From 073f978955c1f74c1566513fd87a177b80ef0f44 Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sat, 26 Sep 2015 21:49:39 -0400 Subject: [PATCH 071/117] Test: Added more ISO8601d tests --- test/iso8601d.t.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/test/iso8601d.t.cpp b/test/iso8601d.t.cpp index cc67d4ed9..d9b4f60e1 100644 --- a/test/iso8601d.t.cpp +++ b/test/iso8601d.t.cpp @@ -71,7 +71,7 @@ void testParse ( //////////////////////////////////////////////////////////////////////////////// int main (int argc, char** argv) { - UnitTest t (845); + UnitTest t (848); ISO8601d iso; std::string::size_type start = 0; @@ -308,6 +308,12 @@ int main (int argc, char** argv) t.is (happyNewYear.toString (), "1/1/2008", "toString 1/1/2008"); + int m, d, y; + happyNewYear.toMDY (m, d, y); + t.is (m, 1, "1/1/2008 == January"); + t.is (d, 1, "1/1/2008 == 1"); + t.is (y, 2008, "1/1/2008 == 2008"); + // int ISO8601d::length (const std::string&); t.is (ISO8601d::length ("m"), 2, "length 'm' --> 2"); t.is (ISO8601d::length ("M"), 2, "length 'M' --> 2"); From 12661b4bde298b44a3b93ebaa31e0d3910ba70f1 Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sat, 26 Sep 2015 21:59:12 -0400 Subject: [PATCH 072/117] Test: Added more ISO8601d tests --- test/iso8601d.t.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/test/iso8601d.t.cpp b/test/iso8601d.t.cpp index d9b4f60e1..d896f3ebd 100644 --- a/test/iso8601d.t.cpp +++ b/test/iso8601d.t.cpp @@ -71,7 +71,7 @@ void testParse ( //////////////////////////////////////////////////////////////////////////////// int main (int argc, char** argv) { - UnitTest t (848); + UnitTest t (850); ISO8601d iso; std::string::size_type start = 0; @@ -314,6 +314,11 @@ int main (int argc, char** argv) t.is (d, 1, "1/1/2008 == 1"); t.is (y, 2008, "1/1/2008 == 2008"); + ISO8601d epoch (9, 8, 2001); + t.ok ((int)epoch.toEpoch () < 1000000000, "9/8/2001 < 1,000,000,000"); + epoch += 172800; + t.ok ((int)epoch.toEpoch () > 1000000000, "9/10/2001 > 1,000,000,000"); + // int ISO8601d::length (const std::string&); t.is (ISO8601d::length ("m"), 2, "length 'm' --> 2"); t.is (ISO8601d::length ("M"), 2, "length 'M' --> 2"); From 1ff4e2ff13a3de92a232e3966145f15e5299bfbb Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sat, 26 Sep 2015 22:07:04 -0400 Subject: [PATCH 073/117] Test: Added more ISO8601d tests --- test/iso8601d.t.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/test/iso8601d.t.cpp b/test/iso8601d.t.cpp index d896f3ebd..bc9cc254d 100644 --- a/test/iso8601d.t.cpp +++ b/test/iso8601d.t.cpp @@ -71,7 +71,7 @@ void testParse ( //////////////////////////////////////////////////////////////////////////////// int main (int argc, char** argv) { - UnitTest t (850); + UnitTest t (855); ISO8601d iso; std::string::size_type start = 0; @@ -319,6 +319,16 @@ int main (int argc, char** argv) epoch += 172800; t.ok ((int)epoch.toEpoch () > 1000000000, "9/10/2001 > 1,000,000,000"); + ISO8601d iso (1000000000); + t.is (iso.toISO (), "20010909T014640Z", "1,000,000,000 -> 20010909T014640Z"); + + // Quantization. + ISO8601d quant (1234526400); + t.is (quant.startOfDay ().toString ("YMDHNS"), "20090213000000", "1234526400 -> 2/13/2009 12:00:00 UTC -> 2/13/2009 0:00:00"); + t.is (quant.startOfWeek ().toString ("YMDHNS"), "20090208000000", "1234526400 -> 2/13/2009 12:00:00 UTC -> 2/8/2009 0:00:00"); + t.is (quant.startOfMonth ().toString ("YMDHNS"), "20090201000000", "1234526400 -> 2/13/2009 12:00:00 UTC -> 2/1/2009 0:00:00"); + t.is (quant.startOfYear ().toString ("YMDHNS"), "20090101000000", "1234526400 -> 2/13/2009 12:00:00 UTC -> 1/1/2009 0:00:00"); + // int ISO8601d::length (const std::string&); t.is (ISO8601d::length ("m"), 2, "length 'm' --> 2"); t.is (ISO8601d::length ("M"), 2, "length 'M' --> 2"); From f32e53c7d638b56c3775206c27a5ee0ab75a3b68 Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sat, 26 Sep 2015 22:23:04 -0400 Subject: [PATCH 074/117] Test: Added more ISO8601d tests --- test/iso8601d.t.cpp | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/test/iso8601d.t.cpp b/test/iso8601d.t.cpp index bc9cc254d..06b7709e6 100644 --- a/test/iso8601d.t.cpp +++ b/test/iso8601d.t.cpp @@ -71,7 +71,7 @@ void testParse ( //////////////////////////////////////////////////////////////////////////////// int main (int argc, char** argv) { - UnitTest t (855); + UnitTest t (860); ISO8601d iso; std::string::size_type start = 0; @@ -329,6 +329,28 @@ int main (int argc, char** argv) t.is (quant.startOfMonth ().toString ("YMDHNS"), "20090201000000", "1234526400 -> 2/13/2009 12:00:00 UTC -> 2/1/2009 0:00:00"); t.is (quant.startOfYear ().toString ("YMDHNS"), "20090101000000", "1234526400 -> 2/13/2009 12:00:00 UTC -> 1/1/2009 0:00:00"); + // Date::operator- + ISO8601d r25 (1234567890); + t.is ((r25 - 1).toEpoch (), 1234567889, "1234567890 - 1 = 1234567889"); + + // ISO8601d::operator-- + ISO8601d r26 (11, 7, 2010, 23, 59, 59); + r26--; + t.is (r26.toString ("YMDHNS"), "20101106235959", "decrement across fall DST boundary"); + + ISO8601d r27 (3, 14, 2010, 23, 59, 59); + r27--; + t.is (r27.toString ("YMDHNS"), "20100313235959", "decrement across spring DST boundary"); + + // ISO8601d::operator++ + ISO8601d r28 (11, 6, 2010, 23, 59, 59); + r28++; + t.is (r28.toString ("YMDHNS"), "20101107235959", "increment across fall DST boundary"); + + ISO8601d r29 (3, 13, 2010, 23, 59, 59); + r29++; + t.is (r29.toString ("YMDHNS"), "20100314235959", "increment across spring DST boundary"); + // int ISO8601d::length (const std::string&); t.is (ISO8601d::length ("m"), 2, "length 'm' --> 2"); t.is (ISO8601d::length ("M"), 2, "length 'M' --> 2"); From 68c6afbdd4705198857dd7f0be244c4f4fcd55d6 Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sat, 26 Sep 2015 23:08:29 -0400 Subject: [PATCH 075/117] ISO8601d: Conversion from Date to ISO8601d --- src/Nibbler.cpp | 9 +++++---- src/columns/ColUDA.cpp | 8 +++----- src/commands/CmdCalendar.cpp | 38 ++++++++++++++++++------------------ src/commands/CmdHistory.cpp | 3 ++- 4 files changed, 29 insertions(+), 29 deletions(-) diff --git a/src/Nibbler.cpp b/src/Nibbler.cpp index b2d020f28..e025c6d42 100644 --- a/src/Nibbler.cpp +++ b/src/Nibbler.cpp @@ -32,6 +32,7 @@ #include #include #ifdef NIBBLER_FEATURE_DATE +#include #include #endif #ifdef NIBBLER_FEATURE_REGEX @@ -818,8 +819,8 @@ bool Nibbler::getDate (const std::string& format, time_t& t) ! Lexer::isDigit ((*_input)[i + 1]) && ! Lexer::isDigit ((*_input)[i + 2])) { - wday = Date::dayOfWeek (_input->substr (i, 3).c_str ()); - i += (format[f] == 'a') ? 3 : Date::dayName (wday).size (); + wday = ISO8601d::dayOfWeek (_input->substr (i, 3).c_str ()); + i += (format[f] == 'a') ? 3 : ISO8601d::dayName (wday).size (); } else return false; @@ -834,8 +835,8 @@ bool Nibbler::getDate (const std::string& format, time_t& t) { if (month != -1) return false; - month = Date::monthOfYear (_input->substr (i, 3).c_str()); - i += (format[f] == 'b') ? 3 : Date::monthName (month).size (); + month = ISO8601d::monthOfYear (_input->substr (i, 3).c_str()); + i += (format[f] == 'b') ? 3 : ISO8601d::monthName (month).size (); } else return false; diff --git a/src/columns/ColUDA.cpp b/src/columns/ColUDA.cpp index 05ab86429..45c9d69f7 100644 --- a/src/columns/ColUDA.cpp +++ b/src/columns/ColUDA.cpp @@ -27,7 +27,6 @@ #include #include #include -#include #include #include #include @@ -89,14 +88,14 @@ void ColumnUDA::measure (Task& task, unsigned int& minimum, unsigned int& maximu // rc.report..dateformat // rc.dateformat.report // rc.dateformat - Date date ((time_t) strtol (value.c_str (), NULL, 10)); + ISO8601d date ((time_t) strtol (value.c_str (), NULL, 10)); std::string format = context.config.get ("report." + _report + ".dateformat"); if (format == "") format = context.config.get ("dateformat.report"); if (format == "") format = context.config.get ("dateformat"); - minimum = maximum = Date::length (format); + minimum = maximum = ISO8601d::length (format); } else if (_type == "duration") { @@ -153,8 +152,7 @@ void ColumnUDA::render ( lines.push_back ( color.colorize ( leftJustify ( - Date ((time_t) strtol (value.c_str (), NULL, 10)) - .toString (format), width))); + ISO8601d ((time_t) strtol (value.c_str (), NULL, 10)).toString (format), width))); } else if (_type == "duration") { diff --git a/src/commands/CmdCalendar.cpp b/src/commands/CmdCalendar.cpp index d137daa3a..b294f89fa 100644 --- a/src/commands/CmdCalendar.cpp +++ b/src/commands/CmdCalendar.cpp @@ -99,7 +99,7 @@ int CmdCalendar::execute (std::string& output) // Set up a vector of months, for autoComplete. std::vector monthNames; for (int i = 1; i <= 12; ++i) - monthNames.push_back (lowerCase (Date::monthName (i))); + monthNames.push_back (lowerCase (ISO8601d::monthName (i))); // For autoComplete results. std::vector matches; @@ -140,7 +140,7 @@ int CmdCalendar::execute (std::string& output) // "January" etc. else if (autoComplete (lowerCase (arg), monthNames, matches, context.config.getInteger ("abbreviation.minimum")) == 1) { - argMonth = Date::monthOfYear (matches[0]); + argMonth = ISO8601d::monthOfYear (matches[0]); if (argMonth == -1) throw format (STRING_CMD_CAL_BAD_MONTH, arg); } @@ -235,7 +235,7 @@ int CmdCalendar::execute (std::string& output) // Print month headers (cheating on the width settings, yes) for (int i = 0 ; i < monthsPerLine ; i++) { - std::string month = Date::monthName (nextM); + std::string month = ISO8601d::monthName (nextM); // 12345678901234567890123456 = 26 chars wide // ^^ = center @@ -426,7 +426,7 @@ std::string CmdCalendar::renderMonths ( int monthsPerLine) { // What day of the week does the user consider the first? - int weekStart = Date::dayOfWeek (context.config.get ("weekstart")); + int weekStart = ISO8601d::dayOfWeek (context.config.get ("weekstart")); if (weekStart != 0 && weekStart != 1) throw std::string (STRING_CMD_CAL_SUN_MON); @@ -441,24 +441,24 @@ std::string CmdCalendar::renderMonths ( if (weekStart == 1) { view.add (Column::factory ("string.right", " ")); - view.add (Column::factory ("string.right", utf8_substr (Date::dayName (1), 0, 2))); - view.add (Column::factory ("string.right", utf8_substr (Date::dayName (2), 0, 2))); - view.add (Column::factory ("string.right", utf8_substr (Date::dayName (3), 0, 2))); - view.add (Column::factory ("string.right", utf8_substr (Date::dayName (4), 0, 2))); - view.add (Column::factory ("string.right", utf8_substr (Date::dayName (5), 0, 2))); - view.add (Column::factory ("string.right", utf8_substr (Date::dayName (6), 0, 2))); - view.add (Column::factory ("string.right", utf8_substr (Date::dayName (0), 0, 2))); + view.add (Column::factory ("string.right", utf8_substr (ISO8601d::dayName (1), 0, 2))); + view.add (Column::factory ("string.right", utf8_substr (ISO8601d::dayName (2), 0, 2))); + view.add (Column::factory ("string.right", utf8_substr (ISO8601d::dayName (3), 0, 2))); + view.add (Column::factory ("string.right", utf8_substr (ISO8601d::dayName (4), 0, 2))); + view.add (Column::factory ("string.right", utf8_substr (ISO8601d::dayName (5), 0, 2))); + view.add (Column::factory ("string.right", utf8_substr (ISO8601d::dayName (6), 0, 2))); + view.add (Column::factory ("string.right", utf8_substr (ISO8601d::dayName (0), 0, 2))); } else { view.add (Column::factory ("string.right", " ")); - view.add (Column::factory ("string.right", utf8_substr (Date::dayName (0), 0, 2))); - view.add (Column::factory ("string.right", utf8_substr (Date::dayName (1), 0, 2))); - view.add (Column::factory ("string.right", utf8_substr (Date::dayName (2), 0, 2))); - view.add (Column::factory ("string.right", utf8_substr (Date::dayName (3), 0, 2))); - view.add (Column::factory ("string.right", utf8_substr (Date::dayName (4), 0, 2))); - view.add (Column::factory ("string.right", utf8_substr (Date::dayName (5), 0, 2))); - view.add (Column::factory ("string.right", utf8_substr (Date::dayName (6), 0, 2))); + view.add (Column::factory ("string.right", utf8_substr (ISO8601d::dayName (0), 0, 2))); + view.add (Column::factory ("string.right", utf8_substr (ISO8601d::dayName (1), 0, 2))); + view.add (Column::factory ("string.right", utf8_substr (ISO8601d::dayName (2), 0, 2))); + view.add (Column::factory ("string.right", utf8_substr (ISO8601d::dayName (3), 0, 2))); + view.add (Column::factory ("string.right", utf8_substr (ISO8601d::dayName (4), 0, 2))); + view.add (Column::factory ("string.right", utf8_substr (ISO8601d::dayName (5), 0, 2))); + view.add (Column::factory ("string.right", utf8_substr (ISO8601d::dayName (6), 0, 2))); } } @@ -511,7 +511,7 @@ std::string CmdCalendar::renderMonths ( // Loop through days in month and add to table. for (int d = 1; d <= daysInMonth[mpl]; ++d) { - Date temp (months[mpl], d, years[mpl]); + ISO8601d temp (months[mpl], d, years[mpl]); int dow = temp.dayOfWeek (); int woy = temp.weekOfYear (weekStart); diff --git a/src/commands/CmdHistory.cpp b/src/commands/CmdHistory.cpp index 335648c8d..dc81af131 100644 --- a/src/commands/CmdHistory.cpp +++ b/src/commands/CmdHistory.cpp @@ -32,6 +32,7 @@ #include #include #include +#include #include extern Context context; @@ -136,7 +137,7 @@ int CmdHistoryMonthly::execute (std::string& output) view.set (row, 0, y); priorYear = y; } - view.set (row, 1, Date::monthName(m)); + view.set (row, 1, ISO8601d::monthName(m)); int net = 0; From 244a80f799af40de78c50c638b0bcf3b711b0726 Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sat, 26 Sep 2015 23:20:08 -0400 Subject: [PATCH 076/117] ISO8601: Migrated more Date instances to ISO8601d --- src/Config.cpp | 4 ++-- src/columns/ColDate.cpp | 2 +- src/columns/ColDescription.cpp | 12 ++++++------ src/commands/CmdBurndown.cpp | 2 +- src/commands/CmdHistory.cpp | 2 +- src/commands/CmdTimesheet.cpp | 3 ++- 6 files changed, 13 insertions(+), 12 deletions(-) diff --git a/src/Config.cpp b/src/Config.cpp index f726176e0..f6617f766 100644 --- a/src/Config.cpp +++ b/src/Config.cpp @@ -33,7 +33,7 @@ #include #include #include -#include +#include #include #include #include @@ -574,7 +574,7 @@ void Config::createDefaultRC (const std::string& rc, const std::string& data) auto loc = _defaults.find ("data.location=~/.task"); // loc+0^ +14^ +21^ - Date now; + ISO8601d now; std::stringstream contents; contents << "# [Created by " << PACKAGE_STRING diff --git a/src/columns/ColDate.cpp b/src/columns/ColDate.cpp index a35a6d386..6bc4e87c7 100644 --- a/src/columns/ColDate.cpp +++ b/src/columns/ColDate.cpp @@ -89,7 +89,7 @@ void ColumnDate::measure (Task& task, unsigned int& minimum, unsigned int& maxim if (format == "") format = context.config.get ("dateformat"); - minimum = maximum = Date::length (format); + minimum = maximum = ISO8601d::length (format); } else if (_style == "countdown") { diff --git a/src/columns/ColDescription.cpp b/src/columns/ColDescription.cpp index abf376db9..4d4304e47 100644 --- a/src/columns/ColDescription.cpp +++ b/src/columns/ColDescription.cpp @@ -27,7 +27,7 @@ #include #include #include -#include +#include #include #include #include @@ -55,7 +55,7 @@ ColumnDescription::ColumnDescription () if (_dateformat == "") _dateformat = context.config.get ("dateformat"); - std::string t = Date ().toString (_dateformat); + std::string t = ISO8601d ().toString (_dateformat); std::string d = STRING_COLUMN_EXAMPLES_DESC; std::string a1 = STRING_COLUMN_EXAMPLES_ANNO1; std::string a2 = STRING_COLUMN_EXAMPLES_ANNO2; @@ -102,7 +102,7 @@ void ColumnDescription::measure (Task& task, unsigned int& minimum, unsigned int if (task.annotation_count) { - unsigned int min_anno = _indent + Date::length (_dateformat); + unsigned int min_anno = _indent + ISO8601d::length (_dateformat); if (min_anno > minimum) minimum = min_anno; @@ -132,7 +132,7 @@ void ColumnDescription::measure (Task& task, unsigned int& minimum, unsigned int if (task.annotation_count) { - auto min_anno = Date::length (_dateformat); + auto min_anno = ISO8601d::length (_dateformat); std::map annos; task.getAnnotations (annos); for (auto& i : annos) @@ -187,7 +187,7 @@ void ColumnDescription::render ( { for (auto& i : annos) { - Date dt (strtol (i.first.substr (11).c_str (), NULL, 10)); + ISO8601d dt (strtol (i.first.substr (11).c_str (), NULL, 10)); description += "\n" + std::string (_indent, ' ') + dt.toString (_dateformat) + " " + i.second; } } @@ -218,7 +218,7 @@ void ColumnDescription::render ( { for (auto& i : annos) { - Date dt (atoi (i.first.substr (11).c_str ())); + ISO8601d dt (strtol (i.first.substr (11).c_str (), NULL, 10)); description += " " + dt.toString (_dateformat) + " " + i.second; } } diff --git a/src/commands/CmdBurndown.cpp b/src/commands/CmdBurndown.cpp index 9ea606b5c..924b487b5 100644 --- a/src/commands/CmdBurndown.cpp +++ b/src/commands/CmdBurndown.cpp @@ -744,7 +744,7 @@ void Chart::generateBars () { case 'D': // month/day { - std::string month = Date::monthName (cursor.month ()); + std::string month = ISO8601d::monthName (cursor.month ()); bar._major_label = month.substr (0, 3); sprintf (str, "%02d", cursor.day ()); diff --git a/src/commands/CmdHistory.cpp b/src/commands/CmdHistory.cpp index dc81af131..4280d6387 100644 --- a/src/commands/CmdHistory.cpp +++ b/src/commands/CmdHistory.cpp @@ -478,7 +478,7 @@ int CmdGHistoryMonthly::execute (std::string& output) view.set (row, 0, y); priorYear = y; } - view.set (row, 1, Date::monthName(m)); + view.set (row, 1, ISO8601d::monthName(m)); unsigned int addedBar = (widthOfBar * addedGroup[i.first]) / maxLine; unsigned int completedBar = (widthOfBar * completedGroup[i.first]) / maxLine; diff --git a/src/commands/CmdTimesheet.cpp b/src/commands/CmdTimesheet.cpp index 775213f69..4afa20393 100644 --- a/src/commands/CmdTimesheet.cpp +++ b/src/commands/CmdTimesheet.cpp @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -64,7 +65,7 @@ int CmdTimesheet::execute (std::string& output) std::vector all = context.tdb2.all_tasks (); // What day of the week does the user consider the first? - int weekStart = Date::dayOfWeek (context.config.get ("weekstart")); + int weekStart = ISO8601d::dayOfWeek (context.config.get ("weekstart")); if (weekStart != 0 && weekStart != 1) throw std::string (STRING_DATE_BAD_WEEKSTART); From b8977c4dd0fd8ebeab154fa3bf91b0873537495b Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sat, 26 Sep 2015 23:25:20 -0400 Subject: [PATCH 077/117] Test: Added more ISO8601d tests --- test/iso8601d.t.cpp | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/test/iso8601d.t.cpp b/test/iso8601d.t.cpp index 06b7709e6..2aa098532 100644 --- a/test/iso8601d.t.cpp +++ b/test/iso8601d.t.cpp @@ -71,7 +71,7 @@ void testParse ( //////////////////////////////////////////////////////////////////////////////// int main (int argc, char** argv) { - UnitTest t (860); + UnitTest t (869); ISO8601d iso; std::string::size_type start = 0; @@ -240,6 +240,22 @@ int main (int argc, char** argv) t.ok (now <= tomorrow, "now <= tomorrow"); t.ok (now < tomorrow, "now < tomorrow"); + // Date::Date ("now") + context.config.set ("weekstart", "monday"); + ISO8601d relative_now; + t.ok (relative_now.sameHour (now), "Date ().sameHour (Date (now))"); + t.ok (relative_now.sameDay (now), "Date ().sameDay (Date (now))"); + t.ok (relative_now.sameWeek (now), "Date ().sameWeek (Date (now))"); + t.ok (relative_now.sameMonth (now), "Date ().sameMonth (Date (now))"); + t.ok (relative_now.sameYear (now), "Date ().sameYear (Date (now))"); + + // Validity. + t.ok (ISO8601d::valid (2, 29, 2008), "valid: 2/29/2008"); + t.notok (ISO8601d::valid (2, 29, 2007), "invalid: 2/29/2007"); + + t.ok (ISO8601d::valid (366, 2008), "valid: 366 days in 2008"); + t.notok (ISO8601d::valid (366, 2007), "invalid: 366 days in 2007"); + // Leap year. t.ok (ISO8601d::leapYear (2008), "2008 is a leap year"); t.notok (ISO8601d::leapYear (2007), "2007 is not a leap year"); From dbb6a209a80352adfeca0ed01e0f170388b9f121 Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sun, 27 Sep 2015 00:18:38 -0400 Subject: [PATCH 078/117] ISO8601: Added formatted date parsing --- src/ISO8601.cpp | 25 ++++- src/ISO8601.h | 2 +- test/iso8601d.t.cpp | 234 +++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 257 insertions(+), 4 deletions(-) diff --git a/src/ISO8601.cpp b/src/ISO8601.cpp index 7c99ed86b..8d3114f1c 100644 --- a/src/ISO8601.cpp +++ b/src/ISO8601.cpp @@ -119,6 +119,17 @@ ISO8601d::ISO8601d () _date = time (NULL); } +//////////////////////////////////////////////////////////////////////////////// +ISO8601d::ISO8601d (const std::string& input, const std::string& format /*= ""*/) +{ + clear (); + std::string::size_type start = 0; + if (parse (input, start, format)) + return; + + throw ::format (STRING_DATE_INVALID_FORMAT, input, format); +} + //////////////////////////////////////////////////////////////////////////////// ISO8601d::ISO8601d (const time_t t) { @@ -222,8 +233,20 @@ bool ISO8601d::parse ( const std::string& format /* = "" */) { auto i = start; - Nibbler n (input.substr (i)); + // Look for a formatted date, if a format is present. + if (format != "") + { + Nibbler n (input.substr (i)); + if (n.getDate (format, _date)) + { + start = n.cursor (); + return true; + } + } + + // Look for an ISO date. + Nibbler n (input.substr (i)); if (parse_date_time (n) || // Strictest first. parse_date_time_ext (n) || parse_date_ext (n) || diff --git a/src/ISO8601.h b/src/ISO8601.h index 94dc69427..b2cd519af 100644 --- a/src/ISO8601.h +++ b/src/ISO8601.h @@ -38,11 +38,11 @@ public: static int minimumMatchLength; ISO8601d (); + ISO8601d (const std::string&, const std::string& format = ""); ISO8601d (time_t); ISO8601d (const int, const int, const int); ISO8601d (const int, const int, const int, const int, const int, const int); ~ISO8601d (); - ISO8601d (const ISO8601d&); // Unimplemented operator time_t () const; bool parse (const std::string&, std::string::size_type&, const std::string& format = ""); diff --git a/test/iso8601d.t.cpp b/test/iso8601d.t.cpp index 2aa098532..ff80bf17d 100644 --- a/test/iso8601d.t.cpp +++ b/test/iso8601d.t.cpp @@ -71,7 +71,7 @@ void testParse ( //////////////////////////////////////////////////////////////////////////////// int main (int argc, char** argv) { - UnitTest t (869); + UnitTest t (865); ISO8601d iso; std::string::size_type start = 0; @@ -249,13 +249,53 @@ int main (int argc, char** argv) t.ok (relative_now.sameMonth (now), "Date ().sameMonth (Date (now))"); t.ok (relative_now.sameYear (now), "Date ().sameYear (Date (now))"); +/* + // Loose comparisons. + ISO8601d left ("7/4/2008", "m/d/Y"); + ISO8601d comp1 ("7/4/2008", "m/d/Y"); + t.ok (left.sameDay (comp1), "7/4/2008 is on the same day as 7/4/2008"); + t.ok (left.sameWeek (comp1), "7/4/2008 is on the same week as 7/4/2008"); + t.ok (left.sameMonth (comp1), "7/4/2008 is in the same month as 7/4/2008"); + t.ok (left.sameYear (comp1), "7/4/2008 is in the same year as 7/4/2008"); + + ISO8601d comp2 ("7/5/2008", "m/d/Y"); + t.notok (left.sameDay (comp2), "7/4/2008 is not on the same day as 7/5/2008"); + t.ok (left.sameMonth (comp2), "7/4/2008 is in the same month as 7/5/2008"); + t.ok (left.sameYear (comp2), "7/4/2008 is in the same year as 7/5/2008"); + + ISO8601d comp3 ("8/4/2008", "m/d/Y"); + t.notok (left.sameDay (comp3), "7/4/2008 is not on the same day as 8/4/2008"); + t.notok (left.sameWeek (comp3), "7/4/2008 is not on the same week as 8/4/2008"); + t.notok (left.sameMonth (comp3), "7/4/2008 is not in the same month as 8/4/2008"); + t.ok (left.sameYear (comp3), "7/4/2008 is in the same year as 8/4/2008"); + + ISO8601d comp4 ("7/4/2009", "m/d/Y"); + t.notok (left.sameDay (comp4), "7/4/2008 is not on the same day as 7/4/2009"); + t.notok (left.sameWeek (comp3), "7/4/2008 is not on the same week as 7/4/2009"); + t.notok (left.sameMonth (comp4), "7/4/2008 is not in the same month as 7/4/2009"); + t.notok (left.sameYear (comp4), "7/4/2008 is not in the same year as 7/4/2009"); +*/ + // Validity. t.ok (ISO8601d::valid (2, 29, 2008), "valid: 2/29/2008"); t.notok (ISO8601d::valid (2, 29, 2007), "invalid: 2/29/2007"); +/* + t.ok (Date::valid ("2/29/2008"), "valid: 2/29/2008"); + t.notok (Date::valid ("2/29/2007"), "invalid: 2/29/2007"); +*/ + t.ok (ISO8601d::valid (366, 2008), "valid: 366 days in 2008"); t.notok (ISO8601d::valid (366, 2007), "invalid: 366 days in 2007"); +/* + // Time validity. + t.ok (Date::valid (2, 28, 2010, 0, 0, 0), "valid 2/28/2010 0:00:00"); + t.ok (Date::valid (2, 28, 2010, 23, 59, 59), "valid 2/28/2010 23:59:59"); + t.notok (Date::valid (2, 28, 2010, 24, 59, 59), "valid 2/28/2010 24:59:59"); + t.notok (Date::valid (2, 28, 2010, -1, 0, 0), "valid 2/28/2010 -1:00:00"); +*/ + // Leap year. t.ok (ISO8601d::leapYear (2008), "2008 is a leap year"); t.notok (ISO8601d::leapYear (2007), "2007 is not a leap year"); @@ -335,9 +375,15 @@ int main (int argc, char** argv) epoch += 172800; t.ok ((int)epoch.toEpoch () > 1000000000, "9/10/2001 > 1,000,000,000"); +/* + Date fromEpoch (epoch.toEpoch ()); + t.is (fromEpoch.toString (), epoch.toString (), "ctor (time_t)"); +*/ + ISO8601d iso (1000000000); t.is (iso.toISO (), "20010909T014640Z", "1,000,000,000 -> 20010909T014640Z"); +/* // Quantization. ISO8601d quant (1234526400); t.is (quant.startOfDay ().toString ("YMDHNS"), "20090213000000", "1234526400 -> 2/13/2009 12:00:00 UTC -> 2/13/2009 0:00:00"); @@ -345,7 +391,180 @@ int main (int argc, char** argv) t.is (quant.startOfMonth ().toString ("YMDHNS"), "20090201000000", "1234526400 -> 2/13/2009 12:00:00 UTC -> 2/1/2009 0:00:00"); t.is (quant.startOfYear ().toString ("YMDHNS"), "20090101000000", "1234526400 -> 2/13/2009 12:00:00 UTC -> 1/1/2009 0:00:00"); - // Date::operator- + // Date parsing. + ISO8601d fromString1 ("1/1/2008", "m/d/Y"); + t.is (fromString1.month (), 1, "ctor (std::string) -> m"); + t.is (fromString1.day (), 1, "ctor (std::string) -> d"); + t.is (fromString1.year (), 2008, "ctor (std::string) -> y"); + + ISO8601d fromString2 ("20080101", "YMD"); + t.is (fromString2.month (), 1, "ctor (std::string) -> m"); + t.is (fromString2.day (), 1, "ctor (std::string) -> d"); + t.is (fromString2.year (), 2008, "ctor (std::string) -> y"); + + ISO8601d fromString3 ("12/31/2007", "m/d/Y"); + t.is (fromString3.month (), 12, "ctor (std::string) -> m"); + t.is (fromString3.day (), 31, "ctor (std::string) -> d"); + t.is (fromString3.year (), 2007, "ctor (std::string) -> y"); + + ISO8601d fromString4 ("01/01/2008", "m/d/Y"); + t.is (fromString4.month (), 1, "ctor (std::string) -> m"); + t.is (fromString4.day (), 1, "ctor (std::string) -> d"); + t.is (fromString4.year (), 2008, "ctor (std::string) -> y"); + + ISO8601d fromString5 ("Tue 05 Feb 2008 (06)", "a D b Y (V)"); + t.is (fromString5.month (), 2, "ctor (std::string) -> m"); + t.is (fromString5.day (), 5, "ctor (std::string) -> d"); + t.is (fromString5.year (), 2008, "ctor (std::string) -> y"); + + ISO8601d fromString6 ("Tuesday, February 5, 2008", "A, B d, Y"); + t.is (fromString6.month (), 2, "ctor (std::string) -> m"); + t.is (fromString6.day (), 5, "ctor (std::string) -> d"); + t.is (fromString6.year (), 2008, "ctor (std::string) -> y"); + + ISO8601d fromString7 ("w01 Tue 2008-01-01", "wV a Y-M-D"); + t.is (fromString7.month (), 1, "ctor (std::string) -> m"); + t.is (fromString7.day (), 1, "ctor (std::string) -> d"); + t.is (fromString7.year (), 2008, "ctor (std::string) -> y"); + + ISO8601d fromString8 ("6/7/2010 1:23:45", "m/d/Y h:N:S"); + t.is (fromString8.month (), 6, "ctor (std::string) -> m"); + t.is (fromString8.day (), 7, "ctor (std::string) -> d"); + t.is (fromString8.year (), 2010, "ctor (std::string) -> Y"); + t.is (fromString8.hour (), 1, "ctor (std::string) -> h"); + t.is (fromString8.minute (), 23, "ctor (std::string) -> N"); + t.is (fromString8.second (), 45, "ctor (std::string) -> S"); + + ISO8601d fromString9 ("6/7/2010 01:23:45", "m/d/Y H:N:S"); + t.is (fromString9.month (), 6, "ctor (std::string) -> m"); + t.is (fromString9.day (), 7, "ctor (std::string) -> d"); + t.is (fromString9.year (), 2010, "ctor (std::string) -> Y"); + t.is (fromString9.hour (), 1, "ctor (std::string) -> h"); + t.is (fromString9.minute (), 23, "ctor (std::string) -> N"); + t.is (fromString9.second (), 45, "ctor (std::string) -> S"); + + ISO8601d fromString10 ("6/7/2010 12:34:56", "m/d/Y H:N:S"); + t.is (fromString10.month (), 6, "ctor (std::string) -> m"); + t.is (fromString10.day (), 7, "ctor (std::string) -> d"); + t.is (fromString10.year (), 2010, "ctor (std::string) -> Y"); + t.is (fromString10.hour (), 12, "ctor (std::string) -> h"); + t.is (fromString10.minute (), 34, "ctor (std::string) -> N"); + t.is (fromString1.second (), 56, "ctor (std::string) -> S"); + + // Day of year + t.is (ISO8601d ("1/1/2011", "m/d/Y").dayOfYear (), 1, "dayOfYear (1/1/2011) -> 1"); + t.is (ISO8601d ("5/1/2011", "m/d/Y").dayOfYear (), 121, "dayOfYear (5/1/2011) -> 121"); + t.is (ISO8601d ("12/31/2011", "m/d/Y").dayOfYear (), 365, "dayOfYear (12/31/2011) -> 365"); + + // Relative dates. + Date r1 ("today"); + t.ok (r1.sameDay (now), "today = now"); + + Date r4 ("sunday"); + if (now.dayOfWeek () >= 0) + t.ok (r4.sameDay (now + (0 - now.dayOfWeek () + 7) * 86400), "next sunday"); + else + t.ok (r4.sameDay (now + (0 - now.dayOfWeek ()) * 86400), "next sunday");; + + Date r5 ("monday"); + if (now.dayOfWeek () >= 1) + t.ok (r5.sameDay (now + (1 - now.dayOfWeek () + 7) * 86400), "next monday"); + else + t.ok (r5.sameDay (now + (1 - now.dayOfWeek ()) * 86400), "next monday");; + + Date r6 ("tuesday"); + if (now.dayOfWeek () >= 2) + t.ok (r6.sameDay (now + (2 - now.dayOfWeek () + 7) * 86400), "next tuesday"); + else + t.ok (r6.sameDay (now + (2 - now.dayOfWeek ()) * 86400), "next tuesday");; + + Date r7 ("wednesday"); + if (now.dayOfWeek () >= 3) + t.ok (r7.sameDay (now + (3 - now.dayOfWeek () + 7) * 86400), "next wednesday"); + else + t.ok (r7.sameDay (now + (3 - now.dayOfWeek ()) * 86400), "next wednesday");; + + Date r8 ("thursday"); + if (now.dayOfWeek () >= 4) + t.ok (r8.sameDay (now + (4 - now.dayOfWeek () + 7) * 86400), "next thursday"); + else + t.ok (r8.sameDay (now + (4 - now.dayOfWeek ()) * 86400), "next thursday");; + + Date r9 ("friday"); + if (now.dayOfWeek () >= 5) + t.ok (r9.sameDay (now + (5 - now.dayOfWeek () + 7) * 86400), "next friday"); + else + t.ok (r9.sameDay (now + (5 - now.dayOfWeek ()) * 86400), "next friday");; + + Date r10 ("saturday"); + if (now.dayOfWeek () >= 6) + t.ok (r10.sameDay (now + (6 - now.dayOfWeek () + 7) * 86400), "next saturday"); + else + t.ok (r10.sameDay (now + (6 - now.dayOfWeek ()) * 86400), "next saturday");; + + Date r11 ("eow"); + t.ok (r11 < now + (8 * 86400), "eow < 7 days away"); + + Date r12 ("eocw"); + t.ok (r12 > now - (8 * 86400), "eocw < 7 days in the past"); + + Date r13 ("eom"); + t.ok (r13.sameMonth (now), "eom in same month as now"); + + Date r14 ("eocm"); + t.ok (r14.sameMonth (now), "eocm in same month as now"); + + Date r15 ("eoy"); + t.ok (r15.sameYear (now), "eoy in same year as now"); + + Date r16 ("sow"); + t.ok (r16 < now + (8 * 86400), "sow < 7 days away"); + + Date r23 ("socw"); + t.ok (r23 > now - (8 * 86400), "sow < 7 days in the past"); + + Date r17 ("som"); + t.notok (r17.sameMonth (now), "som not in same month as now"); + + Date r18 ("socm"); + t.ok (r18.sameMonth (now), "socm in same month as now"); + + Date r19 ("soy"); + t.notok (r19.sameYear (now), "soy not in same year as now"); + + Date first ("1st"); + t.notok (first.sameMonth (now), "1st not in same month as now"); + t.is (first.day (), 1, "1st day is 1"); + + Date later ("later"); + t.is (later.month (), 1, "later -> m = 1"); + t.is (later.day (), 18, "later -> d = 18"); + t.is (later.year (), 2038, "later -> y = 2038"); + + // Quarters + Date soq ("soq"); + Date eoq ("eoq"); + t.is (soq.day (), 1, "soq is the first day of a month"); + t.is (eoq.day () / 10, 3, "eoq is the 30th or 31th of a month"); + t.is (soq.month () % 3, 1, "soq month is 1, 4, 7 or 10"); + t.is (eoq.month () % 3, 0, "eoq month is 3, 6, 9 or 12"); + + // Note: these fail during the night of daylight savings end. + t.ok (soq.sameYear (now) || + (now.month () >= 10 && + soq.year () == now.year () + 1), "soq is in same year as now"); + t.ok (eoq.sameYear (now), "eoq is in same year as now"); + + // ISO8601d::sameHour + ISO8601d r20 ("6/7/2010 01:00:00", "m/d/Y H:N:S"); + ISO8601d r21 ("6/7/2010 01:59:59", "m/d/Y H:N:S"); + t.ok (r20.sameHour (r21), "two dates within the same hour"); + + ISO8601d r22 ("6/7/2010 00:59:59", "m/d/Y H:N:S"); + t.notok (r20.sameHour (r22), "two dates not within the same hour"); +*/ + + // ISO8601d::operator- ISO8601d r25 (1234567890); t.is ((r25 - 1).toEpoch (), 1234567889, "1234567890 - 1 = 1234567889"); @@ -390,6 +609,17 @@ int main (int argc, char** argv) t.is (ISO8601d::length ("J"), 3, "length 'J' --> 3"); t.is (ISO8601d::length (" "), 1, "length ' ' --> 1"); + +/* + // Depletion requirement. + ISO8601d r30 ("Mon Jun 30 2014", "a b D Y"); + t.is (r30.toString ("YMDHNS"), "20140630000000", "Depletion required on complex format with spaces"); + + std::string::size_type i = 0; + ISO8601d r31 ("Mon Jun 30 2014 xxx", i, "a b D Y", false, false); + t.is (r31.toString ("YMDHNS"), "20140630000000", "Depletion not required on complex format with spaces"); + t.is ((int)i, 15, "Depletion not required on complex format with spaces, 15 chars"); +*/ } catch (const std::string& e) From d11b5de3b4a55a869678b85b92913c0177de8421 Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sun, 27 Sep 2015 02:03:00 -0400 Subject: [PATCH 079/117] Nibbler: Code formatting --- src/Nibbler.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Nibbler.cpp b/src/Nibbler.cpp index e025c6d42..44ac6b6f2 100644 --- a/src/Nibbler.cpp +++ b/src/Nibbler.cpp @@ -708,7 +708,8 @@ bool Nibbler::getDateISO (time_t& t) // Parse the longest integer using the next 'limit' characters of 'result' // following position 'i' (when strict is true, the number of digits must be // equal to limit). -bool Nibbler::parseDigits(std::string::size_type& i, +bool Nibbler::parseDigits( + std::string::size_type& i, int& result, unsigned int limit, bool strict /* = true */) From f294bc0c2b61511eaf5cbd16f1e510d7aa12a382 Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sun, 27 Sep 2015 02:08:40 -0400 Subject: [PATCH 080/117] ISO8601d: Integrated formatted dates into ISO8601d - Eliminated call to Nibbler::getDate. - Created structure for Named dates and Epochs, still to be integrated. --- src/ISO8601.cpp | 359 ++++++++++++++++++++++++++++++++++++++++++++---- src/ISO8601.h | 5 +- 2 files changed, 337 insertions(+), 27 deletions(-) diff --git a/src/ISO8601.cpp b/src/ISO8601.cpp index 8d3114f1c..c734c071a 100644 --- a/src/ISO8601.cpp +++ b/src/ISO8601.cpp @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -124,10 +125,8 @@ ISO8601d::ISO8601d (const std::string& input, const std::string& format /*= ""*/ { clear (); std::string::size_type start = 0; - if (parse (input, start, format)) - return; - - throw ::format (STRING_DATE_INVALID_FORMAT, input, format); + if (! parse (input, start, format)) + throw ::format (STRING_DATE_INVALID_FORMAT, input, format); } //////////////////////////////////////////////////////////////////////////////// @@ -233,26 +232,16 @@ bool ISO8601d::parse ( const std::string& format /* = "" */) { auto i = start; - - // Look for a formatted date, if a format is present. - if (format != "") - { - Nibbler n (input.substr (i)); - if (n.getDate (format, _date)) - { - start = n.cursor (); - return true; - } - } - - // Look for an ISO date. Nibbler n (input.substr (i)); - if (parse_date_time (n) || // Strictest first. - parse_date_time_ext (n) || - parse_date_ext (n) || - parse_time_utc_ext (n) || - parse_time_off_ext (n) || - parse_time_ext (n)) // Time last, as it is the most permissive. + if (parse_formatted (n, format) || + parse_date_time (n) || // Strictest first. + parse_date_time_ext (n) || + parse_date_ext (n) || + parse_time_utc_ext (n) || + parse_time_off_ext (n) || + parse_time_ext (n) || + parse_named (n) || + parse_epoch (n)) // Time last, as it is the most permissive. { // Check the values and determine time_t. if (validate ()) @@ -283,6 +272,326 @@ void ISO8601d::clear () _date = 0; } +//////////////////////////////////////////////////////////////////////////////// +bool ISO8601d::parse_formatted (Nibbler& n, const std::string& format) +{ + // Short-circuit on missing format. + if (format == "") + return false; + + n.save (); + + int month = -1; // So we can check later. + int day = -1; + int year = -1; + int hour = -1; + int minute = -1; + int second = -1; + + // For parsing, unused. + int wday = -1; + int week = -1; + + for (unsigned int f = 0; f < format.length (); ++f) + { + switch (format[f]) + { + case 'm': + if (n.getDigit (month)) + { + if (month == 1) + if (n.getDigit (month)) + month += 10; + } + else + { + n.restore (); + return false; + } + break; + + case 'M': + if (! n.getDigit2 (month)) + { + n.restore (); + return false; + } + break; + + case 'd': + if (n.getDigit (day)) + { + if (day == 1 || day == 2 || day == 3) + { + int tens = day; + if (n.getDigit (day)) + day += 10 * tens; + } + } + else + { + n.restore (); + return false; + } + break; + + case 'D': + if (! n.getDigit2 (day)) + { + n.restore (); + return false; + } + break; + + case 'y': + if (! n.getDigit2 (year)) + { + n.restore (); + return false; + } + year += 2000; + break; + + case 'Y': + if (! n.getDigit4 (year)) + { + n.restore (); + return false; + } + break; + + case 'h': + if (n.getDigit (hour)) + { + if (hour == 1 || hour == 2) + { + int tens = hour; + if (n.getDigit (hour)) + hour += 10 * tens; + } + } + else + { + n.restore (); + return false; + } + break; + + case 'H': + if (! n.getDigit2 (hour)) + { + n.restore (); + return false; + } + break; + + case 'n': + if (n.getDigit (minute)) + { + if (minute < 6) + { + int tens = minute; + if (n.getDigit (minute)) + minute += 10 * tens; + } + } + else + { + n.restore (); + return false; + } + break; + + case 'N': + if (! n.getDigit2 (minute)) + { + n.restore (); + return false; + } + break; + + case 's': + if (n.getDigit (second)) + { + if (second < 6) + { + int tens = second; + if (n.getDigit (second)) + second += 10 * tens; + } + } + else + { + n.restore (); + return false; + } + break; + + case 'S': + if (! n.getDigit2 (second)) + { + n.restore (); + return false; + } + break; + + case 'v': + if (n.getDigit (week)) + { + if (week < 6) + { + int tens = week; + if (n.getDigit (week)) + week += 10 * tens; + } + } + else + { + n.restore (); + return false; + } + break; + + case 'V': + if (! n.getDigit2 (week)) + { + n.restore (); + return false; + } + break; + + case 'a': + { + auto cursor = n.cursor (); + wday = ISO8601d::dayOfWeek (n.str ().substr (cursor, 3)); + if (wday == -1) + { + n.restore (); + return false; + } + + n.skipN (3); + } + break; + + case 'A': + { + auto cursor = n.cursor (); + wday = ISO8601d::dayOfWeek (n.str ().substr (cursor)); + if (wday == -1) + { + n.restore (); + return false; + } + + n.skipN (ISO8601d::dayName (wday).size ()); + } + break; + + case 'b': + { + auto cursor = n.cursor (); + month = ISO8601d::monthOfYear (n.str ().substr (cursor, 3)); + if (month == -1) + { + n.restore (); + return false; + } + + n.skipN (3); + } + break; + + case 'B': + { + auto cursor = n.cursor (); + month = ISO8601d::dayOfWeek (n.str ().substr (cursor)); + if (month == -1) + { + n.restore (); + return false; + } + + n.skipN (ISO8601d::monthName (month).size ()); + } + break; + + default: + if (! n.skip (format[f])) + { + n.restore (); + return false; + } + break; + } + } + + // Missing values are filled in from the current date. + if (year == -1) + { + ISO8601d now; + year = now.year (); + if (month == -1) + { + month = now.month (); + if (day == -1) + { + day = now.day (); + if (hour == -1) + { + hour = now.hour (); + if (minute == -1) + { + minute = now.minute (); + if (second == -1) + second = now.second (); + } + } + } + } + } + + // Any remaining undefined values are assigned defaults. + if (month == -1) month = 1; + if (day == -1) day = 1; + if (hour == -1) hour = 0; + if (minute == -1) minute = 0; + if (second == -1) second = 0; + + _year = year; + _month = month; + _day = day; + _seconds = (hour * 3600) + (minute * 60) + second; + + return true; +} + +//////////////////////////////////////////////////////////////////////////////// +bool ISO8601d::parse_named (Nibbler& n) +{ +/* + Variant v; + if (namedDates (input, v)) + { + _date = v.get_date (); + return true; + } +*/ + + return false; +} + +//////////////////////////////////////////////////////////////////////////////// +bool ISO8601d::parse_epoch (Nibbler& n) +{ +/* + if (isEpoch (input)) + return true; +*/ + + return false; +} + //////////////////////////////////////////////////////////////////////////////// bool ISO8601d::parse_date_time (Nibbler& n) { @@ -996,8 +1305,7 @@ ISO8601d ISO8601d::startOfYear () const } //////////////////////////////////////////////////////////////////////////////// -/* -bool ISO8601d::valid (const std::string& input, const std::string& format) +bool ISO8601d::valid (const std::string& input, const std::string& format /*= ""*/) { try { @@ -1011,7 +1319,6 @@ bool ISO8601d::valid (const std::string& input, const std::string& format) return true; } -*/ //////////////////////////////////////////////////////////////////////////////// bool ISO8601d::valid (const int m, const int d, const int y, const int hr, diff --git a/src/ISO8601.h b/src/ISO8601.h index b2cd519af..690b74fdd 100644 --- a/src/ISO8601.h +++ b/src/ISO8601.h @@ -58,7 +58,7 @@ public: ISO8601d startOfMonth () const; ISO8601d startOfYear () const; -// static bool valid (const std::string&, const std::string& format = "m/d/Y"); + static bool valid (const std::string&, const std::string& format = ""); static bool valid (const int, const int, const int, const int, const int, const int); static bool valid (const int, const int, const int); static bool valid (const int, const int); @@ -106,6 +106,9 @@ public: private: void clear (); + bool parse_formatted (Nibbler&, const std::string&); + bool parse_named (Nibbler&); + bool parse_epoch (Nibbler&); bool parse_date_time (Nibbler&); bool parse_date_time_ext (Nibbler&); bool parse_date_ext (Nibbler&); From 49aa62b3b42e788085609d7e3f281c6a8921fc03 Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sun, 27 Sep 2015 02:11:05 -0400 Subject: [PATCH 081/117] Tests: Added more ISO8601d tests --- test/iso8601d.t.cpp | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/test/iso8601d.t.cpp b/test/iso8601d.t.cpp index ff80bf17d..db7a4c8b9 100644 --- a/test/iso8601d.t.cpp +++ b/test/iso8601d.t.cpp @@ -71,7 +71,7 @@ void testParse ( //////////////////////////////////////////////////////////////////////////////// int main (int argc, char** argv) { - UnitTest t (865); + UnitTest t (899); ISO8601d iso; std::string::size_type start = 0; @@ -249,7 +249,6 @@ int main (int argc, char** argv) t.ok (relative_now.sameMonth (now), "Date ().sameMonth (Date (now))"); t.ok (relative_now.sameYear (now), "Date ().sameYear (Date (now))"); -/* // Loose comparisons. ISO8601d left ("7/4/2008", "m/d/Y"); ISO8601d comp1 ("7/4/2008", "m/d/Y"); @@ -274,27 +273,22 @@ int main (int argc, char** argv) t.notok (left.sameWeek (comp3), "7/4/2008 is not on the same week as 7/4/2009"); t.notok (left.sameMonth (comp4), "7/4/2008 is not in the same month as 7/4/2009"); t.notok (left.sameYear (comp4), "7/4/2008 is not in the same year as 7/4/2009"); -*/ // Validity. t.ok (ISO8601d::valid (2, 29, 2008), "valid: 2/29/2008"); t.notok (ISO8601d::valid (2, 29, 2007), "invalid: 2/29/2007"); -/* - t.ok (Date::valid ("2/29/2008"), "valid: 2/29/2008"); - t.notok (Date::valid ("2/29/2007"), "invalid: 2/29/2007"); -*/ + t.ok (ISO8601d::valid ("2/29/2008", "m/d/Y"), "valid: 2/29/2008"); + t.notok (ISO8601d::valid ("2/29/2007", "m/d/Y"), "invalid: 2/29/2007"); t.ok (ISO8601d::valid (366, 2008), "valid: 366 days in 2008"); t.notok (ISO8601d::valid (366, 2007), "invalid: 366 days in 2007"); -/* // Time validity. - t.ok (Date::valid (2, 28, 2010, 0, 0, 0), "valid 2/28/2010 0:00:00"); - t.ok (Date::valid (2, 28, 2010, 23, 59, 59), "valid 2/28/2010 23:59:59"); - t.notok (Date::valid (2, 28, 2010, 24, 59, 59), "valid 2/28/2010 24:59:59"); - t.notok (Date::valid (2, 28, 2010, -1, 0, 0), "valid 2/28/2010 -1:00:00"); -*/ + t.ok (ISO8601d::valid (2, 28, 2010, 0, 0, 0), "valid 2/28/2010 0:00:00"); + t.ok (ISO8601d::valid (2, 28, 2010, 23, 59, 59), "valid 2/28/2010 23:59:59"); + t.notok (ISO8601d::valid (2, 28, 2010, 24, 59, 59), "valid 2/28/2010 24:59:59"); + t.notok (ISO8601d::valid (2, 28, 2010, -1, 0, 0), "valid 2/28/2010 -1:00:00"); // Leap year. t.ok (ISO8601d::leapYear (2008), "2008 is a leap year"); @@ -390,6 +384,7 @@ int main (int argc, char** argv) t.is (quant.startOfWeek ().toString ("YMDHNS"), "20090208000000", "1234526400 -> 2/13/2009 12:00:00 UTC -> 2/8/2009 0:00:00"); t.is (quant.startOfMonth ().toString ("YMDHNS"), "20090201000000", "1234526400 -> 2/13/2009 12:00:00 UTC -> 2/1/2009 0:00:00"); t.is (quant.startOfYear ().toString ("YMDHNS"), "20090101000000", "1234526400 -> 2/13/2009 12:00:00 UTC -> 1/1/2009 0:00:00"); +*/ // Date parsing. ISO8601d fromString1 ("1/1/2008", "m/d/Y"); @@ -407,6 +402,7 @@ int main (int argc, char** argv) t.is (fromString3.day (), 31, "ctor (std::string) -> d"); t.is (fromString3.year (), 2007, "ctor (std::string) -> y"); +/* ISO8601d fromString4 ("01/01/2008", "m/d/Y"); t.is (fromString4.month (), 1, "ctor (std::string) -> m"); t.is (fromString4.day (), 1, "ctor (std::string) -> d"); @@ -450,12 +446,14 @@ int main (int argc, char** argv) t.is (fromString10.hour (), 12, "ctor (std::string) -> h"); t.is (fromString10.minute (), 34, "ctor (std::string) -> N"); t.is (fromString1.second (), 56, "ctor (std::string) -> S"); +*/ // Day of year t.is (ISO8601d ("1/1/2011", "m/d/Y").dayOfYear (), 1, "dayOfYear (1/1/2011) -> 1"); t.is (ISO8601d ("5/1/2011", "m/d/Y").dayOfYear (), 121, "dayOfYear (5/1/2011) -> 121"); t.is (ISO8601d ("12/31/2011", "m/d/Y").dayOfYear (), 365, "dayOfYear (12/31/2011) -> 365"); +/* // Relative dates. Date r1 ("today"); t.ok (r1.sameDay (now), "today = now"); @@ -610,13 +608,13 @@ int main (int argc, char** argv) t.is (ISO8601d::length (" "), 1, "length ' ' --> 1"); -/* // Depletion requirement. ISO8601d r30 ("Mon Jun 30 2014", "a b D Y"); t.is (r30.toString ("YMDHNS"), "20140630000000", "Depletion required on complex format with spaces"); +/* std::string::size_type i = 0; - ISO8601d r31 ("Mon Jun 30 2014 xxx", i, "a b D Y", false, false); + ISO8601d r31 ("Mon Jun 30 2014 xxx", i, "a b D Y"); t.is (r31.toString ("YMDHNS"), "20140630000000", "Depletion not required on complex format with spaces"); t.is ((int)i, 15, "Depletion not required on complex format with spaces, 15 chars"); */ From 1d598d0e8c4366d3859a74a65555c685c6433c3d Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sun, 27 Sep 2015 11:14:49 -0400 Subject: [PATCH 082/117] Context: Converted from Date to ISO8601d --- src/Context.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Context.cpp b/src/Context.cpp index f01dffb92..ce709692b 100644 --- a/src/Context.cpp +++ b/src/Context.cpp @@ -329,7 +329,7 @@ int Context::run () << "-" #endif << " " - << Date ().toISO () + << ISO8601d ().toISO () << " init:" << timer_init.total () << " load:" << timer_load.total () From fdc791a676134b7426a4242bf171aa943c9c2ab9 Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sun, 27 Sep 2015 11:15:28 -0400 Subject: [PATCH 083/117] ISO8601d: Implemented ::parse_epoch --- src/ISO8601.cpp | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/ISO8601.cpp b/src/ISO8601.cpp index c734c071a..5ee96318e 100644 --- a/src/ISO8601.cpp +++ b/src/ISO8601.cpp @@ -582,13 +582,21 @@ bool ISO8601d::parse_named (Nibbler& n) } //////////////////////////////////////////////////////////////////////////////// +// Valid epoch values are unsigned integers after 1980-01-01T00:00:00Z. This +// restriction means that '12' will not be identified as an epoch date. bool ISO8601d::parse_epoch (Nibbler& n) { -/* - if (isEpoch (input)) - return true; -*/ + n.save (); + int epoch; + if (n.getUnsignedInt (epoch) && + epoch >= 315532800) + { + _date = static_cast (epoch); + return true; + } + + n.restore (); return false; } From 69a60103b96b9ddfa42849a29ead5d1c281a7cbf Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sun, 27 Sep 2015 11:19:02 -0400 Subject: [PATCH 084/117] Test: Added more ISO8601d tests --- test/iso8601d.t.cpp | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/test/iso8601d.t.cpp b/test/iso8601d.t.cpp index db7a4c8b9..1fb63a244 100644 --- a/test/iso8601d.t.cpp +++ b/test/iso8601d.t.cpp @@ -71,7 +71,7 @@ void testParse ( //////////////////////////////////////////////////////////////////////////////// int main (int argc, char** argv) { - UnitTest t (899); + UnitTest t (904); ISO8601d iso; std::string::size_type start = 0; @@ -243,11 +243,11 @@ int main (int argc, char** argv) // Date::Date ("now") context.config.set ("weekstart", "monday"); ISO8601d relative_now; - t.ok (relative_now.sameHour (now), "Date ().sameHour (Date (now))"); - t.ok (relative_now.sameDay (now), "Date ().sameDay (Date (now))"); - t.ok (relative_now.sameWeek (now), "Date ().sameWeek (Date (now))"); - t.ok (relative_now.sameMonth (now), "Date ().sameMonth (Date (now))"); - t.ok (relative_now.sameYear (now), "Date ().sameYear (Date (now))"); + t.ok (relative_now.sameHour (now), "ISO8601d ().sameHour (ISO8601d (now))"); + t.ok (relative_now.sameDay (now), "ISO8601d ().sameDay (ISO8601d (now))"); + t.ok (relative_now.sameWeek (now), "ISO8601d ().sameWeek (ISO8601d (now))"); + t.ok (relative_now.sameMonth (now), "ISO8601d ().sameMonth (ISO8601d (now))"); + t.ok (relative_now.sameYear (now), "ISO8601d ().sameYear (ISO8601d (now))"); // Loose comparisons. ISO8601d left ("7/4/2008", "m/d/Y"); @@ -369,22 +369,18 @@ int main (int argc, char** argv) epoch += 172800; t.ok ((int)epoch.toEpoch () > 1000000000, "9/10/2001 > 1,000,000,000"); -/* - Date fromEpoch (epoch.toEpoch ()); + ISO8601d fromEpoch (epoch.toEpoch ()); t.is (fromEpoch.toString (), epoch.toString (), "ctor (time_t)"); -*/ ISO8601d iso (1000000000); t.is (iso.toISO (), "20010909T014640Z", "1,000,000,000 -> 20010909T014640Z"); -/* // Quantization. ISO8601d quant (1234526400); t.is (quant.startOfDay ().toString ("YMDHNS"), "20090213000000", "1234526400 -> 2/13/2009 12:00:00 UTC -> 2/13/2009 0:00:00"); t.is (quant.startOfWeek ().toString ("YMDHNS"), "20090208000000", "1234526400 -> 2/13/2009 12:00:00 UTC -> 2/8/2009 0:00:00"); t.is (quant.startOfMonth ().toString ("YMDHNS"), "20090201000000", "1234526400 -> 2/13/2009 12:00:00 UTC -> 2/1/2009 0:00:00"); t.is (quant.startOfYear ().toString ("YMDHNS"), "20090101000000", "1234526400 -> 2/13/2009 12:00:00 UTC -> 1/1/2009 0:00:00"); -*/ // Date parsing. ISO8601d fromString1 ("1/1/2008", "m/d/Y"); From ae2261258433b2403f915f369a057e3324978080 Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sun, 27 Sep 2015 12:14:18 -0400 Subject: [PATCH 085/117] ISO8601d: Upgraded method from private to static public --- src/ISO8601.cpp | 21 +++++++++++---------- src/ISO8601.h | 2 +- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/ISO8601.cpp b/src/ISO8601.cpp index 5ee96318e..3dd163e0b 100644 --- a/src/ISO8601.cpp +++ b/src/ISO8601.cpp @@ -826,16 +826,6 @@ bool ISO8601d::parse_time_off_ext (Nibbler& n) return false; } -//////////////////////////////////////////////////////////////////////////////// -// Using Zeller's Congruence. -int ISO8601d::dayOfWeek (int year, int month, int day) -{ - int adj = (14 - month) / 12; - int m = month + 12 * adj - 2; - int y = year - adj; - return (day + (13 * m - 1) / 5 + y + y / 4 - y / 100 + y / 400) % 7; -} - //////////////////////////////////////////////////////////////////////////////// // Validation via simple range checking. bool ISO8601d::validate () @@ -1483,6 +1473,17 @@ int ISO8601d::dayOfWeek (const std::string& input) return -1; } +//////////////////////////////////////////////////////////////////////////////// +// Using Zeller's Congruence. +// Static +int ISO8601d::dayOfWeek (int year, int month, int day) +{ + int adj = (14 - month) / 12; + int m = month + 12 * adj - 2; + int y = year - adj; + return (day + (13 * m - 1) / 5 + y + y / 4 - y / 100 + y / 400) % 7; +} + //////////////////////////////////////////////////////////////////////////////// // Static int ISO8601d::monthOfYear (const std::string& input) diff --git a/src/ISO8601.h b/src/ISO8601.h index 690b74fdd..bc995243c 100644 --- a/src/ISO8601.h +++ b/src/ISO8601.h @@ -69,6 +69,7 @@ public: static void dayName (int, std::string&); static std::string dayName (int); static int dayOfWeek (const std::string&); + static int dayOfWeek (int, int, int); static int monthOfYear (const std::string&); static int length (const std::string&); @@ -116,7 +117,6 @@ private: bool parse_time_ext (Nibbler&); bool parse_time_utc_ext (Nibbler&); bool parse_time_off_ext (Nibbler&); - int dayOfWeek (int, int, int); bool validate (); void resolve (); bool isEpoch (const std::string&); From 5cc3c8d05d5cab42c73b4b9b400d844a0f5fb6e8 Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sun, 27 Sep 2015 12:15:18 -0400 Subject: [PATCH 086/117] ISO8601d: Removed obsolete ::isEpoch method --- src/ISO8601.cpp | 13 ------------- src/ISO8601.h | 1 - 2 files changed, 14 deletions(-) diff --git a/src/ISO8601.cpp b/src/ISO8601.cpp index 3dd163e0b..84a59b106 100644 --- a/src/ISO8601.cpp +++ b/src/ISO8601.cpp @@ -960,19 +960,6 @@ void ISO8601d::resolve () _date = utc ? timegm (&t) : mktime (&t); } -//////////////////////////////////////////////////////////////////////////////// -bool ISO8601d::isEpoch (const std::string& input) -{ - if (Lexer::isAllDigits (input) && - input.length () <= 10 ) - { - _date = (time_t) strtol (input.c_str (), NULL, 10); - return true; - } - - return false; -} - //////////////////////////////////////////////////////////////////////////////// ISO8601p::ISO8601p () { diff --git a/src/ISO8601.h b/src/ISO8601.h index bc995243c..32935866d 100644 --- a/src/ISO8601.h +++ b/src/ISO8601.h @@ -119,7 +119,6 @@ private: bool parse_time_off_ext (Nibbler&); bool validate (); void resolve (); - bool isEpoch (const std::string&); public: int _year; From b0e249e56468a3daee9dd132f5bf3f0d555b5891 Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sun, 27 Sep 2015 16:28:25 -0400 Subject: [PATCH 087/117] ISO8601d: Epoch strings are parsed without the same validation as other dates --- src/ISO8601.cpp | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/src/ISO8601.cpp b/src/ISO8601.cpp index 84a59b106..efcd3dde8 100644 --- a/src/ISO8601.cpp +++ b/src/ISO8601.cpp @@ -234,14 +234,13 @@ bool ISO8601d::parse ( auto i = start; Nibbler n (input.substr (i)); if (parse_formatted (n, format) || - parse_date_time (n) || // Strictest first. + parse_date_time (n) || // Strictest first. parse_date_time_ext (n) || parse_date_ext (n) || parse_time_utc_ext (n) || parse_time_off_ext (n) || - parse_time_ext (n) || - parse_named (n) || - parse_epoch (n)) // Time last, as it is the most permissive. + parse_time_ext (n) || // Time last, as it is the most permissive. + parse_named (n)) { // Check the values and determine time_t. if (validate ()) @@ -254,6 +253,13 @@ bool ISO8601d::parse ( } } + // ::parse_epoch doesn't require ::validate and ::resolve. + else if (parse_epoch (n)) + { + start = n.cursor (); + return true; + } + return false; } @@ -953,9 +959,9 @@ void ISO8601d::resolve () seconds %= 86400; } - t.tm_hour = seconds / 3600; - t.tm_min = (seconds % 3600) / 60; - t.tm_sec = seconds % 60; + t.tm_hour = seconds / 3600; + t.tm_min = (seconds % 3600) / 60; + t.tm_sec = seconds % 60; _date = utc ? timegm (&t) : mktime (&t); } From f0e8d2027cd31e93fb09dbda5c2d936e1e65ba4e Mon Sep 17 00:00:00 2001 From: Tomas Babej Date: Tue, 29 Sep 2015 07:20:58 +0200 Subject: [PATCH 088/117] CLI2: Display filter footnote only if some filter token is present --- src/CLI2.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/CLI2.cpp b/src/CLI2.cpp index 677db1e18..6e37b11b2 100644 --- a/src/CLI2.cpp +++ b/src/CLI2.cpp @@ -678,7 +678,8 @@ void CLI2::prepareFilter () } } - context.footnote (std::string (STRING_COLUMN_LABEL_FILTER) + ": " + combined); + if (combined.size ()) + context.footnote (std::string (STRING_COLUMN_LABEL_FILTER) + ": " + combined); } } From 628f6b5fa6164364cfef5c4d45b66763896cd625 Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Tue, 29 Sep 2015 21:40:59 -0400 Subject: [PATCH 089/117] Test: Fixed test that tried to use a floating point epoch date --- test/timesheet.t | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/timesheet.t b/test/timesheet.t index 192837485..693811b69 100755 --- a/test/timesheet.t +++ b/test/timesheet.t @@ -54,7 +54,7 @@ class TestTimesheet(TestCase): # C0 completed, this week # C1 completed, last week # C2 completed, 2wks ago - now = time() + now = int(time()) seven = now - 7 * 86400 fourteen = now - 14 * 86400 From 953e1e4cc159ebe42f038ee55ddff5237634045f Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Wed, 30 Sep 2015 09:47:54 -0400 Subject: [PATCH 090/117] Nibbler: Removed unused comment --- src/Nibbler.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/Nibbler.h b/src/Nibbler.h index 1fda8ac76..b3754aa5a 100644 --- a/src/Nibbler.h +++ b/src/Nibbler.h @@ -57,10 +57,6 @@ public: bool getUntilEOL (std::string&); bool getUntilEOS (std::string&); -/* - bool getAllOneOf (const std::string&, std::string&); -*/ - bool getN (const int, std::string&); bool getQuoted (char, std::string&, bool quote = false); bool getDigit (int&); From 4f156c407c653665a302c9665ca4b4807765ad99 Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Wed, 30 Sep 2015 09:52:09 -0400 Subject: [PATCH 091/117] Recur: Migrated recurrence from Date to ISO8601d - Changed signature of recur functions, which needed a main.h change, which led to removing '#include ' from main.h, which necessitated adding the sam include to various other source files. Temporarily. - Added 'ISO8601d ISO8601d::operator+ (time_t)', because of differences from the original Date object. --- src/ISO8601.cpp | 6 ++++ src/ISO8601.h | 1 + src/commands/CmdEdit.cpp | 1 + src/commands/CmdHistory.cpp | 1 + src/commands/CmdStats.cpp | 1 + src/feedback.cpp | 1 + src/main.h | 6 ++-- src/recur.cpp | 62 ++++++++++++++++++------------------- 8 files changed, 44 insertions(+), 35 deletions(-) diff --git a/src/ISO8601.cpp b/src/ISO8601.cpp index efcd3dde8..d9c09e626 100644 --- a/src/ISO8601.cpp +++ b/src/ISO8601.cpp @@ -1694,6 +1694,12 @@ bool ISO8601d::sameYear (const ISO8601d& rhs) const return this->year () == rhs.year (); } +//////////////////////////////////////////////////////////////////////////////// +ISO8601d ISO8601d::operator+ (time_t delta) +{ + return ISO8601d (_date + delta); +} + //////////////////////////////////////////////////////////////////////////////// ISO8601d ISO8601d::operator+ (const int delta) { diff --git a/src/ISO8601.h b/src/ISO8601.h index 32935866d..ff3e76413 100644 --- a/src/ISO8601.h +++ b/src/ISO8601.h @@ -95,6 +95,7 @@ public: bool sameWeek (const ISO8601d&) const; bool sameMonth (const ISO8601d&) const; bool sameYear (const ISO8601d&) const; + ISO8601d operator+ (time_t); ISO8601d operator+ (const int); ISO8601d operator- (const int); ISO8601d& operator+= (const int); diff --git a/src/commands/CmdEdit.cpp b/src/commands/CmdEdit.cpp index 2a4b71138..b685f4fc9 100644 --- a/src/commands/CmdEdit.cpp +++ b/src/commands/CmdEdit.cpp @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include diff --git a/src/commands/CmdHistory.cpp b/src/commands/CmdHistory.cpp index 4280d6387..6fa54344b 100644 --- a/src/commands/CmdHistory.cpp +++ b/src/commands/CmdHistory.cpp @@ -32,6 +32,7 @@ #include #include #include +#include #include #include diff --git a/src/commands/CmdStats.cpp b/src/commands/CmdStats.cpp index 4c630eefb..b819d84e3 100644 --- a/src/commands/CmdStats.cpp +++ b/src/commands/CmdStats.cpp @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include diff --git a/src/feedback.cpp b/src/feedback.cpp index 40b3fc594..56efbc66b 100644 --- a/src/feedback.cpp +++ b/src/feedback.cpp @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include diff --git a/src/main.h b/src/main.h index da73bc75b..fd8e8f714 100644 --- a/src/main.h +++ b/src/main.h @@ -32,13 +32,13 @@ #include #include #include -#include +#include #include // recur.cpp void handleRecurrence (); -Date getNextRecurrence (Date&, std::string&); -bool generateDueDates (Task&, std::vector &); +ISO8601d getNextRecurrence (ISO8601d&, std::string&); +bool generateDueDates (Task&, std::vector &); void updateRecurrenceMask (Task&); bool nag (Task&); diff --git a/src/recur.cpp b/src/recur.cpp index 6874542b4..cb038ddf0 100644 --- a/src/recur.cpp +++ b/src/recur.cpp @@ -39,8 +39,6 @@ #include #include -#include -#include #include #include #include @@ -62,7 +60,7 @@ void handleRecurrence () return; auto tasks = context.tdb2.pending.get_tasks (); - Date now; + ISO8601d now; // Look at all tasks and find any recurring ones. for (auto& t : tasks) @@ -71,7 +69,7 @@ void handleRecurrence () { // Generate a list of due dates for this recurring task, regardless of // the mask. - std::vector due; + std::vector due; if (!generateDueDates (t, due)) { // Determine the end date. @@ -106,9 +104,9 @@ void handleRecurrence () if (t.has ("wait")) { - Date old_wait (t.get_date ("wait")); - Date old_due (t.get_date ("due")); - Date due (d); + ISO8601d old_wait (t.get_date ("wait")); + ISO8601d old_due (t.get_date ("due")); + ISO8601d due (d); sprintf (dueDate, "%u", (unsigned int) (due + (old_wait - old_due)).toEpoch ()); rec.set ("wait", dueDate); rec.setStatus (Task::waiting); @@ -148,7 +146,7 @@ void handleRecurrence () else { if (t.has ("until") && - Date (t.get_date ("until")) < now) + ISO8601d (t.get_date ("until")) < now) { t.setStatus (Task::deleted); context.tdb2.modify(t); @@ -163,28 +161,28 @@ void handleRecurrence () // period (recur). Then generate a set of corresponding dates. // // Returns false if the parent recurring task is depleted. -bool generateDueDates (Task& parent, std::vector & allDue) +bool generateDueDates (Task& parent, std::vector & allDue) { // Determine due date, recur period and until date. - Date due (parent.get_date ("due")); - if (due == 0) + ISO8601d due (parent.get_date ("due")); + if (due._date == 0) { return false; } std::string recur = parent.get ("recur"); bool specificEnd = false; - Date until; + ISO8601d until; if (parent.get ("until") != "") { - until = Date (parent.get ("until")); + until = ISO8601d (parent.get ("until")); specificEnd = true; } int recurrence_limit = context.config.getInteger ("recurrence.limit"); int recurrence_counter = 0; - Date now; - for (Date i = due; ; i = getNextRecurrence (i, recur)) + ISO8601d now; + for (ISO8601d i = due; ; i = getNextRecurrence (i, recur)) { allDue.push_back (i); @@ -212,7 +210,7 @@ bool generateDueDates (Task& parent, std::vector & allDue) } //////////////////////////////////////////////////////////////////////////////// -Date getNextRecurrence (Date& current, std::string& period) +ISO8601d getNextRecurrence (ISO8601d& current, std::string& period) { int m = current.month (); int d = current.day (); @@ -228,10 +226,10 @@ Date getNextRecurrence (Date& current, std::string& period) ++y; } - while (! Date::valid (m, d, y)) + while (! ISO8601d::valid (m, d, y)) --d; - return Date (m, d, y); + return ISO8601d (m, d, y); } else if (period == "weekdays") @@ -258,10 +256,10 @@ Date getNextRecurrence (Date& current, std::string& period) ++y; } - while (! Date::valid (m, d, y)) + while (! ISO8601d::valid (m, d, y)) --d; - return Date (m, d, y); + return ISO8601d (m, d, y); } else if (period[0] == 'P' && @@ -277,10 +275,10 @@ Date getNextRecurrence (Date& current, std::string& period) ++y; } - while (! Date::valid (m, d, y)) + while (! ISO8601d::valid (m, d, y)) --d; - return Date (m, d, y); + return ISO8601d (m, d, y); } else if (period == "quarterly" || @@ -293,10 +291,10 @@ Date getNextRecurrence (Date& current, std::string& period) ++y; } - while (! Date::valid (m, d, y)) + while (! ISO8601d::valid (m, d, y)) --d; - return Date (m, d, y); + return ISO8601d (m, d, y); } else if (Lexer::isDigit (period[0]) && period[period.length () - 1] == 'q') @@ -310,10 +308,10 @@ Date getNextRecurrence (Date& current, std::string& period) ++y; } - while (! Date::valid (m, d, y)) + while (! ISO8601d::valid (m, d, y)) --d; - return Date (m, d, y); + return ISO8601d (m, d, y); } else if (period == "semiannual" || @@ -326,10 +324,10 @@ Date getNextRecurrence (Date& current, std::string& period) ++y; } - while (! Date::valid (m, d, y)) + while (! ISO8601d::valid (m, d, y)) --d; - return Date (m, d, y); + return ISO8601d (m, d, y); } else if (period == "bimonthly" || @@ -342,10 +340,10 @@ Date getNextRecurrence (Date& current, std::string& period) ++y; } - while (! Date::valid (m, d, y)) + while (! ISO8601d::valid (m, d, y)) --d; - return Date (m, d, y); + return ISO8601d (m, d, y); } else if (period == "biannual" || @@ -354,7 +352,7 @@ Date getNextRecurrence (Date& current, std::string& period) { y += 2; - return Date (m, d, y); + return ISO8601d (m, d, y); } else if (period == "annual" || @@ -368,7 +366,7 @@ Date getNextRecurrence (Date& current, std::string& period) if (m == 2 && d == 29) d = 28; - return Date (m, d, y); + return ISO8601d (m, d, y); } // Add the period to current, and we're done. From 6bb58286dc6887bc7f9924b126d6426b35bd2f0b Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sat, 3 Oct 2015 15:14:39 -0400 Subject: [PATCH 092/117] DOM: Migrated from Date to ISO8601d --- src/DOM.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/DOM.cpp b/src/DOM.cpp index a7f760a14..f9a64a594 100644 --- a/src/DOM.cpp +++ b/src/DOM.cpp @@ -32,7 +32,6 @@ #include #include #include -#include #include #include #include @@ -320,7 +319,7 @@ bool DOM::get (const std::string& name, const Task& task, Variant& value) if (ref.size () && size == 2 && column && column->type () == "date") { - Date date (ref.get_date (canonical)); + ISO8601d date (ref.get_date (canonical)); if (elements[1] == "year") { value = Variant (static_cast (date.year ())); return true; } else if (elements[1] == "month") { value = Variant (static_cast (date.month ())); return true; } else if (elements[1] == "day") { value = Variant (static_cast (date.day ())); return true; } @@ -384,7 +383,7 @@ bool DOM::get (const std::string& name, const Task& task, Variant& value) // ..entry.hour // ..entry.minute // ..entry.second - Date date (i.first.substr (11)); + ISO8601d date (i.first.substr (11)); if (elements[3] == "year") { value = Variant (static_cast (date.year ())); return true; } else if (elements[3] == "month") { value = Variant (static_cast (date.month ())); return true; } else if (elements[3] == "day") { value = Variant (static_cast (date.day ())); return true; } From ec073c5dae6e372fa783538cff271b023dd6877b Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sat, 3 Oct 2015 15:22:22 -0400 Subject: [PATCH 093/117] CmdInfo: Migrated from Date to ISO8601d --- src/commands/CmdInfo.cpp | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/src/commands/CmdInfo.cpp b/src/commands/CmdInfo.cpp index e6521b438..1bf58f70a 100644 --- a/src/commands/CmdInfo.cpp +++ b/src/commands/CmdInfo.cpp @@ -31,7 +31,6 @@ #include #include #include -#include #include #include #include @@ -113,7 +112,7 @@ int CmdInfo::execute (std::string& output) view.colorHeader (label); } - Date now; + ISO8601d now; // id int row = view.addRow (); @@ -133,7 +132,7 @@ int CmdInfo::execute (std::string& output) for (auto& anno : annotations) description += "\n" + std::string (indent, ' ') - + Date (anno.first.substr (11)).toString (dateformatanno) + + ISO8601d (anno.first.substr (11)).toString (dateformatanno) + " " + anno.second; @@ -221,14 +220,14 @@ int CmdInfo::execute (std::string& output) // entry row = view.addRow (); view.set (row, 0, STRING_COLUMN_LABEL_ENTERED); - Date dt (task.get_date ("entry")); + ISO8601d dt (task.get_date ("entry")); std::string entry = dt.toString (dateformat); std::string age; std::string created = task.get ("entry"); if (created.length ()) { - Date dt (strtol (created.c_str (), NULL, 10)); + ISO8601d dt (strtol (created.c_str (), NULL, 10)); age = ISO8601p (now - dt).formatVague (); } @@ -239,7 +238,7 @@ int CmdInfo::execute (std::string& output) { row = view.addRow (); view.set (row, 0, STRING_COLUMN_LABEL_WAITING); - view.set (row, 1, Date (task.get_date ("wait")).toString (dateformat)); + view.set (row, 1, ISO8601d (task.get_date ("wait")).toString (dateformat)); } // scheduled @@ -247,7 +246,7 @@ int CmdInfo::execute (std::string& output) { row = view.addRow (); view.set (row, 0, STRING_COLUMN_LABEL_SCHED); - view.set (row, 1, Date (task.get_date ("scheduled")).toString (dateformat)); + view.set (row, 1, ISO8601d (task.get_date ("scheduled")).toString (dateformat)); } // start @@ -255,7 +254,7 @@ int CmdInfo::execute (std::string& output) { row = view.addRow (); view.set (row, 0, STRING_COLUMN_LABEL_START); - view.set (row, 1, Date (task.get_date ("start")).toString (dateformat)); + view.set (row, 1, ISO8601d (task.get_date ("start")).toString (dateformat)); } // due (colored) @@ -263,7 +262,7 @@ int CmdInfo::execute (std::string& output) { row = view.addRow (); view.set (row, 0, STRING_COLUMN_LABEL_DUE); - view.set (row, 1, Date (task.get_date ("due")).toString (dateformat)); + view.set (row, 1, ISO8601d (task.get_date ("due")).toString (dateformat)); } // end @@ -271,7 +270,7 @@ int CmdInfo::execute (std::string& output) { row = view.addRow (); view.set (row, 0, STRING_COLUMN_LABEL_END); - view.set (row, 1, Date (task.get_date ("end")).toString (dateformat)); + view.set (row, 1, ISO8601d (task.get_date ("end")).toString (dateformat)); } // until @@ -279,7 +278,7 @@ int CmdInfo::execute (std::string& output) { row = view.addRow (); view.set (row, 0, STRING_CMD_INFO_UNTIL); - view.set (row, 1, Date (task.get_date ("until")).toString (dateformat)); + view.set (row, 1, ISO8601d (task.get_date ("until")).toString (dateformat)); } // modified @@ -288,7 +287,7 @@ int CmdInfo::execute (std::string& output) row = view.addRow (); view.set (row, 0, STRING_CMD_INFO_MODIFIED); - Date mod (task.get_date ("modified")); + ISO8601d mod (task.get_date ("modified")); std::string age = ISO8601p (now - mod).formatVague (); view.set (row, 1, mod.toString (dateformat) + " (" + age + ")"); } @@ -373,7 +372,7 @@ int CmdInfo::execute (std::string& output) view.set (row, 0, col->label ()); if (type == "date") - value = Date (value).toString (dateformat); + value = ISO8601d (value).toString (dateformat); else if (type == "duration") { ISO8601p iso; @@ -544,7 +543,7 @@ int CmdInfo::execute (std::string& output) { int row = journal.addRow (); - Date timestamp (strtol (when.substr (5).c_str (), NULL, 10)); + ISO8601d timestamp (strtol (when.substr (5).c_str (), NULL, 10)); journal.set (row, 0, timestamp.toString (dateformat)); Task before (previous.substr (4)); From fb280edbc25e986a0f0c081d37aa18f1ec45169d Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sat, 3 Oct 2015 15:27:23 -0400 Subject: [PATCH 094/117] TND2: Migrated from Date to ISO8601d --- src/TDB2.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/TDB2.cpp b/src/TDB2.cpp index 6a82f10f1..0148a51e6 100644 --- a/src/TDB2.cpp +++ b/src/TDB2.cpp @@ -34,7 +34,7 @@ #include #include #include -#include +#include #include #include #include @@ -638,7 +638,7 @@ void TDB2::update ( // old // new // --- - undo.add_line ("time " + Date ().toEpochString () + "\n"); + undo.add_line ("time " + ISO8601d ().toEpochString () + "\n"); undo.add_line ("old " + original.composeF4 () + "\n"); undo.add_line ("new " + task.composeF4 () + "\n"); undo.add_line ("---\n"); @@ -657,7 +657,7 @@ void TDB2::update ( // time