Date Formatting

- Some bad inefficiencies in date formatting were noticed, and when addressed,
  caused a bug to surface.  The length of a formatted date can be calculated
  from the dateformat, but was done incorrectly.  Very, very incorrectly.
- Added unit tests.
- Promoted date column-specific "countdown" size measurements up to the ColDate
  base class.  This neatly falls out from work on #1218.
- Noted a potential I18N problem in Date.cpp.
This commit is contained in:
Paul Beckingham 2013-04-01 19:49:27 -04:00
parent d895c4a249
commit 656e350291
8 changed files with 79 additions and 122 deletions

View file

@ -95,7 +95,13 @@ void ColumnDate::measure (Task& task, unsigned int& minimum, unsigned int& maxim
if (format == "")
format = context.config.get ("dateformat");
minimum = maximum = date.toString (format).length ();
minimum = maximum = Date::length (format);
}
else if (_style == "countdown")
{
Date date ((time_t) strtol (task.get (_name).c_str (), NULL, 10));
Date now;
minimum = maximum = Duration (now - date).format ().length ();
}
else if (_style == "julian")
{
@ -134,7 +140,7 @@ void ColumnDate::render (
// Determine the output date format, which uses a hierarchy of definitions.
// rc.report.<report>.dateformat
// rc.dateformat.report
// rc.dateformat.
// rc.dateformat
std::string format = context.config.get ("report." + _report + ".dateformat");
if (format == "")
format = context.config.get ("dateformat.report");
@ -147,6 +153,16 @@ void ColumnDate::render (
Date ((time_t) strtol (task.get (_name).c_str (), NULL, 10))
.toString (format), width)));
}
else if (_style == "countdown")
{
Date date ((time_t) strtol (task.get (_name).c_str (), NULL, 10));
Date now;
lines.push_back (
color.colorize (
rightJustify (
Duration (now - date).format (), width)));
}
else if (_style == "julian")
{
lines.push_back (

View file

@ -73,46 +73,3 @@ void ColumnDue::setStyle (const std::string& value)
}
////////////////////////////////////////////////////////////////////////////////
// Set the minimum and maximum widths for the value.
void ColumnDue::measure (Task& task, unsigned int& minimum, unsigned int& maximum)
{
minimum = maximum = 0;
if (task.has (_name))
{
if (_style == "countdown")
{
Date date ((time_t) strtol (task.get (_name).c_str (), NULL, 10));
Date now;
minimum = maximum = Duration (now - date).format ().length ();
}
else
ColumnDate::measure (task, minimum, maximum);
}
}
////////////////////////////////////////////////////////////////////////////////
void ColumnDue::render (
std::vector <std::string>& lines,
Task& task,
int width,
Color& color)
{
if (task.has (_name))
{
if (_style == "countdown")
{
Date date ((time_t) strtol (task.get (_name).c_str (), NULL, 10));
Date now;
lines.push_back (
color.colorize (
rightJustify (
Duration (now - date).format (), width)));
}
else
ColumnDate::render (lines, task, width, color);
}
}
////////////////////////////////////////////////////////////////////////////////

View file

@ -39,8 +39,6 @@ public:
bool validate (std::string&);
void setStyle (const std::string&);
void measure (Task&, unsigned int&, unsigned int&);
void render (std::vector <std::string>&, Task&, int, Color&);
};
#endif

View file

@ -73,46 +73,3 @@ void ColumnScheduled::setStyle (const std::string& value)
}
////////////////////////////////////////////////////////////////////////////////
// Set the minimum and maximum widths for the value.
void ColumnScheduled::measure (Task& task, unsigned int& minimum, unsigned int& maximum)
{
minimum = maximum = 0;
if (task.has (_name))
{
if (_style == "countdown")
{
Date date ((time_t) strtol (task.get (_name).c_str (), NULL, 10));
Date now;
minimum = maximum = Duration (now - date).format ().length ();
}
else
ColumnDate::measure (task, minimum, maximum);
}
}
////////////////////////////////////////////////////////////////////////////////
void ColumnScheduled::render (
std::vector <std::string>& lines,
Task& task,
int width,
Color& color)
{
if (task.has (_name))
{
if (_style == "countdown")
{
Date date ((time_t) strtol (task.get (_name).c_str (), NULL, 10));
Date now;
lines.push_back (
color.colorize (
rightJustify (
Duration (now - date).format (), width)));
}
else
ColumnDate::render (lines, task, width, color);
}
}
////////////////////////////////////////////////////////////////////////////////

View file

@ -39,8 +39,6 @@ public:
bool validate (std::string&);
void setStyle (const std::string&);
void measure (Task&, unsigned int&, unsigned int&);
void render (std::vector <std::string>&, Task&, int, Color&);
};
#endif

View file

@ -92,7 +92,7 @@ void ColumnUDA::measure (Task& task, unsigned int& minimum, unsigned int& maximu
// Determine the output date format, which uses a hierarchy of definitions.
// rc.report.<report>.dateformat
// rc.dateformat.report
// rc.dateformat.
// rc.dateformat
Date date ((time_t) strtol (value.c_str (), NULL, 10));
std::string format = context.config.get ("report." + _report + ".dateformat");
if (format == "")
@ -100,7 +100,7 @@ void ColumnUDA::measure (Task& task, unsigned int& minimum, unsigned int& maximu
if (format == "")
format = context.config.get ("dateformat");
minimum = maximum = utf8_width (date.toString (format));
minimum = maximum = Date::length (format);
}
else if (_type == "duration")
{