forked from npshub/mantid
-
Notifications
You must be signed in to change notification settings - Fork 0
/
DateValidator.cpp
129 lines (117 loc) · 3.71 KB
/
DateValidator.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
// Mantid Repository : https://github.com/mantidproject/mantid
//
// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI,
// NScD Oak Ridge National Laboratory, European Spallation Source,
// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
// SPDX - License - Identifier: GPL - 3.0 +
#include "MantidKernel/DateValidator.h"
#include <boost/lexical_cast.hpp>
#include <ctime>
#include <memory>
namespace Mantid::Kernel {
namespace {
//
// Keeps time.h out of the header
//
/** Checks the validity of date string ,expected format is "DD/MM/YYYY"
* @param sDate :: expected date format
* @param error :: string which describes the error
* @return tm structure with the date information filled in
*/
struct tm getTimeValue(const std::string &sDate, std::string &error) {
struct tm timeinfo;
// Zero it out
timeinfo.tm_sec = 0;
timeinfo.tm_min = 0;
timeinfo.tm_hour = 0;
timeinfo.tm_mday = 0;
timeinfo.tm_mon = 0;
timeinfo.tm_year = 0;
timeinfo.tm_wday = 0;
timeinfo.tm_yday = 0;
timeinfo.tm_isdst = -1;
#ifndef _WIN32
timeinfo.tm_gmtoff = 0;
timeinfo.tm_zone = nullptr;
#endif
std::basic_string<char>::size_type index, off = 0;
int day, month, year;
// look for the first '/' to extract day part from the date string
index = sDate.find('/', off);
if (index == std::string::npos) {
error = "Invalid Date:date format must be DD/MM/YYYY";
timeinfo.tm_mday = 0;
return timeinfo;
}
// get day part of the date
try {
day = boost::lexical_cast<int>(sDate.substr(off, index - off).c_str());
} catch (boost::bad_lexical_cast &) {
error = "Invalid Date";
return timeinfo;
}
timeinfo.tm_mday = day;
// change the offset to the next position after "/"
off = index + 1;
// look for 2nd '/' to get month part from the date string
index = sDate.find('/', off);
if (index == std::string::npos) {
error = "Invalid Date:date format must be DD/MM/YYYY";
return timeinfo;
}
// now get the month part
try {
month = boost::lexical_cast<int>(sDate.substr(off, index - off).c_str());
} catch (boost::bad_lexical_cast &) {
error = "Invalid Date";
return timeinfo;
}
timeinfo.tm_mon = month - 1;
// change the offset to the position after "/"
off = index + 1;
// now get the year part from the date string
try {
year = boost::lexical_cast<int>(sDate.substr(off, 4).c_str());
} catch (boost::bad_lexical_cast &) {
error = "Invalid Date";
return timeinfo;
}
timeinfo.tm_year = year - 1900;
return timeinfo;
}
} // namespace
/// create a copy of the the validator
IValidator_sptr DateValidator::clone() const { return std::make_shared<DateValidator>(*this); }
/** Checks the given value is a valid date
* @param value :: input date property to validate
* @return a string which describes the error else ""
*/
std::string DateValidator::checkValidity(const std::string &value) const {
// empty strings are allowed
if (value.empty()) {
return "";
}
std::string formaterror;
struct tm timeinfo = getTimeValue(value, formaterror);
if (!formaterror.empty()) {
return formaterror;
}
if (timeinfo.tm_mday < 1 || timeinfo.tm_mday > 31) {
return "Invalid Date:Day part of the Date parameter must be between 1 and "
"31";
}
if (timeinfo.tm_mon < 0 || timeinfo.tm_mon > 11) {
return "Invalid Date:Month part of the Date parameter must be between 1 "
"and 12";
}
// get current time
time_t rawtime;
time(&rawtime);
struct tm *currenttime = localtime(&rawtime);
if (timeinfo.tm_year > currenttime->tm_year) {
return "Invalid Date:Year part of the Date parameter can not be greater "
"than the current year";
}
return "";
}
} // namespace Mantid::Kernel