-
Notifications
You must be signed in to change notification settings - Fork 122
/
DateValidator.cpp
149 lines (131 loc) · 3.76 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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
//----------------------------------------------------------------------
// Includes
//----------------------------------------------------------------------
#include "MantidKernel/DateValidator.h"
#include <boost/lexical_cast.hpp>
#include <time.h>
namespace Mantid
{
namespace 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_isdst = -1;
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;
}
}
/// constructor
DateValidator::DateValidator()
{
}
/// destructor
DateValidator::~DateValidator()
{
}
/// create a copy of the the validator
IValidator_sptr DateValidator::clone() const
{
return boost::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 "";
}
}
}