- Date class now supports relative dates for construction (tomorrow, friday, eoy ...)

- Added unit tests for Date enhancements
- Added unit tests for duration recognition
- Task parsing now supports due: using relative dates
- Task parsing now supports recur: and until: attributes
- Task parsing now support private attributes base: and range:
This commit is contained in:
Paul Beckingham 2008-07-04 17:18:01 -04:00
parent 00b7a5f1b4
commit 06d595d944
11 changed files with 421 additions and 88 deletions

View file

@ -22,7 +22,7 @@ Test Suite
Recurrence
+ new T::status recurring (stored as R)
- new user-specifiable attributes - recur:<duration> [until:<date>]
+ new user-specifiable attributes - recur:<duration> [until:<date>]
- duration:
daily, day, 1d
Nd

View file

@ -63,6 +63,10 @@ Date::Date (const std::string& mdy, const std::string& format /* = "m/d/Y" */)
int day = 0;
int year = 0;
// Before parsing according to "format", perhaps this is a relative date?
if (isRelativeDate (mdy))
return;
unsigned int i = 0; // Index into mdy.
for (unsigned int f = 0; f < format.length (); ++f)
@ -184,7 +188,7 @@ Date::Date (const std::string& mdy, const std::string& format /* = "m/d/Y" */)
t.tm_mon = month - 1;
t.tm_year = year - 1900;
mT = mktime (&t);
mT = mktime (&t);
}
////////////////////////////////////////////////////////////////////////////////
@ -357,6 +361,22 @@ int Date::dayOfWeek () const
return t->tm_wday;
}
////////////////////////////////////////////////////////////////////////////////
int Date::dayOfWeek (const std::string& input)
{
std::string in = lowerCase (input);
if (in == "sunday") return 0;
if (in == "monday") return 1;
if (in == "tuesday") return 2;
if (in == "wednesday") return 3;
if (in == "thursday") return 4;
if (in == "friday") return 5;
if (in == "saturday") return 6;
return -1;
}
////////////////////////////////////////////////////////////////////////////////
int Date::month () const
{
@ -414,6 +434,36 @@ bool Date::operator>= (const Date& rhs)
return mT >= rhs.mT;
}
////////////////////////////////////////////////////////////////////////////////
bool Date::sameDay (const Date& rhs)
{
if (this->year () == rhs.year () &&
this->month () == rhs.month () &&
this->day () == rhs.day ())
return true;
return false;
}
////////////////////////////////////////////////////////////////////////////////
bool Date::sameMonth (const Date& rhs)
{
if (this->year () == rhs.year () &&
this->month () == rhs.month ())
return true;
return false;
}
////////////////////////////////////////////////////////////////////////////////
bool Date::sameYear (const Date& rhs)
{
if (this->year () == rhs.year ())
return true;
return false;
}
////////////////////////////////////////////////////////////////////////////////
Date Date::operator+ (const int delta)
{
@ -441,3 +491,94 @@ time_t Date::operator- (const Date& rhs)
}
////////////////////////////////////////////////////////////////////////////////
// If the input string looks like a relative date, determine that date, set mT
// and return true.
//
// What is a relative date? All of the following should be recognizable, and
// converted to an absolute date:
// wednesday
// fri
// 23rd
// today
// tomorrow
// yesterday
// eow (end of week)
// eom (end of month)
// eoy (end of year)
bool Date::isRelativeDate (const std::string& input)
{
std::string in (lowerCase (input));
std::vector <std::string> supported;
supported.push_back ("monday");
supported.push_back ("tuesday");
supported.push_back ("wednesday");
supported.push_back ("thursday");
supported.push_back ("friday");
supported.push_back ("saturday");
supported.push_back ("sunday");
supported.push_back ("today");
supported.push_back ("tomorrow");
supported.push_back ("yesterday");
supported.push_back ("eow");
supported.push_back ("eom");
supported.push_back ("eoy");
std::vector <std::string> matches;
if (autoComplete (in, supported, matches) == 1)
{
std::string found = matches[0];
Date today;
// If day name.
int dow;
if ((dow = Date::dayOfWeek (found)) != -1 ||
found == "eow")
{
if (found == "eow")
dow = 5;
if (today.dayOfWeek () >= dow)
today += (dow - today.dayOfWeek () + 7) * 86400;
else
today += (dow - today.dayOfWeek ()) * 86400;
mT = today.mT;
return true;
}
else if (found == "today")
{
mT = today.mT;
return true;
}
else if (found == "tomorrow")
{
mT = today.mT + 86400;
return true;
}
else if (found == "yesterday")
{
mT = today.mT - 86400;
return true;
}
else if (found == "eom")
{
Date then (today.month (),
daysInMonth (today.month (), today.year ()),
today.year ());
mT = then.mT;
return true;
}
else if (found == "eoy")
{
Date then (12, 31, today.year ());
mT = then.mT;
return true;
}
// \d|\d\d|\d\d\d|\d\d\d\d st|nd|rd|th
}
return false;
}
////////////////////////////////////////////////////////////////////////////////

