ISO8601: Implemented ISO8601p::formatVague for short-form, rounded values

This commit is contained in:
Paul Beckingham 2015-08-12 16:22:13 -04:00
parent 565232eccd
commit 35b52c421b
3 changed files with 156 additions and 135 deletions

View file

@ -831,6 +831,24 @@ const std::string ISO8601p::format () const
} }
} }
////////////////////////////////////////////////////////////////////////////////
const std::string ISO8601p::formatVague () const
{
char formatted[24];
float days = (float) _value / 86400.0;
if (_value >= 86400 * 365) sprintf (formatted, "%.1fy", (days / 365.0));
else if (_value >= 86400 * 84) sprintf (formatted, "%1dmo", (int) (days / 30));
else if (_value >= 86400 * 13) sprintf (formatted, "%dw", (int) (float) (days / 7.0));
else if (_value >= 86400) sprintf (formatted, "%dd", (int) days);
else if (_value >= 3600) sprintf (formatted, "%dh", (int) (_value / 3600));
else if (_value >= 60) sprintf (formatted, "%dmin", (int) (_value / 60));
else if (_value >= 1) sprintf (formatted, "%ds", (int) _value);
else formatted[0] = '\0';
return std::string (formatted);
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// 'P' [nn 'Y'] [nn 'M'] [nn 'D'] ['T' [nn 'H'] [nn 'M'] [nn 'S']] // 'P' [nn 'Y'] [nn 'M'] [nn 'D'] ['T' [nn 'H'] [nn 'M'] [nn 'S']]
bool ISO8601p::parse_designated (Nibbler& n) bool ISO8601p::parse_designated (Nibbler& n)

View file

@ -83,6 +83,7 @@ public:
bool parse (const std::string&, std::string::size_type&); bool parse (const std::string&, std::string::size_type&);
void clear (); void clear ();
const std::string format () const; const std::string format () const;
const std::string formatVague () const;
private: private:
bool parse_designated (Nibbler&); bool parse_designated (Nibbler&);

View file

@ -45,7 +45,8 @@ void testParse (
int in_minutes, int in_minutes,
int in_seconds, int in_seconds,
time_t in_value, time_t in_value,
const std::string& output) const std::string& output,
const std::string& vague)
{ {
std::string label = std::string ("parse (\"") + input + "\") --> "; std::string label = std::string ("parse (\"") + input + "\") --> ";
@ -62,12 +63,13 @@ void testParse (
t.is (iso._seconds, in_seconds, label + "_seconds"); t.is (iso._seconds, in_seconds, label + "_seconds");
t.is ((size_t) iso._value, (size_t) in_value, label + "_value"); t.is ((size_t) iso._value, (size_t) in_value, label + "_value");
t.is (iso.format (), output, label + " format"); t.is (iso.format (), output, label + " format");
t.is (iso.formatVague (), vague, label + " formatVague");
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
int main (int argc, char** argv) int main (int argc, char** argv)
{ {
UnitTest t (1355); UnitTest t (1487);
ISO8601p iso; ISO8601p iso;
std::string::size_type start = 0; std::string::size_type start = 0;
@ -96,171 +98,171 @@ int main (int argc, char** argv)
int m = 60; int m = 60;
// Designated. // Designated.
// input i Year Mo Da Ho Mi Se time_t format // input i Year Mo Da Ho Mi Se time_t format vague
testParse (t, "P1Y", 3, 1, 0, 0, 0, 0, 0, year, "P365D"); testParse (t, "P1Y", 3, 1, 0, 0, 0, 0, 0, year, "P365D", "1.0y");
testParse (t, "P1M", 3, 0, 1, 0, 0, 0, 0, month, "P30D"); testParse (t, "P1M", 3, 0, 1, 0, 0, 0, 0, month, "P30D", "4w");
testParse (t, "P1D", 3, 0, 0, 1, 0, 0, 0, day, "P1D"); testParse (t, "P1D", 3, 0, 0, 1, 0, 0, 0, day, "P1D", "1d");
testParse (t, "P1Y1M", 5, 1, 1, 0, 0, 0, 0, year + month, "P395D"); testParse (t, "P1Y1M", 5, 1, 1, 0, 0, 0, 0, year + month, "P395D", "1.1y");
testParse (t, "P1Y1D", 5, 1, 0, 1, 0, 0, 0, year + day, "P366D"); testParse (t, "P1Y1D", 5, 1, 0, 1, 0, 0, 0, year + day, "P366D", "1.0y");
testParse (t, "P1M1D", 5, 0, 1, 1, 0, 0, 0, month + day, "P31D"); testParse (t, "P1M1D", 5, 0, 1, 1, 0, 0, 0, month + day, "P31D", "4w");
testParse (t, "P1Y1M1D", 7, 1, 1, 1, 0, 0, 0, year + month + day, "P396D"); testParse (t, "P1Y1M1D", 7, 1, 1, 1, 0, 0, 0, year + month + day, "P396D", "1.1y");
testParse (t, "PT1H", 4, 0, 0, 0, 1, 0, 0, h, "PT1H"); testParse (t, "PT1H", 4, 0, 0, 0, 1, 0, 0, h, "PT1H", "1h");
testParse (t, "PT1M", 4, 0, 0, 0, 0, 1, 0, m, "PT1M"); testParse (t, "PT1M", 4, 0, 0, 0, 0, 1, 0, m, "PT1M", "1min");
testParse (t, "PT1S", 4, 0, 0, 0, 0, 0, 1, 1, "PT1S"); testParse (t, "PT1S", 4, 0, 0, 0, 0, 0, 1, 1, "PT1S", "1s");
testParse (t, "PT1H1M", 6, 0, 0, 0, 1, 1, 0, h + m, "PT1H1M"); testParse (t, "PT1H1M", 6, 0, 0, 0, 1, 1, 0, h + m, "PT1H1M", "1h");
testParse (t, "PT1H1S", 6, 0, 0, 0, 1, 0, 1, h + 1, "PT1H1S"); testParse (t, "PT1H1S", 6, 0, 0, 0, 1, 0, 1, h + 1, "PT1H1S", "1h");
testParse (t, "PT1M1S", 6, 0, 0, 0, 0, 1, 1, m + 1, "PT1M1S"); testParse (t, "PT1M1S", 6, 0, 0, 0, 0, 1, 1, m + 1, "PT1M1S", "1min");
testParse (t, "PT1H1M1S", 8, 0, 0, 0, 1, 1, 1, h + m + 1, "PT1H1M1S"); testParse (t, "PT1H1M1S", 8, 0, 0, 0, 1, 1, 1, h + m + 1, "PT1H1M1S", "1h");
testParse (t, "P1Y1M1DT1H1M1S", 14, 1, 1, 1, 1, 1, 1, year + month + day + h + m + 1, "P396DT1H1M1S"); testParse (t, "P1Y1M1DT1H1M1S", 14, 1, 1, 1, 1, 1, 1, year + month + day + h + m + 1, "P396DT1H1M1S", "1.1y");
testParse (t, "PT24H", 5, 0, 0, 0, 24, 0, 0, day, "P1D"); testParse (t, "PT24H", 5, 0, 0, 0, 24, 0, 0, day, "P1D", "1d");
testParse (t, "PT40000000S", 11, 0, 0, 0, 0, 0, 40000000, 40000000, "P462DT23H6M40S"); testParse (t, "PT40000000S", 11, 0, 0, 0, 0, 0, 40000000, 40000000, "P462DT23H6M40S", "1.3y");
testParse (t, "PT3600S", 7, 0, 0, 0, 0, 0, 3600, h, "PT1H"); testParse (t, "PT3600S", 7, 0, 0, 0, 0, 0, 3600, h, "PT1H", "1h");
testParse (t, "PT60M", 5, 0, 0, 0, 0, 60, 0, h, "PT1H"); testParse (t, "PT60M", 5, 0, 0, 0, 0, 60, 0, h, "PT1H", "1h");
testParse (t, "0seconds", 8, 0, 0, 0, 0, 0, 0, 0, "PT0S"); testParse (t, "0seconds", 8, 0, 0, 0, 0, 0, 0, 0, "PT0S", "");
testParse (t, "2 seconds", 9, 0, 0, 0, 0, 0, 0, 2, "PT2S"); testParse (t, "2 seconds", 9, 0, 0, 0, 0, 0, 0, 2, "PT2S", "2s");
testParse (t, "10seconds", 9, 0, 0, 0, 0, 0, 0, 10, "PT10S"); testParse (t, "10seconds", 9, 0, 0, 0, 0, 0, 0, 10, "PT10S", "10s");
testParse (t, "1.5seconds", 10, 0, 0, 0, 0, 0, 0, 1, "PT1S"); testParse (t, "1.5seconds", 10, 0, 0, 0, 0, 0, 0, 1, "PT1S", "1s");
testParse (t, "0second", 7, 0, 0, 0, 0, 0, 0, 0, "PT0S"); testParse (t, "0second", 7, 0, 0, 0, 0, 0, 0, 0, "PT0S", "");
testParse (t, "2 second", 8, 0, 0, 0, 0, 0, 0, 2, "PT2S"); testParse (t, "2 second", 8, 0, 0, 0, 0, 0, 0, 2, "PT2S", "2s");
testParse (t, "10second", 8, 0, 0, 0, 0, 0, 0, 10, "PT10S"); testParse (t, "10second", 8, 0, 0, 0, 0, 0, 0, 10, "PT10S", "10s");
testParse (t, "1.5second", 9, 0, 0, 0, 0, 0, 0, 1, "PT1S"); testParse (t, "1.5second", 9, 0, 0, 0, 0, 0, 0, 1, "PT1S", "1s");
testParse (t, "0s", 2, 0, 0, 0, 0, 0, 0, 0, "PT0S"); testParse (t, "0s", 2, 0, 0, 0, 0, 0, 0, 0, "PT0S", "");
testParse (t, "2 s", 3, 0, 0, 0, 0, 0, 0, 2, "PT2S"); testParse (t, "2 s", 3, 0, 0, 0, 0, 0, 0, 2, "PT2S", "2s");
testParse (t, "10s", 3, 0, 0, 0, 0, 0, 0, 10, "PT10S"); testParse (t, "10s", 3, 0, 0, 0, 0, 0, 0, 10, "PT10S", "10s");
testParse (t, "1.5s", 4, 0, 0, 0, 0, 0, 0, 1, "PT1S"); testParse (t, "1.5s", 4, 0, 0, 0, 0, 0, 0, 1, "PT1S", "1s");
testParse (t, "0minutes", 8, 0, 0, 0, 0, 0, 0, 0, "PT0S"); testParse (t, "0minutes", 8, 0, 0, 0, 0, 0, 0, 0, "PT0S", "");
testParse (t, "2 minutes", 9, 0, 0, 0, 0, 0, 0, 2 * m, "PT2M"); testParse (t, "2 minutes", 9, 0, 0, 0, 0, 0, 0, 2 * m, "PT2M", "2min");
testParse (t, "10minutes", 9, 0, 0, 0, 0, 0, 0, 10 * m, "PT10M"); testParse (t, "10minutes", 9, 0, 0, 0, 0, 0, 0, 10 * m, "PT10M", "10min");
testParse (t, "1.5minutes", 10, 0, 0, 0, 0, 0, 0, m + 30, "PT1M30S"); testParse (t, "1.5minutes", 10, 0, 0, 0, 0, 0, 0, m + 30, "PT1M30S", "1min");
testParse (t, "0minute", 7, 0, 0, 0, 0, 0, 0, 0, "PT0S"); testParse (t, "0minute", 7, 0, 0, 0, 0, 0, 0, 0, "PT0S", "");
testParse (t, "2 minute", 8, 0, 0, 0, 0, 0, 0, 2 * m, "PT2M"); testParse (t, "2 minute", 8, 0, 0, 0, 0, 0, 0, 2 * m, "PT2M", "2min");
testParse (t, "10minute", 8, 0, 0, 0, 0, 0, 0, 10 * m, "PT10M"); testParse (t, "10minute", 8, 0, 0, 0, 0, 0, 0, 10 * m, "PT10M", "10min");
testParse (t, "1.5minute", 9, 0, 0, 0, 0, 0, 0, m + 30, "PT1M30S"); testParse (t, "1.5minute", 9, 0, 0, 0, 0, 0, 0, m + 30, "PT1M30S", "1min");
testParse (t, "0min", 4, 0, 0, 0, 0, 0, 0, 0, "PT0S"); testParse (t, "0min", 4, 0, 0, 0, 0, 0, 0, 0, "PT0S", "");
testParse (t, "2 min", 5, 0, 0, 0, 0, 0, 0, 2 * m, "PT2M"); testParse (t, "2 min", 5, 0, 0, 0, 0, 0, 0, 2 * m, "PT2M", "2min");
testParse (t, "10min", 5, 0, 0, 0, 0, 0, 0, 10 * m, "PT10M"); testParse (t, "10min", 5, 0, 0, 0, 0, 0, 0, 10 * m, "PT10M", "10min");
testParse (t, "1.5min", 6, 0, 0, 0, 0, 0, 0, m + 30, "PT1M30S"); testParse (t, "1.5min", 6, 0, 0, 0, 0, 0, 0, m + 30, "PT1M30S", "1min");
testParse (t, "0hours", 6, 0, 0, 0, 0, 0, 0, 0, "PT0S"); testParse (t, "0hours", 6, 0, 0, 0, 0, 0, 0, 0, "PT0S", "");
testParse (t, "2 hours", 7, 0, 0, 0, 0, 0, 0, 2 * h, "PT2H"); testParse (t, "2 hours", 7, 0, 0, 0, 0, 0, 0, 2 * h, "PT2H", "2h");
testParse (t, "10hours", 7, 0, 0, 0, 0, 0, 0, 10 * h, "PT10H"); testParse (t, "10hours", 7, 0, 0, 0, 0, 0, 0, 10 * h, "PT10H", "10h");
testParse (t, "1.5hours", 8, 0, 0, 0, 0, 0, 0, h + 30 * m, "PT1H30M"); testParse (t, "1.5hours", 8, 0, 0, 0, 0, 0, 0, h + 30 * m, "PT1H30M", "1h");
testParse (t, "0hour", 5, 0, 0, 0, 0, 0, 0, 0, "PT0S"); testParse (t, "0hour", 5, 0, 0, 0, 0, 0, 0, 0, "PT0S", "");
testParse (t, "2 hour", 6, 0, 0, 0, 0, 0, 0, 2 * h, "PT2H"); testParse (t, "2 hour", 6, 0, 0, 0, 0, 0, 0, 2 * h, "PT2H", "2h");
testParse (t, "10hour", 6, 0, 0, 0, 0, 0, 0, 10 * h, "PT10H"); testParse (t, "10hour", 6, 0, 0, 0, 0, 0, 0, 10 * h, "PT10H", "10h");
testParse (t, "1.5hour", 7, 0, 0, 0, 0, 0, 0, h + 30 * m, "PT1H30M"); testParse (t, "1.5hour", 7, 0, 0, 0, 0, 0, 0, h + 30 * m, "PT1H30M", "1h");
testParse (t, "0h", 2, 0, 0, 0, 0, 0, 0, 0, "PT0S"); testParse (t, "0h", 2, 0, 0, 0, 0, 0, 0, 0, "PT0S", "");
testParse (t, "2 h", 3, 0, 0, 0, 0, 0, 0, 2 * h, "PT2H"); testParse (t, "2 h", 3, 0, 0, 0, 0, 0, 0, 2 * h, "PT2H", "2h");
testParse (t, "10h", 3, 0, 0, 0, 0, 0, 0, 10 * h, "PT10H"); testParse (t, "10h", 3, 0, 0, 0, 0, 0, 0, 10 * h, "PT10H", "10h");
testParse (t, "1.5h", 4, 0, 0, 0, 0, 0, 0, h + 30 * m, "PT1H30M"); testParse (t, "1.5h", 4, 0, 0, 0, 0, 0, 0, h + 30 * m, "PT1H30M", "1h");
testParse (t, "weekdays", 8, 0, 0, 0, 0, 0, 0, day, "P1D"); testParse (t, "weekdays", 8, 0, 0, 0, 0, 0, 0, day, "P1D", "1d");
testParse (t, "daily", 5, 0, 0, 0, 0, 0, 0, day, "P1D"); testParse (t, "daily", 5, 0, 0, 0, 0, 0, 0, day, "P1D", "1d");
testParse (t, "0days", 5, 0, 0, 0, 0, 0, 0, 0, "PT0S"); testParse (t, "0days", 5, 0, 0, 0, 0, 0, 0, 0, "PT0S", "");
testParse (t, "2 days", 6, 0, 0, 0, 0, 0, 0, 2 * day, "P2D"); testParse (t, "2 days", 6, 0, 0, 0, 0, 0, 0, 2 * day, "P2D", "2d");
testParse (t, "10days", 6, 0, 0, 0, 0, 0, 0, 10 * day, "P10D"); testParse (t, "10days", 6, 0, 0, 0, 0, 0, 0, 10 * day, "P10D", "10d");
testParse (t, "1.5days", 7, 0, 0, 0, 0, 0, 0, day + 12 * h, "P1DT12H"); testParse (t, "1.5days", 7, 0, 0, 0, 0, 0, 0, day + 12 * h, "P1DT12H", "1d");
testParse (t, "0day", 4, 0, 0, 0, 0, 0, 0, 0, "PT0S"); testParse (t, "0day", 4, 0, 0, 0, 0, 0, 0, 0, "PT0S", "");
testParse (t, "2 day", 5, 0, 0, 0, 0, 0, 0, 2 * day, "P2D"); testParse (t, "2 day", 5, 0, 0, 0, 0, 0, 0, 2 * day, "P2D", "2d");
testParse (t, "10day", 5, 0, 0, 0, 0, 0, 0, 10 * day, "P10D"); testParse (t, "10day", 5, 0, 0, 0, 0, 0, 0, 10 * day, "P10D", "10d");
testParse (t, "1.5day", 6, 0, 0, 0, 0, 0, 0, day + 12 * h, "P1DT12H"); testParse (t, "1.5day", 6, 0, 0, 0, 0, 0, 0, day + 12 * h, "P1DT12H", "1d");
testParse (t, "0d", 2, 0, 0, 0, 0, 0, 0, 0, "PT0S"); testParse (t, "0d", 2, 0, 0, 0, 0, 0, 0, 0, "PT0S", "");
testParse (t, "2 d", 3, 0, 0, 0, 0, 0, 0, 2 * day, "P2D"); testParse (t, "2 d", 3, 0, 0, 0, 0, 0, 0, 2 * day, "P2D", "2d");
testParse (t, "10d", 3, 0, 0, 0, 0, 0, 0, 10 * day, "P10D"); testParse (t, "10d", 3, 0, 0, 0, 0, 0, 0, 10 * day, "P10D", "10d");
testParse (t, "1.5d", 4, 0, 0, 0, 0, 0, 0, day + 12 * h, "P1DT12H"); testParse (t, "1.5d", 4, 0, 0, 0, 0, 0, 0, day + 12 * h, "P1DT12H", "1d");
testParse (t, "weekly", 6, 0, 0, 0, 0, 0, 0, 7 * day, "P7D"); testParse (t, "weekly", 6, 0, 0, 0, 0, 0, 0, 7 * day, "P7D", "7d");
testParse (t, "0weeks", 6, 0, 0, 0, 0, 0, 0, 0, "PT0S"); testParse (t, "0weeks", 6, 0, 0, 0, 0, 0, 0, 0, "PT0S", "");
testParse (t, "2 weeks", 7, 0, 0, 0, 0, 0, 0, 14 * day, "P14D"); testParse (t, "2 weeks", 7, 0, 0, 0, 0, 0, 0, 14 * day, "P14D", "2w");
testParse (t, "10weeks", 7, 0, 0, 0, 0, 0, 0, 70 * day, "P70D"); testParse (t, "10weeks", 7, 0, 0, 0, 0, 0, 0, 70 * day, "P70D", "10w");
testParse (t, "1.5weeks", 8, 0, 0, 0, 0, 0, 0, 10 * day + 12 * h, "P10DT12H"); testParse (t, "1.5weeks", 8, 0, 0, 0, 0, 0, 0, 10 * day + 12 * h, "P10DT12H", "10d");
testParse (t, "0week", 5, 0, 0, 0, 0, 0, 0, 0, "PT0S"); testParse (t, "0week", 5, 0, 0, 0, 0, 0, 0, 0, "PT0S", "");
testParse (t, "2 week", 6, 0, 0, 0, 0, 0, 0, 14 * day, "P14D"); testParse (t, "2 week", 6, 0, 0, 0, 0, 0, 0, 14 * day, "P14D", "2w");
testParse (t, "10week", 6, 0, 0, 0, 0, 0, 0, 70 * day, "P70D"); testParse (t, "10week", 6, 0, 0, 0, 0, 0, 0, 70 * day, "P70D", "10w");
testParse (t, "1.5week", 7, 0, 0, 0, 0, 0, 0, 10 * day + 12 * h, "P10DT12H"); testParse (t, "1.5week", 7, 0, 0, 0, 0, 0, 0, 10 * day + 12 * h, "P10DT12H", "10d");
testParse (t, "0w", 2, 0, 0, 0, 0, 0, 0, 0, "PT0S"); testParse (t, "0w", 2, 0, 0, 0, 0, 0, 0, 0, "PT0S", "");
testParse (t, "2 w", 3, 0, 0, 0, 0, 0, 0, 14 * day, "P14D"); testParse (t, "2 w", 3, 0, 0, 0, 0, 0, 0, 14 * day, "P14D", "2w");
testParse (t, "10w", 3, 0, 0, 0, 0, 0, 0, 70 * day, "P70D"); testParse (t, "10w", 3, 0, 0, 0, 0, 0, 0, 70 * day, "P70D", "10w");
testParse (t, "1.5w", 4, 0, 0, 0, 0, 0, 0, 10 * day + 12 * h, "P10DT12H"); testParse (t, "1.5w", 4, 0, 0, 0, 0, 0, 0, 10 * day + 12 * h, "P10DT12H", "10d");
testParse (t, "monthly", 7, 0, 0, 0, 0, 0, 0, 30 * day, "P30D"); testParse (t, "monthly", 7, 0, 0, 0, 0, 0, 0, 30 * day, "P30D", "4w");
testParse (t, "0months", 7, 0, 0, 0, 0, 0, 0, 0, "PT0S"); testParse (t, "0months", 7, 0, 0, 0, 0, 0, 0, 0, "PT0S", "");
testParse (t, "2 months", 8, 0, 0, 0, 0, 0, 0, 60 * day, "P60D"); testParse (t, "2 months", 8, 0, 0, 0, 0, 0, 0, 60 * day, "P60D", "8w");
testParse (t, "10months", 8, 0, 0, 0, 0, 0, 0, 300 * day, "P300D"); testParse (t, "10months", 8, 0, 0, 0, 0, 0, 0, 300 * day, "P300D", "10mo");
testParse (t, "1.5months", 9, 0, 0, 0, 0, 0, 0, 45 * day, "P45D"); testParse (t, "1.5months", 9, 0, 0, 0, 0, 0, 0, 45 * day, "P45D", "6w");
testParse (t, "0month", 6, 0, 0, 0, 0, 0, 0, 0, "PT0S"); testParse (t, "0month", 6, 0, 0, 0, 0, 0, 0, 0, "PT0S", "");
testParse (t, "2 month", 7, 0, 0, 0, 0, 0, 0, 60 * day, "P60D"); testParse (t, "2 month", 7, 0, 0, 0, 0, 0, 0, 60 * day, "P60D", "8w");
testParse (t, "10month", 7, 0, 0, 0, 0, 0, 0, 300 * day, "P300D"); testParse (t, "10month", 7, 0, 0, 0, 0, 0, 0, 300 * day, "P300D", "10mo");
testParse (t, "1.5month", 8, 0, 0, 0, 0, 0, 0, 45 * day, "P45D"); testParse (t, "1.5month", 8, 0, 0, 0, 0, 0, 0, 45 * day, "P45D", "6w");
testParse (t, "0mo", 3, 0, 0, 0, 0, 0, 0, 0, "PT0S"); testParse (t, "0mo", 3, 0, 0, 0, 0, 0, 0, 0, "PT0S", "");
testParse (t, "2 mo", 4, 0, 0, 0, 0, 0, 0, 60 * day, "P60D"); testParse (t, "2 mo", 4, 0, 0, 0, 0, 0, 0, 60 * day, "P60D", "8w");
testParse (t, "10mo", 4, 0, 0, 0, 0, 0, 0, 300 * day, "P300D"); testParse (t, "10mo", 4, 0, 0, 0, 0, 0, 0, 300 * day, "P300D", "10mo");
testParse (t, "1.5mo", 5, 0, 0, 0, 0, 0, 0, 45 * day, "P45D"); testParse (t, "1.5mo", 5, 0, 0, 0, 0, 0, 0, 45 * day, "P45D", "6w");
testParse (t, "quarterly", 9, 0, 0, 0, 0, 0, 0, 91 * day, "P91D"); testParse (t, "quarterly", 9, 0, 0, 0, 0, 0, 0, 91 * day, "P91D", "3mo");
testParse (t, "0quarters", 9, 0, 0, 0, 0, 0, 0, 0, "PT0S"); testParse (t, "0quarters", 9, 0, 0, 0, 0, 0, 0, 0, "PT0S", "");
testParse (t, "2 quarters", 10, 0, 0, 0, 0, 0, 0, 182 * day, "P182D"); testParse (t, "2 quarters", 10, 0, 0, 0, 0, 0, 0, 182 * day, "P182D", "6mo");
testParse (t, "10quarters", 10, 0, 0, 0, 0, 0, 0, 910 * day, "P910D"); testParse (t, "10quarters", 10, 0, 0, 0, 0, 0, 0, 910 * day, "P910D", "2.5y");
testParse (t, "1.5quarters", 11, 0, 0, 0, 0, 0, 0, 136 * day + 12 * h, "P136DT12H"); testParse (t, "1.5quarters", 11, 0, 0, 0, 0, 0, 0, 136 * day + 12 * h, "P136DT12H", "4mo");
testParse (t, "0quarter", 8, 0, 0, 0, 0, 0, 0, 0, "PT0S"); testParse (t, "0quarter", 8, 0, 0, 0, 0, 0, 0, 0, "PT0S", "");
testParse (t, "2 quarter", 9, 0, 0, 0, 0, 0, 0, 182 * day, "P182D"); testParse (t, "2 quarter", 9, 0, 0, 0, 0, 0, 0, 182 * day, "P182D", "6mo");
testParse (t, "10quarter", 9, 0, 0, 0, 0, 0, 0, 910 * day, "P910D"); testParse (t, "10quarter", 9, 0, 0, 0, 0, 0, 0, 910 * day, "P910D", "2.5y");
testParse (t, "1.5quarter", 10, 0, 0, 0, 0, 0, 0, 136 * day + 12 * h, "P136DT12H"); testParse (t, "1.5quarter", 10, 0, 0, 0, 0, 0, 0, 136 * day + 12 * h, "P136DT12H", "4mo");
testParse (t, "0q", 2, 0, 0, 0, 0, 0, 0, 0, "PT0S"); testParse (t, "0q", 2, 0, 0, 0, 0, 0, 0, 0, "PT0S", "");
testParse (t, "2 q", 3, 0, 0, 0, 0, 0, 0, 182 * day, "P182D"); testParse (t, "2 q", 3, 0, 0, 0, 0, 0, 0, 182 * day, "P182D", "6mo");
testParse (t, "10q", 3, 0, 0, 0, 0, 0, 0, 910 * day, "P910D"); testParse (t, "10q", 3, 0, 0, 0, 0, 0, 0, 910 * day, "P910D", "2.5y");
testParse (t, "1.5q", 4, 0, 0, 0, 0, 0, 0, 136 * day + 12 * h, "P136DT12H"); testParse (t, "1.5q", 4, 0, 0, 0, 0, 0, 0, 136 * day + 12 * h, "P136DT12H", "4mo");
testParse (t, "yearly", 6, 0, 0, 0, 0, 0, 0, year, "P365D"); testParse (t, "yearly", 6, 0, 0, 0, 0, 0, 0, year, "P365D", "1.0y");
testParse (t, "0years", 6, 0, 0, 0, 0, 0, 0, 0, "PT0S"); testParse (t, "0years", 6, 0, 0, 0, 0, 0, 0, 0, "PT0S", "");
testParse (t, "2 years", 7, 0, 0, 0, 0, 0, 0, 2 * year, "P730D"); testParse (t, "2 years", 7, 0, 0, 0, 0, 0, 0, 2 * year, "P730D", "2.0y");
testParse (t, "10years", 7, 0, 0, 0, 0, 0, 0, 10 * year, "P3650D"); testParse (t, "10years", 7, 0, 0, 0, 0, 0, 0, 10 * year, "P3650D", "10.0y");
testParse (t, "1.5years", 8, 0, 0, 0, 0, 0, 0, 547 * day + 12 * h, "P547DT12H"); testParse (t, "1.5years", 8, 0, 0, 0, 0, 0, 0, 547 * day + 12 * h, "P547DT12H", "1.5y");
testParse (t, "0year", 5, 0, 0, 0, 0, 0, 0, 0, "PT0S"); testParse (t, "0year", 5, 0, 0, 0, 0, 0, 0, 0, "PT0S", "");
testParse (t, "2 year", 6, 0, 0, 0, 0, 0, 0, 2 * year, "P730D"); testParse (t, "2 year", 6, 0, 0, 0, 0, 0, 0, 2 * year, "P730D", "2.0y");
testParse (t, "10year", 6, 0, 0, 0, 0, 0, 0, 10 * year, "P3650D"); testParse (t, "10year", 6, 0, 0, 0, 0, 0, 0, 10 * year, "P3650D", "10.0y");
testParse (t, "1.5year", 7, 0, 0, 0, 0, 0, 0, 547 * day + 12 * h, "P547DT12H"); testParse (t, "1.5year", 7, 0, 0, 0, 0, 0, 0, 547 * day + 12 * h, "P547DT12H", "1.5y");
testParse (t, "0y", 2, 0, 0, 0, 0, 0, 0, 0, "PT0S"); testParse (t, "0y", 2, 0, 0, 0, 0, 0, 0, 0, "PT0S", "");
testParse (t, "2 y", 3, 0, 0, 0, 0, 0, 0, 2 * year, "P730D"); testParse (t, "2 y", 3, 0, 0, 0, 0, 0, 0, 2 * year, "P730D", "2.0y");
testParse (t, "10y", 3, 0, 0, 0, 0, 0, 0, 10 * year, "P3650D"); testParse (t, "10y", 3, 0, 0, 0, 0, 0, 0, 10 * year, "P3650D", "10.0y");
testParse (t, "1.5y", 4, 0, 0, 0, 0, 0, 0, 547 * day + 12 * h, "P547DT12H"); testParse (t, "1.5y", 4, 0, 0, 0, 0, 0, 0, 547 * day + 12 * h, "P547DT12H", "1.5y");
testParse (t, "annual", 6, 0, 0, 0, 0, 0, 0, year, "P365D"); testParse (t, "annual", 6, 0, 0, 0, 0, 0, 0, year, "P365D", "1.0y");
testParse (t, "biannual", 8, 0, 0, 0, 0, 0, 0, 2 * year, "P730D"); testParse (t, "biannual", 8, 0, 0, 0, 0, 0, 0, 2 * year, "P730D", "2.0y");
testParse (t, "bimonthly", 9, 0, 0, 0, 0, 0, 0, 61 * day, "P61D"); testParse (t, "bimonthly", 9, 0, 0, 0, 0, 0, 0, 61 * day, "P61D", "8w");
testParse (t, "biweekly", 8, 0, 0, 0, 0, 0, 0, 14 * day, "P14D"); testParse (t, "biweekly", 8, 0, 0, 0, 0, 0, 0, 14 * day, "P14D", "2w");
testParse (t, "biyearly", 8, 0, 0, 0, 0, 0, 0, 2 * year, "P730D"); testParse (t, "biyearly", 8, 0, 0, 0, 0, 0, 0, 2 * year, "P730D", "2.0y");
testParse (t, "fortnight", 9, 0, 0, 0, 0, 0, 0, 14 * day, "P14D"); testParse (t, "fortnight", 9, 0, 0, 0, 0, 0, 0, 14 * day, "P14D", "2w");
testParse (t, "semiannual", 10, 0, 0, 0, 0, 0, 0, 183 * day, "P183D"); testParse (t, "semiannual", 10, 0, 0, 0, 0, 0, 0, 183 * day, "P183D", "6mo");
testParse (t, "0sennight", 9, 0, 0, 0, 0, 0, 0, 0, "PT0S"); testParse (t, "0sennight", 9, 0, 0, 0, 0, 0, 0, 0, "PT0S", "");
testParse (t, "2 sennight", 10, 0, 0, 0, 0, 0, 0, 28 * day, "P28D"); testParse (t, "2 sennight", 10, 0, 0, 0, 0, 0, 0, 28 * day, "P28D", "4w");
testParse (t, "10sennight", 10, 0, 0, 0, 0, 0, 0, 140 * day, "P140D"); testParse (t, "10sennight", 10, 0, 0, 0, 0, 0, 0, 140 * day, "P140D", "4mo");
testParse (t, "1.5sennight", 11, 0, 0, 0, 0, 0, 0, 21 * day, "P21D"); testParse (t, "1.5sennight", 11, 0, 0, 0, 0, 0, 0, 21 * day, "P21D", "3w");
ISO8601p left, right; ISO8601p left, right;