Skip to content

Commit

Permalink
added support for negative time/step
Browse files Browse the repository at this point in the history
  • Loading branch information
danovaro committed Oct 20, 2023
1 parent ded272c commit 66302b1
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 7 deletions.
19 changes: 12 additions & 7 deletions src/eckit/types/Time.cc
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,14 @@ Time::Time(const std::string& s, bool extended) {
long ss = 0, mm = 0, hh = 0, dd = 0;
std::smatch m;

if (std::regex_match (s, m, std::regex("^[0-9]+$"))) { // only digits
if (std::regex_match (s, m, std::regex("^-?[0-9]+$"))) { // only digits
long t = std::stol(s);
if (extended || s.length() <= 2) { // cases: h, hh, (or hhh..h for step parsing)
int sign = (s[0] == '-' ? 1 : 0);
std::cout << "\"" << s << "\" " << t << " " << sign << std::endl;
if (extended || s.length() <= 2+sign) { // cases: h, hh, (or hhh..h for step parsing)
hh = t;
} else {
if (s.length() <= 4) { // cases: hmm, hhmm
if (s.length() <= 4+sign) { // cases: hmm, hhmm
hh = t / 100;
mm = t % 100;
} else { // cases: hmmss, hhmmss
Expand All @@ -60,7 +62,7 @@ Time::Time(const std::string& s, bool extended) {
}
}
else {
if (std::regex_match (s, m, std::regex("^[0-9]*\\.[0-9]+$"))) { // floating point (hours)
if (std::regex_match (s, m, std::regex("^-?[0-9]*\\.[0-9]+$"))) { // floating point (hours)
long sec = std::round(std::stod(s)*3600);
hh = sec/3600;
sec -= hh*3600;
Expand All @@ -83,7 +85,7 @@ Time::Time(const std::string& s, bool extended) {
}
}
else {
if (std::regex_match (s, m, std::regex("^([0-9]+[dD])?([0-9]+[hH])?([0-9]+[mM])?([0-9]+[sS])?$"))) {
if (std::regex_match (s, m, std::regex("^-?([0-9]+[dD])?([0-9]+[hH])?([0-9]+[mM])?([0-9]+[sS])?$"))) {
for (int i=1; i<m.size(); i++) {
if (m[i].matched) {
std::string aux = m[i].str();
Expand All @@ -98,6 +100,9 @@ Time::Time(const std::string& s, bool extended) {
}
}
ss += 60 * (mm + 60 * (hh + 24 * dd));
if (s[0] == '-') {
ss = -ss;
}
dd = ss / 86400;
hh = (ss / 3600) % 24;
mm = (ss / 60) % 60;
Expand All @@ -111,7 +116,7 @@ Time::Time(const std::string& s, bool extended) {
}
}

if ((!extended && (hh >= 24 || dd > 0)) || mm >= 60 || ss >= 60 || hh < 0 || mm < 0 || ss < 0) {
if (mm >= 60 || ss >= 60 || (!extended && (hh >= 24 || dd > 0 || hh < 0 || mm < 0 || ss < 0))) {
std::string msg = "Wrong input for time: ";
Translator<long, std::string> t;
if (dd>0) {
Expand Down Expand Up @@ -145,7 +150,7 @@ Time& Time::operator=(const Time& other) {

Time::Time(long hh, long mm, long ss, bool extended) :
seconds_(hh * 3600 + mm * 60 + ss) {
if ((hh >= 24 && !extended) || mm >= 60 || ss >= 60 || hh < 0 || mm < 0 || ss < 0) {
if (mm >= 60 || ss >= 60 || (!extended && (hh >= 24 || hh < 0 || mm < 0 || ss < 0))) {
std::string msg = "Wrong input for time: ";
Translator<long, std::string> t;
msg += t(hh);
Expand Down
14 changes: 14 additions & 0 deletions tests/types/test_time.cc
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,18 @@ CASE("Time only digits (hhmmss)") {
EXPECT_THROWS(Time(24*3600));
EXPECT_THROWS(Time(24,0,0));
EXPECT_THROWS(Time("24"));
EXPECT_THROWS(Time(-1));
EXPECT_THROWS(Time("-1"));
EXPECT_NO_THROW(Time(-1,0,0, true));
EXPECT_NO_THROW(Time("-1", true));
EXPECT(Time(-1,0,0, true) == Time("-1", true));
EXPECT(Time(24,0,0, true) == Time(24*3600, true));
EXPECT(Time(24,0,0, true) == Time("24", true));
EXPECT(Time(-1,0,0, true) == Time("-1", true));
EXPECT(Time(-1,0,0, true) == Time("-01", true));
EXPECT(Time(-100,0,0, true) == Time("-100", true));
EXPECT(Time(-100,0,0, true) == Time("-0100", true));
EXPECT(Time(0,-30,0, true) == Time("-0.5", true));

EXPECT(Time(2,0,0) == Time("2"));
EXPECT(Time(2,0,0) == Time("02"));
Expand Down Expand Up @@ -147,6 +157,10 @@ CASE("Time with unit (__h__m__s)") {
EXPECT_THROWS(Time("25h"));
EXPECT_NO_THROW(Time("25h", true));

EXPECT(Time(0,-30,0, true) == Time("-30m", true));
EXPECT(Time(-1,-30,0, true) == Time("-1h30m", true));
EXPECT(Time(0,-90,0, true) == Time("-1h30m", true));

EXPECT(Time("0d3h10m20s") == Time("3h10m20s"));
EXPECT(Time("0d3h10m20s") == Time("3h620s"));
EXPECT(Time("2D3h", true) == Time("51h", true));
Expand Down

0 comments on commit 66302b1

Please sign in to comment.