mirror of
https://github.com/GothenburgBitFactory/timewarrior.git
synced 2025-06-26 10:54:28 +02:00
Exclusion: Added range expansion for weekday exclusions
This commit is contained in:
parent
72b8f39848
commit
6e70c49c7f
2 changed files with 122 additions and 3 deletions
|
@ -27,6 +27,7 @@
|
|||
#include <cmake.h>
|
||||
#include <Exclusion.h>
|
||||
#include <Datetime.h>
|
||||
#include <Pig.h>
|
||||
#include <shared.h>
|
||||
#include <format.h>
|
||||
|
||||
|
@ -86,12 +87,16 @@ std::vector <std::string> Exclusion::tokens () const
|
|||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Within range, yield a collection of recurring ranges as defined by _tokens.
|
||||
// exc monday <block> [<block> ...]
|
||||
// exc day on <date>
|
||||
// exc day off <date>
|
||||
//
|
||||
// exc monday <block> [<block> ...] --> yields a day range for every monday,
|
||||
// and every block within
|
||||
// exc day on <date> --> yields single day range
|
||||
// exc day off <date> --> yields single day range
|
||||
//
|
||||
std::vector <Daterange> Exclusion::ranges (const Daterange& range) const
|
||||
{
|
||||
std::vector <Daterange> results;
|
||||
int dayOfWeek;
|
||||
|
||||
if (_tokens[1] == "day" &&
|
||||
(_tokens[2] == "on" ||
|
||||
|
@ -105,6 +110,26 @@ std::vector <Daterange> Exclusion::ranges (const Daterange& range) const
|
|||
results.push_back (day);
|
||||
}
|
||||
|
||||
else if ((dayOfWeek = Datetime::dayOfWeek (_tokens[1])) != -1)
|
||||
{
|
||||
Datetime start = range.start ();
|
||||
while (start < range.end ())
|
||||
{
|
||||
if (start.dayOfWeek () == dayOfWeek)
|
||||
{
|
||||
Datetime end = start;
|
||||
++end;
|
||||
|
||||
// Now that 'start' and 'end' respresent the correct day, compose a set
|
||||
// of Daterange objects for each time block.
|
||||
for (unsigned int b = 2; b < _tokens.size (); ++b)
|
||||
results.push_back (daterangeFromTimeBlock (_tokens[b], start, end));
|
||||
}
|
||||
|
||||
++start;
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
|
@ -127,3 +152,94 @@ std::string Exclusion::dump () const
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
Daterange Exclusion::daterangeFromTimeBlock (
|
||||
const std::string& block,
|
||||
const Datetime& start,
|
||||
const Datetime& end) const
|
||||
{
|
||||
Pig pig (block);
|
||||
|
||||
if (pig.skip ('<'))
|
||||
{
|
||||
int hh;
|
||||
int mm;
|
||||
if ((pig.getDigit2 (hh) ||
|
||||
pig.getDigit (hh)) &&
|
||||
pig.skip (':') &&
|
||||
pig.getDigit2 (mm))
|
||||
{
|
||||
int ss {0};
|
||||
if (pig.skip (':') &&
|
||||
pig.getDigit2 (ss))
|
||||
{
|
||||
// That's nice.
|
||||
}
|
||||
|
||||
return Daterange (start, Datetime (start.month (), start.day (), start.year (), hh, mm, ss));
|
||||
}
|
||||
|
||||
throw format ("Malformed time block '{1}'.", block);
|
||||
}
|
||||
else if (pig.skip ('>'))
|
||||
{
|
||||
int hh;
|
||||
int mm;
|
||||
if ((pig.getDigit2 (hh) ||
|
||||
pig.getDigit (hh)) &&
|
||||
pig.skip (':') &&
|
||||
pig.getDigit2 (mm))
|
||||
{
|
||||
int ss {0};
|
||||
if (pig.skip (':') &&
|
||||
pig.getDigit2 (ss))
|
||||
{
|
||||
// That's nice.
|
||||
}
|
||||
|
||||
return Daterange (Datetime (start.month (), start.day (), start.year (), hh, mm, ss), end);
|
||||
}
|
||||
|
||||
throw format ("Malformed time block '{1}'.", block);
|
||||
}
|
||||
|
||||
int hh1;
|
||||
int mm1;
|
||||
if ((pig.getDigit2 (hh1) ||
|
||||
pig.getDigit (hh1)) &&
|
||||
pig.skip (':') &&
|
||||
pig.getDigit2 (mm1))
|
||||
{
|
||||
int ss1 {0};
|
||||
if (pig.skip (':') &&
|
||||
pig.getDigit2 (ss1))
|
||||
{
|
||||
// That's nice.
|
||||
}
|
||||
|
||||
if (pig.skip ('-'))
|
||||
{
|
||||
int hh2;
|
||||
int mm2;
|
||||
if ((pig.getDigit2 (hh2) ||
|
||||
pig.getDigit (hh2)) &&
|
||||
pig.skip (':') &&
|
||||
pig.getDigit2 (mm2))
|
||||
{
|
||||
int ss2 {0};
|
||||
if (pig.skip (':') &&
|
||||
pig.getDigit2 (ss2))
|
||||
{
|
||||
// That's nice.
|
||||
}
|
||||
|
||||
return Daterange (
|
||||
Datetime (start.month (), start.day (), start.year (), hh1, mm1, ss1),
|
||||
Datetime (start.month (), start.day (), start.year (), hh2, mm2, ss2));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
throw format ("Malformed time block '{1}'.", block);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -44,6 +44,9 @@ public:
|
|||
std::string serialize () const;
|
||||
std::string dump () const;
|
||||
|
||||
private:
|
||||
Daterange daterangeFromTimeBlock (const std::string&, const Datetime&, const Datetime&) const;
|
||||
|
||||
private:
|
||||
std::vector <std::string> _tokens {};
|
||||
bool _additive {false};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue