Thursday, September 29, 2011 Replicating Jira's time tracking functionality in ColdFusion
I've been working on a project where I wanted to replicate the time tracking functionality used in Jira. Jira allows you to enter a time period in the format of "4d 12h 30m" (4 days, 12 hours and 30 minutes) which, behind the scenes, is converted to seconds and stored in a database. For the purpose of my application I also need to take into account the number of working hours per day.
I've created two functions (shown below), one to convert the time period string to seconds and another to convert the value back again.
You can test the two functions using the following code.
Tags
Share
Comments
Thursday, September 29, 2011 Jeff Coughlin
That's pretty cool. Have you submitted it to cflib.org?
Thursday, September 29, 2011 Simon Bingham
Hi Jeff. Yes, that's a good idea. Have submitted the code. :)
Sunday, October 2, 2011 Sohail Somani
Interesting post! Here's the code I use for my app (Worklog Assistant). Warning: it's in C++/Qt
// To JIRA format (1h 20m [30s]), days/weeks ignored because it's not easy to know hours/day days/week
ssci::secondsElapsedToJIRATimeString(int seconds_elapsed, bool include_seconds)
{
time_t t(seconds_elapsed);
tm * ptm = gmtime(&t);
int minutes = ptm->tm_min;
int total_hours = ptm->tm_hour + ptm->tm_yday * 24;
int seconds = ptm->tm_sec;
if(!include_seconds)
{
if(total_hours == 0)
return QString::fromLatin1("%1m").arg(minutes);
else if(minutes == 0)
return QString::fromLatin1("%1h").arg(total_hours);
else
return QString::fromLatin1("%1h %2m").arg(total_hours).arg(minutes);
}
else
return QString::fromLatin1("%1h %2m %3s").arg(total_hours).arg(minutes).arg(seconds);
}
// From JIRA string to seconds elapsed. I was fooling around with Boost Spirit :)
int
ssci::jiraTimeStringToSecondsElapsed(QString const & s)
{
using namespace boost::spirit::classic;
using namespace phoenix;
float
hours = 0,
p_hours = 0;
unsigned int
minutes = 0,
p_minutes = 0;
rule<> hours_p =
ureal_p[assign_a(p_hours)] >> *space_p >> ch_p('h')
;
rule <> minutes_p =
uint_p[assign_a(p_minutes)] >> *space_p >> ch_p('m')
;
rule <> timestring_p =
(hours_p >> *space_p >> minutes_p)[var(hours) = var(p_hours)][var(minutes) = var(p_minutes)]
| hours_p[var(hours) = var(p_hours)]
| minutes_p[var(minutes) = var(p_minutes)]
;
std::string str = s.toStdString();
SSCI_ASSERT_1((parse(str.c_str(),
timestring_p,
space_p).full),
QObject::tr("Cannot parse JIRA time string. \n"
"Valid strings are: \n"
" - 1.5h\n"
" - 1h 5m\n"
" - 50m"));
if(minutes != 0)
{
SSCI_ASSERT_1( std::floor(hours) == hours,
QObject::tr("Cannot have both fractional hours and minutes"));
}
return int(hours * 60 * 60 +
minutes * 60);
}