View file

@ -52,11 +52,12 @@ public:
static std::string monthName (int);
static void dayName (int, std::string&);
static std::string dayName (int);
int dayOfWeek () const;
static int dayOfWeek (const std::string&);
int month () const;
int day () const;
int year () const;
int dayOfWeek () const;
bool operator== (const Date&);
bool operator!= (const Date&);
@ -64,6 +65,9 @@ public:
bool operator> (const Date&);
bool operator<= (const Date&);
bool operator>= (const Date&);
bool sameDay (const Date&);
bool sameMonth (const Date&);
bool sameYear (const Date&);
Date operator+ (const int);
Date& operator+= (const int);
@ -71,6 +75,9 @@ public:
time_t operator- (const Date&);
private:
bool isRelativeDate (const std::string&);
protected:
time_t mT;
};

View file

@ -241,9 +241,12 @@ static bool validAttribute (
return validPriority (value);
}
// Some attributes are intended to be private.
else if (name == "entry" ||
name == "start" ||
name == "end")
name == "end" ||
name == "base" ||
name == "range")
throw std::string ("\"") +
name +
"\" is not an attribute you may modify directly.";
@ -321,8 +324,7 @@ static bool validSubstitution (
////////////////////////////////////////////////////////////////////////////////
bool validDuration (const std::string& input)
{
// TODO
return false;
return convertDuration (input) != 0 ? true : false;
}
////////////////////////////////////////////////////////////////////////////////
@ -379,7 +381,10 @@ void parse (
std::string value = arg.substr (colon + 1, std::string::npos);
if (validAttribute (name, value, conf))
task.setAttribute (name, value);
{
if (name != "recur" || validDuration (value))
task.setAttribute (name, value);
}
}
// Substitution of description text.

View file

@ -31,6 +31,7 @@
#include <sys/types.h>
#include "Config.h"
#include "Table.h"
#include "Date.h"
#include "color.h"
#include "TDB.h"
#include "T.h"
@ -106,6 +107,8 @@ void formatTimeDeltaDays (std::string&, time_t);
std::string formatSeconds (time_t);
const std::string uuid ();
const char* optionalBlankLine (Config&);
int convertDuration (const std::string&);
Date convertRelativeDate (const std::string&);
// rules.cpp
void initializeColorRules (Config&);

View file

@ -1,6 +1,7 @@
t.t
tdb.t
date.t
duration.t
pending.data
completed.data

View file

@ -1,4 +1,4 @@
PROJECT = t.t tdb.t date.t
PROJECT = t.t tdb.t date.t duration.t
CFLAGS = -I. -I.. -Wall -pedantic -ggdb3 -fno-rtti
LFLAGS = -L/usr/local/lib
OBJECTS = ../TDB.o ../T.o ../parse.o ../text.o ../Date.o ../util.o ../Config.o
@ -26,3 +26,6 @@ tdb.t: tdb.t.o $(OBJECTS) test.o
date.t: date.t.o $(OBJECTS) test.o
g++ date.t.o $(OBJECTS) test.o $(LFLAGS) -o date.t
duration.t: duration.t.o $(OBJECTS) test.o
g++ duration.t.o $(OBJECTS) test.o $(LFLAGS) -o duration.t

View file

@ -9,104 +9,211 @@
////////////////////////////////////////////////////////////////////////////////
int main (int argc, char** argv)
{
plan (63);
plan (97);
Date now;
Date yesterday;
yesterday -= 1;
try
{
Date now;
Date yesterday;
yesterday -= 1;
ok (yesterday <= now, "yesterday <= now");
ok (yesterday < now, "yesterday < now");
notok (yesterday == now, "!(yesterday == now)");
ok (yesterday != now, "yesterday != now");
ok (now >= yesterday, "now >= yesterday");
ok (now > yesterday, "now > yesterday");
ok (yesterday <= now, "yesterday <= now");
ok (yesterday < now, "yesterday < now");
notok (yesterday == now, "!(yesterday == now)");
ok (yesterday != now, "yesterday != now");
ok (now >= yesterday, "now >= yesterday");
ok (now > yesterday, "now > yesterday");
ok (Date::valid (2, 29, 2008), "valid: 2/29/2008");
notok (Date::valid (2, 29, 2007), "invalid: 2/29/2007");
// Loose comparisons.
Date left ("7/4/2008");
Date comp1 ("7/4/2008");
ok (left.sameDay (comp1), "7/4/2008 is on the same day as 7/4/2008");
ok (left.sameMonth (comp1), "7/4/2008 is in the same month as 7/4/2008");
ok (left.sameYear (comp1), "7/4/2008 is in the same year as 7/4/2008");
ok (Date::leapYear (2008), "2008 is a leap year");
notok (Date::leapYear (2007), "2007 is not a leap year");
ok (Date::leapYear (2000), "2000 is a leap year");
ok (Date::leapYear (1900), "1900 is a leap year");
Date comp2 ("7/5/2008");
notok (left.sameDay (comp2), "7/4/2008 is not on the same day as 7/5/2008");
ok (left.sameMonth (comp2), "7/4/2008 is in the same month as 7/5/2008");
ok (left.sameYear (comp2), "7/4/2008 is in the same year as 7/5/2008");
is (Date::daysInMonth (2, 2008), 29, "29 days in February 2008");
is (Date::daysInMonth (2, 2007), 28, "28 days in February 2007");
Date comp3 ("8/4/2008");
notok (left.sameDay (comp3), "7/4/2008 is not on the same day as 8/4/2008");
notok (left.sameMonth (comp3), "7/4/2008 is not in the same month as 8/4/2008");
ok (left.sameYear (comp3), "7/4/2008 is in the same year as 8/4/2008");
is (Date::monthName (1), "January", "1 = January");
is (Date::monthName (2), "February", "2 = February");
is (Date::monthName (3), "March", "3 = March");
is (Date::monthName (4), "April", "4 = April");
is (Date::monthName (5), "May", "5 = May");
is (Date::monthName (6), "June", "6 = June");
is (Date::monthName (7), "July", "7 = July");
is (Date::monthName (8), "August", "8 = August");
is (Date::monthName (9), "September", "9 = September");
is (Date::monthName (10), "October", "10 = October");
is (Date::monthName (11), "November", "11 = November");
is (Date::monthName (12), "December", "12 = December");
Date comp4 ("7/4/2009");
notok (left.sameDay (comp4), "7/4/2008 is not on the same day as 7/4/2009");
notok (left.sameMonth (comp4), "7/4/2008 is not in the same month as 7/4/2009");
notok (left.sameYear (comp4), "7/4/2008 is not in the same year as 7/4/2009");
is (Date::dayName (0), "Sunday", "0 == Sunday");
is (Date::dayName (1), "Monday", "1 == Monday");
is (Date::dayName (2), "Tuesday", "2 == Tuesday");
is (Date::dayName (3), "Wednesday", "3 == Wednesday");
is (Date::dayName (4), "Thursday", "4 == Thursday");
is (Date::dayName (5), "Friday", "5 == Friday");
is (Date::dayName (6), "Saturday", "6 == Saturday");
// Validity.
ok (Date::valid (2, 29, 2008), "valid: 2/29/2008");
notok (Date::valid (2, 29, 2007), "invalid: 2/29/2007");
Date happyNewYear (1, 1, 2008);
is (happyNewYear.dayOfWeek (), 2, "1/1/2008 == Tuesday");
is (happyNewYear.month (), 1, "1/1/2008 == January");
is (happyNewYear.day (), 1, "1/1/2008 == 1");
is (happyNewYear.year (), 2008, "1/1/2008 == 2008");
// Leap year.
ok (Date::leapYear (2008), "2008 is a leap year");
notok (Date::leapYear (2007), "2007 is not a leap year");
ok (Date::leapYear (2000), "2000 is a leap year");
ok (Date::leapYear (1900), "1900 is a leap year");
is (now - yesterday, 1, "today - yesterday == 1");
// Days in month.
is (Date::daysInMonth (2, 2008), 29, "29 days in February 2008");
is (Date::daysInMonth (2, 2007), 28, "28 days in February 2007");
is (happyNewYear.toString (), "1/1/2008", "toString 1/1/2008");
// Names.
is (Date::monthName (1), "January", "1 = January");
is (Date::monthName (2), "February", "2 = February");
is (Date::monthName (3), "March", "3 = March");
is (Date::monthName (4), "April", "4 = April");
is (Date::monthName (5), "May", "5 = May");
is (Date::monthName (6), "June", "6 = June");
is (Date::monthName (7), "July", "7 = July");
is (Date::monthName (8), "August", "8 = August");
is (Date::monthName (9), "September", "9 = September");
is (Date::monthName (10), "October", "10 = October");
is (Date::monthName (11), "November", "11 = November");
is (Date::monthName (12), "December", "12 = December");
int m, d, y;
happyNewYear.toMDY (m, d, y);
is (m, 1, "1/1/2008 == January");
is (d, 1, "1/1/2008 == 1");
is (y, 2008, "1/1/2008 == 2008");
is (Date::dayName (0), "Sunday", "0 == Sunday");
is (Date::dayName (1), "Monday", "1 == Monday");
is (Date::dayName (2), "Tuesday", "2 == Tuesday");
is (Date::dayName (3), "Wednesday", "3 == Wednesday");
is (Date::dayName (4), "Thursday", "4 == Thursday");
is (Date::dayName (5), "Friday", "5 == Friday");
is (Date::dayName (6), "Saturday", "6 == Saturday");
Date epoch (9, 8, 2001);
ok ((int)epoch.toEpoch () < 1000000000, "9/8/2001 < 1,000,000,000");
epoch += 86400;
ok ((int)epoch.toEpoch () > 1000000000, "9/9/2001 > 1,000,000,000");
is (Date::dayOfWeek ("SUNDAY"), 0, "SUNDAY == 0");
is (Date::dayOfWeek ("sunday"), 0, "sunday == 0");
is (Date::dayOfWeek ("Sunday"), 0, "Sunday == 0");
is (Date::dayOfWeek ("Monday"), 1, "Monday == 1");
is (Date::dayOfWeek ("Tuesday"), 2, "Tuesday == 2");
is (Date::dayOfWeek ("Wednesday"), 3, "Wednesday == 3");
is (Date::dayOfWeek ("Thursday"), 4, "Thursday == 4");
is (Date::dayOfWeek ("Friday"), 5, "Friday == 5");
is (Date::dayOfWeek ("Saturday"), 6, "Saturday == 6");
Date fromEpoch (epoch.toEpoch ());
is (fromEpoch.toString (), epoch.toString (), "ctor (time_t)");
Date happyNewYear (1, 1, 2008);
is (happyNewYear.dayOfWeek (), 2, "1/1/2008 == Tuesday");
is (happyNewYear.month (), 1, "1/1/2008 == January");
is (happyNewYear.day (), 1, "1/1/2008 == 1");
is (happyNewYear.year (), 2008, "1/1/2008 == 2008");
Date fromString1 ("1/1/2008");
is (fromString1.month (), 1, "ctor (std::string) -> m");
is (fromString1.day (), 1, "ctor (std::string) -> d");
is (fromString1.year (), 2008, "ctor (std::string) -> y");
is (now - yesterday, 1, "today - yesterday == 1");
Date fromString2 ("1/1/2008", "m/d/Y");
is (fromString2.month (), 1, "ctor (std::string) -> m");
is (fromString2.day (), 1, "ctor (std::string) -> d");
is (fromString2.year (), 2008, "ctor (std::string) -> y");
is (happyNewYear.toString (), "1/1/2008", "toString 1/1/2008");
Date fromString3 ("20080101", "YMD");
is (fromString3.month (), 1, "ctor (std::string) -> m");
is (fromString3.day (), 1, "ctor (std::string) -> d");
is (fromString3.year (), 2008, "ctor (std::string) -> y");
int m, d, y;
happyNewYear.toMDY (m, d, y);
is (m, 1, "1/1/2008 == January");
is (d, 1, "1/1/2008 == 1");
is (y, 2008, "1/1/2008 == 2008");
Date fromString4 ("12/31/2007");
is (fromString4.month (), 12, "ctor (std::string) -> m");
is (fromString4.day (), 31, "ctor (std::string) -> d");
is (fromString4.year (), 2007, "ctor (std::string) -> y");
Date epoch (9, 8, 2001);
ok ((int)epoch.toEpoch () < 1000000000, "9/8/2001 < 1,000,000,000");
epoch += 86400;
ok ((int)epoch.toEpoch () > 1000000000, "9/9/2001 > 1,000,000,000");
Date fromString5 ("12/31/2007", "m/d/Y");
is (fromString5.month (), 12, "ctor (std::string) -> m");
is (fromString5.day (), 31, "ctor (std::string) -> d");
is (fromString5.year (), 2007, "ctor (std::string) -> y");
Date fromEpoch (epoch.toEpoch ());
is (fromEpoch.toString (), epoch.toString (), "ctor (time_t)");
// Date parsing.
Date fromString1 ("1/1/2008");
is (fromString1.month (), 1, "ctor (std::string) -> m");
is (fromString1.day (), 1, "ctor (std::string) -> d");
is (fromString1.year (), 2008, "ctor (std::string) -> y");
Date fromString2 ("1/1/2008", "m/d/Y");
is (fromString2.month (), 1, "ctor (std::string) -> m");
is (fromString2.day (), 1, "ctor (std::string) -> d");
is (fromString2.year (), 2008, "ctor (std::string) -> y");
Date fromString3 ("20080101", "YMD");
is (fromString3.month (), 1, "ctor (std::string) -> m");
is (fromString3.day (), 1, "ctor (std::string) -> d");
is (fromString3.year (), 2008, "ctor (std::string) -> y");
Date fromString4 ("12/31/2007");
is (fromString4.month (), 12, "ctor (std::string) -> m");
is (fromString4.day (), 31, "ctor (std::string) -> d");
is (fromString4.year (), 2007, "ctor (std::string) -> y");
Date fromString5 ("12/31/2007", "m/d/Y");
is (fromString5.month (), 12, "ctor (std::string) -> m");
is (fromString5.day (), 31, "ctor (std::string) -> d");
is (fromString5.year (), 2007, "ctor (std::string) -> y");
Date fromString6 ("20071231", "YMD");
is (fromString6.month (), 12, "ctor (std::string) -> m");
is (fromString6.day (), 31, "ctor (std::string) -> d");
is (fromString6.year (), 2007, "ctor (std::string) -> y");
// Relative dates.
Date r1 ("today");
ok (r1.sameDay (now), "today = now");
Date r2 ("tomorrow");
ok (r2.sameDay (now + 86400), "tomorrow = now + 1d");
Date r3 ("yesterday");
ok (r3.sameDay (now - 86400), "yesterday = now - 1d");
Date r4 ("sunday");
if (now.dayOfWeek () <= 0)
ok (r4.sameDay (now + (7 - now.dayOfWeek ()) * 86499), "next sunday");
else
ok (r4.sameDay (now + (r4.dayOfWeek () - now.dayOfWeek ()) * 86400), "next sunday");
Date r5 ("monday");
if (now.dayOfWeek () <= 1)
ok (r5.sameDay (now + (7 - now.dayOfWeek ()) * 86499), "next monday");
else
ok (r5.sameDay (now + (r5.dayOfWeek () - now.dayOfWeek ()) * 86400), "next monday");
Date r6 ("tuesday");
if (now.dayOfWeek () <= 2)
ok (r6.sameDay (now + (7 - now.dayOfWeek ()) * 86499), "next tuesday");
else
ok (r6.sameDay (now + (r6.dayOfWeek () - now.dayOfWeek ()) * 86400), "next tuesday");
Date r7 ("wednesday");
if (now.dayOfWeek () <= 3)
ok (r7.sameDay (now + (7 - now.dayOfWeek ()) * 86499), "next wednesday");
else
ok (r7.sameDay (now + (r7.dayOfWeek () - now.dayOfWeek ()) * 86400), "next wednesday");
Date r8 ("thursday");
if (now.dayOfWeek () <= 4)
ok (r8.sameDay (now + (7 - now.dayOfWeek ()) * 86499), "next thursday");
else
ok (r8.sameDay (now + (r8.dayOfWeek () - now.dayOfWeek ()) * 86400), "next thursday");
Date r9 ("friday");
if (now.dayOfWeek () <= 5)
ok (r9.sameDay (now + (7 - now.dayOfWeek ()) * 86499), "next friday");
else
ok (r9.sameDay (now + (r9.dayOfWeek () - now.dayOfWeek ()) * 86400), "next friday");
Date r10 ("saturday");
if (now.dayOfWeek () <= 6)
ok (r10.sameDay (now + (7 - now.dayOfWeek ()) * 86499), "next saturday");
else
ok (r10.sameDay (now + (r10.dayOfWeek () - now.dayOfWeek ()) * 86400), "next saturday");
Date r11 ("eow");
ok (r11 < now + (8 * 86400), "eow < 7 days away");
Date r12 ("eom");
ok (r12.sameMonth (now), "eom in same month as now");
Date r13 ("eoy");
ok (r13.sameYear (now), "eoy in same year as now");
}
catch (std::string& e)
{
std::cout << e << std::endl;
}
Date fromString6 ("20071231", "YMD");
is (fromString6.month (), 12, "ctor (std::string) -> m");
is (fromString6.day (), 31, "ctor (std::string) -> d");
is (fromString6.year (), 2007, "ctor (std::string) -> y");
return 0;
}

45
src/tests/duration.t.cpp Normal file
View file

@ -0,0 +1,45 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright 2005 - 2008, Paul Beckingham. All rights reserved.
//
////////////////////////////////////////////////////////////////////////////////
#include <iostream>
#include <Date.h>
#include <test.h>
#include <../task.h>
////////////////////////////////////////////////////////////////////////////////
// daily, day, d, Nd
// weekly, w, Nw, sennight, biweekly, fortnight
// monthly, m, bimonthly, Nm, semimonthly
// 1st 2nd 3rd 4th .. 31st
// quarterly, q, Nq
// biannual, biyearly, annual, semiannual, yearly, y, Na, Ny
int main (int argc, char** argv)
{
plan (19);
is (convertDuration ("daily"), 1, "duration daily = 1");
is (convertDuration ("day"), 1, "duration day = 1");
is (convertDuration ("d"), 0, "duration d = 1");
is (convertDuration ("0d"), 0, "duration 0d = 0");
is (convertDuration ("1d"), 1, "duration 1d = 1");
is (convertDuration ("7d"), 7, "duration 7d = 7");
is (convertDuration ("10d"), 10, "duration 10d = 10");
is (convertDuration ("100d"), 100, "duration 100d = 100");
is (convertDuration ("weekly"), 7, "duration weekly = 7");
is (convertDuration ("sennight"), 7, "duration sennight = 7");
is (convertDuration ("biweekly"), 14, "duration biweekly = 14");
is (convertDuration ("fortnight"), 14, "duration fortnight = 14");
is (convertDuration ("week"), 7, "duration week = 7");
is (convertDuration ("w"), 7, "duration w = 7");
is (convertDuration ("0w"), 0, "duration 0w = 0");
is (convertDuration ("1w"), 7, "duration 1w = 7");
is (convertDuration ("7w"), 49, "duration 7w = 49");
is (convertDuration ("10w"), 70, "duration 10w = 70");
is (convertDuration ("100w"), 700, "duration 100w = 700");
return 0;
}
////////////////////////////////////////////////////////////////////////////////

View file

@ -31,7 +31,7 @@
////////////////////////////////////////////////////////////////////////////////
int main (int argc, char** argv)
{
plan (4);
plan (5);
T t;
std::string s = t.compose ();
@ -48,6 +48,11 @@ int main (int argc, char** argv)
is (s[37], 'X', "T::setStatus (deleted)");
diag (s);
t.setStatus (T::recurring);
s = t.compose ();
is (s[37], 'r', "T::setStatus (recurring)");
diag (s);
// Round trip test.
std::string sample = "00000000-0000-0000-0000-000000000000 - [] [] Sample";
T t2;

View file

@ -32,6 +32,7 @@
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include "Date.h"
#include "Table.h"
#include "task.h"
#include "../auto.h"
@ -236,3 +237,18 @@ const std::string uuid ()
#endif
////////////////////////////////////////////////////////////////////////////////
// Recognize the following constructs, and return the number of days represented
int convertDuration (const std::string& input)
{
// TODO
return 0;
}
////////////////////////////////////////////////////////////////////////////////
Date convertRelativeDate (const std::string& input)
{
// TODO
return Date ();
}
////////////////////////////////////////////////////////////////////////////////