mirror of
https://github.com/GothenburgBitFactory/taskwarrior.git
synced 2025-08-26 15:47:19 +02:00
Merge branch 'isodate' into 2.5.0
This commit is contained in:
commit
79886e03ce
42 changed files with 1916 additions and 1898 deletions
|
@ -10,7 +10,6 @@ set (task_SRCS CLI2.cpp CLI2.h
|
||||||
Config.cpp Config.h
|
Config.cpp Config.h
|
||||||
Context.cpp Context.h
|
Context.cpp Context.h
|
||||||
DOM.cpp DOM.h
|
DOM.cpp DOM.h
|
||||||
Date.cpp Date.h
|
|
||||||
Dates.cpp Dates.h
|
Dates.cpp Dates.h
|
||||||
Eval.cpp Eval.h
|
Eval.cpp Eval.h
|
||||||
Filter.cpp Filter.h
|
Filter.cpp Filter.h
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <Date.h>
|
#include <ISO8601.h>
|
||||||
#include <FS.h>
|
#include <FS.h>
|
||||||
#include <Timer.h>
|
#include <Timer.h>
|
||||||
#include <JSON.h>
|
#include <JSON.h>
|
||||||
|
@ -574,7 +574,7 @@ void Config::createDefaultRC (const std::string& rc, const std::string& data)
|
||||||
auto loc = _defaults.find ("data.location=~/.task");
|
auto loc = _defaults.find ("data.location=~/.task");
|
||||||
// loc+0^ +14^ +21^
|
// loc+0^ +14^ +21^
|
||||||
|
|
||||||
Date now;
|
ISO8601d now;
|
||||||
std::stringstream contents;
|
std::stringstream contents;
|
||||||
contents << "# [Created by "
|
contents << "# [Created by "
|
||||||
<< PACKAGE_STRING
|
<< PACKAGE_STRING
|
||||||
|
|
|
@ -37,6 +37,7 @@
|
||||||
#include <FS.h>
|
#include <FS.h>
|
||||||
#include <Eval.h>
|
#include <Eval.h>
|
||||||
#include <Variant.h>
|
#include <Variant.h>
|
||||||
|
#include <ISO8601.h>
|
||||||
#include <text.h>
|
#include <text.h>
|
||||||
#include <util.h>
|
#include <util.h>
|
||||||
#include <main.h>
|
#include <main.h>
|
||||||
|
@ -328,7 +329,7 @@ int Context::run ()
|
||||||
<< "-"
|
<< "-"
|
||||||
#endif
|
#endif
|
||||||
<< " "
|
<< " "
|
||||||
<< Date ().toISO ()
|
<< ISO8601d ().toISO ()
|
||||||
|
|
||||||
<< " init:" << timer_init.total ()
|
<< " init:" << timer_init.total ()
|
||||||
<< " load:" << timer_load.total ()
|
<< " load:" << timer_load.total ()
|
||||||
|
@ -621,8 +622,9 @@ void Context::getLimits (int& rows, int& lines)
|
||||||
// easier, it has been decoupled from Context.
|
// easier, it has been decoupled from Context.
|
||||||
void Context::staticInitialization ()
|
void Context::staticInitialization ()
|
||||||
{
|
{
|
||||||
CLI2::minimumMatchLength = config.getInteger ("abbreviation.minimum");
|
CLI2::minimumMatchLength = config.getInteger ("abbreviation.minimum");
|
||||||
Lexer::minimumMatchLength = config.getInteger ("abbreviation.minimum");
|
Lexer::minimumMatchLength = config.getInteger ("abbreviation.minimum");
|
||||||
|
ISO8601d::minimumMatchLength = config.getInteger ("abbreviation.minimum");
|
||||||
|
|
||||||
Task::defaultProject = config.get ("default.project");
|
Task::defaultProject = config.get ("default.project");
|
||||||
Task::defaultDue = config.get ("default.due");
|
Task::defaultDue = config.get ("default.due");
|
||||||
|
@ -630,10 +632,12 @@ void Context::staticInitialization ()
|
||||||
Task::searchCaseSensitive = Variant::searchCaseSensitive = config.getBoolean ("search.case.sensitive");
|
Task::searchCaseSensitive = Variant::searchCaseSensitive = config.getBoolean ("search.case.sensitive");
|
||||||
Task::regex = Variant::searchUsingRegex = config.getBoolean ("regex");
|
Task::regex = Variant::searchUsingRegex = config.getBoolean ("regex");
|
||||||
Lexer::dateFormat = Variant::dateFormat = config.get ("dateformat");
|
Lexer::dateFormat = Variant::dateFormat = config.get ("dateformat");
|
||||||
Lexer::isoEnabled = Variant::isoEnabled = config.getBoolean ("date.iso");
|
ISO8601p::isoEnabled = ISO8601d::isoEnabled = config.getBoolean ("date.iso");
|
||||||
|
|
||||||
TDB2::debug_mode = config.getBoolean ("debug");
|
TDB2::debug_mode = config.getBoolean ("debug");
|
||||||
|
|
||||||
|
ISO8601d::weekstart = config.get ("weekstart");
|
||||||
|
|
||||||
for (auto& rc : config)
|
for (auto& rc : config)
|
||||||
{
|
{
|
||||||
if (rc.first.substr (0, 4) == "uda." &&
|
if (rc.first.substr (0, 4) == "uda." &&
|
||||||
|
|
|
@ -32,7 +32,6 @@
|
||||||
#include <Context.h>
|
#include <Context.h>
|
||||||
#include <Nibbler.h>
|
#include <Nibbler.h>
|
||||||
#include <ISO8601.h>
|
#include <ISO8601.h>
|
||||||
#include <Date.h>
|
|
||||||
#include <text.h>
|
#include <text.h>
|
||||||
#include <i18n.h>
|
#include <i18n.h>
|
||||||
#include <DOM.h>
|
#include <DOM.h>
|
||||||
|
@ -300,7 +299,7 @@ bool DOM::get (const std::string& name, const Task& task, Variant& value)
|
||||||
ISO8601p iso;
|
ISO8601p iso;
|
||||||
std::string::size_type cursor = 0;
|
std::string::size_type cursor = 0;
|
||||||
if (iso.parse (period, cursor))
|
if (iso.parse (period, cursor))
|
||||||
value = Variant ((time_t) iso._value, Variant::type_duration);
|
value = Variant ((time_t) iso, Variant::type_duration);
|
||||||
else
|
else
|
||||||
value = Variant ((time_t) ISO8601p (ref.get (canonical)), Variant::type_duration);
|
value = Variant ((time_t) ISO8601p (ref.get (canonical)), Variant::type_duration);
|
||||||
}
|
}
|
||||||
|
@ -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")
|
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<int> (date.year ())); return true; }
|
if (elements[1] == "year") { value = Variant (static_cast<int> (date.year ())); return true; }
|
||||||
else if (elements[1] == "month") { value = Variant (static_cast<int> (date.month ())); return true; }
|
else if (elements[1] == "month") { value = Variant (static_cast<int> (date.month ())); return true; }
|
||||||
else if (elements[1] == "day") { value = Variant (static_cast<int> (date.day ())); return true; }
|
else if (elements[1] == "day") { value = Variant (static_cast<int> (date.day ())); return true; }
|
||||||
|
@ -384,7 +383,7 @@ bool DOM::get (const std::string& name, const Task& task, Variant& value)
|
||||||
// <annotations>.<N>.entry.hour
|
// <annotations>.<N>.entry.hour
|
||||||
// <annotations>.<N>.entry.minute
|
// <annotations>.<N>.entry.minute
|
||||||
// <annotations>.<N>.entry.second
|
// <annotations>.<N>.entry.second
|
||||||
Date date (i.first.substr (11));
|
ISO8601d date (i.first.substr (11));
|
||||||
if (elements[3] == "year") { value = Variant (static_cast<int> (date.year ())); return true; }
|
if (elements[3] == "year") { value = Variant (static_cast<int> (date.year ())); return true; }
|
||||||
else if (elements[3] == "month") { value = Variant (static_cast<int> (date.month ())); return true; }
|
else if (elements[3] == "month") { value = Variant (static_cast<int> (date.month ())); return true; }
|
||||||
else if (elements[3] == "day") { value = Variant (static_cast<int> (date.day ())); return true; }
|
else if (elements[3] == "day") { value = Variant (static_cast<int> (date.day ())); return true; }
|
||||||
|
|
839
src/Date.cpp
839
src/Date.cpp
|
@ -1,839 +0,0 @@
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Copyright 2006 - 2015, Paul Beckingham, Federico Hernandez.
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included
|
|
||||||
// in all copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
||||||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
||||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
// SOFTWARE.
|
|
||||||
//
|
|
||||||
// http://www.opensource.org/licenses/mit-license.php
|
|
||||||
//
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#include <cmake.h>
|
|
||||||
#include <iomanip>
|
|
||||||
#include <sstream>
|
|
||||||
#include <time.h>
|
|
||||||
#include <assert.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <Nibbler.h>
|
|
||||||
#include <Date.h>
|
|
||||||
#include <Variant.h>
|
|
||||||
#include <Dates.h>
|
|
||||||
#include <text.h>
|
|
||||||
#include <util.h>
|
|
||||||
#include <utf8.h>
|
|
||||||
#include <i18n.h>
|
|
||||||
#include <Context.h>
|
|
||||||
|
|
||||||
extern Context context;
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Defaults to "now".
|
|
||||||
Date::Date ()
|
|
||||||
{
|
|
||||||
_t = time (NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
Date::Date (const time_t t)
|
|
||||||
{
|
|
||||||
_t = t;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
Date::Date (const int m, const int d, const int y)
|
|
||||||
{
|
|
||||||
// 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 = mktime (&t);
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
Date::Date (const int m, const int d, const int y,
|
|
||||||
const int hr, const int mi, const int se)
|
|
||||||
{
|
|
||||||
// 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;
|
|
||||||
|
|
||||||
_t = mktime (&t);
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
Date::Date (
|
|
||||||
const std::string& input,
|
|
||||||
const std::string& format /* = "m/d/Y" */,
|
|
||||||
const bool iso /* = true */,
|
|
||||||
const bool epoch /* = true */)
|
|
||||||
{
|
|
||||||
// Check first to see if this is supported as a named date.
|
|
||||||
Variant v;
|
|
||||||
if (namedDates (input, v))
|
|
||||||
{
|
|
||||||
_t = v.get_date ();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parse a formatted date.
|
|
||||||
Nibbler n (input);
|
|
||||||
n.save ();
|
|
||||||
#ifdef NIBBLER_FEATURE_DATE
|
|
||||||
if (n.getDate (format, _t) && n.depleted ())
|
|
||||||
return;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Parse an ISO date.
|
|
||||||
n.restore ();
|
|
||||||
if (iso && n.getDateISO (_t) && n.depleted ())
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Perhaps it is an epoch date, in string form?
|
|
||||||
n.restore ();
|
|
||||||
if (epoch && isEpoch (input))
|
|
||||||
return;
|
|
||||||
|
|
||||||
throw ::format (STRING_DATE_INVALID_FORMAT, input, format);
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
Date::Date (
|
|
||||||
const std::string& input,
|
|
||||||
std::string::size_type& i,
|
|
||||||
const std::string& format /* = "m/d/Y" */,
|
|
||||||
const bool iso /* = true */,
|
|
||||||
const bool epoch /* = true */)
|
|
||||||
{
|
|
||||||
// Check first to see if this is supported as a named date.
|
|
||||||
Variant v;
|
|
||||||
if (namedDates (input, v))
|
|
||||||
{
|
|
||||||
i = v.source ().length ();
|
|
||||||
_t = v.get_date ();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parse a formatted date.
|
|
||||||
Nibbler n (input);
|
|
||||||
n.save ();
|
|
||||||
#ifdef NIBBLER_FEATURE_DATE
|
|
||||||
if (n.getDate (format, _t))
|
|
||||||
{
|
|
||||||
i = n.cursor ();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Parse an ISO date.
|
|
||||||
n.restore ();
|
|
||||||
if (iso && n.getDateISO (_t))
|
|
||||||
{
|
|
||||||
i = n.cursor ();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Perhaps it is an epoch date, in string form?
|
|
||||||
n.restore ();
|
|
||||||
if (epoch && isEpoch (input))
|
|
||||||
{
|
|
||||||
i = 10;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
throw ::format (STRING_DATE_INVALID_FORMAT, input, format);
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
Date::Date (const Date& rhs)
|
|
||||||
{
|
|
||||||
_t = rhs._t;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
Date::~Date ()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
time_t Date::toEpoch ()
|
|
||||||
{
|
|
||||||
return _t;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
std::string Date::toEpochString ()
|
|
||||||
{
|
|
||||||
std::stringstream epoch;
|
|
||||||
epoch << _t;
|
|
||||||
return epoch.str ();
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// 19980119T070000Z = YYYYMMDDThhmmssZ
|
|
||||||
std::string Date::toISO ()
|
|
||||||
{
|
|
||||||
struct tm* t = gmtime (&_t);
|
|
||||||
|
|
||||||
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 Date::toJulian ()
|
|
||||||
{
|
|
||||||
return (_t / 86400.0) + 2440587.5;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
void Date::toEpoch (time_t& epoch)
|
|
||||||
{
|
|
||||||
epoch = _t;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
void Date::toMDY (int& m, int& d, int& y)
|
|
||||||
{
|
|
||||||
struct tm* t = localtime (&_t);
|
|
||||||
|
|
||||||
m = t->tm_mon + 1;
|
|
||||||
d = t->tm_mday;
|
|
||||||
y = t->tm_year + 1900;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
const std::string Date::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", Date::dayName (dayOfWeek ()).c_str ()); break;
|
|
||||||
case 'A': sprintf (buffer, "%.10s", Date::dayName (dayOfWeek ()).c_str ()); break;
|
|
||||||
case 'b': sprintf (buffer, "%.3s", Date::monthName (month ()).c_str ()); break;
|
|
||||||
case 'B': sprintf (buffer, "%.10s", Date::monthName (month ()).c_str ()); break;
|
|
||||||
case 'v': sprintf (buffer, "%d", Date::weekOfYear (Date::dayOfWeek (context.config.get ("weekstart")))); break;
|
|
||||||
case 'V': sprintf (buffer, "%02d", Date::weekOfYear (Date::dayOfWeek (context.config.get ("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;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
Date Date::startOfDay () const
|
|
||||||
{
|
|
||||||
return Date (month (), day (), year ());
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
Date Date::startOfWeek () const
|
|
||||||
{
|
|
||||||
Date sow (_t);
|
|
||||||
sow -= (dayOfWeek () * 86400);
|
|
||||||
return Date (sow.month (), sow.day (), sow.year ());
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
Date Date::startOfMonth () const
|
|
||||||
{
|
|
||||||
return Date (month (), 1, year ());
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
Date Date::startOfYear () const
|
|
||||||
{
|
|
||||||
return Date (1, 1, year ());
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
bool Date::valid (const std::string& input, const std::string& format)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Date test (input, format);
|
|
||||||
}
|
|
||||||
|
|
||||||
catch (...)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
bool Date::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 Date::valid (m, d, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
bool Date::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 > Date::daysInMonth (m, y))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Julian
|
|
||||||
bool Date::valid (const int d, const int y)
|
|
||||||
{
|
|
||||||
// Check that the year is valid.
|
|
||||||
if (y < 0)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (d < 1 || d > Date::daysInYear (y))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
bool Date::leapYear (int year)
|
|
||||||
{
|
|
||||||
bool ly = false;
|
|
||||||
|
|
||||||
// (year % 4 == 0) && (year % 100 !=0) OR
|
|
||||||
// (year % 400 == 0)
|
|
||||||
// are leapyears
|
|
||||||
|
|
||||||
if (((!(year % 4)) && (year % 100)) || (!(year % 400))) ly = true;
|
|
||||||
|
|
||||||
return ly;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
int Date::daysInMonth (int month, int year)
|
|
||||||
{
|
|
||||||
static int days[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
|
|
||||||
|
|
||||||
if (month == 2 && Date::leapYear (year))
|
|
||||||
return 29;
|
|
||||||
|
|
||||||
return days[month - 1];
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
int Date::daysInYear (int year)
|
|
||||||
{
|
|
||||||
return Date::leapYear (year) ? 366 : 365;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
std::string Date::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]);
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
void Date::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 Date::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]);
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
int Date::weekOfYear (int weekStart) const
|
|
||||||
{
|
|
||||||
struct tm* t = localtime (&_t);
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
int Date::dayOfWeek () const
|
|
||||||
{
|
|
||||||
struct tm* t = localtime (&_t);
|
|
||||||
return t->tm_wday;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
int Date::dayOfWeek (const std::string& input)
|
|
||||||
{
|
|
||||||
int minimum = CLI2::minimumMatchLength;
|
|
||||||
if (minimum == 0)
|
|
||||||
minimum = 3;
|
|
||||||
|
|
||||||
if (closeEnough (STRING_DATE_SUNDAY, input, minimum)) return 0;
|
|
||||||
else if (closeEnough (STRING_DATE_MONDAY, input, minimum)) return 1;
|
|
||||||
else if (closeEnough (STRING_DATE_TUESDAY, input, minimum)) return 2;
|
|
||||||
else if (closeEnough (STRING_DATE_WEDNESDAY, input, minimum)) return 3;
|
|
||||||
else if (closeEnough (STRING_DATE_THURSDAY, input, minimum)) return 4;
|
|
||||||
else if (closeEnough (STRING_DATE_FRIDAY, input, minimum)) return 5;
|
|
||||||
else if (closeEnough (STRING_DATE_SATURDAY, input, minimum)) return 6;
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
int Date::dayOfYear () const
|
|
||||||
{
|
|
||||||
struct tm* t = localtime (&_t);
|
|
||||||
return t->tm_yday + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
int Date::monthOfYear (const std::string& input)
|
|
||||||
{
|
|
||||||
int minimum = CLI2::minimumMatchLength;
|
|
||||||
if (minimum == 0)
|
|
||||||
minimum = 3;
|
|
||||||
|
|
||||||
if (closeEnough (STRING_DATE_JANUARY, input, minimum)) return 1;
|
|
||||||
else if (closeEnough (STRING_DATE_FEBRUARY, input, minimum)) return 2;
|
|
||||||
else if (closeEnough (STRING_DATE_MARCH, input, minimum)) return 3;
|
|
||||||
else if (closeEnough (STRING_DATE_APRIL, input, minimum)) return 4;
|
|
||||||
else if (closeEnough (STRING_DATE_MAY, input, minimum)) return 5;
|
|
||||||
else if (closeEnough (STRING_DATE_JUNE, input, minimum)) return 6;
|
|
||||||
else if (closeEnough (STRING_DATE_JULY, input, minimum)) return 7;
|
|
||||||
else if (closeEnough (STRING_DATE_AUGUST, input, minimum)) return 8;
|
|
||||||
else if (closeEnough (STRING_DATE_SEPTEMBER, input, minimum)) return 9;
|
|
||||||
else if (closeEnough (STRING_DATE_OCTOBER, input, minimum)) return 10;
|
|
||||||
else if (closeEnough (STRING_DATE_NOVEMBER, input, minimum)) return 11;
|
|
||||||
else if (closeEnough (STRING_DATE_DECEMBER, input, minimum)) return 12;
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
int Date::length (const std::string& format)
|
|
||||||
{
|
|
||||||
int total = 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': total += 2; break;
|
|
||||||
case 'b':
|
|
||||||
case 'j':
|
|
||||||
case 'J':
|
|
||||||
case 'a': total += 3; break;
|
|
||||||
case 'Y': total += 4; break;
|
|
||||||
case 'A':
|
|
||||||
case 'B': total += 10; break;
|
|
||||||
|
|
||||||
// Calculate the width, don't assume a single character width.
|
|
||||||
default: total += mk_wcwidth (i); break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
|
||||||
{
|
|
||||||
struct tm* t = localtime (&_t);
|
|
||||||
return t->tm_mon + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
int Date::week () const
|
|
||||||
{
|
|
||||||
return Date::weekOfYear (Date::dayOfWeek (context.config.get ("weekstart")));
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
int Date::day () const
|
|
||||||
{
|
|
||||||
struct tm* t = localtime (&_t);
|
|
||||||
return t->tm_mday;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
int Date::year () const
|
|
||||||
{
|
|
||||||
struct tm* t = localtime (&_t);
|
|
||||||
return t->tm_year + 1900;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
int Date::hour () const
|
|
||||||
{
|
|
||||||
struct tm* t = localtime (&_t);
|
|
||||||
return t->tm_hour;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
int Date::minute () const
|
|
||||||
{
|
|
||||||
struct tm* t = localtime (&_t);
|
|
||||||
return t->tm_min;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
int Date::second () const
|
|
||||||
{
|
|
||||||
struct tm* t = localtime (&_t);
|
|
||||||
return t->tm_sec;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
bool Date::operator== (const Date& rhs) const
|
|
||||||
{
|
|
||||||
return rhs._t == _t;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
bool Date::operator!= (const Date& rhs) const
|
|
||||||
{
|
|
||||||
return rhs._t != _t;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
bool Date::operator< (const Date& rhs) const
|
|
||||||
{
|
|
||||||
return _t < rhs._t;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
bool Date::operator> (const Date& rhs) const
|
|
||||||
{
|
|
||||||
return _t > rhs._t;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
bool Date::operator<= (const Date& rhs) const
|
|
||||||
{
|
|
||||||
return _t <= rhs._t;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
bool Date::operator>= (const Date& rhs) const
|
|
||||||
{
|
|
||||||
return _t >= rhs._t;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
bool Date::sameHour (const Date& rhs) const
|
|
||||||
{
|
|
||||||
if (this->year () == rhs.year () &&
|
|
||||||
this->month () == rhs.month () &&
|
|
||||||
this->day () == rhs.day () &&
|
|
||||||
this->hour () == rhs.hour ())
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
bool Date::sameDay (const Date& rhs) const
|
|
||||||
{
|
|
||||||
if (this->year () == rhs.year () &&
|
|
||||||
this->month () == rhs.month () &&
|
|
||||||
this->day () == rhs.day ())
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
bool Date::sameWeek (const Date& rhs) const
|
|
||||||
{
|
|
||||||
if (this->year () == rhs.year () &&
|
|
||||||
this->week () == rhs.week ())
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
bool Date::sameMonth (const Date& rhs) const
|
|
||||||
{
|
|
||||||
if (this->year () == rhs.year () &&
|
|
||||||
this->month () == rhs.month ())
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
bool Date::sameYear (const Date& rhs) const
|
|
||||||
{
|
|
||||||
if (this->year () == rhs.year ())
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
Date Date::operator- (const int delta)
|
|
||||||
{
|
|
||||||
return Date (_t - delta);
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
Date Date::operator+ (const int delta)
|
|
||||||
{
|
|
||||||
return Date (_t + delta);
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
Date& Date::operator+= (const int delta)
|
|
||||||
{
|
|
||||||
_t += (time_t) delta;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
Date& Date::operator-= (const int delta)
|
|
||||||
{
|
|
||||||
_t -= (time_t) delta;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
time_t Date::operator- (const Date& rhs)
|
|
||||||
{
|
|
||||||
return _t - rhs._t;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Prefix decrement by one day.
|
|
||||||
void Date::operator-- ()
|
|
||||||
{
|
|
||||||
Date yesterday = startOfDay () - 1;
|
|
||||||
yesterday = Date (yesterday.month (),
|
|
||||||
yesterday.day (),
|
|
||||||
yesterday.year (),
|
|
||||||
hour (),
|
|
||||||
minute (),
|
|
||||||
second ());
|
|
||||||
_t = yesterday._t;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Postfix decrement by one day.
|
|
||||||
void Date::operator-- (int)
|
|
||||||
{
|
|
||||||
Date yesterday = startOfDay () - 1;
|
|
||||||
yesterday = Date (yesterday.month (),
|
|
||||||
yesterday.day (),
|
|
||||||
yesterday.year (),
|
|
||||||
hour (),
|
|
||||||
minute (),
|
|
||||||
second ());
|
|
||||||
_t = yesterday._t;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Prefix increment by one day.
|
|
||||||
void Date::operator++ ()
|
|
||||||
{
|
|
||||||
Date tomorrow = (startOfDay () + 90001).startOfDay ();
|
|
||||||
tomorrow = Date (tomorrow.month (),
|
|
||||||
tomorrow.day (),
|
|
||||||
tomorrow.year (),
|
|
||||||
hour (),
|
|
||||||
minute (),
|
|
||||||
second ());
|
|
||||||
_t = tomorrow._t;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Postfix increment by one day.
|
|
||||||
void Date::operator++ (int)
|
|
||||||
{
|
|
||||||
Date tomorrow = (startOfDay () + 90001).startOfDay ();
|
|
||||||
tomorrow = Date (tomorrow.month (),
|
|
||||||
tomorrow.day (),
|
|
||||||
tomorrow.year (),
|
|
||||||
hour (),
|
|
||||||
minute (),
|
|
||||||
second ());
|
|
||||||
_t = tomorrow._t;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
bool Date::isEpoch (const std::string& input)
|
|
||||||
{
|
|
||||||
if (Lexer::isAllDigits (input) &&
|
|
||||||
input.length () <= 10 )
|
|
||||||
{
|
|
||||||
_t = (time_t) atoi (input.c_str ());
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
129
src/Date.h
129
src/Date.h
|
@ -1,129 +0,0 @@
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Copyright 2006 - 2015, Paul Beckingham, Federico Hernandez.
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included
|
|
||||||
// in all copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
||||||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
||||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
// SOFTWARE.
|
|
||||||
//
|
|
||||||
// http://www.opensource.org/licenses/mit-license.php
|
|
||||||
//
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#ifndef INCLUDED_DATE
|
|
||||||
#define INCLUDED_DATE
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <vector>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
class Date;
|
|
||||||
|
|
||||||
class Date
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Date ();
|
|
||||||
Date (time_t);
|
|
||||||
Date (const int, const int, const int);
|
|
||||||
Date (const int, const int, const int, const int, const int, const int);
|
|
||||||
Date (const std::string&,
|
|
||||||
const std::string& format = "m/d/Y",
|
|
||||||
const bool iso = true,
|
|
||||||
const bool epoch = true);
|
|
||||||
Date (const std::string&,
|
|
||||||
std::string::size_type&,
|
|
||||||
const std::string& format = "m/d/Y",
|
|
||||||
const bool iso = true,
|
|
||||||
const bool epoch = true);
|
|
||||||
Date (const Date&);
|
|
||||||
virtual ~Date ();
|
|
||||||
|
|
||||||
void toEpoch (time_t&);
|
|
||||||
time_t toEpoch ();
|
|
||||||
std::string toEpochString ();
|
|
||||||
std::string toISO ();
|
|
||||||
double toJulian ();
|
|
||||||
void toMDY (int&, int&, int&);
|
|
||||||
const std::string toString (const std::string& format = "m/d/Y") const;
|
|
||||||
|
|
||||||
Date startOfDay () const;
|
|
||||||
Date startOfWeek () const;
|
|
||||||
Date startOfMonth () const;
|
|
||||||
Date 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 time_t easter (int year);
|
|
||||||
static bool leapYear (int);
|
|
||||||
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 weekOfYear (const std::string&);
|
|
||||||
static int dayOfWeek (const std::string&);
|
|
||||||
static int monthOfYear (const std::string&);
|
|
||||||
static int length (const std::string&);
|
|
||||||
|
|
||||||
int month () const;
|
|
||||||
int week () const;
|
|
||||||
int day () const;
|
|
||||||
int year () const;
|
|
||||||
int weekOfYear (int) const;
|
|
||||||
int dayOfWeek () const;
|
|
||||||
int dayOfYear () const;
|
|
||||||
int hour () const;
|
|
||||||
int minute () const;
|
|
||||||
int second () const;
|
|
||||||
|
|
||||||
bool operator== (const Date&) const;
|
|
||||||
bool operator!= (const Date&) const;
|
|
||||||
bool operator< (const Date&) const;
|
|
||||||
bool operator> (const Date&) const;
|
|
||||||
bool operator<= (const Date&) const;
|
|
||||||
bool operator>= (const Date&) const;
|
|
||||||
bool sameHour (const Date&) const;
|
|
||||||
bool sameDay (const Date&) const;
|
|
||||||
bool sameWeek (const Date&) const;
|
|
||||||
bool sameMonth (const Date&) const;
|
|
||||||
bool sameYear (const Date&) const;
|
|
||||||
|
|
||||||
Date operator+ (const int);
|
|
||||||
Date operator- (const int);
|
|
||||||
Date& operator+= (const int);
|
|
||||||
Date& operator-= (const int);
|
|
||||||
|
|
||||||
time_t operator- (const Date&);
|
|
||||||
|
|
||||||
void operator-- (); // Prefix
|
|
||||||
void operator-- (int); // Postfix
|
|
||||||
void operator++ (); // Prefix
|
|
||||||
void operator++ (int); // Postfix
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool isEpoch (const std::string&);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
time_t _t;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
|
@ -30,7 +30,7 @@
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <text.h>
|
#include <text.h>
|
||||||
#include <Dates.h>
|
#include <Dates.h>
|
||||||
#include <Date.h>
|
#include <ISO8601.h>
|
||||||
#include <Lexer.h>
|
#include <Lexer.h>
|
||||||
#include <CLI2.h>
|
#include <CLI2.h>
|
||||||
#include <i18n.h>
|
#include <i18n.h>
|
||||||
|
@ -38,14 +38,14 @@
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
static bool isMonth (const std::string& name, int& i)
|
static bool isMonth (const std::string& name, int& i)
|
||||||
{
|
{
|
||||||
i = Date::monthOfYear (name) - 1;
|
i = ISO8601d::monthOfYear (name) - 1;
|
||||||
return i != -2 ? true : false;
|
return i != -2 ? true : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
static bool isDay (const std::string& name, int& i)
|
static bool isDay (const std::string& name, int& i)
|
||||||
{
|
{
|
||||||
i = Date::dayOfWeek (name);
|
i = ISO8601d::dayOfWeek (name);
|
||||||
return i != -1 ? true : false;
|
return i != -1 ? true : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,32 +103,33 @@ static void midsommarafton (struct tm* t)
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// <day>
|
// Note how these are all single words:
|
||||||
// <month>
|
// <day>
|
||||||
// Nth
|
// <month>
|
||||||
// socy, eocy
|
// Nth
|
||||||
// socq, eocq
|
// socy, eocy
|
||||||
// socm, eocm
|
// socq, eocq
|
||||||
// som, eom
|
// socm, eocm
|
||||||
// soq, eoq
|
// som, eom
|
||||||
// soy, eoy
|
// soq, eoq
|
||||||
// socw, eocw
|
// soy, eoy
|
||||||
// sow, eow
|
// socw, eocw
|
||||||
// soww, eoww
|
// sow, eow
|
||||||
// sod, eod
|
// soww, eoww
|
||||||
// yesterday
|
// sod, eod
|
||||||
// today
|
// yesterday
|
||||||
// now
|
// today
|
||||||
// tomorrow
|
// now
|
||||||
// later = midnight, Jan 18th, 2038.
|
// tomorrow
|
||||||
// someday = midnight, Jan 18th, 2038.
|
// later = midnight, Jan 18th, 2038.
|
||||||
// easter
|
// someday = midnight, Jan 18th, 2038.
|
||||||
// eastermonday
|
// easter
|
||||||
// ascension
|
// eastermonday
|
||||||
// pentecost
|
// ascension
|
||||||
// goodfriday
|
// pentecost
|
||||||
// midsommar = midnight, 1st Saturday after 20th June
|
// goodfriday
|
||||||
// midsommarafton = midnight, 1st Friday after 19th June
|
// midsommar = midnight, 1st Saturday after 20th June
|
||||||
|
// midsommarafton = midnight, 1st Friday after 19th June
|
||||||
//
|
//
|
||||||
bool namedDates (const std::string& name, Variant& value)
|
bool namedDates (const std::string& name, Variant& value)
|
||||||
{
|
{
|
||||||
|
@ -302,7 +303,7 @@ bool namedDates (const std::string& name, Variant& value)
|
||||||
t->tm_hour = 24;
|
t->tm_hour = 24;
|
||||||
t->tm_min = 0;
|
t->tm_min = 0;
|
||||||
t->tm_sec = -1;
|
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;
|
t->tm_isdst = -1;
|
||||||
value = Variant (mktime (t), Variant::type_date);
|
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 it is this month.
|
||||||
if (d < number &&
|
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_hour = t->tm_min = t->tm_sec = 0;
|
||||||
t->tm_mon = m - 1;
|
t->tm_mon = m - 1;
|
||||||
|
|
1141
src/ISO8601.cpp
1141
src/ISO8601.cpp
File diff suppressed because it is too large
Load diff
|
@ -23,6 +23,7 @@
|
||||||
// http://www.opensource.org/licenses/mit-license.php
|
// http://www.opensource.org/licenses/mit-license.php
|
||||||
//
|
//
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#ifndef INCLUDED_ISO8601
|
#ifndef INCLUDED_ISO8601
|
||||||
#define INCLUDED_ISO8601
|
#define INCLUDED_ISO8601
|
||||||
|
|
||||||
|
@ -33,15 +34,84 @@
|
||||||
class ISO8601d
|
class ISO8601d
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
static std::string weekstart;
|
||||||
|
static int minimumMatchLength;
|
||||||
|
static bool isoEnabled;
|
||||||
|
|
||||||
ISO8601d ();
|
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 ();
|
||||||
ISO8601d (const ISO8601d&); // Unimplemented
|
|
||||||
ISO8601d& operator= (const ISO8601d&); // Unimplemented
|
|
||||||
operator time_t () const;
|
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 ();
|
|
||||||
|
time_t toEpoch ();
|
||||||
|
std::string toEpochString ();
|
||||||
|
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;
|
||||||
|
ISO8601d startOfMonth () const;
|
||||||
|
ISO8601d startOfYear () const;
|
||||||
|
|
||||||
|
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);
|
||||||
|
static bool leapYear (int);
|
||||||
|
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&);
|
||||||
|
static int dayOfWeek (int, int, int);
|
||||||
|
static int monthOfYear (const std::string&);
|
||||||
|
static int length (const std::string&);
|
||||||
|
|
||||||
|
int month () const;
|
||||||
|
int week () const;
|
||||||
|
int day () const;
|
||||||
|
int year () const;
|
||||||
|
int weekOfYear (int) const;
|
||||||
|
int dayOfWeek () const;
|
||||||
|
int dayOfYear () const;
|
||||||
|
int hour () const;
|
||||||
|
int minute () const;
|
||||||
|
int second () const;
|
||||||
|
|
||||||
|
bool operator== (const ISO8601d&) const;
|
||||||
|
bool operator!= (const ISO8601d&) const;
|
||||||
|
bool operator< (const ISO8601d&) const;
|
||||||
|
bool operator> (const ISO8601d&) const;
|
||||||
|
bool operator<= (const ISO8601d&) const;
|
||||||
|
bool operator>= (const ISO8601d&) const;
|
||||||
|
bool sameHour (const ISO8601d&) const;
|
||||||
|
bool sameDay (const ISO8601d&) const;
|
||||||
|
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);
|
||||||
|
ISO8601d& operator-= (const int);
|
||||||
|
time_t operator- (const ISO8601d&);
|
||||||
|
void operator-- (); // Prefix
|
||||||
|
void operator-- (int); // Postfix
|
||||||
|
void operator++ (); // Prefix
|
||||||
|
void operator++ (int); // Postfix
|
||||||
|
|
||||||
private:
|
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 (Nibbler&);
|
||||||
bool parse_date_time_ext (Nibbler&);
|
bool parse_date_time_ext (Nibbler&);
|
||||||
bool parse_date_ext (Nibbler&);
|
bool parse_date_ext (Nibbler&);
|
||||||
|
@ -49,7 +119,6 @@ private:
|
||||||
bool parse_time_ext (Nibbler&);
|
bool parse_time_ext (Nibbler&);
|
||||||
bool parse_time_utc_ext (Nibbler&);
|
bool parse_time_utc_ext (Nibbler&);
|
||||||
bool parse_time_off_ext (Nibbler&);
|
bool parse_time_off_ext (Nibbler&);
|
||||||
int dayOfWeek (int, int, int);
|
|
||||||
bool validate ();
|
bool validate ();
|
||||||
void resolve ();
|
void resolve ();
|
||||||
|
|
||||||
|
@ -63,13 +132,15 @@ public:
|
||||||
int _seconds;
|
int _seconds;
|
||||||
int _offset;
|
int _offset;
|
||||||
bool _utc;
|
bool _utc;
|
||||||
time_t _value;
|
time_t _date;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Period
|
// Period
|
||||||
class ISO8601p
|
class ISO8601p
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
static bool isoEnabled;
|
||||||
|
|
||||||
ISO8601p ();
|
ISO8601p ();
|
||||||
ISO8601p (time_t);
|
ISO8601p (time_t);
|
||||||
ISO8601p (const std::string&);
|
ISO8601p (const std::string&);
|
||||||
|
@ -81,11 +152,11 @@ public:
|
||||||
operator std::string () const;
|
operator std::string () const;
|
||||||
operator time_t () const;
|
operator time_t () const;
|
||||||
bool parse (const std::string&, std::string::size_type&);
|
bool parse (const std::string&, std::string::size_type&);
|
||||||
void clear ();
|
|
||||||
const std::string format () const;
|
const std::string format () const;
|
||||||
const std::string formatVague () const;
|
const std::string formatVague () const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void clear ();
|
||||||
bool parse_designated (Nibbler&);
|
bool parse_designated (Nibbler&);
|
||||||
bool validate ();
|
bool validate ();
|
||||||
void resolve ();
|
void resolve ();
|
||||||
|
@ -97,11 +168,9 @@ public:
|
||||||
int _hours;
|
int _hours;
|
||||||
int _minutes;
|
int _minutes;
|
||||||
int _seconds;
|
int _seconds;
|
||||||
time_t _value;
|
time_t _period;
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO Recurrence
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -28,14 +28,12 @@
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <Lexer.h>
|
#include <Lexer.h>
|
||||||
#include <ISO8601.h>
|
#include <ISO8601.h>
|
||||||
#include <Date.h>
|
|
||||||
#include <utf8.h>
|
#include <utf8.h>
|
||||||
|
|
||||||
static const std::string uuid_pattern = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";
|
static const std::string uuid_pattern = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";
|
||||||
static const unsigned int uuid_min_length = 8;
|
static const unsigned int uuid_min_length = 8;
|
||||||
|
|
||||||
std::string Lexer::dateFormat = "";
|
std::string Lexer::dateFormat = "";
|
||||||
bool Lexer::isoEnabled = true;
|
|
||||||
std::string::size_type Lexer::minimumMatchLength = 3;
|
std::string::size_type Lexer::minimumMatchLength = 3;
|
||||||
std::map <std::string, std::string> Lexer::attributes;
|
std::map <std::string, std::string> Lexer::attributes;
|
||||||
|
|
||||||
|
@ -432,38 +430,18 @@ bool Lexer::isString (std::string& token, Lexer::Type& type, const std::string&
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// Lexer::Type::date
|
// Lexer::Type::date
|
||||||
// <ISO8601d> | <Date>
|
// <ISO8601d>
|
||||||
bool Lexer::isDate (std::string& token, Lexer::Type& type)
|
bool Lexer::isDate (std::string& token, Lexer::Type& type)
|
||||||
{
|
{
|
||||||
// Try an ISO date parse.
|
// Try an ISO date parse.
|
||||||
if (Lexer::isoEnabled)
|
std::size_t iso_i = 0;
|
||||||
|
ISO8601d iso;
|
||||||
|
if (iso.parse (_text.substr (_cursor), iso_i, Lexer::dateFormat))
|
||||||
{
|
{
|
||||||
std::size_t iso_i = 0;
|
type = Lexer::Type::date;
|
||||||
ISO8601d iso;
|
token = _text.substr (_cursor, iso_i);
|
||||||
if (iso.parse (_text.substr (_cursor), iso_i))
|
_cursor += iso_i;
|
||||||
{
|
return true;
|
||||||
type = Lexer::Type::date;
|
|
||||||
token = _text.substr (_cursor, iso_i);
|
|
||||||
_cursor += iso_i;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Try a legacy rc.dateformat parse here.
|
|
||||||
if (Lexer::dateFormat != "")
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
std::size_t legacy_i = 0;
|
|
||||||
Date legacyDate (_text.substr (_cursor), legacy_i, Lexer::dateFormat, false, false);
|
|
||||||
|
|
||||||
type = Lexer::Type::date;
|
|
||||||
token = _text.substr (_cursor, legacy_i);
|
|
||||||
_cursor += legacy_i;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
catch (...) { /* Never mind. */ }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -40,7 +40,6 @@ class Lexer
|
||||||
public:
|
public:
|
||||||
// These are overridable.
|
// These are overridable.
|
||||||
static std::string dateFormat;
|
static std::string dateFormat;
|
||||||
static bool isoEnabled;
|
|
||||||
static std::string::size_type minimumMatchLength;
|
static std::string::size_type minimumMatchLength;
|
||||||
static std::map <std::string, std::string> attributes;
|
static std::map <std::string, std::string> attributes;
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
#include <Nibbler.h>
|
#include <Nibbler.h>
|
||||||
#include <util.h>
|
#include <util.h>
|
||||||
#ifdef NIBBLER_FEATURE_DATE
|
#ifdef NIBBLER_FEATURE_DATE
|
||||||
#include <Date.h>
|
#include <ISO8601.h>
|
||||||
#endif
|
#endif
|
||||||
#ifdef NIBBLER_FEATURE_REGEX
|
#ifdef NIBBLER_FEATURE_REGEX
|
||||||
#include <RX.h>
|
#include <RX.h>
|
||||||
|
@ -708,7 +708,8 @@ bool Nibbler::getDateISO (time_t& t)
|
||||||
// Parse the longest integer using the next 'limit' characters of 'result'
|
// Parse the longest integer using the next 'limit' characters of 'result'
|
||||||
// following position 'i' (when strict is true, the number of digits must be
|
// following position 'i' (when strict is true, the number of digits must be
|
||||||
// equal to limit).
|
// equal to limit).
|
||||||
bool Nibbler::parseDigits(std::string::size_type& i,
|
bool Nibbler::parseDigits(
|
||||||
|
std::string::size_type& i,
|
||||||
int& result,
|
int& result,
|
||||||
unsigned int limit,
|
unsigned int limit,
|
||||||
bool strict /* = true */)
|
bool strict /* = true */)
|
||||||
|
@ -819,8 +820,8 @@ bool Nibbler::getDate (const std::string& format, time_t& t)
|
||||||
! Lexer::isDigit ((*_input)[i + 1]) &&
|
! Lexer::isDigit ((*_input)[i + 1]) &&
|
||||||
! Lexer::isDigit ((*_input)[i + 2]))
|
! Lexer::isDigit ((*_input)[i + 2]))
|
||||||
{
|
{
|
||||||
wday = Date::dayOfWeek (_input->substr (i, 3).c_str ());
|
wday = ISO8601d::dayOfWeek (_input->substr (i, 3).c_str ());
|
||||||
i += (format[f] == 'a') ? 3 : Date::dayName (wday).size ();
|
i += (format[f] == 'a') ? 3 : ISO8601d::dayName (wday).size ();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
|
@ -835,8 +836,8 @@ bool Nibbler::getDate (const std::string& format, time_t& t)
|
||||||
{
|
{
|
||||||
if (month != -1)
|
if (month != -1)
|
||||||
return false;
|
return false;
|
||||||
month = Date::monthOfYear (_input->substr (i, 3).c_str());
|
month = ISO8601d::monthOfYear (_input->substr (i, 3).c_str());
|
||||||
i += (format[f] == 'b') ? 3 : Date::monthName (month).size ();
|
i += (format[f] == 'b') ? 3 : ISO8601d::monthName (month).size ();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
|
@ -858,7 +859,7 @@ bool Nibbler::getDate (const std::string& format, time_t& t)
|
||||||
// now.
|
// now.
|
||||||
if (year == -1)
|
if (year == -1)
|
||||||
{
|
{
|
||||||
Date now = Date ();
|
ISO8601d now;
|
||||||
year = now.year ();
|
year = now.year ();
|
||||||
if (month == -1)
|
if (month == -1)
|
||||||
{
|
{
|
||||||
|
@ -889,7 +890,7 @@ bool Nibbler::getDate (const std::string& format, time_t& t)
|
||||||
second = (second == -1) ? 0 : second;
|
second = (second == -1) ? 0 : second;
|
||||||
|
|
||||||
// Check that values are correct
|
// Check that values are correct
|
||||||
if (! Date::valid (month, day, year, hour, minute, second))
|
if (! ISO8601d::valid (month, day, year, hour, minute, second))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Convert to epoch.
|
// Convert to epoch.
|
||||||
|
|
|
@ -57,10 +57,6 @@ public:
|
||||||
bool getUntilEOL (std::string&);
|
bool getUntilEOL (std::string&);
|
||||||
bool getUntilEOS (std::string&);
|
bool getUntilEOS (std::string&);
|
||||||
|
|
||||||
/*
|
|
||||||
bool getAllOneOf (const std::string&, std::string&);
|
|
||||||
*/
|
|
||||||
|
|
||||||
bool getN (const int, std::string&);
|
bool getN (const int, std::string&);
|
||||||
bool getQuoted (char, std::string&, bool quote = false);
|
bool getQuoted (char, std::string&, bool quote = false);
|
||||||
bool getDigit (int&);
|
bool getDigit (int&);
|
||||||
|
|
14
src/TDB2.cpp
14
src/TDB2.cpp
|
@ -34,7 +34,7 @@
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <Context.h>
|
#include <Context.h>
|
||||||
#include <Color.h>
|
#include <Color.h>
|
||||||
#include <Date.h>
|
#include <ISO8601.h>
|
||||||
#include <i18n.h>
|
#include <i18n.h>
|
||||||
#include <text.h>
|
#include <text.h>
|
||||||
#include <util.h>
|
#include <util.h>
|
||||||
|
@ -638,7 +638,7 @@ void TDB2::update (
|
||||||
// old <task>
|
// old <task>
|
||||||
// new <task>
|
// new <task>
|
||||||
// ---
|
// ---
|
||||||
undo.add_line ("time " + Date ().toEpochString () + "\n");
|
undo.add_line ("time " + ISO8601d ().toEpochString () + "\n");
|
||||||
undo.add_line ("old " + original.composeF4 () + "\n");
|
undo.add_line ("old " + original.composeF4 () + "\n");
|
||||||
undo.add_line ("new " + task.composeF4 () + "\n");
|
undo.add_line ("new " + task.composeF4 () + "\n");
|
||||||
undo.add_line ("---\n");
|
undo.add_line ("---\n");
|
||||||
|
@ -657,7 +657,7 @@ void TDB2::update (
|
||||||
// time <time>
|
// time <time>
|
||||||
// new <task>
|
// new <task>
|
||||||
// ---
|
// ---
|
||||||
undo.add_line ("time " + Date ().toEpochString () + "\n");
|
undo.add_line ("time " + ISO8601d ().toEpochString () + "\n");
|
||||||
undo.add_line ("new " + task.composeF4 () + "\n");
|
undo.add_line ("new " + task.composeF4 () + "\n");
|
||||||
undo.add_line ("---\n");
|
undo.add_line ("---\n");
|
||||||
}
|
}
|
||||||
|
@ -962,7 +962,7 @@ void TDB2::show_diff (
|
||||||
const std::string& prior,
|
const std::string& prior,
|
||||||
const std::string& when)
|
const std::string& when)
|
||||||
{
|
{
|
||||||
Date lastChange (strtol (when.c_str (), NULL, 10));
|
ISO8601d lastChange (strtol (when.c_str (), NULL, 10));
|
||||||
|
|
||||||
// Set the colors.
|
// Set the colors.
|
||||||
Color color_red (context.color () ? context.config.get ("color.undo.before") : "");
|
Color color_red (context.color () ? context.config.get ("color.undo.before") : "");
|
||||||
|
@ -1209,7 +1209,7 @@ int TDB2::gc ()
|
||||||
|
|
||||||
// Scan all pending tasks, looking for any that need to be relocated to
|
// Scan all pending tasks, looking for any that need to be relocated to
|
||||||
// completed, or need to be 'woken'.
|
// completed, or need to be 'woken'.
|
||||||
Date now;
|
ISO8601d now;
|
||||||
std::string status;
|
std::string status;
|
||||||
for (auto& task : pending_tasks)
|
for (auto& task : pending_tasks)
|
||||||
{
|
{
|
||||||
|
@ -1221,7 +1221,7 @@ int TDB2::gc ()
|
||||||
}
|
}
|
||||||
else if (status == "waiting")
|
else if (status == "waiting")
|
||||||
{
|
{
|
||||||
Date wait (task.get_date ("wait"));
|
ISO8601d wait (task.get_date ("wait"));
|
||||||
if (wait < now)
|
if (wait < now)
|
||||||
{
|
{
|
||||||
task.set ("status", "pending");
|
task.set ("status", "pending");
|
||||||
|
@ -1261,7 +1261,7 @@ int TDB2::gc ()
|
||||||
}
|
}
|
||||||
else if (status == "waiting")
|
else if (status == "waiting")
|
||||||
{
|
{
|
||||||
Date wait (task.get_date ("wait"));
|
ISO8601d wait (task.get_date ("wait"));
|
||||||
if (wait < now)
|
if (wait < now)
|
||||||
{
|
{
|
||||||
task.set ("status", "pending");
|
task.set ("status", "pending");
|
||||||
|
|
59
src/Task.cpp
59
src/Task.cpp
|
@ -40,7 +40,6 @@
|
||||||
#include <Lexer.h>
|
#include <Lexer.h>
|
||||||
#include <Nibbler.h>
|
#include <Nibbler.h>
|
||||||
#endif
|
#endif
|
||||||
#include <Date.h>
|
|
||||||
#include <ISO8601.h>
|
#include <ISO8601.h>
|
||||||
#include <Task.h>
|
#include <Task.h>
|
||||||
#ifdef PRODUCT_TASKWARRIOR
|
#ifdef PRODUCT_TASKWARRIOR
|
||||||
|
@ -341,9 +340,9 @@ Task::dateState Task::getDateState (const std::string& name) const
|
||||||
std::string value = get (name);
|
std::string value = get (name);
|
||||||
if (value.length ())
|
if (value.length ())
|
||||||
{
|
{
|
||||||
Date reference (value);
|
ISO8601d reference (value);
|
||||||
Date now;
|
ISO8601d now;
|
||||||
Date today ("today");
|
ISO8601d today ("today");
|
||||||
|
|
||||||
if (reference < today)
|
if (reference < today)
|
||||||
return dateBeforeToday;
|
return dateBeforeToday;
|
||||||
|
@ -360,7 +359,7 @@ Task::dateState Task::getDateState (const std::string& name) const
|
||||||
if (imminentperiod == 0)
|
if (imminentperiod == 0)
|
||||||
return dateAfterToday;
|
return dateAfterToday;
|
||||||
|
|
||||||
Date imminentDay = today + imminentperiod * 86400;
|
ISO8601d imminentDay = today + imminentperiod * 86400;
|
||||||
if (reference < imminentDay)
|
if (reference < imminentDay)
|
||||||
return dateAfterToday;
|
return dateAfterToday;
|
||||||
}
|
}
|
||||||
|
@ -377,7 +376,7 @@ bool Task::is_ready () const
|
||||||
return getStatus () == Task::pending &&
|
return getStatus () == Task::pending &&
|
||||||
! is_blocked &&
|
! is_blocked &&
|
||||||
(! has ("scheduled") ||
|
(! has ("scheduled") ||
|
||||||
Date ("now").operator> (get_date ("scheduled")));
|
ISO8601d ("now").operator> (get_date ("scheduled")));
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -411,7 +410,7 @@ bool Task::is_dueyesterday () const
|
||||||
if (status != Task::completed &&
|
if (status != Task::completed &&
|
||||||
status != Task::deleted)
|
status != Task::deleted)
|
||||||
{
|
{
|
||||||
if (Date ("yesterday").sameDay (get_date ("due")))
|
if (ISO8601d ("yesterday").sameDay (get_date ("due")))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -449,7 +448,7 @@ bool Task::is_duetomorrow () const
|
||||||
if (status != Task::completed &&
|
if (status != Task::completed &&
|
||||||
status != Task::deleted)
|
status != Task::deleted)
|
||||||
{
|
{
|
||||||
if (Date ("tomorrow").sameDay (get_date ("due")))
|
if (ISO8601d ("tomorrow").sameDay (get_date ("due")))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -467,9 +466,9 @@ bool Task::is_dueweek () const
|
||||||
if (status != Task::completed &&
|
if (status != Task::completed &&
|
||||||
status != Task::deleted)
|
status != Task::deleted)
|
||||||
{
|
{
|
||||||
Date due (get_date ("due"));
|
ISO8601d due (get_date ("due"));
|
||||||
if (due >= Date ("socw") &&
|
if (due >= ISO8601d ("socw") &&
|
||||||
due <= Date ("eocw"))
|
due <= ISO8601d ("eocw"))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -487,9 +486,9 @@ bool Task::is_duemonth () const
|
||||||
if (status != Task::completed &&
|
if (status != Task::completed &&
|
||||||
status != Task::deleted)
|
status != Task::deleted)
|
||||||
{
|
{
|
||||||
Date due (get_date ("due"));
|
ISO8601d due (get_date ("due"));
|
||||||
if (due >= Date ("socm") &&
|
if (due >= ISO8601d ("socm") &&
|
||||||
due <= Date ("eocm"))
|
due <= ISO8601d ("eocm"))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -507,8 +506,8 @@ bool Task::is_dueyear () const
|
||||||
if (status != Task::completed &&
|
if (status != Task::completed &&
|
||||||
status != Task::deleted)
|
status != Task::deleted)
|
||||||
{
|
{
|
||||||
Date now;
|
ISO8601d now;
|
||||||
Date due (get_date ("due"));
|
ISO8601d due (get_date ("due"));
|
||||||
if (now.year () == due.year ())
|
if (now.year () == due.year ())
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -674,7 +673,7 @@ void Task::parseJSON (const json::object* root_obj)
|
||||||
// TW-1274 Standardization.
|
// TW-1274 Standardization.
|
||||||
else if (i.first == "modification")
|
else if (i.first == "modification")
|
||||||
{
|
{
|
||||||
Date d (unquoteText (i.second->dump ()));
|
ISO8601d d (unquoteText (i.second->dump ()));
|
||||||
set ("modified", d.toEpochString ());
|
set ("modified", d.toEpochString ());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -682,7 +681,7 @@ void Task::parseJSON (const json::object* root_obj)
|
||||||
else if (type == "date")
|
else if (type == "date")
|
||||||
{
|
{
|
||||||
std::string text = unquoteText (i.second->dump ());
|
std::string text = unquoteText (i.second->dump ());
|
||||||
Date d (text);
|
ISO8601d d (text);
|
||||||
set (i.first, text == "" ? "" : d.toEpochString ());
|
set (i.first, text == "" ? "" : d.toEpochString ());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -747,7 +746,7 @@ void Task::parseJSON (const json::object* root_obj)
|
||||||
if (! what)
|
if (! what)
|
||||||
throw format (STRING_TASK_NO_DESC, root_obj->dump ());
|
throw format (STRING_TASK_NO_DESC, root_obj->dump ());
|
||||||
|
|
||||||
std::string name = "annotation_" + Date (when->_data).toEpochString ();
|
std::string name = "annotation_" + ISO8601d (when->_data).toEpochString ();
|
||||||
annos.insert (std::make_pair (name, json::decode (what->_data)));
|
annos.insert (std::make_pair (name, json::decode (what->_data)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -865,7 +864,7 @@ std::string Task::composeJSON (bool decorate /*= false*/) const
|
||||||
// Date fields are written as ISO 8601.
|
// Date fields are written as ISO 8601.
|
||||||
if (type == "date")
|
if (type == "date")
|
||||||
{
|
{
|
||||||
Date d (i.second);
|
ISO8601d d (i.second);
|
||||||
out << "\""
|
out << "\""
|
||||||
<< (i.first == "modification" ? "modified" : i.first)
|
<< (i.first == "modification" ? "modified" : i.first)
|
||||||
<< "\":\""
|
<< "\":\""
|
||||||
|
@ -960,7 +959,7 @@ std::string Task::composeJSON (bool decorate /*= false*/) const
|
||||||
if (annotations_written)
|
if (annotations_written)
|
||||||
out << ",";
|
out << ",";
|
||||||
|
|
||||||
Date d (i.first.substr (11));
|
ISO8601d d (i.first.substr (11));
|
||||||
out << "{\"entry\":\""
|
out << "{\"entry\":\""
|
||||||
<< d.toISO ()
|
<< d.toISO ()
|
||||||
<< "\",\"description\":\""
|
<< "\",\"description\":\""
|
||||||
|
@ -1487,9 +1486,9 @@ void Task::validate (bool applyDefault /* = true */)
|
||||||
{
|
{
|
||||||
ISO8601p dur (Task::defaultDue);
|
ISO8601p dur (Task::defaultDue);
|
||||||
if ((time_t) dur != 0)
|
if ((time_t) dur != 0)
|
||||||
set ("due", (Date () + dur).toEpoch ());
|
set ("due", (ISO8601d () + dur).toEpoch ());
|
||||||
else
|
else
|
||||||
set ("due", Date (Task::defaultDue).toEpoch ());
|
set ("due", ISO8601d (Task::defaultDue).toEpoch ());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1568,11 +1567,11 @@ void Task::validate_before (const std::string& left, const std::string& right)
|
||||||
if (has (left) &&
|
if (has (left) &&
|
||||||
has (right))
|
has (right))
|
||||||
{
|
{
|
||||||
Date date_left (get_date (left));
|
ISO8601d date_left (get_date (left));
|
||||||
Date date_right (get_date (right));
|
ISO8601d date_right (get_date (right));
|
||||||
|
|
||||||
// if date is zero, then it is being removed (e.g. "due: wait:1day")
|
// if date is zero, then it is being removed (e.g. "due: wait:1day")
|
||||||
if (date_left > date_right && date_right != 0)
|
if (date_left > date_right && date_right.toEpoch () != 0)
|
||||||
context.footnote (format (STRING_TASK_VALID_BEFORE, left, right));
|
context.footnote (format (STRING_TASK_VALID_BEFORE, left, right));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -1923,8 +1922,8 @@ float Task::urgency_due () const
|
||||||
{
|
{
|
||||||
if (has ("due"))
|
if (has ("due"))
|
||||||
{
|
{
|
||||||
Date now;
|
ISO8601d now;
|
||||||
Date due (get_date ("due"));
|
ISO8601d due (get_date ("due"));
|
||||||
|
|
||||||
// Map a range of 21 days to the value 0.2 - 1.0
|
// Map a range of 21 days to the value 0.2 - 1.0
|
||||||
float days_overdue = (now - due) / 86400.0;
|
float days_overdue = (now - due) / 86400.0;
|
||||||
|
@ -1941,8 +1940,8 @@ float Task::urgency_age () const
|
||||||
{
|
{
|
||||||
assert (has ("entry"));
|
assert (has ("entry"));
|
||||||
|
|
||||||
Date now;
|
ISO8601d now;
|
||||||
Date entry (get_date ("entry"));
|
ISO8601d entry (get_date ("entry"));
|
||||||
int age = (now - entry) / 86400; // in days
|
int age = (now - entry) / 86400; // in days
|
||||||
|
|
||||||
if (Task::urgencyAgeMax == 0 || age > Task::urgencyAgeMax)
|
if (Task::urgencyAgeMax == 0 || age > Task::urgencyAgeMax)
|
||||||
|
|
|
@ -33,7 +33,6 @@
|
||||||
#include <Variant.h>
|
#include <Variant.h>
|
||||||
#include <ISO8601.h>
|
#include <ISO8601.h>
|
||||||
#include <Lexer.h>
|
#include <Lexer.h>
|
||||||
#include <Date.h>
|
|
||||||
#include <RX.h>
|
#include <RX.h>
|
||||||
#include <text.h>
|
#include <text.h>
|
||||||
#include <i18n.h>
|
#include <i18n.h>
|
||||||
|
@ -41,7 +40,6 @@
|
||||||
std::string Variant::dateFormat = "";
|
std::string Variant::dateFormat = "";
|
||||||
bool Variant::searchCaseSensitive = true;
|
bool Variant::searchCaseSensitive = true;
|
||||||
bool Variant::searchUsingRegex = true;
|
bool Variant::searchUsingRegex = true;
|
||||||
bool Variant::isoEnabled = true;
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
Variant::Variant ()
|
Variant::Variant ()
|
||||||
|
@ -1010,8 +1008,8 @@ bool Variant::operator_partial (const Variant& other) const
|
||||||
case type_date:
|
case type_date:
|
||||||
{
|
{
|
||||||
left.cast (type_date);
|
left.cast (type_date);
|
||||||
Date left_date (left._date);
|
ISO8601d left_date (left._date);
|
||||||
Date right_date (right._date);
|
ISO8601d right_date (right._date);
|
||||||
return left_date.sameDay (right_date);
|
return left_date.sameDay (right_date);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1031,8 +1029,8 @@ bool Variant::operator_partial (const Variant& other) const
|
||||||
case type_date:
|
case type_date:
|
||||||
{
|
{
|
||||||
left.cast (type_date);
|
left.cast (type_date);
|
||||||
Date left_date (left._date);
|
ISO8601d left_date (left._date);
|
||||||
Date right_date (right._date);
|
ISO8601d right_date (right._date);
|
||||||
return left_date.sameDay (right_date);
|
return left_date.sameDay (right_date);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1057,8 +1055,8 @@ bool Variant::operator_partial (const Variant& other) const
|
||||||
case type_date:
|
case type_date:
|
||||||
{
|
{
|
||||||
left.cast (type_date);
|
left.cast (type_date);
|
||||||
Date left_date (left._date);
|
ISO8601d left_date (left._date);
|
||||||
Date right_date (right._date);
|
ISO8601d right_date (right._date);
|
||||||
return left_date.sameDay (right_date);
|
return left_date.sameDay (right_date);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1100,8 +1098,8 @@ bool Variant::operator_partial (const Variant& other) const
|
||||||
case type_date:
|
case type_date:
|
||||||
{
|
{
|
||||||
left.cast (type_date);
|
left.cast (type_date);
|
||||||
Date left_date (left._date);
|
ISO8601d left_date (left._date);
|
||||||
Date right_date (right._date);
|
ISO8601d right_date (right._date);
|
||||||
return left_date.sameDay (right_date);
|
return left_date.sameDay (right_date);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1123,8 +1121,8 @@ bool Variant::operator_partial (const Variant& other) const
|
||||||
case type_duration:
|
case type_duration:
|
||||||
{
|
{
|
||||||
right.cast (type_date);
|
right.cast (type_date);
|
||||||
Date left_date (left._date);
|
ISO8601d left_date (left._date);
|
||||||
Date right_date (right._date);
|
ISO8601d right_date (right._date);
|
||||||
return left_date.sameDay (right_date);
|
return left_date.sameDay (right_date);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1933,30 +1931,27 @@ void Variant::cast (const enum type new_type)
|
||||||
case type_date:
|
case type_date:
|
||||||
{
|
{
|
||||||
_date = 0;
|
_date = 0;
|
||||||
|
|
||||||
ISO8601d iso;
|
ISO8601d iso;
|
||||||
std::string::size_type pos = 0;
|
std::string::size_type pos = 0;
|
||||||
if (isoEnabled &&
|
if (iso.parse (_string, pos, dateFormat) &&
|
||||||
iso.parse (_string, pos) &&
|
|
||||||
pos == _string.length ())
|
pos == _string.length ())
|
||||||
{
|
{
|
||||||
_date = (time_t) iso;
|
_date = iso.toEpoch ();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
pos = 0;
|
pos = 0;
|
||||||
ISO8601p isop;
|
ISO8601p isop;
|
||||||
if (isoEnabled &&
|
if (isop.parse (_string, pos) &&
|
||||||
isop.parse (_string, pos) &&
|
|
||||||
pos == _string.length ())
|
pos == _string.length ())
|
||||||
{
|
{
|
||||||
_date = Date ().toEpoch () + (time_t) isop;
|
_date = ISO8601d ().toEpoch () + (time_t) isop;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dateFormat != "")
|
if (dateFormat != "")
|
||||||
{
|
{
|
||||||
_date = Date (_string, dateFormat).toEpoch ();
|
_date = ISO8601d (_string, dateFormat).toEpoch ();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,6 @@
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <Context.h>
|
#include <Context.h>
|
||||||
#include <ColDate.h>
|
#include <ColDate.h>
|
||||||
#include <Date.h>
|
|
||||||
#include <ISO8601.h>
|
#include <ISO8601.h>
|
||||||
#include <text.h>
|
#include <text.h>
|
||||||
#include <i18n.h>
|
#include <i18n.h>
|
||||||
|
@ -50,15 +49,15 @@ ColumnDate::ColumnDate ()
|
||||||
"remaining",
|
"remaining",
|
||||||
"countdown"};
|
"countdown"};
|
||||||
|
|
||||||
Date now;
|
ISO8601d now;
|
||||||
now -= 125; // So that "age" is non-zero.
|
now -= 125; // So that "age" is non-zero.
|
||||||
_examples = {now.toString (context.config.get ("dateformat")),
|
_examples = {now.toString (context.config.get ("dateformat")),
|
||||||
format (now.toJulian (), 13, 12),
|
format (now.toJulian (), 13, 12),
|
||||||
now.toEpochString (),
|
now.toEpochString (),
|
||||||
now.toISO (),
|
now.toISO (),
|
||||||
ISO8601p (Date () - now).formatVague (),
|
ISO8601p (ISO8601d () - now).formatVague (),
|
||||||
"",
|
"",
|
||||||
ISO8601p (Date () - now).format ()};
|
ISO8601p (ISO8601d () - now).format ()};
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -74,7 +73,7 @@ void ColumnDate::measure (Task& task, unsigned int& minimum, unsigned int& maxim
|
||||||
|
|
||||||
if (task.has (_name))
|
if (task.has (_name))
|
||||||
{
|
{
|
||||||
Date date (task.get_date (_name));
|
ISO8601d date (task.get_date (_name));
|
||||||
|
|
||||||
if (_style == "default" ||
|
if (_style == "default" ||
|
||||||
_style == "formatted")
|
_style == "formatted")
|
||||||
|
@ -89,11 +88,11 @@ void ColumnDate::measure (Task& task, unsigned int& minimum, unsigned int& maxim
|
||||||
if (format == "")
|
if (format == "")
|
||||||
format = context.config.get ("dateformat");
|
format = context.config.get ("dateformat");
|
||||||
|
|
||||||
minimum = maximum = Date::length (format);
|
minimum = maximum = ISO8601d::length (format);
|
||||||
}
|
}
|
||||||
else if (_style == "countdown")
|
else if (_style == "countdown")
|
||||||
{
|
{
|
||||||
Date now;
|
ISO8601d now;
|
||||||
minimum = maximum = ISO8601p (now - date).formatVague ().length ();
|
minimum = maximum = ISO8601p (now - date).formatVague ().length ();
|
||||||
}
|
}
|
||||||
else if (_style == "julian")
|
else if (_style == "julian")
|
||||||
|
@ -110,12 +109,12 @@ void ColumnDate::measure (Task& task, unsigned int& minimum, unsigned int& maxim
|
||||||
}
|
}
|
||||||
else if (_style == "age")
|
else if (_style == "age")
|
||||||
{
|
{
|
||||||
Date now;
|
ISO8601d now;
|
||||||
minimum = maximum = ISO8601p (now - date).formatVague ().length ();
|
minimum = maximum = ISO8601p (now - date).formatVague ().length ();
|
||||||
}
|
}
|
||||||
else if (_style == "remaining")
|
else if (_style == "remaining")
|
||||||
{
|
{
|
||||||
Date now;
|
ISO8601d now;
|
||||||
if (date > now)
|
if (date > now)
|
||||||
minimum = maximum = ISO8601p (date - now).formatVague ().length ();
|
minimum = maximum = ISO8601p (date - now).formatVague ().length ();
|
||||||
}
|
}
|
||||||
|
@ -133,7 +132,7 @@ void ColumnDate::render (
|
||||||
{
|
{
|
||||||
if (task.has (_name))
|
if (task.has (_name))
|
||||||
{
|
{
|
||||||
Date date (task.get_date (_name));
|
ISO8601d date (task.get_date (_name));
|
||||||
|
|
||||||
if (_style == "default" ||
|
if (_style == "default" ||
|
||||||
_style == "formatted")
|
_style == "formatted")
|
||||||
|
@ -155,7 +154,7 @@ void ColumnDate::render (
|
||||||
}
|
}
|
||||||
else if (_style == "countdown")
|
else if (_style == "countdown")
|
||||||
{
|
{
|
||||||
Date now;
|
ISO8601d now;
|
||||||
|
|
||||||
lines.push_back (
|
lines.push_back (
|
||||||
color.colorize (
|
color.colorize (
|
||||||
|
@ -185,7 +184,7 @@ void ColumnDate::render (
|
||||||
}
|
}
|
||||||
else if (_style == "age")
|
else if (_style == "age")
|
||||||
{
|
{
|
||||||
Date now;
|
ISO8601d now;
|
||||||
|
|
||||||
lines.push_back (
|
lines.push_back (
|
||||||
color.colorize (
|
color.colorize (
|
||||||
|
@ -194,7 +193,7 @@ void ColumnDate::render (
|
||||||
}
|
}
|
||||||
else if (_style == "remaining")
|
else if (_style == "remaining")
|
||||||
{
|
{
|
||||||
Date now;
|
ISO8601d now;
|
||||||
if (date > now)
|
if (date > now)
|
||||||
lines.push_back (
|
lines.push_back (
|
||||||
color.colorize (
|
color.colorize (
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
#include <cmake.h>
|
#include <cmake.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <Context.h>
|
#include <Context.h>
|
||||||
#include <Date.h>
|
#include <ISO8601.h>
|
||||||
#include <ColDescription.h>
|
#include <ColDescription.h>
|
||||||
#include <text.h>
|
#include <text.h>
|
||||||
#include <utf8.h>
|
#include <utf8.h>
|
||||||
|
@ -55,7 +55,7 @@ ColumnDescription::ColumnDescription ()
|
||||||
if (_dateformat == "")
|
if (_dateformat == "")
|
||||||
_dateformat = context.config.get ("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 d = STRING_COLUMN_EXAMPLES_DESC;
|
||||||
std::string a1 = STRING_COLUMN_EXAMPLES_ANNO1;
|
std::string a1 = STRING_COLUMN_EXAMPLES_ANNO1;
|
||||||
std::string a2 = STRING_COLUMN_EXAMPLES_ANNO2;
|
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)
|
if (task.annotation_count)
|
||||||
{
|
{
|
||||||
unsigned int min_anno = _indent + Date::length (_dateformat);
|
unsigned int min_anno = _indent + ISO8601d::length (_dateformat);
|
||||||
if (min_anno > minimum)
|
if (min_anno > minimum)
|
||||||
minimum = min_anno;
|
minimum = min_anno;
|
||||||
|
|
||||||
|
@ -132,7 +132,7 @@ void ColumnDescription::measure (Task& task, unsigned int& minimum, unsigned int
|
||||||
|
|
||||||
if (task.annotation_count)
|
if (task.annotation_count)
|
||||||
{
|
{
|
||||||
auto min_anno = Date::length (_dateformat);
|
auto min_anno = ISO8601d::length (_dateformat);
|
||||||
std::map <std::string, std::string> annos;
|
std::map <std::string, std::string> annos;
|
||||||
task.getAnnotations (annos);
|
task.getAnnotations (annos);
|
||||||
for (auto& i : annos)
|
for (auto& i : annos)
|
||||||
|
@ -187,7 +187,7 @@ void ColumnDescription::render (
|
||||||
{
|
{
|
||||||
for (auto& i : annos)
|
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;
|
description += "\n" + std::string (_indent, ' ') + dt.toString (_dateformat) + " " + i.second;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -218,7 +218,7 @@ void ColumnDescription::render (
|
||||||
{
|
{
|
||||||
for (auto& i : annos)
|
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;
|
description += " " + dt.toString (_dateformat) + " " + i.second;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,8 +28,6 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <Context.h>
|
#include <Context.h>
|
||||||
#include <ColDue.h>
|
#include <ColDue.h>
|
||||||
#include <Date.h>
|
|
||||||
#include <ISO8601.h>
|
|
||||||
#include <text.h>
|
#include <text.h>
|
||||||
#include <i18n.h>
|
#include <i18n.h>
|
||||||
|
|
||||||
|
|
|
@ -28,8 +28,6 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <Context.h>
|
#include <Context.h>
|
||||||
#include <ColScheduled.h>
|
#include <ColScheduled.h>
|
||||||
#include <Date.h>
|
|
||||||
#include <ISO8601.h>
|
|
||||||
#include <text.h>
|
#include <text.h>
|
||||||
#include <i18n.h>
|
#include <i18n.h>
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,6 @@
|
||||||
#include <cmake.h>
|
#include <cmake.h>
|
||||||
#include <Context.h>
|
#include <Context.h>
|
||||||
#include <ISO8601.h>
|
#include <ISO8601.h>
|
||||||
#include <Date.h>
|
|
||||||
#include <ColUDA.h>
|
#include <ColUDA.h>
|
||||||
#include <text.h>
|
#include <text.h>
|
||||||
#include <utf8.h>
|
#include <utf8.h>
|
||||||
|
@ -89,14 +88,14 @@ void ColumnUDA::measure (Task& task, unsigned int& minimum, unsigned int& maximu
|
||||||
// rc.report.<report>.dateformat
|
// rc.report.<report>.dateformat
|
||||||
// rc.dateformat.report
|
// rc.dateformat.report
|
||||||
// rc.dateformat
|
// 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");
|
std::string format = context.config.get ("report." + _report + ".dateformat");
|
||||||
if (format == "")
|
if (format == "")
|
||||||
format = context.config.get ("dateformat.report");
|
format = context.config.get ("dateformat.report");
|
||||||
if (format == "")
|
if (format == "")
|
||||||
format = context.config.get ("dateformat");
|
format = context.config.get ("dateformat");
|
||||||
|
|
||||||
minimum = maximum = Date::length (format);
|
minimum = maximum = ISO8601d::length (format);
|
||||||
}
|
}
|
||||||
else if (_type == "duration")
|
else if (_type == "duration")
|
||||||
{
|
{
|
||||||
|
@ -153,8 +152,7 @@ void ColumnUDA::render (
|
||||||
lines.push_back (
|
lines.push_back (
|
||||||
color.colorize (
|
color.colorize (
|
||||||
leftJustify (
|
leftJustify (
|
||||||
Date ((time_t) strtol (value.c_str (), NULL, 10))
|
ISO8601d ((time_t) strtol (value.c_str (), NULL, 10)).toString (format), width)));
|
||||||
.toString (format), width)));
|
|
||||||
}
|
}
|
||||||
else if (_type == "duration")
|
else if (_type == "duration")
|
||||||
{
|
{
|
||||||
|
|
|
@ -32,7 +32,6 @@
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <Context.h>
|
#include <Context.h>
|
||||||
#include <Filter.h>
|
#include <Filter.h>
|
||||||
#include <Date.h>
|
|
||||||
#include <ISO8601.h>
|
#include <ISO8601.h>
|
||||||
#include <main.h>
|
#include <main.h>
|
||||||
#include <i18n.h>
|
#include <i18n.h>
|
||||||
|
@ -152,10 +151,10 @@ public:
|
||||||
private:
|
private:
|
||||||
void generateBars ();
|
void generateBars ();
|
||||||
void optimizeGrid ();
|
void optimizeGrid ();
|
||||||
Date quantize (const Date&);
|
ISO8601d quantize (const ISO8601d&);
|
||||||
|
|
||||||
Date increment (const Date&);
|
ISO8601d increment (const ISO8601d&);
|
||||||
Date decrement (const Date&);
|
ISO8601d decrement (const ISO8601d&);
|
||||||
void maxima ();
|
void maxima ();
|
||||||
void yLabels (std::vector <int>&);
|
void yLabels (std::vector <int>&);
|
||||||
void calculateRates (std::vector <time_t>&);
|
void calculateRates (std::vector <time_t>&);
|
||||||
|
@ -173,7 +172,7 @@ public:
|
||||||
int _estimated_bars; // Estimated bar count
|
int _estimated_bars; // Estimated bar count
|
||||||
int _actual_bars; // Calculated bar count
|
int _actual_bars; // Calculated bar count
|
||||||
std::map <time_t, Bar> _bars; // Epoch-indexed set of bars
|
std::map <time_t, Bar> _bars; // Epoch-indexed set of bars
|
||||||
Date _earliest; // Date of earliest estimated bar
|
ISO8601d _earliest; // Date of earliest estimated bar
|
||||||
int _carryover_done; // Number of 'done' tasks prior to chart range
|
int _carryover_done; // Number of 'done' tasks prior to chart range
|
||||||
char _period; // D, W, M
|
char _period; // D, W, M
|
||||||
std::string _title; // Additional description
|
std::string _title; // Additional description
|
||||||
|
@ -226,13 +225,13 @@ void Chart::scan (std::vector <Task>& tasks)
|
||||||
generateBars ();
|
generateBars ();
|
||||||
|
|
||||||
// Not quantized, so that "while (xxx < now)" is inclusive.
|
// Not quantized, so that "while (xxx < now)" is inclusive.
|
||||||
Date now;
|
ISO8601d now;
|
||||||
|
|
||||||
time_t epoch;
|
time_t epoch;
|
||||||
for (auto& task : tasks)
|
for (auto& task : tasks)
|
||||||
{
|
{
|
||||||
// The entry date is when the counting starts.
|
// The entry date is when the counting starts.
|
||||||
Date from = quantize (Date (task.get_date ("entry")));
|
ISO8601d from = quantize (ISO8601d (task.get_date ("entry")));
|
||||||
epoch = from.toEpoch ();
|
epoch = from.toEpoch ();
|
||||||
|
|
||||||
if (_bars.find (epoch) != _bars.end ())
|
if (_bars.find (epoch) != _bars.end ())
|
||||||
|
@ -246,7 +245,7 @@ void Chart::scan (std::vector <Task>& tasks)
|
||||||
{
|
{
|
||||||
if (task.has ("start"))
|
if (task.has ("start"))
|
||||||
{
|
{
|
||||||
Date start = quantize (Date (task.get_date ("start")));
|
ISO8601d start = quantize (ISO8601d (task.get_date ("start")));
|
||||||
while (from < start)
|
while (from < start)
|
||||||
{
|
{
|
||||||
epoch = from.toEpoch ();
|
epoch = from.toEpoch ();
|
||||||
|
@ -280,7 +279,7 @@ void Chart::scan (std::vector <Task>& tasks)
|
||||||
else if (status == Task::completed)
|
else if (status == Task::completed)
|
||||||
{
|
{
|
||||||
// Truncate history so it starts at 'earliest' for completed tasks.
|
// Truncate history so it starts at 'earliest' for completed tasks.
|
||||||
Date end = quantize (Date (task.get_date ("end")));
|
ISO8601d end = quantize (ISO8601d (task.get_date ("end")));
|
||||||
epoch = end.toEpoch ();
|
epoch = end.toEpoch ();
|
||||||
|
|
||||||
if (_bars.find (epoch) != _bars.end ())
|
if (_bars.find (epoch) != _bars.end ())
|
||||||
|
@ -296,7 +295,7 @@ void Chart::scan (std::vector <Task>& tasks)
|
||||||
|
|
||||||
if (task.has ("start"))
|
if (task.has ("start"))
|
||||||
{
|
{
|
||||||
Date start = quantize (Date (task.get_date ("start")));
|
ISO8601d start = quantize (ISO8601d (task.get_date ("start")));
|
||||||
while (from < start)
|
while (from < start)
|
||||||
{
|
{
|
||||||
epoch = from.toEpoch ();
|
epoch = from.toEpoch ();
|
||||||
|
@ -323,7 +322,7 @@ void Chart::scan (std::vector <Task>& tasks)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Date end = quantize (Date (task.get_date ("end")));
|
ISO8601d end = quantize (ISO8601d (task.get_date ("end")));
|
||||||
while (from < end)
|
while (from < end)
|
||||||
{
|
{
|
||||||
epoch = from.toEpoch ();
|
epoch = from.toEpoch ();
|
||||||
|
@ -347,7 +346,7 @@ void Chart::scan (std::vector <Task>& tasks)
|
||||||
else if (status == Task::deleted)
|
else if (status == Task::deleted)
|
||||||
{
|
{
|
||||||
// Skip old deleted tasks.
|
// Skip old deleted tasks.
|
||||||
Date end = quantize (Date (task.get_date ("end")));
|
ISO8601d end = quantize (ISO8601d (task.get_date ("end")));
|
||||||
epoch = end.toEpoch ();
|
epoch = end.toEpoch ();
|
||||||
if (_bars.find (epoch) != _bars.end ())
|
if (_bars.find (epoch) != _bars.end ())
|
||||||
++_bars[epoch]._removed;
|
++_bars[epoch]._removed;
|
||||||
|
@ -357,7 +356,7 @@ void Chart::scan (std::vector <Task>& tasks)
|
||||||
|
|
||||||
if (task.has ("start"))
|
if (task.has ("start"))
|
||||||
{
|
{
|
||||||
Date start = quantize (Date (task.get_date ("start")));
|
ISO8601d start = quantize (ISO8601d (task.get_date ("start")));
|
||||||
while (from < start)
|
while (from < start)
|
||||||
{
|
{
|
||||||
epoch = from.toEpoch ();
|
epoch = from.toEpoch ();
|
||||||
|
@ -376,7 +375,7 @@ void Chart::scan (std::vector <Task>& tasks)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Date end = quantize (Date (task.get_date ("end")));
|
ISO8601d end = quantize (ISO8601d (task.get_date ("end")));
|
||||||
while (from < end)
|
while (from < end)
|
||||||
{
|
{
|
||||||
epoch = from.toEpoch ();
|
epoch = from.toEpoch ();
|
||||||
|
@ -608,7 +607,7 @@ void Chart::optimizeGrid ()
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
Date Chart::quantize (const Date& input)
|
ISO8601d Chart::quantize (const ISO8601d& input)
|
||||||
{
|
{
|
||||||
if (_period == 'D') return input.startOfDay ();
|
if (_period == 'D') return input.startOfDay ();
|
||||||
if (_period == 'W') return input.startOfWeek ();
|
if (_period == 'W') return input.startOfWeek ();
|
||||||
|
@ -618,7 +617,7 @@ Date Chart::quantize (const Date& input)
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
Date Chart::increment (const Date& input)
|
ISO8601d Chart::increment (const ISO8601d& input)
|
||||||
{
|
{
|
||||||
// Move to the next period.
|
// Move to the next period.
|
||||||
int d = input.day ();
|
int d = input.day ();
|
||||||
|
@ -630,7 +629,7 @@ Date Chart::increment (const Date& input)
|
||||||
switch (_period)
|
switch (_period)
|
||||||
{
|
{
|
||||||
case 'D':
|
case 'D':
|
||||||
if (++d > Date::daysInMonth (m, y))
|
if (++d > ISO8601d::daysInMonth (m, y))
|
||||||
{
|
{
|
||||||
d = 1;
|
d = 1;
|
||||||
|
|
||||||
|
@ -644,7 +643,7 @@ Date Chart::increment (const Date& input)
|
||||||
|
|
||||||
case 'W':
|
case 'W':
|
||||||
d += 7;
|
d += 7;
|
||||||
days = Date::daysInMonth (m, y);
|
days = ISO8601d::daysInMonth (m, y);
|
||||||
if (d > days)
|
if (d > days)
|
||||||
{
|
{
|
||||||
d -= days;
|
d -= days;
|
||||||
|
@ -667,11 +666,11 @@ Date Chart::increment (const Date& input)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Date (m, d, y, 0, 0, 0);
|
return ISO8601d (m, d, y, 0, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
Date Chart::decrement (const Date& input)
|
ISO8601d Chart::decrement (const ISO8601d& input)
|
||||||
{
|
{
|
||||||
// Move to the previous period.
|
// Move to the previous period.
|
||||||
int d = input.day ();
|
int d = input.day ();
|
||||||
|
@ -689,7 +688,7 @@ Date Chart::decrement (const Date& input)
|
||||||
--y;
|
--y;
|
||||||
}
|
}
|
||||||
|
|
||||||
d = Date::daysInMonth (m, y);
|
d = ISO8601d::daysInMonth (m, y);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -703,7 +702,7 @@ Date Chart::decrement (const Date& input)
|
||||||
y--;
|
y--;
|
||||||
}
|
}
|
||||||
|
|
||||||
d += Date::daysInMonth (m, y);
|
d += ISO8601d::daysInMonth (m, y);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -717,7 +716,7 @@ Date Chart::decrement (const Date& input)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Date (m, d, y, 0, 0, 0);
|
return ISO8601d (m, d, y, 0, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -727,12 +726,12 @@ void Chart::generateBars ()
|
||||||
Bar bar;
|
Bar bar;
|
||||||
|
|
||||||
// Determine the last bar date.
|
// Determine the last bar date.
|
||||||
Date cursor;
|
ISO8601d cursor;
|
||||||
switch (_period)
|
switch (_period)
|
||||||
{
|
{
|
||||||
case 'D': cursor = Date ().startOfDay (); break;
|
case 'D': cursor = ISO8601d ().startOfDay (); break;
|
||||||
case 'W': cursor = Date ().startOfWeek (); break;
|
case 'W': cursor = ISO8601d ().startOfWeek (); break;
|
||||||
case 'M': cursor = Date ().startOfMonth (); break;
|
case 'M': cursor = ISO8601d ().startOfMonth (); break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Iterate and determine all the other bar dates.
|
// Iterate and determine all the other bar dates.
|
||||||
|
@ -744,7 +743,7 @@ void Chart::generateBars ()
|
||||||
{
|
{
|
||||||
case 'D': // month/day
|
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);
|
bar._major_label = month.substr (0, 3);
|
||||||
|
|
||||||
sprintf (str, "%02d", cursor.day ());
|
sprintf (str, "%02d", cursor.day ());
|
||||||
|
@ -934,7 +933,7 @@ void Chart::calculateRates (std::vector <time_t>& sequence)
|
||||||
int current_pending = _bars[sequence.back ()]._pending;
|
int current_pending = _bars[sequence.back ()]._pending;
|
||||||
int remaining_days = (int) (current_pending / (_fix_rate - _find_rate));
|
int remaining_days = (int) (current_pending / (_fix_rate - _find_rate));
|
||||||
|
|
||||||
Date now;
|
ISO8601d now;
|
||||||
ISO8601p delta (remaining_days * 86400);
|
ISO8601p delta (remaining_days * 86400);
|
||||||
now += delta;
|
now += delta;
|
||||||
|
|
||||||
|
|
|
@ -74,7 +74,7 @@ int CmdCalendar::execute (std::string& output)
|
||||||
handleRecurrence ();
|
handleRecurrence ();
|
||||||
auto tasks = context.tdb2.pending.get_tasks ();
|
auto tasks = context.tdb2.pending.get_tasks ();
|
||||||
|
|
||||||
Date today;
|
ISO8601d today;
|
||||||
bool getpendingdate = false;
|
bool getpendingdate = false;
|
||||||
int monthsToDisplay = 1;
|
int monthsToDisplay = 1;
|
||||||
int mFrom = today.month ();
|
int mFrom = today.month ();
|
||||||
|
@ -98,7 +98,7 @@ int CmdCalendar::execute (std::string& output)
|
||||||
// Set up a vector of months, for autoComplete.
|
// Set up a vector of months, for autoComplete.
|
||||||
std::vector <std::string> monthNames;
|
std::vector <std::string> monthNames;
|
||||||
for (int i = 1; i <= 12; ++i)
|
for (int i = 1; i <= 12; ++i)
|
||||||
monthNames.push_back (lowerCase (Date::monthName (i)));
|
monthNames.push_back (lowerCase (ISO8601d::monthName (i)));
|
||||||
|
|
||||||
// For autoComplete results.
|
// For autoComplete results.
|
||||||
std::vector <std::string> matches;
|
std::vector <std::string> matches;
|
||||||
|
@ -139,7 +139,7 @@ int CmdCalendar::execute (std::string& output)
|
||||||
// "January" etc.
|
// "January" etc.
|
||||||
else if (autoComplete (lowerCase (arg), monthNames, matches, context.config.getInteger ("abbreviation.minimum")) == 1)
|
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)
|
if (argMonth == -1)
|
||||||
throw format (STRING_CMD_CAL_BAD_MONTH, arg);
|
throw format (STRING_CMD_CAL_BAD_MONTH, arg);
|
||||||
}
|
}
|
||||||
|
@ -176,7 +176,7 @@ int CmdCalendar::execute (std::string& output)
|
||||||
if (getpendingdate == true)
|
if (getpendingdate == true)
|
||||||
{
|
{
|
||||||
// Find the oldest pending due date.
|
// Find the oldest pending due date.
|
||||||
Date oldest (12, 31, 2037);
|
ISO8601d oldest (12, 31, 2037);
|
||||||
for (auto& task : tasks)
|
for (auto& task : tasks)
|
||||||
{
|
{
|
||||||
if (task.getStatus () == Task::pending)
|
if (task.getStatus () == Task::pending)
|
||||||
|
@ -185,7 +185,7 @@ int CmdCalendar::execute (std::string& output)
|
||||||
!task.hasTag ("nocal"))
|
!task.hasTag ("nocal"))
|
||||||
{
|
{
|
||||||
++countDueDates;
|
++countDueDates;
|
||||||
Date d (task.get ("due"));
|
ISO8601d d (task.get ("due"));
|
||||||
if (d < oldest) oldest = d;
|
if (d < oldest) oldest = d;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -234,7 +234,7 @@ int CmdCalendar::execute (std::string& output)
|
||||||
// Print month headers (cheating on the width settings, yes)
|
// Print month headers (cheating on the width settings, yes)
|
||||||
for (int i = 0 ; i < monthsPerLine ; i++)
|
for (int i = 0 ; i < monthsPerLine ; i++)
|
||||||
{
|
{
|
||||||
std::string month = Date::monthName (nextM);
|
std::string month = ISO8601d::monthName (nextM);
|
||||||
|
|
||||||
// 12345678901234567890123456 = 26 chars wide
|
// 12345678901234567890123456 = 26 chars wide
|
||||||
// ^^ = center
|
// ^^ = center
|
||||||
|
@ -317,7 +317,7 @@ int CmdCalendar::execute (std::string& output)
|
||||||
details_mFrom = 12;
|
details_mFrom = 12;
|
||||||
--details_yFrom;
|
--details_yFrom;
|
||||||
}
|
}
|
||||||
int details_dFrom = Date::daysInMonth (details_mFrom, details_yFrom);
|
int details_dFrom = ISO8601d::daysInMonth (details_mFrom, details_yFrom);
|
||||||
|
|
||||||
++mTo;
|
++mTo;
|
||||||
if (mTo == 13)
|
if (mTo == 13)
|
||||||
|
@ -326,10 +326,10 @@ int CmdCalendar::execute (std::string& output)
|
||||||
++yTo;
|
++yTo;
|
||||||
}
|
}
|
||||||
|
|
||||||
Date date_after (details_mFrom, details_dFrom, details_yFrom);
|
ISO8601d date_after (details_mFrom, details_dFrom, details_yFrom);
|
||||||
std::string after = date_after.toString (context.config.get ("dateformat"));
|
std::string after = date_after.toString (context.config.get ("dateformat"));
|
||||||
|
|
||||||
Date date_before (mTo, 1, yTo);
|
ISO8601d date_before (mTo, 1, yTo);
|
||||||
std::string before = date_before.toString (context.config.get ("dateformat"));
|
std::string before = date_before.toString (context.config.get ("dateformat"));
|
||||||
|
|
||||||
// Table with due date information
|
// Table with due date information
|
||||||
|
@ -379,7 +379,7 @@ int CmdCalendar::execute (std::string& output)
|
||||||
{
|
{
|
||||||
std::string holName = context.config.get ("holiday." + it.first.substr (8, it.first.size () - 13) + ".name");
|
std::string holName = context.config.get ("holiday." + it.first.substr (8, it.first.size () - 13) + ".name");
|
||||||
std::string holDate = context.config.get ("holiday." + it.first.substr (8, it.first.size () - 13) + ".date");
|
std::string holDate = context.config.get ("holiday." + it.first.substr (8, it.first.size () - 13) + ".date");
|
||||||
Date hDate (holDate.c_str (), context.config.get ("dateformat.holiday"));
|
ISO8601d hDate (holDate.c_str (), context.config.get ("dateformat.holiday"));
|
||||||
|
|
||||||
if (date_after < hDate && hDate < date_before)
|
if (date_after < hDate && hDate < date_before)
|
||||||
hm[hDate.toEpoch()].push_back(holName);
|
hm[hDate.toEpoch()].push_back(holName);
|
||||||
|
@ -396,7 +396,7 @@ int CmdCalendar::execute (std::string& output)
|
||||||
for (auto& hm_it : hm)
|
for (auto& hm_it : hm)
|
||||||
{
|
{
|
||||||
std::vector <std::string> v = hm_it.second;
|
std::vector <std::string> v = hm_it.second;
|
||||||
Date hDate (hm_it.first);
|
ISO8601d hDate (hm_it.first);
|
||||||
std::string d = hDate.toString (format);
|
std::string d = hDate.toString (format);
|
||||||
for (size_t i = 0; i < v.size(); i++)
|
for (size_t i = 0; i < v.size(); i++)
|
||||||
{
|
{
|
||||||
|
@ -420,12 +420,12 @@ int CmdCalendar::execute (std::string& output)
|
||||||
std::string CmdCalendar::renderMonths (
|
std::string CmdCalendar::renderMonths (
|
||||||
int firstMonth,
|
int firstMonth,
|
||||||
int firstYear,
|
int firstYear,
|
||||||
const Date& today,
|
const ISO8601d& today,
|
||||||
std::vector <Task>& all,
|
std::vector <Task>& all,
|
||||||
int monthsPerLine)
|
int monthsPerLine)
|
||||||
{
|
{
|
||||||
// What day of the week does the user consider the first?
|
// 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)
|
if (weekStart != 0 && weekStart != 1)
|
||||||
throw std::string (STRING_CMD_CAL_SUN_MON);
|
throw std::string (STRING_CMD_CAL_SUN_MON);
|
||||||
|
|
||||||
|
@ -440,24 +440,24 @@ std::string CmdCalendar::renderMonths (
|
||||||
if (weekStart == 1)
|
if (weekStart == 1)
|
||||||
{
|
{
|
||||||
view.add (Column::factory ("string.right", " "));
|
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 (ISO8601d::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 (ISO8601d::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 (ISO8601d::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 (ISO8601d::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 (ISO8601d::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 (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 (0), 0, 2)));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
view.add (Column::factory ("string.right", " "));
|
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 (ISO8601d::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 (ISO8601d::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 (ISO8601d::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 (ISO8601d::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 (ISO8601d::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 (ISO8601d::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 (6), 0, 2)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -487,7 +487,7 @@ std::string CmdCalendar::renderMonths (
|
||||||
years.push_back (++thisYear);
|
years.push_back (++thisYear);
|
||||||
}
|
}
|
||||||
months.push_back (thisMonth);
|
months.push_back (thisMonth);
|
||||||
daysInMonth.push_back (Date::daysInMonth (thisMonth++, thisYear));
|
daysInMonth.push_back (ISO8601d::daysInMonth (thisMonth++, thisYear));
|
||||||
}
|
}
|
||||||
|
|
||||||
int row = 0;
|
int row = 0;
|
||||||
|
@ -510,7 +510,7 @@ std::string CmdCalendar::renderMonths (
|
||||||
// Loop through days in month and add to table.
|
// Loop through days in month and add to table.
|
||||||
for (int d = 1; d <= daysInMonth[mpl]; ++d)
|
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 dow = temp.dayOfWeek ();
|
||||||
int woy = temp.weekOfYear (weekStart);
|
int woy = temp.weekOfYear (weekStart);
|
||||||
|
|
||||||
|
@ -543,7 +543,7 @@ std::string CmdCalendar::renderMonths (
|
||||||
if (hol.first.substr (hol.first.size () - 4) == "date")
|
if (hol.first.substr (hol.first.size () - 4) == "date")
|
||||||
{
|
{
|
||||||
std::string value = hol.second;
|
std::string value = hol.second;
|
||||||
Date holDate (value.c_str (), context.config.get ("dateformat.holiday"));
|
ISO8601d holDate (value.c_str (), context.config.get ("dateformat.holiday"));
|
||||||
if (holDate.day () == d &&
|
if (holDate.day () == d &&
|
||||||
holDate.month () == months[mpl] &&
|
holDate.month () == months[mpl] &&
|
||||||
holDate.year () == years[mpl])
|
holDate.year () == years[mpl])
|
||||||
|
@ -568,7 +568,7 @@ std::string CmdCalendar::renderMonths (
|
||||||
task.has ("due"))
|
task.has ("due"))
|
||||||
{
|
{
|
||||||
std::string due = task.get ("due");
|
std::string due = task.get ("due");
|
||||||
Date duedmy (strtol (due.c_str(), NULL, 10));
|
ISO8601d duedmy (strtol (due.c_str(), NULL, 10));
|
||||||
|
|
||||||
if (duedmy.day () == d &&
|
if (duedmy.day () == d &&
|
||||||
duedmy.month () == months[mpl] &&
|
duedmy.month () == months[mpl] &&
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <Date.h>
|
#include <ISO8601.h>
|
||||||
#include <Task.h>
|
#include <Task.h>
|
||||||
#include <Command.h>
|
#include <Command.h>
|
||||||
|
|
||||||
|
@ -40,7 +40,7 @@ public:
|
||||||
int execute (std::string&);
|
int execute (std::string&);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string renderMonths (int, int, const Date&, std::vector <Task>&, int);
|
std::string renderMonths (int, int, const ISO8601d&, std::vector <Task>&, int);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -166,7 +166,7 @@ std::string CmdEdit::formatDate (
|
||||||
std::string value = task.get (attribute);
|
std::string value = task.get (attribute);
|
||||||
if (value.length ())
|
if (value.length ())
|
||||||
{
|
{
|
||||||
Date dt (value);
|
ISO8601d dt (value);
|
||||||
value = dt.toString (dateformat);
|
value = dt.toString (dateformat);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -250,12 +250,12 @@ std::string CmdEdit::formatTask (Task task, const std::string& dateformat)
|
||||||
task.getAnnotations (annotations);
|
task.getAnnotations (annotations);
|
||||||
for (auto& anno : annotations)
|
for (auto& anno : annotations)
|
||||||
{
|
{
|
||||||
Date dt (strtol (anno.first.substr (11).c_str (), NULL, 10));
|
ISO8601d dt (strtol (anno.first.substr (11).c_str (), NULL, 10));
|
||||||
before << " Annotation: " << dt.toString (dateformat)
|
before << " Annotation: " << dt.toString (dateformat)
|
||||||
<< " -- " << json::encode (anno.second) << "\n";
|
<< " -- " << json::encode (anno.second) << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
Date now;
|
ISO8601d now;
|
||||||
before << " Annotation: " << now.toString (dateformat) << " -- \n";
|
before << " Annotation: " << now.toString (dateformat) << " -- \n";
|
||||||
|
|
||||||
// Add dependencies here.
|
// Add dependencies here.
|
||||||
|
@ -379,7 +379,7 @@ void CmdEdit::parseTask (Task& task, const std::string& after, const std::string
|
||||||
if (formatted != value)
|
if (formatted != value)
|
||||||
{
|
{
|
||||||
context.footnote (STRING_EDIT_ENTRY_MOD);
|
context.footnote (STRING_EDIT_ENTRY_MOD);
|
||||||
task.set ("entry", Date(value, dateformat).toEpochString ());
|
task.set ("entry", ISO8601d (value, dateformat).toEpochString ());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -396,13 +396,13 @@ void CmdEdit::parseTask (Task& task, const std::string& after, const std::string
|
||||||
if (formatted != value)
|
if (formatted != value)
|
||||||
{
|
{
|
||||||
context.footnote (STRING_EDIT_START_MOD);
|
context.footnote (STRING_EDIT_START_MOD);
|
||||||
task.set ("start", Date(value, dateformat).toEpochString ());
|
task.set ("start", ISO8601d (value, dateformat).toEpochString ());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
context.footnote (STRING_EDIT_START_MOD);
|
context.footnote (STRING_EDIT_START_MOD);
|
||||||
task.set ("start", Date(value, dateformat).toEpochString ());
|
task.set ("start", ISO8601d (value, dateformat).toEpochString ());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -425,7 +425,7 @@ void CmdEdit::parseTask (Task& task, const std::string& after, const std::string
|
||||||
if (formatted != value)
|
if (formatted != value)
|
||||||
{
|
{
|
||||||
context.footnote (STRING_EDIT_END_MOD);
|
context.footnote (STRING_EDIT_END_MOD);
|
||||||
task.set ("end", Date(value, dateformat).toEpochString ());
|
task.set ("end", ISO8601d (value, dateformat).toEpochString ());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (task.getStatus () != Task::deleted)
|
else if (task.getStatus () != Task::deleted)
|
||||||
|
@ -452,13 +452,13 @@ void CmdEdit::parseTask (Task& task, const std::string& after, const std::string
|
||||||
if (formatted != value)
|
if (formatted != value)
|
||||||
{
|
{
|
||||||
context.footnote (STRING_EDIT_SCHED_MOD);
|
context.footnote (STRING_EDIT_SCHED_MOD);
|
||||||
task.set ("scheduled", Date(value, dateformat).toEpochString ());
|
task.set ("scheduled", ISO8601d (value, dateformat).toEpochString ());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
context.footnote (STRING_EDIT_SCHED_MOD);
|
context.footnote (STRING_EDIT_SCHED_MOD);
|
||||||
task.set ("scheduled", Date(value, dateformat).toEpochString ());
|
task.set ("scheduled", ISO8601d (value, dateformat).toEpochString ());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -482,13 +482,13 @@ void CmdEdit::parseTask (Task& task, const std::string& after, const std::string
|
||||||
if (formatted != value)
|
if (formatted != value)
|
||||||
{
|
{
|
||||||
context.footnote (STRING_EDIT_DUE_MOD);
|
context.footnote (STRING_EDIT_DUE_MOD);
|
||||||
task.set ("due", Date(value, dateformat).toEpochString ());
|
task.set ("due", ISO8601d (value, dateformat).toEpochString ());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
context.footnote (STRING_EDIT_DUE_MOD);
|
context.footnote (STRING_EDIT_DUE_MOD);
|
||||||
task.set ("due", Date(value, dateformat).toEpochString ());
|
task.set ("due", ISO8601d (value, dateformat).toEpochString ());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -519,13 +519,13 @@ void CmdEdit::parseTask (Task& task, const std::string& after, const std::string
|
||||||
if (formatted != value)
|
if (formatted != value)
|
||||||
{
|
{
|
||||||
context.footnote (STRING_EDIT_UNTIL_MOD);
|
context.footnote (STRING_EDIT_UNTIL_MOD);
|
||||||
task.set ("until", Date(value, dateformat).toEpochString ());
|
task.set ("until", ISO8601d (value, dateformat).toEpochString ());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
context.footnote (STRING_EDIT_UNTIL_MOD);
|
context.footnote (STRING_EDIT_UNTIL_MOD);
|
||||||
task.set ("until", Date(value, dateformat).toEpochString ());
|
task.set ("until", ISO8601d (value, dateformat).toEpochString ());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -581,14 +581,14 @@ void CmdEdit::parseTask (Task& task, const std::string& after, const std::string
|
||||||
if (formatted != value)
|
if (formatted != value)
|
||||||
{
|
{
|
||||||
context.footnote (STRING_EDIT_WAIT_MOD);
|
context.footnote (STRING_EDIT_WAIT_MOD);
|
||||||
task.set ("wait", Date(value, dateformat).toEpochString ());
|
task.set ("wait", ISO8601d (value, dateformat).toEpochString ());
|
||||||
task.setStatus (Task::waiting);
|
task.setStatus (Task::waiting);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
context.footnote (STRING_EDIT_WAIT_MOD);
|
context.footnote (STRING_EDIT_WAIT_MOD);
|
||||||
task.set ("wait", Date(value, dateformat).toEpochString ());
|
task.set ("wait", ISO8601d (value, dateformat).toEpochString ());
|
||||||
task.setStatus (Task::waiting);
|
task.setStatus (Task::waiting);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -642,7 +642,7 @@ void CmdEdit::parseTask (Task& task, const std::string& after, const std::string
|
||||||
// for each line: if the annotation is the same, then it is copied; if
|
// for each line: if the annotation is the same, then it is copied; if
|
||||||
// the annotation is modified, then its original date may be kept; and
|
// the annotation is modified, then its original date may be kept; and
|
||||||
// if there is no corresponding id, then a new unique date is created).
|
// if there is no corresponding id, then a new unique date is created).
|
||||||
Date when (value.substr (0, gap), dateformat);
|
ISO8601d when (value.substr (0, gap), dateformat);
|
||||||
|
|
||||||
// If the map already contains a annotation for a given timestamp
|
// If the map already contains a annotation for a given timestamp
|
||||||
// we need to increment until we find an unused key
|
// we need to increment until we find an unused key
|
||||||
|
@ -688,7 +688,7 @@ void CmdEdit::parseTask (Task& task, const std::string& after, const std::string
|
||||||
{
|
{
|
||||||
std::string value = findValue (after, "\n UDA " + col.first + ":");
|
std::string value = findValue (after, "\n UDA " + col.first + ":");
|
||||||
if ((task.get (col.first) != value) && (type != "date" ||
|
if ((task.get (col.first) != value) && (type != "date" ||
|
||||||
(task.get (col.first) != Date (value, dateformat).toEpochString ())) &&
|
(task.get (col.first) != ISO8601d (value, dateformat).toEpochString ())) &&
|
||||||
(type != "duration" ||
|
(type != "duration" ||
|
||||||
(task.get (col.first) != (std::string) ISO8601p (value))))
|
(task.get (col.first) != (std::string) ISO8601p (value))))
|
||||||
{
|
{
|
||||||
|
@ -712,7 +712,7 @@ void CmdEdit::parseTask (Task& task, const std::string& after, const std::string
|
||||||
}
|
}
|
||||||
else if (type == "date")
|
else if (type == "date")
|
||||||
{
|
{
|
||||||
task.set (col.first, Date (value, dateformat).toEpochString ());
|
task.set (col.first, ISO8601d (value, dateformat).toEpochString ());
|
||||||
}
|
}
|
||||||
else if (type == "duration")
|
else if (type == "duration")
|
||||||
{
|
{
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
#include <main.h>
|
#include <main.h>
|
||||||
#include <text.h>
|
#include <text.h>
|
||||||
#include <i18n.h>
|
#include <i18n.h>
|
||||||
|
#include <ISO8601.h>
|
||||||
#include <CmdHistory.h>
|
#include <CmdHistory.h>
|
||||||
|
|
||||||
extern Context context;
|
extern Context context;
|
||||||
|
@ -70,11 +71,11 @@ int CmdHistoryMonthly::execute (std::string& output)
|
||||||
|
|
||||||
for (auto& task : filtered)
|
for (auto& task : filtered)
|
||||||
{
|
{
|
||||||
Date entry (task.get_date ("entry"));
|
ISO8601d entry (task.get_date ("entry"));
|
||||||
|
|
||||||
Date end;
|
ISO8601d end;
|
||||||
if (task.has ("end"))
|
if (task.has ("end"))
|
||||||
end = Date (task.get_date ("end"));
|
end = ISO8601d (task.get_date ("end"));
|
||||||
|
|
||||||
time_t epoch = entry.startOfMonth ().toEpoch ();
|
time_t epoch = entry.startOfMonth ().toEpoch ();
|
||||||
groups[epoch] = 0;
|
groups[epoch] = 0;
|
||||||
|
@ -127,7 +128,7 @@ int CmdHistoryMonthly::execute (std::string& output)
|
||||||
totalCompleted += completedGroup [i.first];
|
totalCompleted += completedGroup [i.first];
|
||||||
totalDeleted += deletedGroup [i.first];
|
totalDeleted += deletedGroup [i.first];
|
||||||
|
|
||||||
Date dt (i.first);
|
ISO8601d dt (i.first);
|
||||||
int m, d, y;
|
int m, d, y;
|
||||||
dt.toMDY (m, d, y);
|
dt.toMDY (m, d, y);
|
||||||
|
|
||||||
|
@ -136,7 +137,7 @@ int CmdHistoryMonthly::execute (std::string& output)
|
||||||
view.set (row, 0, y);
|
view.set (row, 0, y);
|
||||||
priorYear = y;
|
priorYear = y;
|
||||||
}
|
}
|
||||||
view.set (row, 1, Date::monthName(m));
|
view.set (row, 1, ISO8601d::monthName(m));
|
||||||
|
|
||||||
int net = 0;
|
int net = 0;
|
||||||
|
|
||||||
|
@ -232,11 +233,11 @@ int CmdHistoryAnnual::execute (std::string& output)
|
||||||
|
|
||||||
for (auto& task : filtered)
|
for (auto& task : filtered)
|
||||||
{
|
{
|
||||||
Date entry (task.get_date ("entry"));
|
ISO8601d entry (task.get_date ("entry"));
|
||||||
|
|
||||||
Date end;
|
ISO8601d end;
|
||||||
if (task.has ("end"))
|
if (task.has ("end"))
|
||||||
end = Date (task.get_date ("end"));
|
end = ISO8601d (task.get_date ("end"));
|
||||||
|
|
||||||
time_t epoch = entry.startOfYear ().toEpoch ();
|
time_t epoch = entry.startOfYear ().toEpoch ();
|
||||||
groups[epoch] = 0;
|
groups[epoch] = 0;
|
||||||
|
@ -288,7 +289,7 @@ int CmdHistoryAnnual::execute (std::string& output)
|
||||||
totalCompleted += completedGroup [i.first];
|
totalCompleted += completedGroup [i.first];
|
||||||
totalDeleted += deletedGroup [i.first];
|
totalDeleted += deletedGroup [i.first];
|
||||||
|
|
||||||
Date dt (i.first);
|
ISO8601d dt (i.first);
|
||||||
int m, d, y;
|
int m, d, y;
|
||||||
dt.toMDY (m, d, y);
|
dt.toMDY (m, d, y);
|
||||||
|
|
||||||
|
@ -391,11 +392,11 @@ int CmdGHistoryMonthly::execute (std::string& output)
|
||||||
|
|
||||||
for (auto& task : filtered)
|
for (auto& task : filtered)
|
||||||
{
|
{
|
||||||
Date entry (task.get_date ("entry"));
|
ISO8601d entry (task.get_date ("entry"));
|
||||||
|
|
||||||
Date end;
|
ISO8601d end;
|
||||||
if (task.has ("end"))
|
if (task.has ("end"))
|
||||||
end = Date (task.get_date ("end"));
|
end = ISO8601d (task.get_date ("end"));
|
||||||
|
|
||||||
time_t epoch = entry.startOfMonth ().toEpoch ();
|
time_t epoch = entry.startOfMonth ().toEpoch ();
|
||||||
groups[epoch] = 0;
|
groups[epoch] = 0;
|
||||||
|
@ -468,7 +469,7 @@ int CmdGHistoryMonthly::execute (std::string& output)
|
||||||
totalCompleted += completedGroup[i.first];
|
totalCompleted += completedGroup[i.first];
|
||||||
totalDeleted += deletedGroup[i.first];
|
totalDeleted += deletedGroup[i.first];
|
||||||
|
|
||||||
Date dt (i.first);
|
ISO8601d dt (i.first);
|
||||||
int m, d, y;
|
int m, d, y;
|
||||||
dt.toMDY (m, d, y);
|
dt.toMDY (m, d, y);
|
||||||
|
|
||||||
|
@ -477,7 +478,7 @@ int CmdGHistoryMonthly::execute (std::string& output)
|
||||||
view.set (row, 0, y);
|
view.set (row, 0, y);
|
||||||
priorYear = 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 addedBar = (widthOfBar * addedGroup[i.first]) / maxLine;
|
||||||
unsigned int completedBar = (widthOfBar * completedGroup[i.first]) / maxLine;
|
unsigned int completedBar = (widthOfBar * completedGroup[i.first]) / maxLine;
|
||||||
|
@ -591,11 +592,11 @@ int CmdGHistoryAnnual::execute (std::string& output)
|
||||||
|
|
||||||
for (auto& task : filtered)
|
for (auto& task : filtered)
|
||||||
{
|
{
|
||||||
Date entry (task.get_date ("entry"));
|
ISO8601d entry (task.get_date ("entry"));
|
||||||
|
|
||||||
Date end;
|
ISO8601d end;
|
||||||
if (task.has ("end"))
|
if (task.has ("end"))
|
||||||
end = Date (task.get_date ("end"));
|
end = ISO8601d (task.get_date ("end"));
|
||||||
|
|
||||||
time_t epoch = entry.startOfYear ().toEpoch ();
|
time_t epoch = entry.startOfYear ().toEpoch ();
|
||||||
groups[epoch] = 0;
|
groups[epoch] = 0;
|
||||||
|
@ -667,7 +668,7 @@ int CmdGHistoryAnnual::execute (std::string& output)
|
||||||
totalCompleted += completedGroup[i.first];
|
totalCompleted += completedGroup[i.first];
|
||||||
totalDeleted += deletedGroup[i.first];
|
totalDeleted += deletedGroup[i.first];
|
||||||
|
|
||||||
Date dt (i.first);
|
ISO8601d dt (i.first);
|
||||||
int m, d, y;
|
int m, d, y;
|
||||||
dt.toMDY (m, d, y);
|
dt.toMDY (m, d, y);
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,6 @@
|
||||||
#include <Context.h>
|
#include <Context.h>
|
||||||
#include <Filter.h>
|
#include <Filter.h>
|
||||||
#include <ISO8601.h>
|
#include <ISO8601.h>
|
||||||
#include <Date.h>
|
|
||||||
#include <main.h>
|
#include <main.h>
|
||||||
#include <text.h>
|
#include <text.h>
|
||||||
#include <i18n.h>
|
#include <i18n.h>
|
||||||
|
@ -113,7 +112,7 @@ int CmdInfo::execute (std::string& output)
|
||||||
view.colorHeader (label);
|
view.colorHeader (label);
|
||||||
}
|
}
|
||||||
|
|
||||||
Date now;
|
ISO8601d now;
|
||||||
|
|
||||||
// id
|
// id
|
||||||
int row = view.addRow ();
|
int row = view.addRow ();
|
||||||
|
@ -133,7 +132,7 @@ int CmdInfo::execute (std::string& output)
|
||||||
for (auto& anno : annotations)
|
for (auto& anno : annotations)
|
||||||
description += "\n"
|
description += "\n"
|
||||||
+ std::string (indent, ' ')
|
+ std::string (indent, ' ')
|
||||||
+ Date (anno.first.substr (11)).toString (dateformatanno)
|
+ ISO8601d (anno.first.substr (11)).toString (dateformatanno)
|
||||||
+ " "
|
+ " "
|
||||||
+ anno.second;
|
+ anno.second;
|
||||||
|
|
||||||
|
@ -221,14 +220,14 @@ int CmdInfo::execute (std::string& output)
|
||||||
// entry
|
// entry
|
||||||
row = view.addRow ();
|
row = view.addRow ();
|
||||||
view.set (row, 0, STRING_COLUMN_LABEL_ENTERED);
|
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 entry = dt.toString (dateformat);
|
||||||
|
|
||||||
std::string age;
|
std::string age;
|
||||||
std::string created = task.get ("entry");
|
std::string created = task.get ("entry");
|
||||||
if (created.length ())
|
if (created.length ())
|
||||||
{
|
{
|
||||||
Date dt (strtol (created.c_str (), NULL, 10));
|
ISO8601d dt (strtol (created.c_str (), NULL, 10));
|
||||||
age = ISO8601p (now - dt).formatVague ();
|
age = ISO8601p (now - dt).formatVague ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -239,7 +238,7 @@ int CmdInfo::execute (std::string& output)
|
||||||
{
|
{
|
||||||
row = view.addRow ();
|
row = view.addRow ();
|
||||||
view.set (row, 0, STRING_COLUMN_LABEL_WAITING);
|
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
|
// scheduled
|
||||||
|
@ -247,7 +246,7 @@ int CmdInfo::execute (std::string& output)
|
||||||
{
|
{
|
||||||
row = view.addRow ();
|
row = view.addRow ();
|
||||||
view.set (row, 0, STRING_COLUMN_LABEL_SCHED);
|
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
|
// start
|
||||||
|
@ -255,7 +254,7 @@ int CmdInfo::execute (std::string& output)
|
||||||
{
|
{
|
||||||
row = view.addRow ();
|
row = view.addRow ();
|
||||||
view.set (row, 0, STRING_COLUMN_LABEL_START);
|
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)
|
// due (colored)
|
||||||
|
@ -263,7 +262,7 @@ int CmdInfo::execute (std::string& output)
|
||||||
{
|
{
|
||||||
row = view.addRow ();
|
row = view.addRow ();
|
||||||
view.set (row, 0, STRING_COLUMN_LABEL_DUE);
|
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
|
// end
|
||||||
|
@ -271,7 +270,7 @@ int CmdInfo::execute (std::string& output)
|
||||||
{
|
{
|
||||||
row = view.addRow ();
|
row = view.addRow ();
|
||||||
view.set (row, 0, STRING_COLUMN_LABEL_END);
|
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
|
// until
|
||||||
|
@ -279,7 +278,7 @@ int CmdInfo::execute (std::string& output)
|
||||||
{
|
{
|
||||||
row = view.addRow ();
|
row = view.addRow ();
|
||||||
view.set (row, 0, STRING_CMD_INFO_UNTIL);
|
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
|
// modified
|
||||||
|
@ -288,7 +287,7 @@ int CmdInfo::execute (std::string& output)
|
||||||
row = view.addRow ();
|
row = view.addRow ();
|
||||||
view.set (row, 0, STRING_CMD_INFO_MODIFIED);
|
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 ();
|
std::string age = ISO8601p (now - mod).formatVague ();
|
||||||
view.set (row, 1, mod.toString (dateformat) + " (" + age + ")");
|
view.set (row, 1, mod.toString (dateformat) + " (" + age + ")");
|
||||||
}
|
}
|
||||||
|
@ -373,13 +372,13 @@ int CmdInfo::execute (std::string& output)
|
||||||
view.set (row, 0, col->label ());
|
view.set (row, 0, col->label ());
|
||||||
|
|
||||||
if (type == "date")
|
if (type == "date")
|
||||||
value = Date (value).toString (dateformat);
|
value = ISO8601d (value).toString (dateformat);
|
||||||
else if (type == "duration")
|
else if (type == "duration")
|
||||||
{
|
{
|
||||||
ISO8601p iso;
|
ISO8601p iso;
|
||||||
std::string::size_type cursor = 0;
|
std::string::size_type cursor = 0;
|
||||||
if (iso.parse (value, cursor))
|
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
|
else
|
||||||
value = "PT0S";
|
value = "PT0S";
|
||||||
}
|
}
|
||||||
|
@ -544,7 +543,7 @@ int CmdInfo::execute (std::string& output)
|
||||||
{
|
{
|
||||||
int row = journal.addRow ();
|
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));
|
journal.set (row, 0, timestamp.toString (dateformat));
|
||||||
|
|
||||||
Task before (previous.substr (4));
|
Task before (previous.substr (4));
|
||||||
|
|
|
@ -90,7 +90,7 @@ int CmdStats::execute (std::string& output)
|
||||||
std::vector <Task> filtered;
|
std::vector <Task> filtered;
|
||||||
filter.subset (all, filtered);
|
filter.subset (all, filtered);
|
||||||
|
|
||||||
Date now;
|
ISO8601d now;
|
||||||
time_t earliest = time (NULL);
|
time_t earliest = time (NULL);
|
||||||
time_t latest = 1;
|
time_t latest = 1;
|
||||||
int totalT = 0;
|
int totalT = 0;
|
||||||
|
@ -235,12 +235,12 @@ int CmdStats::execute (std::string& output)
|
||||||
|
|
||||||
if (filtered.size ())
|
if (filtered.size ())
|
||||||
{
|
{
|
||||||
Date e (earliest);
|
ISO8601d e (earliest);
|
||||||
row = view.addRow ();
|
row = view.addRow ();
|
||||||
view.set (row, 0, STRING_CMD_STATS_OLDEST);
|
view.set (row, 0, STRING_CMD_STATS_OLDEST);
|
||||||
view.set (row, 1, e.toString (dateformat));
|
view.set (row, 1, e.toString (dateformat));
|
||||||
|
|
||||||
Date l (latest);
|
ISO8601d l (latest);
|
||||||
row = view.addRow ();
|
row = view.addRow ();
|
||||||
view.set (row, 0, STRING_CMD_STATS_NEWEST);
|
view.set (row, 0, STRING_CMD_STATS_NEWEST);
|
||||||
view.set (row, 1, l.toString (dateformat));
|
view.set (row, 1, l.toString (dateformat));
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
#include <Context.h>
|
#include <Context.h>
|
||||||
#include <Filter.h>
|
#include <Filter.h>
|
||||||
#include <ViewText.h>
|
#include <ViewText.h>
|
||||||
#include <Date.h>
|
#include <ISO8601.h>
|
||||||
#include <main.h>
|
#include <main.h>
|
||||||
#include <i18n.h>
|
#include <i18n.h>
|
||||||
#include <text.h>
|
#include <text.h>
|
||||||
|
@ -64,18 +64,18 @@ int CmdTimesheet::execute (std::string& output)
|
||||||
std::vector <Task> all = context.tdb2.all_tasks ();
|
std::vector <Task> all = context.tdb2.all_tasks ();
|
||||||
|
|
||||||
// What day of the week does the user consider the first?
|
// 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)
|
if (weekStart != 0 && weekStart != 1)
|
||||||
throw std::string (STRING_DATE_BAD_WEEKSTART);
|
throw std::string (STRING_DATE_BAD_WEEKSTART);
|
||||||
|
|
||||||
// Determine the date of the first day of the most recent report.
|
// Determine the date of the first day of the most recent report.
|
||||||
Date today;
|
ISO8601d today;
|
||||||
Date start;
|
ISO8601d start;
|
||||||
start -= (((today.dayOfWeek () - weekStart) + 7) % 7) * 86400;
|
start -= (((today.dayOfWeek () - weekStart) + 7) % 7) * 86400;
|
||||||
|
|
||||||
// Roll back to midnight.
|
// Roll back to midnight.
|
||||||
start = Date (start.month (), start.day (), start.year ());
|
start = ISO8601d (start.month (), start.day (), start.year ());
|
||||||
Date end = start + (7 * 86400);
|
ISO8601d end = start + (7 * 86400);
|
||||||
|
|
||||||
// Determine how many reports to run.
|
// Determine how many reports to run.
|
||||||
int quantity = 1;
|
int quantity = 1;
|
||||||
|
@ -86,7 +86,7 @@ int CmdTimesheet::execute (std::string& output)
|
||||||
std::stringstream out;
|
std::stringstream out;
|
||||||
for (int week = 0; week < quantity; ++week)
|
for (int week = 0; week < quantity; ++week)
|
||||||
{
|
{
|
||||||
Date endString (end);
|
ISO8601d endString (end);
|
||||||
endString -= 86400;
|
endString -= 86400;
|
||||||
|
|
||||||
std::string title = start.toString (context.config.get ("dateformat"))
|
std::string title = start.toString (context.config.get ("dateformat"))
|
||||||
|
@ -114,7 +114,7 @@ int CmdTimesheet::execute (std::string& output)
|
||||||
// If task completed within range.
|
// If task completed within range.
|
||||||
if (task.getStatus () == Task::completed)
|
if (task.getStatus () == Task::completed)
|
||||||
{
|
{
|
||||||
Date compDate (task.get_date ("end"));
|
ISO8601d compDate (task.get_date ("end"));
|
||||||
if (compDate >= start && compDate < end)
|
if (compDate >= start && compDate < end)
|
||||||
{
|
{
|
||||||
Color c;
|
Color c;
|
||||||
|
@ -129,7 +129,7 @@ int CmdTimesheet::execute (std::string& output)
|
||||||
|
|
||||||
if(task.has ("due"))
|
if(task.has ("due"))
|
||||||
{
|
{
|
||||||
Date dt (task.get_date ("due"));
|
ISO8601d dt (task.get_date ("due"));
|
||||||
completed.set (row, 2, dt.toString (format));
|
completed.set (row, 2, dt.toString (format));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -141,7 +141,7 @@ int CmdTimesheet::execute (std::string& output)
|
||||||
for (auto& ann : annotations)
|
for (auto& ann : annotations)
|
||||||
description += "\n"
|
description += "\n"
|
||||||
+ std::string (indent, ' ')
|
+ std::string (indent, ' ')
|
||||||
+ Date (ann.first.substr (11)).toString (context.config.get ("dateformat"))
|
+ ISO8601d (ann.first.substr (11)).toString (context.config.get ("dateformat"))
|
||||||
+ " "
|
+ " "
|
||||||
+ ann.second;
|
+ ann.second;
|
||||||
|
|
||||||
|
@ -171,7 +171,7 @@ int CmdTimesheet::execute (std::string& output)
|
||||||
if (task.getStatus () == Task::pending &&
|
if (task.getStatus () == Task::pending &&
|
||||||
task.has ("start"))
|
task.has ("start"))
|
||||||
{
|
{
|
||||||
Date startDate (task.get_date ("start"));
|
ISO8601d startDate (task.get_date ("start"));
|
||||||
if (startDate >= start && startDate < end)
|
if (startDate >= start && startDate < end)
|
||||||
{
|
{
|
||||||
Color c;
|
Color c;
|
||||||
|
@ -186,7 +186,7 @@ int CmdTimesheet::execute (std::string& output)
|
||||||
|
|
||||||
if (task.has ("due"))
|
if (task.has ("due"))
|
||||||
{
|
{
|
||||||
Date dt (task.get_date ("due"));
|
ISO8601d dt (task.get_date ("due"));
|
||||||
started.set (row, 2, dt.toString (format));
|
started.set (row, 2, dt.toString (format));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -198,7 +198,7 @@ int CmdTimesheet::execute (std::string& output)
|
||||||
for (auto& ann : annotations)
|
for (auto& ann : annotations)
|
||||||
description += "\n"
|
description += "\n"
|
||||||
+ std::string (indent, ' ')
|
+ std::string (indent, ' ')
|
||||||
+ Date (ann.first.substr (11)).toString (context.config.get ("dateformat"))
|
+ ISO8601d (ann.first.substr (11)).toString (context.config.get ("dateformat"))
|
||||||
+ " "
|
+ " "
|
||||||
+ ann.second;
|
+ ann.second;
|
||||||
|
|
||||||
|
|
|
@ -266,15 +266,11 @@ std::string renderAttribute (const std::string& name, const std::string& value,
|
||||||
col->type () == "date" &&
|
col->type () == "date" &&
|
||||||
value != "")
|
value != "")
|
||||||
{
|
{
|
||||||
Date d ((time_t)strtol (value.c_str (), NULL, 10));
|
ISO8601d d ((time_t)strtol (value.c_str (), NULL, 10));
|
||||||
if (format == "")
|
if (format == "")
|
||||||
{
|
|
||||||
return d.toString (context.config.get ("dateformat"));
|
return d.toString (context.config.get ("dateformat"));
|
||||||
}
|
|
||||||
else
|
return d.toString (format);
|
||||||
{
|
|
||||||
return d.toString (format);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
|
|
|
@ -32,13 +32,13 @@
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <Context.h>
|
#include <Context.h>
|
||||||
#include <Date.h>
|
#include <ISO8601.h>
|
||||||
#include <Color.h>
|
#include <Color.h>
|
||||||
|
|
||||||
// recur.cpp
|
// recur.cpp
|
||||||
void handleRecurrence ();
|
void handleRecurrence ();
|
||||||
Date getNextRecurrence (Date&, std::string&);
|
ISO8601d getNextRecurrence (ISO8601d&, std::string&);
|
||||||
bool generateDueDates (Task&, std::vector <Date>&);
|
bool generateDueDates (Task&, std::vector <ISO8601d>&);
|
||||||
void updateRecurrenceMask (Task&);
|
void updateRecurrenceMask (Task&);
|
||||||
bool nag (Task&);
|
bool nag (Task&);
|
||||||
|
|
||||||
|
|
|
@ -39,8 +39,6 @@
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
#include <Context.h>
|
#include <Context.h>
|
||||||
#include <Date.h>
|
|
||||||
#include <ISO8601.h>
|
|
||||||
#include <Lexer.h>
|
#include <Lexer.h>
|
||||||
#include <ISO8601.h>
|
#include <ISO8601.h>
|
||||||
#include <text.h>
|
#include <text.h>
|
||||||
|
@ -62,7 +60,7 @@ void handleRecurrence ()
|
||||||
return;
|
return;
|
||||||
|
|
||||||
auto tasks = context.tdb2.pending.get_tasks ();
|
auto tasks = context.tdb2.pending.get_tasks ();
|
||||||
Date now;
|
ISO8601d now;
|
||||||
|
|
||||||
// Look at all tasks and find any recurring ones.
|
// Look at all tasks and find any recurring ones.
|
||||||
for (auto& t : tasks)
|
for (auto& t : tasks)
|
||||||
|
@ -71,7 +69,7 @@ void handleRecurrence ()
|
||||||
{
|
{
|
||||||
// Generate a list of due dates for this recurring task, regardless of
|
// Generate a list of due dates for this recurring task, regardless of
|
||||||
// the mask.
|
// the mask.
|
||||||
std::vector <Date> due;
|
std::vector <ISO8601d> due;
|
||||||
if (!generateDueDates (t, due))
|
if (!generateDueDates (t, due))
|
||||||
{
|
{
|
||||||
// Determine the end date.
|
// Determine the end date.
|
||||||
|
@ -106,9 +104,9 @@ void handleRecurrence ()
|
||||||
|
|
||||||
if (t.has ("wait"))
|
if (t.has ("wait"))
|
||||||
{
|
{
|
||||||
Date old_wait (t.get_date ("wait"));
|
ISO8601d old_wait (t.get_date ("wait"));
|
||||||
Date old_due (t.get_date ("due"));
|
ISO8601d old_due (t.get_date ("due"));
|
||||||
Date due (d);
|
ISO8601d due (d);
|
||||||
sprintf (dueDate, "%u", (unsigned int) (due + (old_wait - old_due)).toEpoch ());
|
sprintf (dueDate, "%u", (unsigned int) (due + (old_wait - old_due)).toEpoch ());
|
||||||
rec.set ("wait", dueDate);
|
rec.set ("wait", dueDate);
|
||||||
rec.setStatus (Task::waiting);
|
rec.setStatus (Task::waiting);
|
||||||
|
@ -148,7 +146,7 @@ void handleRecurrence ()
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (t.has ("until") &&
|
if (t.has ("until") &&
|
||||||
Date (t.get_date ("until")) < now)
|
ISO8601d (t.get_date ("until")) < now)
|
||||||
{
|
{
|
||||||
t.setStatus (Task::deleted);
|
t.setStatus (Task::deleted);
|
||||||
context.tdb2.modify(t);
|
context.tdb2.modify(t);
|
||||||
|
@ -163,28 +161,28 @@ void handleRecurrence ()
|
||||||
// period (recur). Then generate a set of corresponding dates.
|
// period (recur). Then generate a set of corresponding dates.
|
||||||
//
|
//
|
||||||
// Returns false if the parent recurring task is depleted.
|
// Returns false if the parent recurring task is depleted.
|
||||||
bool generateDueDates (Task& parent, std::vector <Date>& allDue)
|
bool generateDueDates (Task& parent, std::vector <ISO8601d>& allDue)
|
||||||
{
|
{
|
||||||
// Determine due date, recur period and until date.
|
// Determine due date, recur period and until date.
|
||||||
Date due (parent.get_date ("due"));
|
ISO8601d due (parent.get_date ("due"));
|
||||||
if (due == 0)
|
if (due._date == 0)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
std::string recur = parent.get ("recur");
|
std::string recur = parent.get ("recur");
|
||||||
|
|
||||||
bool specificEnd = false;
|
bool specificEnd = false;
|
||||||
Date until;
|
ISO8601d until;
|
||||||
if (parent.get ("until") != "")
|
if (parent.get ("until") != "")
|
||||||
{
|
{
|
||||||
until = Date (parent.get ("until"));
|
until = ISO8601d (parent.get ("until"));
|
||||||
specificEnd = true;
|
specificEnd = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int recurrence_limit = context.config.getInteger ("recurrence.limit");
|
int recurrence_limit = context.config.getInteger ("recurrence.limit");
|
||||||
int recurrence_counter = 0;
|
int recurrence_counter = 0;
|
||||||
Date now;
|
ISO8601d now;
|
||||||
for (Date i = due; ; i = getNextRecurrence (i, recur))
|
for (ISO8601d i = due; ; i = getNextRecurrence (i, recur))
|
||||||
{
|
{
|
||||||
allDue.push_back (i);
|
allDue.push_back (i);
|
||||||
|
|
||||||
|
@ -212,7 +210,7 @@ bool generateDueDates (Task& parent, std::vector <Date>& allDue)
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
Date getNextRecurrence (Date& current, std::string& period)
|
ISO8601d getNextRecurrence (ISO8601d& current, std::string& period)
|
||||||
{
|
{
|
||||||
int m = current.month ();
|
int m = current.month ();
|
||||||
int d = current.day ();
|
int d = current.day ();
|
||||||
|
@ -228,10 +226,10 @@ Date getNextRecurrence (Date& current, std::string& period)
|
||||||
++y;
|
++y;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (! Date::valid (m, d, y))
|
while (! ISO8601d::valid (m, d, y))
|
||||||
--d;
|
--d;
|
||||||
|
|
||||||
return Date (m, d, y);
|
return ISO8601d (m, d, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (period == "weekdays")
|
else if (period == "weekdays")
|
||||||
|
@ -258,10 +256,10 @@ Date getNextRecurrence (Date& current, std::string& period)
|
||||||
++y;
|
++y;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (! Date::valid (m, d, y))
|
while (! ISO8601d::valid (m, d, y))
|
||||||
--d;
|
--d;
|
||||||
|
|
||||||
return Date (m, d, y);
|
return ISO8601d (m, d, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (period[0] == 'P' &&
|
else if (period[0] == 'P' &&
|
||||||
|
@ -277,10 +275,10 @@ Date getNextRecurrence (Date& current, std::string& period)
|
||||||
++y;
|
++y;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (! Date::valid (m, d, y))
|
while (! ISO8601d::valid (m, d, y))
|
||||||
--d;
|
--d;
|
||||||
|
|
||||||
return Date (m, d, y);
|
return ISO8601d (m, d, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (period == "quarterly" ||
|
else if (period == "quarterly" ||
|
||||||
|
@ -293,10 +291,10 @@ Date getNextRecurrence (Date& current, std::string& period)
|
||||||
++y;
|
++y;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (! Date::valid (m, d, y))
|
while (! ISO8601d::valid (m, d, y))
|
||||||
--d;
|
--d;
|
||||||
|
|
||||||
return Date (m, d, y);
|
return ISO8601d (m, d, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (Lexer::isDigit (period[0]) && period[period.length () - 1] == 'q')
|
else if (Lexer::isDigit (period[0]) && period[period.length () - 1] == 'q')
|
||||||
|
@ -310,10 +308,10 @@ Date getNextRecurrence (Date& current, std::string& period)
|
||||||
++y;
|
++y;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (! Date::valid (m, d, y))
|
while (! ISO8601d::valid (m, d, y))
|
||||||
--d;
|
--d;
|
||||||
|
|
||||||
return Date (m, d, y);
|
return ISO8601d (m, d, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (period == "semiannual" ||
|
else if (period == "semiannual" ||
|
||||||
|
@ -326,10 +324,10 @@ Date getNextRecurrence (Date& current, std::string& period)
|
||||||
++y;
|
++y;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (! Date::valid (m, d, y))
|
while (! ISO8601d::valid (m, d, y))
|
||||||
--d;
|
--d;
|
||||||
|
|
||||||
return Date (m, d, y);
|
return ISO8601d (m, d, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (period == "bimonthly" ||
|
else if (period == "bimonthly" ||
|
||||||
|
@ -342,10 +340,10 @@ Date getNextRecurrence (Date& current, std::string& period)
|
||||||
++y;
|
++y;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (! Date::valid (m, d, y))
|
while (! ISO8601d::valid (m, d, y))
|
||||||
--d;
|
--d;
|
||||||
|
|
||||||
return Date (m, d, y);
|
return ISO8601d (m, d, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (period == "biannual" ||
|
else if (period == "biannual" ||
|
||||||
|
@ -354,7 +352,7 @@ Date getNextRecurrence (Date& current, std::string& period)
|
||||||
{
|
{
|
||||||
y += 2;
|
y += 2;
|
||||||
|
|
||||||
return Date (m, d, y);
|
return ISO8601d (m, d, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (period == "annual" ||
|
else if (period == "annual" ||
|
||||||
|
@ -368,7 +366,7 @@ Date getNextRecurrence (Date& current, std::string& period)
|
||||||
if (m == 2 && d == 29)
|
if (m == 2 && d == 29)
|
||||||
d = 28;
|
d = 28;
|
||||||
|
|
||||||
return Date (m, d, y);
|
return ISO8601d (m, d, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the period to current, and we're done.
|
// Add the period to current, and we're done.
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
#include <cmake.h>
|
#include <cmake.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <Context.h>
|
#include <Context.h>
|
||||||
#include <Date.h>
|
#include <ISO8601.h>
|
||||||
#include <text.h>
|
#include <text.h>
|
||||||
#include <util.h>
|
#include <util.h>
|
||||||
#include <main.h>
|
#include <main.h>
|
||||||
|
@ -36,7 +36,7 @@ extern Context context;
|
||||||
|
|
||||||
static std::map <std::string, Color> gsColor;
|
static std::map <std::string, Color> gsColor;
|
||||||
static std::vector <std::string> gsPrecedence;
|
static std::vector <std::string> gsPrecedence;
|
||||||
static Date now;
|
static ISO8601d now;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
void initializeColorRules ()
|
void initializeColorRules ()
|
||||||
|
@ -130,7 +130,7 @@ static void colorizeActive (Task& task, const Color& base, Color& c, bool merge)
|
||||||
static void colorizeScheduled (Task& task, const Color& base, Color& c, bool merge)
|
static void colorizeScheduled (Task& task, const Color& base, Color& c, bool merge)
|
||||||
{
|
{
|
||||||
if (task.has ("scheduled") &&
|
if (task.has ("scheduled") &&
|
||||||
Date (task.get_date ("scheduled")) <= now)
|
ISO8601d (task.get_date ("scheduled")) <= now)
|
||||||
applyColor (base, c, merge);
|
applyColor (base, c, merge);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -51,7 +51,6 @@
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <sys/select.h>
|
#include <sys/select.h>
|
||||||
|
|
||||||
#include <Date.h>
|
|
||||||
#include <text.h>
|
#include <text.h>
|
||||||
#include <main.h>
|
#include <main.h>
|
||||||
#include <i18n.h>
|
#include <i18n.h>
|
||||||
|
|
1
test/.gitignore
vendored
1
test/.gitignore
vendored
|
@ -7,7 +7,6 @@ autocomplete.t
|
||||||
col.t
|
col.t
|
||||||
color.t
|
color.t
|
||||||
config.t
|
config.t
|
||||||
date.t
|
|
||||||
dates.t
|
dates.t
|
||||||
eval.t
|
eval.t
|
||||||
fs.t
|
fs.t
|
||||||
|
|
|
@ -9,15 +9,15 @@ include_directories (${CMAKE_SOURCE_DIR}
|
||||||
${CMAKE_SOURCE_DIR}/test
|
${CMAKE_SOURCE_DIR}/test
|
||||||
${TASK_INCLUDE_DIRS})
|
${TASK_INCLUDE_DIRS})
|
||||||
|
|
||||||
set (test_SRCS autocomplete.t col.t color.t config.t date.t fs.t i18n.t json.t
|
set (test_SRCS autocomplete.t col.t color.t config.t fs.t i18n.t json.t list.t
|
||||||
list.t msg.t nibbler.t rx.t t.t t2.t t3.t tdb2.t text.t utf8.t
|
msg.t nibbler.t rx.t t.t t2.t t3.t tdb2.t text.t utf8.t util.t
|
||||||
util.t view.t json_test lexer.t iso8601d.t iso8601p.t eval.t
|
view.t json_test lexer.t iso8601d.t iso8601p.t eval.t dates.t
|
||||||
variant_add.t variant_and.t variant_cast.t variant_divide.t
|
variant_add.t variant_and.t variant_cast.t variant_divide.t
|
||||||
variant_equal.t variant_exp.t variant_gt.t variant_gte.t
|
variant_equal.t variant_exp.t variant_gt.t variant_gte.t
|
||||||
variant_inequal.t variant_lt.t variant_lte.t variant_match.t
|
variant_inequal.t variant_lt.t variant_lte.t variant_match.t
|
||||||
variant_math.t variant_modulo.t variant_multiply.t
|
variant_math.t variant_modulo.t variant_multiply.t
|
||||||
variant_nomatch.t variant_not.t variant_or.t variant_partial.t
|
variant_nomatch.t variant_not.t variant_or.t variant_partial.t
|
||||||
variant_subtract.t variant_xor.t dates.t)
|
variant_subtract.t variant_xor.t)
|
||||||
|
|
||||||
add_custom_target (test ./run_all --verbose
|
add_custom_target (test ./run_all --verbose
|
||||||
DEPENDS ${test_SRCS} task_executable
|
DEPENDS ${test_SRCS} task_executable
|
||||||
|
|
461
test/date.t.cpp
461
test/date.t.cpp
|
@ -1,461 +0,0 @@
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Copyright 2006 - 2015, Paul Beckingham, Federico Hernandez.
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included
|
|
||||||
// in all copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
||||||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
||||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
// SOFTWARE.
|
|
||||||
//
|
|
||||||
// http://www.opensource.org/licenses/mit-license.php
|
|
||||||
//
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#include <cmake.h>
|
|
||||||
#include <iostream>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <Context.h>
|
|
||||||
#include <Date.h>
|
|
||||||
#include <test.h>
|
|
||||||
|
|
||||||
Context context;
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
int main (int argc, char** argv)
|
|
||||||
{
|
|
||||||
UnitTest t (211);
|
|
||||||
|
|
||||||
// Ensure environment has no influence.
|
|
||||||
unsetenv ("TASKDATA");
|
|
||||||
unsetenv ("TASKRC");
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Date now;
|
|
||||||
Date yesterday;
|
|
||||||
yesterday -= 86400;
|
|
||||||
Date 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");
|
|
||||||
|
|
||||||
// Date::Date ("now")
|
|
||||||
context.config.set ("weekstart", "monday");
|
|
||||||
Date relative_now ("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))");
|
|
||||||
|
|
||||||
// Loose comparisons.
|
|
||||||
Date left ("7/4/2008");
|
|
||||||
Date comp1 ("7/4/2008");
|
|
||||||
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");
|
|
||||||
|
|
||||||
Date comp2 ("7/5/2008");
|
|
||||||
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");
|
|
||||||
|
|
||||||
Date comp3 ("8/4/2008");
|
|
||||||
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");
|
|
||||||
|
|
||||||
Date comp4 ("7/4/2009");
|
|
||||||
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 (Date::valid (2, 29, 2008), "valid: 2/29/2008");
|
|
||||||
t.notok (Date::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 (Date::valid (366, 2008), "valid: 366 days in 2008");
|
|
||||||
t.notok (Date::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 (Date::leapYear (2008), "2008 is a leap year");
|
|
||||||
t.notok (Date::leapYear (2007), "2007 is not a leap year");
|
|
||||||
t.ok (Date::leapYear (2000), "2000 is a leap year");
|
|
||||||
t.notok (Date::leapYear (1900), "1900 is not a leap year");
|
|
||||||
|
|
||||||
// Days in month.
|
|
||||||
t.is (Date::daysInMonth (2, 2008), 29, "29 days in February 2008");
|
|
||||||
t.is (Date::daysInMonth (2, 2007), 28, "28 days in February 2007");
|
|
||||||
|
|
||||||
// Names.
|
|
||||||
t.is (Date::monthName (1), "January", "1 = January");
|
|
||||||
t.is (Date::monthName (2), "February", "2 = February");
|
|
||||||
t.is (Date::monthName (3), "March", "3 = March");
|
|
||||||
t.is (Date::monthName (4), "April", "4 = April");
|
|
||||||
t.is (Date::monthName (5), "May", "5 = May");
|
|
||||||
t.is (Date::monthName (6), "June", "6 = June");
|
|
||||||
t.is (Date::monthName (7), "July", "7 = July");
|
|
||||||
t.is (Date::monthName (8), "August", "8 = August");
|
|
||||||
t.is (Date::monthName (9), "September", "9 = September");
|
|
||||||
t.is (Date::monthName (10), "October", "10 = October");
|
|
||||||
t.is (Date::monthName (11), "November", "11 = November");
|
|
||||||
t.is (Date::monthName (12), "December", "12 = December");
|
|
||||||
|
|
||||||
t.is (Date::dayName (0), "Sunday", "0 == Sunday");
|
|
||||||
t.is (Date::dayName (1), "Monday", "1 == Monday");
|
|
||||||
t.is (Date::dayName (2), "Tuesday", "2 == Tuesday");
|
|
||||||
t.is (Date::dayName (3), "Wednesday", "3 == Wednesday");
|
|
||||||
t.is (Date::dayName (4), "Thursday", "4 == Thursday");
|
|
||||||
t.is (Date::dayName (5), "Friday", "5 == Friday");
|
|
||||||
t.is (Date::dayName (6), "Saturday", "6 == Saturday");
|
|
||||||
|
|
||||||
t.is (Date::dayOfWeek ("SUNDAY"), 0, "SUNDAY == 0");
|
|
||||||
t.is (Date::dayOfWeek ("sunday"), 0, "sunday == 0");
|
|
||||||
t.is (Date::dayOfWeek ("Sunday"), 0, "Sunday == 0");
|
|
||||||
t.is (Date::dayOfWeek ("Monday"), 1, "Monday == 1");
|
|
||||||
t.is (Date::dayOfWeek ("Tuesday"), 2, "Tuesday == 2");
|
|
||||||
t.is (Date::dayOfWeek ("Wednesday"), 3, "Wednesday == 3");
|
|
||||||
t.is (Date::dayOfWeek ("Thursday"), 4, "Thursday == 4");
|
|
||||||
t.is (Date::dayOfWeek ("Friday"), 5, "Friday == 5");
|
|
||||||
t.is (Date::dayOfWeek ("Saturday"), 6, "Saturday == 6");
|
|
||||||
|
|
||||||
Date 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 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");
|
|
||||||
|
|
||||||
Date 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");
|
|
||||||
|
|
||||||
Date fromEpoch (epoch.toEpoch ());
|
|
||||||
t.is (fromEpoch.toString (), epoch.toString (), "ctor (time_t)");
|
|
||||||
|
|
||||||
Date iso (1000000000);
|
|
||||||
t.is (iso.toISO (), "20010909T014640Z", "1,000,000,000 -> 20010909T014640Z");
|
|
||||||
|
|
||||||
// Quantization.
|
|
||||||
Date 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.
|
|
||||||
Date fromString1 ("1/1/2008");
|
|
||||||
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");
|
|
||||||
|
|
||||||
Date fromString2 ("1/1/2008", "m/d/Y");
|
|
||||||
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");
|
|
||||||
|
|
||||||
Date fromString3 ("20080101", "YMD");
|
|
||||||
t.is (fromString3.month (), 1, "ctor (std::string) -> m");
|
|
||||||
t.is (fromString3.day (), 1, "ctor (std::string) -> d");
|
|
||||||
t.is (fromString3.year (), 2008, "ctor (std::string) -> y");
|
|
||||||
|
|
||||||
Date fromString4 ("12/31/2007");
|
|
||||||
t.is (fromString4.month (), 12, "ctor (std::string) -> m");
|
|
||||||
t.is (fromString4.day (), 31, "ctor (std::string) -> d");
|
|
||||||
t.is (fromString4.year (), 2007, "ctor (std::string) -> y");
|
|
||||||
|
|
||||||
Date fromString5 ("12/31/2007", "m/d/Y");
|
|
||||||
t.is (fromString5.month (), 12, "ctor (std::string) -> m");
|
|
||||||
t.is (fromString5.day (), 31, "ctor (std::string) -> d");
|
|
||||||
t.is (fromString5.year (), 2007, "ctor (std::string) -> y");
|
|
||||||
|
|
||||||
Date fromString6 ("20071231", "YMD");
|
|
||||||
t.is (fromString6.month (), 12, "ctor (std::string) -> m");
|
|
||||||
t.is (fromString6.day (), 31, "ctor (std::string) -> d");
|
|
||||||
t.is (fromString6.year (), 2007, "ctor (std::string) -> y");
|
|
||||||
|
|
||||||
Date fromString7 ("01/01/2008", "m/d/Y");
|
|
||||||
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");
|
|
||||||
|
|
||||||
Date fromString8 ("Tue 05 Feb 2008 (06)", "a D b Y (V)");
|
|
||||||
t.is (fromString8.month (), 2, "ctor (std::string) -> m");
|
|
||||||
t.is (fromString8.day (), 5, "ctor (std::string) -> d");
|
|
||||||
t.is (fromString8.year (), 2008, "ctor (std::string) -> y");
|
|
||||||
|
|
||||||
Date fromString9 ("Tuesday, February 5, 2008", "A, B d, Y");
|
|
||||||
t.is (fromString9.month (), 2, "ctor (std::string) -> m");
|
|
||||||
t.is (fromString9.day (), 5, "ctor (std::string) -> d");
|
|
||||||
t.is (fromString9.year (), 2008, "ctor (std::string) -> y");
|
|
||||||
|
|
||||||
Date fromString10 ("w01 Tue 2008-01-01", "wV a Y-M-D");
|
|
||||||
t.is (fromString10.month (), 1, "ctor (std::string) -> m");
|
|
||||||
t.is (fromString10.day (), 1, "ctor (std::string) -> d");
|
|
||||||
t.is (fromString10.year (), 2008, "ctor (std::string) -> y");
|
|
||||||
|
|
||||||
Date fromString11 ("6/7/2010 1:23:45", "m/d/Y h:N:S");
|
|
||||||
t.is (fromString11.month (), 6, "ctor (std::string) -> m");
|
|
||||||
t.is (fromString11.day (), 7, "ctor (std::string) -> d");
|
|
||||||
t.is (fromString11.year (), 2010, "ctor (std::string) -> Y");
|
|
||||||
t.is (fromString11.hour (), 1, "ctor (std::string) -> h");
|
|
||||||
t.is (fromString11.minute (), 23, "ctor (std::string) -> N");
|
|
||||||
t.is (fromString11.second (), 45, "ctor (std::string) -> S");
|
|
||||||
|
|
||||||
Date fromString12 ("6/7/2010 01:23:45", "m/d/Y H:N:S");
|
|
||||||
t.is (fromString12.month (), 6, "ctor (std::string) -> m");
|
|
||||||
t.is (fromString12.day (), 7, "ctor (std::string) -> d");
|
|
||||||
t.is (fromString12.year (), 2010, "ctor (std::string) -> Y");
|
|
||||||
t.is (fromString12.hour (), 1, "ctor (std::string) -> h");
|
|
||||||
t.is (fromString12.minute (), 23, "ctor (std::string) -> N");
|
|
||||||
t.is (fromString12.second (), 45, "ctor (std::string) -> S");
|
|
||||||
|
|
||||||
Date fromString13 ("6/7/2010 12:34:56", "m/d/Y H:N:S");
|
|
||||||
t.is (fromString13.month (), 6, "ctor (std::string) -> m");
|
|
||||||
t.is (fromString13.day (), 7, "ctor (std::string) -> d");
|
|
||||||
t.is (fromString13.year (), 2010, "ctor (std::string) -> Y");
|
|
||||||
t.is (fromString13.hour (), 12, "ctor (std::string) -> h");
|
|
||||||
t.is (fromString13.minute (), 34, "ctor (std::string) -> N");
|
|
||||||
t.is (fromString13.second (), 56, "ctor (std::string) -> S");
|
|
||||||
|
|
||||||
// Day of year
|
|
||||||
t.is (Date ("1/1/2011", "m/d/Y").dayOfYear (), 1, "dayOfYear (1/1/2011) -> 1");
|
|
||||||
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");
|
|
||||||
|
|
||||||
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");
|
|
||||||
|
|
||||||
// Date::sameHour
|
|
||||||
Date r20 ("6/7/2010 01:00:00", "m/d/Y H:N:S");
|
|
||||||
Date r21 ("6/7/2010 01:59:59", "m/d/Y H:N:S");
|
|
||||||
t.ok (r20.sameHour (r21), "two dates within the same hour");
|
|
||||||
|
|
||||||
Date 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");
|
|
||||||
|
|
||||||
// Date::operator-
|
|
||||||
Date r25 (1234567890);
|
|
||||||
t.is ((r25 - 1).toEpoch (), 1234567889, "1234567890 - 1 = 1234567889");
|
|
||||||
|
|
||||||
// Date::operator--
|
|
||||||
Date r26 (11, 7, 2010, 23, 59, 59);
|
|
||||||
r26--;
|
|
||||||
t.is (r26.toString ("YMDHNS"), "20101106235959", "decrement across fall DST boundary");
|
|
||||||
|
|
||||||
Date r27 (3, 14, 2010, 23, 59, 59);
|
|
||||||
r27--;
|
|
||||||
t.is (r27.toString ("YMDHNS"), "20100313235959", "decrement across spring DST boundary");
|
|
||||||
|
|
||||||
// Date::operator++
|
|
||||||
Date r28 (11, 6, 2010, 23, 59, 59);
|
|
||||||
r28++;
|
|
||||||
t.is (r28.toString ("YMDHNS"), "20101107235959", "increment across fall DST boundary");
|
|
||||||
|
|
||||||
Date r29 (3, 13, 2010, 23, 59, 59);
|
|
||||||
r29++;
|
|
||||||
t.is (r29.toString ("YMDHNS"), "20100314235959", "increment across spring DST boundary");
|
|
||||||
|
|
||||||
// int Date::length (const std::string&);
|
|
||||||
t.is (Date::length ("m"), 2, "length 'm' --> 2");
|
|
||||||
t.is (Date::length ("M"), 2, "length 'M' --> 2");
|
|
||||||
t.is (Date::length ("d"), 2, "length 'd' --> 2");
|
|
||||||
t.is (Date::length ("D"), 2, "length 'D' --> 2");
|
|
||||||
t.is (Date::length ("y"), 2, "length 'y' --> 2");
|
|
||||||
t.is (Date::length ("Y"), 4, "length 'Y' --> 4");
|
|
||||||
t.is (Date::length ("a"), 3, "length 'a' --> 3");
|
|
||||||
t.is (Date::length ("A"), 10, "length 'A' --> 10");
|
|
||||||
t.is (Date::length ("b"), 3, "length 'b' --> 3");
|
|
||||||
t.is (Date::length ("B"), 10, "length 'B' --> 10");
|
|
||||||
t.is (Date::length ("v"), 2, "length 'v' --> 2");
|
|
||||||
t.is (Date::length ("V"), 2, "length 'V' --> 2");
|
|
||||||
t.is (Date::length ("h"), 2, "length 'h' --> 2");
|
|
||||||
t.is (Date::length ("H"), 2, "length 'H' --> 2");
|
|
||||||
t.is (Date::length ("n"), 2, "length 'n' --> 2");
|
|
||||||
t.is (Date::length ("N"), 2, "length 'N' --> 2");
|
|
||||||
t.is (Date::length ("s"), 2, "length 's' --> 2");
|
|
||||||
t.is (Date::length ("S"), 2, "length 'S' --> 2");
|
|
||||||
t.is (Date::length ("j"), 3, "length 'j' --> 3");
|
|
||||||
t.is (Date::length ("J"), 3, "length 'J' --> 3");
|
|
||||||
|
|
||||||
t.is (Date::length (" "), 1, "length ' ' --> 1");
|
|
||||||
|
|
||||||
// Depletion requirement.
|
|
||||||
Date r30 ("Mon Jun 30 2014", "a b D Y", false, false);
|
|
||||||
t.is (r30.toString ("YMDHNS"), "20140630000000", "Depletion required on complex format with spaces");
|
|
||||||
|
|
||||||
std::string::size_type i = 0;
|
|
||||||
Date 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)
|
|
||||||
{
|
|
||||||
t.fail ("Exception thrown.");
|
|
||||||
t.diag (e);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
|
@ -47,31 +47,31 @@ void testParse (
|
||||||
int in_seconds,
|
int in_seconds,
|
||||||
int in_offset,
|
int in_offset,
|
||||||
bool in_utc,
|
bool in_utc,
|
||||||
time_t in_value)
|
time_t in_date)
|
||||||
{
|
{
|
||||||
std::string label = std::string ("parse (\"") + input + "\") --> ";
|
std::string label = std::string ("parse (\"") + input + "\") --> ";
|
||||||
|
|
||||||
ISO8601d iso;
|
ISO8601d iso;
|
||||||
std::string::size_type start = 0;
|
std::string::size_type start = 0;
|
||||||
|
|
||||||
t.ok (iso.parse (input, start), label + "true");
|
t.ok (iso.parse (input, start), label + "true");
|
||||||
t.is ((int) start, in_start, label + "[]");
|
t.is ((int) start, in_start, label + "[]");
|
||||||
t.is (iso._year, in_year, label + "_year");
|
t.is (iso._year, in_year, label + "_year");
|
||||||
t.is (iso._month, in_month, label + "_month");
|
t.is (iso._month, in_month, label + "_month");
|
||||||
t.is (iso._week, in_week, label + "_week");
|
t.is (iso._week, in_week, label + "_week");
|
||||||
t.is (iso._weekday, in_weekday, label + "_weekday");
|
t.is (iso._weekday, in_weekday, label + "_weekday");
|
||||||
t.is (iso._julian, in_julian, label + "_julian");
|
t.is (iso._julian, in_julian, label + "_julian");
|
||||||
t.is (iso._day, in_day, label + "_day");
|
t.is (iso._day, in_day, label + "_day");
|
||||||
t.is (iso._seconds, in_seconds, label + "_seconds");
|
t.is (iso._seconds, in_seconds, label + "_seconds");
|
||||||
t.is (iso._offset, in_offset, label + "_offset");
|
t.is (iso._offset, in_offset, label + "_offset");
|
||||||
t.is (iso._utc, in_utc, label + "_utc");
|
t.is (iso._utc, in_utc, label + "_utc");
|
||||||
t.is ((size_t) iso._value, (size_t) in_value, label + "_value");
|
t.is ((size_t) iso._date, (size_t) in_date, label + "_date");
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
int main (int argc, char** argv)
|
int main (int argc, char** argv)
|
||||||
{
|
{
|
||||||
UnitTest t (758);
|
UnitTest t (904);
|
||||||
|
|
||||||
ISO8601d iso;
|
ISO8601d iso;
|
||||||
std::string::size_type start = 0;
|
std::string::size_type start = 0;
|
||||||
|
@ -216,6 +216,412 @@ int main (int argc, char** argv)
|
||||||
testParse (t, "20131206T123456Z", 16, 2013, 12, 0, 0, 0, 6, hms, 0, true, utc6+hms );
|
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);
|
testParse (t, "20131206T123456", 15, 2013, 12, 0, 0, 0, 6, hms, 0, false, local6+hms);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
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");
|
||||||
|
|
||||||
|
// Date::Date ("now")
|
||||||
|
context.config.set ("weekstart", "monday");
|
||||||
|
ISO8601d relative_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");
|
||||||
|
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 (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 (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");
|
||||||
|
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");
|
||||||
|
|
||||||
|
// 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");
|
||||||
|
|
||||||
|
// 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");
|
||||||
|
|
||||||
|
// 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");
|
||||||
|
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");
|
||||||
|
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");
|
||||||
|
|
||||||
|
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 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");
|
||||||
|
|
||||||
|
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");
|
||||||
|
|
||||||
|
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");
|
||||||
|
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");
|
||||||
|
|
||||||
|
// 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");
|
||||||
|
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");
|
||||||
|
|
||||||
|
// 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");
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
t.fail ("Exception thrown.");
|
||||||
|
t.diag (e);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -44,7 +44,7 @@ void testParse (
|
||||||
int in_hours,
|
int in_hours,
|
||||||
int in_minutes,
|
int in_minutes,
|
||||||
int in_seconds,
|
int in_seconds,
|
||||||
time_t in_value,
|
time_t in_period,
|
||||||
const std::string& output,
|
const std::string& output,
|
||||||
const std::string& vague)
|
const std::string& vague)
|
||||||
{
|
{
|
||||||
|
@ -53,17 +53,17 @@ void testParse (
|
||||||
ISO8601p iso;
|
ISO8601p iso;
|
||||||
std::string::size_type start = 0;
|
std::string::size_type start = 0;
|
||||||
|
|
||||||
t.ok (iso.parse (input, start), label + "true");
|
t.ok (iso.parse (input, start), label + "true");
|
||||||
t.is ((int) start, in_start, label + "[]");
|
t.is ((int) start, in_start, label + "[]");
|
||||||
t.is (iso._year, in_year, label + "_year");
|
t.is (iso._year, in_year, label + "_year");
|
||||||
t.is (iso._month, in_month, label + "_month");
|
t.is (iso._month, in_month, label + "_month");
|
||||||
t.is (iso._day, in_day, label + "_day");
|
t.is (iso._day, in_day, label + "_day");
|
||||||
t.is (iso._hours, in_hours, label + "_hours");
|
t.is (iso._hours, in_hours, label + "_hours");
|
||||||
t.is (iso._minutes, in_minutes, label + "_minutes");
|
t.is (iso._minutes, in_minutes, label + "_minutes");
|
||||||
t.is (iso._seconds, in_seconds, label + "_seconds");
|
t.is (iso._seconds, in_seconds, label + "_seconds");
|
||||||
t.is ((size_t) iso._value, (size_t) in_value, label + "_value");
|
t.is ((size_t) iso._period, (size_t) in_period, label + "_period");
|
||||||
t.is (iso.format (), output, label + " format");
|
t.is (iso.format (), output, label + " format");
|
||||||
t.is (iso.formatVague (), vague, label + " formatVague");
|
t.is (iso.formatVague (), vague, label + " formatVague");
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -335,8 +335,6 @@ int main (int argc, char** argv)
|
||||||
{ "/long/path/to/file.txt", { { "/long/path/to/file.txt", Lexer::Type::path }, NO, NO, NO, NO }, },
|
{ "/long/path/to/file.txt", { { "/long/path/to/file.txt", Lexer::Type::path }, NO, NO, NO, NO }, },
|
||||||
|
|
||||||
// Word
|
// Word
|
||||||
{ "9th", { { "9th", Lexer::Type::word }, NO, NO, NO, NO }, },
|
|
||||||
{ "10th", { { "10th", Lexer::Type::word }, NO, NO, NO, NO }, },
|
|
||||||
{ "1.foo.bar", { { "1.foo.bar", Lexer::Type::word }, NO, NO, NO, NO }, },
|
{ "1.foo.bar", { { "1.foo.bar", Lexer::Type::word }, NO, NO, NO, NO }, },
|
||||||
|
|
||||||
// Identifier
|
// Identifier
|
||||||
|
@ -348,10 +346,7 @@ int main (int argc, char** argv)
|
||||||
{ "foo.bar", { { "foo.bar", Lexer::Type::identifier }, NO, NO, NO, NO }, },
|
{ "foo.bar", { { "foo.bar", Lexer::Type::identifier }, NO, NO, NO, NO }, },
|
||||||
{ "a1a1a1a1_a1a1_a1a1_a1a1_a1a1a1a1a1a1", { { "a1a1a1a1_a1a1_a1a1_a1a1_a1a1a1a1a1a1", Lexer::Type::identifier }, NO, NO, NO, NO }, },
|
{ "a1a1a1a1_a1a1_a1a1_a1a1_a1a1a1a1a1a1", { { "a1a1a1a1_a1a1_a1a1_a1a1_a1a1a1a1a1a1", Lexer::Type::identifier }, NO, NO, NO, NO }, },
|
||||||
|
|
||||||
// Not a date, because Eval extracts named dates via data source, and Date/ISO8601d does not do that.
|
// Word that starts wih 'or', which is an operator, but should be ignored.
|
||||||
{ "today", { { "today", Lexer::Type::identifier }, NO, NO, NO, NO }, },
|
|
||||||
|
|
||||||
// Word that starts wih 'or', which is an operator, but should be ignored.
|
|
||||||
{ "ordinary", { { "ordinary", Lexer::Type::identifier }, NO, NO, NO, NO }, },
|
{ "ordinary", { { "ordinary", Lexer::Type::identifier }, NO, NO, NO, NO }, },
|
||||||
|
|
||||||
// DOM
|
// DOM
|
||||||
|
@ -458,6 +453,9 @@ int main (int argc, char** argv)
|
||||||
{ "2015-02-17", { { "2015-02-17", Lexer::Type::date }, NO, NO, NO, NO }, },
|
{ "2015-02-17", { { "2015-02-17", Lexer::Type::date }, NO, NO, NO, NO }, },
|
||||||
{ "2013-11-29T22:58:00Z", { { "2013-11-29T22:58:00Z", Lexer::Type::date }, NO, NO, NO, NO }, },
|
{ "2013-11-29T22:58:00Z", { { "2013-11-29T22:58:00Z", Lexer::Type::date }, NO, NO, NO, NO }, },
|
||||||
{ "20131129T225800Z", { { "20131129T225800Z", Lexer::Type::date }, NO, NO, NO, NO }, },
|
{ "20131129T225800Z", { { "20131129T225800Z", Lexer::Type::date }, NO, NO, NO, NO }, },
|
||||||
|
{ "9th", { { "9th", Lexer::Type::date }, NO, NO, NO, NO }, },
|
||||||
|
{ "10th", { { "10th", Lexer::Type::date }, NO, NO, NO, NO }, },
|
||||||
|
{ "today", { { "today", Lexer::Type::date }, NO, NO, NO, NO }, },
|
||||||
|
|
||||||
// Duration
|
// Duration
|
||||||
{ "year", { { "year", Lexer::Type::duration }, NO, NO, NO, NO }, },
|
{ "year", { { "year", Lexer::Type::duration }, NO, NO, NO, NO }, },
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
#include <Context.h>
|
#include <Context.h>
|
||||||
#include <Nibbler.h>
|
#include <Nibbler.h>
|
||||||
#ifdef NIBBLER_FEATURE_DATE
|
#ifdef NIBBLER_FEATURE_DATE
|
||||||
#include <Date.h>
|
#include <ISO8601.h>
|
||||||
#endif
|
#endif
|
||||||
#include <test.h>
|
#include <test.h>
|
||||||
|
|
||||||
|
@ -65,7 +65,7 @@ int main (int argc, char** argv)
|
||||||
time_t ti;
|
time_t ti;
|
||||||
|
|
||||||
#ifdef NIBBLER_FEATURE_DATE
|
#ifdef NIBBLER_FEATURE_DATE
|
||||||
Date dt;
|
ISO8601d dt;
|
||||||
#endif
|
#endif
|
||||||
std::vector <std::string> options;
|
std::vector <std::string> options;
|
||||||
|
|
||||||
|
@ -533,56 +533,56 @@ int main (int argc, char** argv)
|
||||||
t.diag ("Nibbler::getDate");
|
t.diag ("Nibbler::getDate");
|
||||||
n = Nibbler ("1/1/2008");
|
n = Nibbler ("1/1/2008");
|
||||||
t.ok (n.getDate ("m/d/Y", ti), "m/d/Y ok");
|
t.ok (n.getDate ("m/d/Y", ti), "m/d/Y ok");
|
||||||
dt = Date (ti);
|
dt = ISO8601d (ti);
|
||||||
t.is (dt.month (), 1, "ctor (std::string) -> m");
|
t.is (dt.month (), 1, "ctor (std::string) -> m");
|
||||||
t.is (dt.day (), 1, "ctor (std::string) -> d");
|
t.is (dt.day (), 1, "ctor (std::string) -> d");
|
||||||
t.is (dt.year (), 2008, "ctor (std::string) -> y");
|
t.is (dt.year (), 2008, "ctor (std::string) -> y");
|
||||||
|
|
||||||
n = Nibbler ("20080101");
|
n = Nibbler ("20080101");
|
||||||
t.ok (n.getDate ("YMD", ti), "YMD ok");
|
t.ok (n.getDate ("YMD", ti), "YMD ok");
|
||||||
dt = Date (ti);
|
dt = ISO8601d (ti);
|
||||||
t.is (dt.month (), 1, "ctor (std::string) -> m");
|
t.is (dt.month (), 1, "ctor (std::string) -> m");
|
||||||
t.is (dt.day (), 1, "ctor (std::string) -> d");
|
t.is (dt.day (), 1, "ctor (std::string) -> d");
|
||||||
t.is (dt.year (), 2008, "ctor (std::string) -> y");
|
t.is (dt.year (), 2008, "ctor (std::string) -> y");
|
||||||
|
|
||||||
n = Nibbler ("12/31/2007");
|
n = Nibbler ("12/31/2007");
|
||||||
t.ok (n.getDate ("m/d/Y", ti), "m/d/Y ok");
|
t.ok (n.getDate ("m/d/Y", ti), "m/d/Y ok");
|
||||||
dt = Date (ti);
|
dt = ISO8601d (ti);
|
||||||
t.is (dt.month (), 12, "ctor (std::string) -> m");
|
t.is (dt.month (), 12, "ctor (std::string) -> m");
|
||||||
t.is (dt.day (), 31, "ctor (std::string) -> d");
|
t.is (dt.day (), 31, "ctor (std::string) -> d");
|
||||||
t.is (dt.year (), 2007, "ctor (std::string) -> y");
|
t.is (dt.year (), 2007, "ctor (std::string) -> y");
|
||||||
|
|
||||||
n = Nibbler ("20071231");
|
n = Nibbler ("20071231");
|
||||||
t.ok (n.getDate ("YMD", ti), "YMD ok");
|
t.ok (n.getDate ("YMD", ti), "YMD ok");
|
||||||
dt = Date (ti);
|
dt = ISO8601d (ti);
|
||||||
t.is (dt.month (), 12, "ctor (std::string) -> m");
|
t.is (dt.month (), 12, "ctor (std::string) -> m");
|
||||||
t.is (dt.day (), 31, "ctor (std::string) -> d");
|
t.is (dt.day (), 31, "ctor (std::string) -> d");
|
||||||
t.is (dt.year (), 2007, "ctor (std::string) -> y");
|
t.is (dt.year (), 2007, "ctor (std::string) -> y");
|
||||||
|
|
||||||
n = Nibbler ("Tue 01 Jan 2008 (01)");
|
n = Nibbler ("Tue 01 Jan 2008 (01)");
|
||||||
t.ok (n.getDate ("a D b Y (V)", ti), "a D b Y (V)");
|
t.ok (n.getDate ("a D b Y (V)", ti), "a D b Y (V)");
|
||||||
dt = Date (ti);
|
dt = ISO8601d (ti);
|
||||||
t.is (dt.month (), 1, "ctor (std::string) -> m");
|
t.is (dt.month (), 1, "ctor (std::string) -> m");
|
||||||
t.is (dt.day (), 1, "ctor (std::string) -> d");
|
t.is (dt.day (), 1, "ctor (std::string) -> d");
|
||||||
t.is (dt.year (), 2008, "ctor (std::string) -> y");
|
t.is (dt.year (), 2008, "ctor (std::string) -> y");
|
||||||
|
|
||||||
n = Nibbler ("Tuesday, January 1, 2008");
|
n = Nibbler ("Tuesday, January 1, 2008");
|
||||||
t.ok (n.getDate ("A, B d, Y", ti), "A, B d, Y ok");
|
t.ok (n.getDate ("A, B d, Y", ti), "A, B d, Y ok");
|
||||||
dt = Date (ti);
|
dt = ISO8601d (ti);
|
||||||
t.is (dt.month (), 1, "ctor (std::string) -> m");
|
t.is (dt.month (), 1, "ctor (std::string) -> m");
|
||||||
t.is (dt.day (), 1, "ctor (std::string) -> d");
|
t.is (dt.day (), 1, "ctor (std::string) -> d");
|
||||||
t.is (dt.year (), 2008, "ctor (std::string) -> y");
|
t.is (dt.year (), 2008, "ctor (std::string) -> y");
|
||||||
|
|
||||||
n = Nibbler ("w01 Tue 2008-01-01");
|
n = Nibbler ("w01 Tue 2008-01-01");
|
||||||
t.ok (n.getDate ("wV a Y-M-D", ti), "wV a Y-M-D ok");
|
t.ok (n.getDate ("wV a Y-M-D", ti), "wV a Y-M-D ok");
|
||||||
dt = Date (ti);
|
dt = ISO8601d (ti);
|
||||||
t.is (dt.month (), 1, "ctor (std::string) -> m");
|
t.is (dt.month (), 1, "ctor (std::string) -> m");
|
||||||
t.is (dt.day (), 1, "ctor (std::string) -> d");
|
t.is (dt.day (), 1, "ctor (std::string) -> d");
|
||||||
t.is (dt.year (), 2008, "ctor (std::string) -> y");
|
t.is (dt.year (), 2008, "ctor (std::string) -> y");
|
||||||
|
|
||||||
n = Nibbler ("6/7/2010 1:23:45");
|
n = Nibbler ("6/7/2010 1:23:45");
|
||||||
t.ok (n.getDate ("m/d/Y h:N:S", ti), "m/d/Y h:N:S ok");
|
t.ok (n.getDate ("m/d/Y h:N:S", ti), "m/d/Y h:N:S ok");
|
||||||
dt = Date (ti);
|
dt = ISO8601d (ti);
|
||||||
t.is (dt.month (), 6, "ctor (std::string) -> m");
|
t.is (dt.month (), 6, "ctor (std::string) -> m");
|
||||||
t.is (dt.day (), 7, "ctor (std::string) -> d");
|
t.is (dt.day (), 7, "ctor (std::string) -> d");
|
||||||
t.is (dt.year (), 2010, "ctor (std::string) -> Y");
|
t.is (dt.year (), 2010, "ctor (std::string) -> Y");
|
||||||
|
@ -592,7 +592,7 @@ int main (int argc, char** argv)
|
||||||
|
|
||||||
n = Nibbler ("6/7/2010 01:23:45");
|
n = Nibbler ("6/7/2010 01:23:45");
|
||||||
t.ok (n.getDate ("m/d/Y H:N:S", ti), "m/d/Y H:N:S ok");
|
t.ok (n.getDate ("m/d/Y H:N:S", ti), "m/d/Y H:N:S ok");
|
||||||
dt = Date (ti);
|
dt = ISO8601d (ti);
|
||||||
t.is (dt.month (), 6, "ctor (std::string) -> m");
|
t.is (dt.month (), 6, "ctor (std::string) -> m");
|
||||||
t.is (dt.day (), 7, "ctor (std::string) -> d");
|
t.is (dt.day (), 7, "ctor (std::string) -> d");
|
||||||
t.is (dt.year (), 2010, "ctor (std::string) -> Y");
|
t.is (dt.year (), 2010, "ctor (std::string) -> Y");
|
||||||
|
@ -602,7 +602,7 @@ int main (int argc, char** argv)
|
||||||
|
|
||||||
n = Nibbler ("6/7/2010 12:34:56");
|
n = Nibbler ("6/7/2010 12:34:56");
|
||||||
t.ok (n.getDate ("m/d/Y H:N:S", ti), "m/d/Y H:N:S ok");
|
t.ok (n.getDate ("m/d/Y H:N:S", ti), "m/d/Y H:N:S ok");
|
||||||
dt = Date (ti);
|
dt = ISO8601d (ti);
|
||||||
t.is (dt.month (), 6, "ctor (std::string) -> m");
|
t.is (dt.month (), 6, "ctor (std::string) -> m");
|
||||||
t.is (dt.day (), 7, "ctor (std::string) -> d");
|
t.is (dt.day (), 7, "ctor (std::string) -> d");
|
||||||
t.is (dt.year (), 2010, "ctor (std::string) -> Y");
|
t.is (dt.year (), 2010, "ctor (std::string) -> Y");
|
||||||
|
@ -612,7 +612,7 @@ int main (int argc, char** argv)
|
||||||
|
|
||||||
n = Nibbler ("2010");
|
n = Nibbler ("2010");
|
||||||
t.ok (n.getDate ("Y", ti), "Y ok");
|
t.ok (n.getDate ("Y", ti), "Y ok");
|
||||||
dt = Date (ti);
|
dt = ISO8601d (ti);
|
||||||
t.is (dt.month (), 1, "ctor (std::string) -> m");
|
t.is (dt.month (), 1, "ctor (std::string) -> m");
|
||||||
t.is (dt.day (), 1, "ctor (std::string) -> d");
|
t.is (dt.day (), 1, "ctor (std::string) -> d");
|
||||||
t.is (dt.year (), 2010, "ctor (std::string) -> Y");
|
t.is (dt.year (), 2010, "ctor (std::string) -> Y");
|
||||||
|
@ -622,8 +622,8 @@ int main (int argc, char** argv)
|
||||||
|
|
||||||
n = Nibbler ("17:18:19");
|
n = Nibbler ("17:18:19");
|
||||||
t.ok (n.getDate ("H:N:S", ti), "H:N:S ok");
|
t.ok (n.getDate ("H:N:S", ti), "H:N:S ok");
|
||||||
dt = Date (ti);
|
dt = ISO8601d (ti);
|
||||||
Date now = Date ();
|
ISO8601d now;
|
||||||
t.is (dt.month (), now.month(), "ctor (std::string) -> m");
|
t.is (dt.month (), now.month(), "ctor (std::string) -> m");
|
||||||
t.is (dt.day (), now.day(), "ctor (std::string) -> d");
|
t.is (dt.day (), now.day(), "ctor (std::string) -> d");
|
||||||
t.is (dt.year (), now.year(), "ctor (std::string) -> Y");
|
t.is (dt.year (), now.year(), "ctor (std::string) -> Y");
|
||||||
|
|
|
@ -54,7 +54,7 @@ class TestTimesheet(TestCase):
|
||||||
# C0 completed, this week
|
# C0 completed, this week
|
||||||
# C1 completed, last week
|
# C1 completed, last week
|
||||||
# C2 completed, 2wks ago
|
# C2 completed, 2wks ago
|
||||||
now = time()
|
now = int(time())
|
||||||
seven = now - 7 * 86400
|
seven = now - 7 * 86400
|
||||||
fourteen = now - 14 * 86400
|
fourteen = now - 14 * 86400
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue