/* This file is part of MAUS: http://micewww.pp.rl.ac.uk/projects/maus * * MAUS is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * MAUS is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with MAUS. If not, see . */ #include #include #include "Utils/Exception.hh" #include "src/common_cpp/DataStructure/DateTime.hh" namespace MAUS { DateTime::DateTime() : _date_time("1976-04-04T00:00:00.000000") { } DateTime::DateTime(const DateTime& rhs) : _date_time(rhs._date_time) { } DateTime& DateTime::operator=(const DateTime& rhs) { if (this == &rhs) { return *this; } _date_time = rhs._date_time; return *this; } DateTime::~DateTime() {} std::string DateTime::GetDateTime() const { return _date_time; } void DateTime::SetDateTime(std::string datetime) { if (!CheckFormat(datetime)) throw(Exceptions::Exception(Exceptions::recoverable, "Malformatted date time string "+datetime+\ " should be like YYYY-MM-DDTHH:MM:SS.mmmmmm", "DateTime::SetDateTime" )); _date_time = datetime; } bool DateTime::CheckFormat(std::string datetime) { // there is strptime, it's pretty clunky and doesnt seem terribly well done. // (#include "time.h" in linux only) e.g. doesn't check even months properly if (datetime.size() != 26) return false; try { bool out = Check(datetime.substr(0, 4), 0, 10000); // years out &= Check(datetime.substr(5, 2), 1, 13); // months out &= CheckDay(datetime.substr(8, 2), datetime.substr(5, 2)); // days out &= Check(datetime.substr(11, 2), 0, 24); // hours out &= Check(datetime.substr(14, 2), 0, 60); // minutes out &= Check(datetime.substr(17, 2), 0, 60); // seconds out &= Check(datetime.substr(20, 6), 0, 1000000); // milliseconds out &= CheckSeparators(datetime); // separators return out; } catch (Exceptions::Exception exc) { return false; } } int DateTime::ToInt(std::string some_string) { std::stringstream in(some_string); int out; in >> out; // should be able to do this using failbits etc but for some reason fail() // wasn't getting set. I always find error handling on these streamer ops // a bit obscure. std::stringstream out_test; out_test.fill('0'); out_test.width(some_string.size()); out_test << out; if (out_test.str() != some_string) { throw(Exceptions::Exception(Exceptions::recoverable, "Failed to convert "+some_string+" to an int", "DateTime::ToInt")); } return out; } bool DateTime::Check(std::string int_as_string, int lower, int upper_plus_one) { int target = ToInt(int_as_string); return target >= lower && target < upper_plus_one; } bool DateTime::CheckDay(std::string day, std::string month) { if (month == "01") { return Check(day, 1, 32); } else if (month == "02") { return Check(day, 1, 29); } else if (month == "03") { return Check(day, 1, 32); } else if (month == "04") { return Check(day, 1, 31); } else if (month == "05") { return Check(day, 1, 32); } else if (month == "06") { return Check(day, 1, 31); } else if (month == "07") { return Check(day, 1, 32); } else if (month == "08") { return Check(day, 1, 32); } else if (month == "09") { return Check(day, 1, 31); } else if (month == "10") { return Check(day, 1, 32); } else if (month == "11") { return Check(day, 1, 31); } else if (month == "12") { return Check(day, 1, 32); } else { throw(Exceptions::Exception(Exceptions::recoverable, "Could not resolve month "+month, "DateTime::CheckDay")); } } bool DateTime::CheckSeparators(std::string datetime) { // YYYY-MM-DDTHH:MM:SS.mmmmmm bool out = datetime[4] == '-'; out &= datetime[7] == '-'; out &= datetime[13] == ':'; out &= datetime[16] == ':'; out &= datetime[19] == '.'; return out; } }