- Added the ability to control date formats via the 'dateformat' configuration variable.
This commit is contained in:
71
src/Date.cpp
71
src/Date.cpp
@@ -116,20 +116,77 @@ void Date::toMDY (int& m, int& d, int& y)
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void Date::toString (std::string& output)
|
||||
{
|
||||
output = toString ();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
std::string Date::toString (void)
|
||||
std::string Date::toString (const std::string& format /*= "m/d/Y"*/)
|
||||
{
|
||||
/*
|
||||
int m, d, y;
|
||||
toMDY (m, d, y);
|
||||
|
||||
char formatted [11];
|
||||
sprintf (formatted, "%d/%d/%d", m, d, y);
|
||||
return std::string (formatted);
|
||||
*/
|
||||
|
||||
std::string formatted;
|
||||
for (unsigned int i = 0; i < format.length (); ++i)
|
||||
{
|
||||
switch (format[i])
|
||||
{
|
||||
case 'm':
|
||||
{
|
||||
char m[3];
|
||||
sprintf (m, "%d", this->month ());
|
||||
formatted += m;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'M':
|
||||
{
|
||||
char m[3];
|
||||
sprintf (m, "%02d", this->month ());
|
||||
formatted += m;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
{
|
||||
char d[3];
|
||||
sprintf (d, "%d", this->day ());
|
||||
formatted += d;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'D':
|
||||
{
|
||||
char d[3];
|
||||
sprintf (d, "%02d", this->day ());
|
||||
formatted += d;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'y':
|
||||
{
|
||||
char y[3];
|
||||
sprintf (y, "%02d", this->year () % 100);
|
||||
formatted += y;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'Y':
|
||||
{
|
||||
char y[5];
|
||||
sprintf (y, "%d", this->year ());
|
||||
formatted += y;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
formatted += format[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return formatted;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -44,8 +44,7 @@ public:
|
||||
void toEpoch (time_t&);
|
||||
time_t toEpoch ();
|
||||
void toMDY (int&, int&, int&);
|
||||
void toString (std::string&);
|
||||
std::string toString (void);
|
||||
std::string toString (const std::string& format = "m/d/Y");
|
||||
static bool valid (const int, const int, const int);
|
||||
|
||||
static bool leapYear (int);
|
||||
|
||||
84
src/task.cpp
84
src/task.cpp
@@ -285,22 +285,6 @@ int main (int argc, char** argv)
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
std::string epochToString (const std::string& epoch)
|
||||
{
|
||||
char formatted[12] = {0};
|
||||
|
||||
if (epoch.length () && epoch.find ("/") == std::string::npos)
|
||||
{
|
||||
Date dt (::atoi (epoch.c_str ()));
|
||||
int m, d, y;
|
||||
dt.toMDY (m, d, y);
|
||||
sprintf (formatted, "%d/%d/%04d", m, d, y);
|
||||
}
|
||||
|
||||
return formatted;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void handleAdd (const TDB& tdb, T& task, Config& conf)
|
||||
{
|
||||
@@ -507,11 +491,7 @@ void handleList (const TDB& tdb, T& task, Config& conf)
|
||||
if (due.length () && due.find ("/") == std::string::npos)
|
||||
{
|
||||
Date dt (::atoi (due.c_str ()));
|
||||
int m, d, y;
|
||||
dt.toMDY (m, d, y);
|
||||
char formatted[12];
|
||||
sprintf (formatted, "%d/%d/%04d", m, d, y);
|
||||
due = formatted;
|
||||
due = dt.toString (conf.get ("dateformat", "m/d/Y"));
|
||||
|
||||
overdue = (dt < now) ? true : false;
|
||||
now += 7 * 86400;
|
||||
@@ -671,11 +651,7 @@ void handleSmallList (const TDB& tdb, T& task, Config& conf)
|
||||
if (due.length () && due.find ("/") == std::string::npos)
|
||||
{
|
||||
Date dt (::atoi (due.c_str ()));
|
||||
int m, d, y;
|
||||
dt.toMDY (m, d, y);
|
||||
char formatted[12];
|
||||
sprintf (formatted, "%d/%d/%04d", m, d, y);
|
||||
due = formatted;
|
||||
due = dt.toString (conf.get ("dateformat", "m/d/Y"));
|
||||
|
||||
overdue = (dt < now) ? true : false;
|
||||
now += 7 * 86400;
|
||||
@@ -826,7 +802,7 @@ void handleCompleted (const TDB& tdb, T& task, Config& conf)
|
||||
// All criteria match, so add refTask to the output table.
|
||||
int row = table.addRow ();
|
||||
|
||||
table.addCell (row, 0, end.toString ());
|
||||
table.addCell (row, 0, end.toString (conf.get ("dateformat", "m/d/Y")));
|
||||
table.addCell (row, 1, refTask.getAttribute ("project"));
|
||||
table.addCell (row, 2, refTask.getDescription ());
|
||||
|
||||
@@ -935,7 +911,10 @@ void handleInfo (const TDB& tdb, T& task, Config& conf)
|
||||
{
|
||||
row = table.addRow ();
|
||||
table.addCell (row, 0, "Due");
|
||||
table.addCell (row, 1, epochToString (due));
|
||||
|
||||
Date dt (::atoi (due.c_str ()));
|
||||
due = dt.toString (conf.get ("dateformat", "m/d/Y"));
|
||||
table.addCell (row, 1, due);
|
||||
|
||||
if (due.length () && due.find ("/") == std::string::npos)
|
||||
{
|
||||
@@ -960,7 +939,8 @@ void handleInfo (const TDB& tdb, T& task, Config& conf)
|
||||
{
|
||||
row = table.addRow ();
|
||||
table.addCell (row, 0, "Start");
|
||||
table.addCell (row, 1, epochToString (refTask.getAttribute ("start")));
|
||||
Date dt (::atoi (refTask.getAttribute ("start").c_str ()));
|
||||
table.addCell (row, 1, dt.toString (conf.get ("dateformat", "m/d/Y")));
|
||||
}
|
||||
|
||||
// end
|
||||
@@ -968,7 +948,8 @@ void handleInfo (const TDB& tdb, T& task, Config& conf)
|
||||
{
|
||||
row = table.addRow ();
|
||||
table.addCell (row, 0, "End");
|
||||
table.addCell (row, 1, epochToString (refTask.getAttribute ("end")));
|
||||
Date dt (::atoi (refTask.getAttribute ("end").c_str ()));
|
||||
table.addCell (row, 1, dt.toString (conf.get ("dateformat", "m/d/Y")));
|
||||
}
|
||||
|
||||
// tags ...
|
||||
@@ -990,7 +971,8 @@ void handleInfo (const TDB& tdb, T& task, Config& conf)
|
||||
|
||||
row = table.addRow ();
|
||||
table.addCell (row, 0, "Entered");
|
||||
std::string entry = epochToString (refTask.getAttribute ("entry"));
|
||||
Date dt (::atoi (refTask.getAttribute ("entry").c_str ()));
|
||||
std::string entry = dt.toString (conf.get ("dateformat", "m/d/Y"));
|
||||
|
||||
std::string age;
|
||||
std::string created = refTask.getAttribute ("entry");
|
||||
@@ -1126,22 +1108,14 @@ void handleLongList (const TDB& tdb, T& task, Config& conf)
|
||||
if (started.length () && started.find ("/") == std::string::npos)
|
||||
{
|
||||
Date dt (::atoi (started.c_str ()));
|
||||
int m, d, y;
|
||||
dt.toMDY (m, d, y);
|
||||
char formatted[12];
|
||||
sprintf (formatted, "%d/%d/%04d", m, d, y);
|
||||
started = formatted;
|
||||
started = dt.toString (conf.get ("dateformat", "m/d/Y"));
|
||||
}
|
||||
|
||||
std::string entered = refTask.getAttribute ("entry");
|
||||
if (entered.length () && entered.find ("/") == std::string::npos)
|
||||
{
|
||||
Date dt (::atoi (entered.c_str ()));
|
||||
int m, d, y;
|
||||
dt.toMDY (m, d, y);
|
||||
char formatted[12];
|
||||
sprintf (formatted, "%d/%d/%04d", m, d, y);
|
||||
entered = formatted;
|
||||
entered = dt.toString (conf.get ("dateformat", "m/d/Y"));
|
||||
}
|
||||
|
||||
// Now format the matching task.
|
||||
@@ -1151,11 +1125,7 @@ void handleLongList (const TDB& tdb, T& task, Config& conf)
|
||||
if (due.length () && due.find ("/") == std::string::npos)
|
||||
{
|
||||
Date dt (::atoi (due.c_str ()));
|
||||
int m, d, y;
|
||||
dt.toMDY (m, d, y);
|
||||
char formatted[12];
|
||||
sprintf (formatted, "%d/%d/%04d", m, d, y);
|
||||
due = formatted;
|
||||
due = dt.toString (conf.get ("dateformat", "m/d/Y"));
|
||||
|
||||
overdue = (dt < now) ? true : false;
|
||||
now += 7 * 86400;
|
||||
@@ -1491,11 +1461,7 @@ void handleReportNext (const TDB& tdb, T& task, Config& conf)
|
||||
if (due.length () && due.find ("/") == std::string::npos)
|
||||
{
|
||||
Date dt (::atoi (due.c_str ()));
|
||||
int m, d, y;
|
||||
dt.toMDY (m, d, y);
|
||||
char formatted[12];
|
||||
sprintf (formatted, "%d/%d/%04d", m, d, y);
|
||||
due = formatted;
|
||||
due = dt.toString (conf.get ("dateformat", "m/d/Y"));
|
||||
|
||||
overdue = (dt < now) ? true : false;
|
||||
now += 7 * 86400;
|
||||
@@ -2007,11 +1973,7 @@ void handleReportActive (const TDB& tdb, T& task, Config& conf)
|
||||
if (due.length () && due.find ("/") == std::string::npos)
|
||||
{
|
||||
Date dt (::atoi (due.c_str ()));
|
||||
int m, d, y;
|
||||
dt.toMDY (m, d, y);
|
||||
char formatted[12];
|
||||
sprintf (formatted, "%d/%d/%04d", m, d, y);
|
||||
due = formatted;
|
||||
due = dt.toString (conf.get ("dateformat", "m/d/Y"));
|
||||
|
||||
Date now;
|
||||
overdue = dt < now ? true : false;
|
||||
@@ -2129,11 +2091,7 @@ void handleReportOverdue (const TDB& tdb, T& task, Config& conf)
|
||||
if (due.length () && due.find ("/") == std::string::npos)
|
||||
{
|
||||
Date dt (::atoi (due.c_str ()));
|
||||
int m, d, y;
|
||||
dt.toMDY (m, d, y);
|
||||
char formatted[12];
|
||||
sprintf (formatted, "%d/%d/%04d", m, d, y);
|
||||
due = formatted;
|
||||
due = dt.toString (conf.get ("dateformat", "m/d/Y"));
|
||||
|
||||
// If overdue.
|
||||
if (dt < now)
|
||||
@@ -2227,9 +2185,9 @@ void handleReportStats (const TDB& tdb, T& task, Config& conf)
|
||||
if (tasks.size ())
|
||||
{
|
||||
Date e (earliest);
|
||||
std::cout << "Oldest task " << e.toString () << std::endl;
|
||||
std::cout << "Oldest task " << e.toString (conf.get ("dateformat", "m/d/Y")) << std::endl;
|
||||
Date l (latest);
|
||||
std::cout << "Newest task " << l.toString () << std::endl;
|
||||
std::cout << "Newest task " << l.toString (conf.get ("dateformat", "m/d/Y")) << std::endl;
|
||||
std::cout << "Task used for " << formatSeconds (latest - earliest) << std::endl;
|
||||
}
|
||||
|
||||
|
||||
87
src/tests/date.t.cpp
Normal file
87
src/tests/date.t.cpp
Normal file
@@ -0,0 +1,87 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright 2005 - 2008, Paul Beckingham. All rights reserved.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#include <iostream>
|
||||
#include <Date.h>
|
||||
#include <test.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
int main (int argc, char** argv)
|
||||
{
|
||||
UnitTest t (46);
|
||||
|
||||
Date now;
|
||||
Date yesterday;
|
||||
yesterday -= 1;
|
||||
|
||||
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 (Date::valid (2, 29, 2008), "valid: 2/29/2008");
|
||||
t.notok (Date::valid (2, 29, 2007), "invalid: 2/29/2007");
|
||||
|
||||
t.ok (Date::leapYear (2008), "2008 is a leap year");
|
||||
t.notok (Date::leapYear (2007), "2007 is not a leap year");
|
||||
|
||||
t.is (Date::daysInMonth (2, 2008), 29, "29 days in February 2008");
|
||||
t.is (Date::daysInMonth (2, 2007), 28, "28 days in February 2007");
|
||||
|
||||
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");
|
||||
|
||||
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 (now - yesterday, 1, "today - yesterday == 1");
|
||||
|
||||
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 += 86400;
|
||||
t.ok ((int)epoch.toEpoch () > 1000000000, "9/9/2001 > 1,000,000,000");
|
||||
|
||||
Date fromEpoch (epoch.toEpoch ());
|
||||
t.is (fromEpoch.toString (), epoch.toString (), "ctor (time_t)");
|
||||
|
||||
Date fromString ("1/1/2008");
|
||||
t.is (fromString.month (), 1, "ctor (std::string) -> m");
|
||||
t.is (fromString.day (), 1, "ctor (std::string) -> d");
|
||||
t.is (fromString.year (), 2008, "ctor (std::string) -> y");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
Reference in New Issue
Block a user