mirror of
https://github.com/pocoproject/poco.git
synced 2025-03-27 00:35:23 +01:00
* GH #569: Cherry pick and correct code from devel-experimental. * GH #569: Add missing timezone codes. * enh(Foundation): DateTimeParser: stricter checks of timezones, more tests for invalid inputs. (#569) * enh(Foundation): Small fixes of issues detected by CodeQL --------- Co-authored-by: Alex Fabijanic <alex@pocoproject.org>
This commit is contained in:
parent
24b7122f43
commit
4f1cf68307
@ -19,16 +19,21 @@
|
||||
|
||||
|
||||
#include "Poco/Foundation.h"
|
||||
#include <unordered_set>
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
class RegularExpression;
|
||||
|
||||
|
||||
class Foundation_API DateTimeFormat
|
||||
/// Definition of date/time formats and various
|
||||
/// constants used by DateTimeFormatter and DateTimeParser.
|
||||
{
|
||||
public:
|
||||
|
||||
// predefined date formats
|
||||
static const std::string ISO8601_FORMAT;
|
||||
/// The date/time format defined in the ISO 8601 standard.
|
||||
@ -37,6 +42,8 @@ public:
|
||||
/// 2005-01-01T12:00:00+01:00
|
||||
/// 2005-01-01T11:00:00Z
|
||||
|
||||
static const std::string ISO8601_REGEX;
|
||||
|
||||
static const std::string ISO8601_FRAC_FORMAT;
|
||||
/// The date/time format defined in the ISO 8601 standard,
|
||||
/// with fractional seconds.
|
||||
@ -52,6 +59,8 @@ public:
|
||||
/// Sat, 1 Jan 05 12:00:00 +0100
|
||||
/// Sat, 1 Jan 05 11:00:00 GMT
|
||||
|
||||
static const std::string RFC822_REGEX;
|
||||
|
||||
static const std::string RFC1123_FORMAT;
|
||||
/// The date/time format defined in RFC 1123 (obsoletes RFC 822).
|
||||
///
|
||||
@ -59,6 +68,8 @@ public:
|
||||
/// Sat, 1 Jan 2005 12:00:00 +0100
|
||||
/// Sat, 1 Jan 2005 11:00:00 GMT
|
||||
|
||||
static const std::string RFC1123_REGEX;
|
||||
|
||||
static const std::string HTTP_FORMAT;
|
||||
/// The date/time format defined in the HTTP specification (RFC 2616),
|
||||
/// which is basically a variant of RFC 1036 with a zero-padded day field.
|
||||
@ -67,6 +78,8 @@ public:
|
||||
/// Sat, 01 Jan 2005 12:00:00 +0100
|
||||
/// Sat, 01 Jan 2005 11:00:00 GMT
|
||||
|
||||
static const std::string HTTP_REGEX;
|
||||
|
||||
static const std::string RFC850_FORMAT;
|
||||
/// The date/time format defined in RFC 850 (obsoleted by RFC 1036).
|
||||
///
|
||||
@ -74,6 +87,8 @@ public:
|
||||
/// Saturday, 1-Jan-05 12:00:00 +0100
|
||||
/// Saturday, 1-Jan-05 11:00:00 GMT
|
||||
|
||||
static const std::string RFC850_REGEX;
|
||||
|
||||
static const std::string RFC1036_FORMAT;
|
||||
/// The date/time format defined in RFC 1036 (obsoletes RFC 850).
|
||||
///
|
||||
@ -81,18 +96,24 @@ public:
|
||||
/// Saturday, 1 Jan 05 12:00:00 +0100
|
||||
/// Saturday, 1 Jan 05 11:00:00 GMT
|
||||
|
||||
static const std::string RFC1036_REGEX;
|
||||
|
||||
static const std::string ASCTIME_FORMAT;
|
||||
/// The date/time format produced by the ANSI C asctime() function.
|
||||
///
|
||||
/// Example:
|
||||
/// Sat Jan 1 12:00:00 2005
|
||||
|
||||
static const std::string ASCTIME_REGEX;
|
||||
|
||||
static const std::string SORTABLE_FORMAT;
|
||||
/// A simple, sortable date/time format.
|
||||
///
|
||||
/// Example:
|
||||
/// 2005-01-01 12:00:00
|
||||
|
||||
static const std::string SORTABLE_REGEX;
|
||||
// ^(\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d)$
|
||||
|
||||
// names used by formatter and parser
|
||||
static const std::string WEEKDAY_NAMES[7];
|
||||
@ -100,6 +121,19 @@ public:
|
||||
|
||||
static const std::string MONTH_NAMES[12];
|
||||
/// English names of months (January, February, ...).
|
||||
|
||||
static bool hasFormat(const std::string& fmt);
|
||||
/// Returns true if fmt is a known standard format.
|
||||
|
||||
static bool isValid(const std::string& dateTime);
|
||||
/// Returns true if dateTime validates against at least one supported format.
|
||||
|
||||
typedef std::unordered_set<const std::string*> RegexList;
|
||||
static RegexList REGEX_LIST;
|
||||
|
||||
private:
|
||||
typedef std::unordered_set<std::string> Formatlist;
|
||||
static Formatlist FORMAT_LIST;
|
||||
};
|
||||
|
||||
|
||||
|
@ -53,6 +53,8 @@ class Foundation_API DateTimeParser
|
||||
/// If more strict format validation of date/time strings is required, a regular
|
||||
/// expression could be used for initial validation, before passing the string
|
||||
/// to DateTimeParser.
|
||||
/// TODO: Correct description
|
||||
|
||||
{
|
||||
public:
|
||||
static void parse(const std::string& fmt, const std::string& str, DateTime& dateTime, int& timeZoneDifferential);
|
||||
|
@ -14,6 +14,8 @@
|
||||
|
||||
#include "Poco/DateTime.h"
|
||||
#include "Poco/Timespan.h"
|
||||
#include "Poco/Exception.h"
|
||||
#include "Poco/Format.h"
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <ctime>
|
||||
@ -70,16 +72,28 @@ DateTime::DateTime(int year, int month, int day, int hour, int minute, int secon
|
||||
_millisecond(millisecond),
|
||||
_microsecond(microsecond)
|
||||
{
|
||||
poco_assert (year >= 0 && year <= 9999);
|
||||
poco_assert (month >= 1 && month <= 12);
|
||||
poco_assert (day >= 1 && day <= daysOfMonth(year, month));
|
||||
poco_assert (hour >= 0 && hour <= 23);
|
||||
poco_assert (minute >= 0 && minute <= 59);
|
||||
poco_assert (second >= 0 && second <= 60); // allow leap seconds
|
||||
poco_assert (millisecond >= 0 && millisecond <= 999);
|
||||
poco_assert (microsecond >= 0 && microsecond <= 999);
|
||||
|
||||
_utcTime = toUtcTime(toJulianDay(year, month, day)) + 10*(hour*Timespan::HOURS + minute*Timespan::MINUTES + second*Timespan::SECONDS + millisecond*Timespan::MILLISECONDS + microsecond);
|
||||
if (isValid(_year, _month, _day, _hour, _minute, _second, _millisecond, _microsecond))
|
||||
{
|
||||
_utcTime = toUtcTime(toJulianDay(year, month, day)) +
|
||||
10 * (hour*Timespan::HOURS + minute*Timespan::MINUTES + second*Timespan::SECONDS +
|
||||
millisecond*Timespan::MILLISECONDS + microsecond);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw Poco::InvalidArgumentException(Poco::format("Date time is %d-%d-%dT%d:%d:%d.%d.%d\n"
|
||||
"Valid values:\n"
|
||||
"0 <= year <= 9999\n"
|
||||
"1 <= month <= 12\n"
|
||||
"1 <= day <= %d\n"
|
||||
"0 <= hour <= 23\n"
|
||||
"0 <= minute <= 59\n"
|
||||
"0 <= second <= 59\n"
|
||||
"0 <= millisecond <= 999\n"
|
||||
"0 <= microsecond <= 999",
|
||||
_year, _month, _day, _hour, _minute,
|
||||
_second, _millisecond, _microsecond,
|
||||
daysOfMonth(_year, _month)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -12,21 +12,92 @@
|
||||
//
|
||||
|
||||
|
||||
#include <Poco/Exception.h>
|
||||
#include "Poco/DateTimeFormat.h"
|
||||
#include "Poco/RegularExpression.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
// NOTE: Must be in sync with DateTimeParser::parseTZD
|
||||
// TODO: Validate timezone strings separately and simplify regex?
|
||||
#define TIMEZONES_REGEX_PART \
|
||||
"(UT)|(GMT)|(BST)|(IST)|(WET)|(WEST)|(CET)|(CEST)|(EET)|(EEST)|(EST)|(MSK)|" \
|
||||
"(MSD)|(NST)|(NDT)|(AST)|(ADT)|(EST)|(EDT)|(CST)|(CDT)|(MST)|(MDT)|(PST)|" \
|
||||
"(PDT)|(AKST)|(AKDT)|(HST)|(AEST)|(AEDT)|(ACST)|(ACDT)|(AWST)|(AWDT)"
|
||||
|
||||
const std::string DateTimeFormat::ISO8601_FORMAT("%Y-%m-%dT%H:%M:%S%z");
|
||||
const std::string DateTimeFormat::ISO8601_FRAC_FORMAT("%Y-%m-%dT%H:%M:%s%z");
|
||||
const std::string DateTimeFormat::ISO8601_REGEX("([\\+-]?\\d{4}(?!\\d{2}\\b))"
|
||||
"((-?)"
|
||||
"((0[1-9]|1[0-2])(\\3([12]\\d|0[1-9]|3[01]))?|W([0-4]\\d|5[0-2])(-?[1-7])?|"
|
||||
"(00[1-9]|0[1-9]\\d|[12]\\d{2}|3([0-5]\\d|6[1-6])))"
|
||||
"([T\\s]"
|
||||
"((([01]\\d|2[0-3])((:?)[0-5]\\d)?|24\\:?00)([\\.,]\\d+(?!:))?)?"
|
||||
"(\\17[0-5]\\d([\\.,]\\d+)?)?([A-I]|[K-Z]|([\\+-])([01]\\d|2[0-3]):?([0-5]\\d)?)?)?)?");
|
||||
|
||||
const std::string DateTimeFormat::RFC822_FORMAT("%w, %e %b %y %H:%M:%S %Z");
|
||||
|
||||
const std::string DateTimeFormat::RFC822_REGEX("(((Mon)|(Tue)|(Wed)|(Thu)|(Fri)|(Sat)|(Sun)), *)?"
|
||||
"\\d\\d? +"
|
||||
"((Jan)|(Feb)|(Mar)|(Apr)|(May)|(Jun)|(Jul)|(Aug)|(Sep)|(Oct)|(Nov)|(Dec)) +"
|
||||
"\\d\\d(\\d\\d)? +"
|
||||
"\\d\\d:\\d\\d(:\\d\\d)? +"
|
||||
"(([+\\-]?\\d\\d\\d\\d)|" TIMEZONES_REGEX_PART "|\\w)");
|
||||
|
||||
const std::string DateTimeFormat::RFC1123_FORMAT("%w, %e %b %Y %H:%M:%S %Z");
|
||||
const std::string DateTimeFormat::RFC1123_REGEX(DateTimeFormat::RFC822_REGEX);
|
||||
|
||||
const std::string DateTimeFormat::HTTP_FORMAT("%w, %d %b %Y %H:%M:%S %Z");
|
||||
const std::string DateTimeFormat::HTTP_REGEX("(((Mon)|(Tue)|(Wed)|(Thu)|(Fri)|(Sat)|(Sun)), *)?"
|
||||
"\\d\\d? +"
|
||||
"((Jan)|(Feb)|(Mar)|(Apr)|(May)|(Jun)|(Jul)|(Aug)|(Sep)|(Oct)|(Nov)|(Dec)) +"
|
||||
"\\d\\d(\\d\\d)? +\\d\\d:\\d\\d(:\\d\\d)? "
|
||||
"(" TIMEZONES_REGEX_PART "|)?+"
|
||||
"(([+\\-]?\\d\\d\\d\\d)?|" TIMEZONES_REGEX_PART "|\\w)");
|
||||
|
||||
const std::string DateTimeFormat::RFC850_FORMAT("%W, %e-%b-%y %H:%M:%S %Z");
|
||||
const std::string DateTimeFormat::RFC850_REGEX(
|
||||
"(((Monday)|(Tuesday)|(Wednesday)|(Thursday)|(Friday)|(Saturday)|(Sunday)|"
|
||||
"(Mon)|(Tue)|(Wed)|(Thu)|(Fri)|(Sat)|(Sun)), *)?"
|
||||
"\\d\\d?-((Jan)|(Feb)|(Mar)|(Apr)|(May)|(Jun)|(Jul)|(Aug)|(Sep)|(Oct)|(Nov)|(Dec))-"
|
||||
"\\d\\d(\\d\\d)? +\\d\\d:\\d\\d(:\\d\\d)? "
|
||||
"(" TIMEZONES_REGEX_PART "|)?+"
|
||||
"(([+\\-]?\\d\\d\\d\\d)?|" TIMEZONES_REGEX_PART "|\\w)");
|
||||
|
||||
const std::string DateTimeFormat::RFC1036_FORMAT("%W, %e %b %y %H:%M:%S %Z");
|
||||
const std::string DateTimeFormat::RFC1036_REGEX(
|
||||
"(((Monday)|(Tuesday)|(Wednesday)|(Thursday)|(Friday)|(Saturday)|(Sun)), *)?"
|
||||
"\\d\\d? +"
|
||||
"((Jan)|(Feb)|(Mar)|(Apr)|(May)|(Jun)|(Jul)|(Aug)|(Sep)|(Oct)|(Nov)|(Dec)) +"
|
||||
"\\d\\d(\\d\\d)? +\\d\\d:\\d\\d(:\\d\\d)? "
|
||||
"(" TIMEZONES_REGEX_PART "|)?+"
|
||||
"(([+\\-]?\\d\\d\\d\\d)?|" TIMEZONES_REGEX_PART "|\\w)");
|
||||
|
||||
// It would perhaps be useful to add RFC 2822 (successor of 822)
|
||||
// https://www.rfc-editor.org/rfc/rfc2822#section-3.3
|
||||
|
||||
const std::string DateTimeFormat::ASCTIME_FORMAT("%w %b %f %H:%M:%S %Y");
|
||||
const std::string DateTimeFormat::ASCTIME_REGEX("((Mon)|(Tue)|(Wed)|(Thu)|(Fri)|(Sat)|(Sun)) +"
|
||||
"((Jan)|(Feb)|(Mar)|(Apr)|(May)|(Jun)|(Jul)|(Aug)|(Sep)|(Oct)|(Nov)|(Dec)) +"
|
||||
"\\d\\d? +\\d\\d:\\d\\d:\\d\\d +(\\d\\d\\d\\d)");
|
||||
|
||||
const std::string DateTimeFormat::SORTABLE_FORMAT("%Y-%m-%d %H:%M:%S");
|
||||
const std::string DateTimeFormat::SORTABLE_REGEX("(\\d\\d\\d\\d-\\d\\d-\\d\\d \\d\\d:\\d\\d:\\d\\d)");
|
||||
|
||||
|
||||
DateTimeFormat::Formatlist DateTimeFormat::FORMAT_LIST(
|
||||
{
|
||||
DateTimeFormat::ISO8601_FORMAT,
|
||||
DateTimeFormat::ISO8601_FRAC_FORMAT,
|
||||
DateTimeFormat::RFC822_FORMAT,
|
||||
DateTimeFormat::RFC1123_FORMAT,
|
||||
DateTimeFormat::HTTP_FORMAT,
|
||||
DateTimeFormat::RFC850_FORMAT,
|
||||
DateTimeFormat::RFC1036_FORMAT,
|
||||
DateTimeFormat::ASCTIME_FORMAT,
|
||||
DateTimeFormat::SORTABLE_FORMAT
|
||||
});
|
||||
|
||||
|
||||
const std::string DateTimeFormat::WEEKDAY_NAMES[] =
|
||||
@ -58,4 +129,33 @@ const std::string DateTimeFormat::MONTH_NAMES[] =
|
||||
};
|
||||
|
||||
|
||||
DateTimeFormat::RegexList DateTimeFormat::REGEX_LIST =
|
||||
{
|
||||
&DateTimeFormat::ISO8601_REGEX,
|
||||
&DateTimeFormat::RFC822_REGEX,
|
||||
&DateTimeFormat::RFC1123_REGEX,
|
||||
&DateTimeFormat::HTTP_REGEX,
|
||||
&DateTimeFormat::RFC850_REGEX,
|
||||
&DateTimeFormat::RFC1036_REGEX,
|
||||
&DateTimeFormat::ASCTIME_REGEX,
|
||||
&DateTimeFormat::SORTABLE_REGEX
|
||||
};
|
||||
|
||||
|
||||
bool DateTimeFormat::hasFormat(const std::string& fmt)
|
||||
{
|
||||
return FORMAT_LIST.find(fmt) != FORMAT_LIST.end();
|
||||
}
|
||||
|
||||
|
||||
bool DateTimeFormat::isValid(const std::string& dateTime)
|
||||
{
|
||||
for (const auto& f : REGEX_LIST)
|
||||
{
|
||||
if (RegularExpression(*f).match(dateTime)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
|
@ -44,8 +44,8 @@ namespace Poco {
|
||||
|
||||
void DateTimeParser::parse(const std::string& fmt, const std::string& str, DateTime& dateTime, int& timeZoneDifferential)
|
||||
{
|
||||
if (fmt.empty() || str.empty())
|
||||
throw SyntaxException("Empty string.");
|
||||
if (fmt.empty() || str.empty() || (DateTimeFormat::hasFormat(fmt) && !DateTimeFormat::isValid(str)))
|
||||
throw SyntaxException("Invalid DateTimeString:" + str);
|
||||
|
||||
int year = 0;
|
||||
int month = 0;
|
||||
@ -57,6 +57,9 @@ void DateTimeParser::parse(const std::string& fmt, const std::string& str, DateT
|
||||
int micros = 0;
|
||||
int tzd = 0;
|
||||
|
||||
bool dayParsed = false;
|
||||
bool monthParsed = false;
|
||||
|
||||
std::string::const_iterator it = str.begin();
|
||||
std::string::const_iterator end = str.end();
|
||||
std::string::const_iterator itf = fmt.begin();
|
||||
@ -78,18 +81,21 @@ void DateTimeParser::parse(const std::string& fmt, const std::string& str, DateT
|
||||
case 'b':
|
||||
case 'B':
|
||||
month = parseMonth(it, end);
|
||||
monthParsed = true;
|
||||
break;
|
||||
case 'd':
|
||||
case 'e':
|
||||
case 'f':
|
||||
SKIP_JUNK();
|
||||
PARSE_NUMBER_N(day, 2);
|
||||
dayParsed = true;
|
||||
break;
|
||||
case 'm':
|
||||
case 'n':
|
||||
case 'o':
|
||||
SKIP_JUNK();
|
||||
PARSE_NUMBER_N(month, 2);
|
||||
monthParsed = true;
|
||||
break;
|
||||
case 'y':
|
||||
SKIP_JUNK();
|
||||
@ -167,12 +173,13 @@ void DateTimeParser::parse(const std::string& fmt, const std::string& str, DateT
|
||||
}
|
||||
else ++itf;
|
||||
}
|
||||
if (month == 0) month = 1;
|
||||
if (day == 0) day = 1;
|
||||
if (!monthParsed) month = 1;
|
||||
if (!dayParsed) day = 1;
|
||||
if (DateTime::isValid(year, month, day, hour, minute, second, millis, micros))
|
||||
dateTime.assign(year, month, day, hour, minute, second, millis, micros);
|
||||
else
|
||||
throw SyntaxException("date/time component out of range");
|
||||
|
||||
timeZoneDifferential = tzd;
|
||||
}
|
||||
|
||||
@ -191,7 +198,7 @@ bool DateTimeParser::tryParse(const std::string& fmt, const std::string& str, Da
|
||||
{
|
||||
parse(fmt, str, dateTime, timeZoneDifferential);
|
||||
}
|
||||
catch (Exception&)
|
||||
catch (const Exception&)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@ -245,53 +252,55 @@ int DateTimeParser::parseTZD(std::string::const_iterator& it, const std::string:
|
||||
{
|
||||
const char* designator;
|
||||
int timeZoneDifferential;
|
||||
bool allowsDifference;
|
||||
};
|
||||
|
||||
static Zone zones[] =
|
||||
static const Zone zones[] =
|
||||
{
|
||||
{"Z", 0},
|
||||
{"UT", 0},
|
||||
{"GMT", 0},
|
||||
{"BST", 1*3600},
|
||||
{"IST", 1*3600},
|
||||
{"WET", 0},
|
||||
{"WEST", 1*3600},
|
||||
{"CET", 1*3600},
|
||||
{"CEST", 2*3600},
|
||||
{"EET", 2*3600},
|
||||
{"EEST", 3*3600},
|
||||
{"MSK", 3*3600},
|
||||
{"MSD", 4*3600},
|
||||
{"NST", -3*3600-1800},
|
||||
{"NDT", -2*3600-1800},
|
||||
{"AST", -4*3600},
|
||||
{"ADT", -3*3600},
|
||||
{"EST", -5*3600},
|
||||
{"EDT", -4*3600},
|
||||
{"CST", -6*3600},
|
||||
{"CDT", -5*3600},
|
||||
{"MST", -7*3600},
|
||||
{"MDT", -6*3600},
|
||||
{"PST", -8*3600},
|
||||
{"PDT", -7*3600},
|
||||
{"AKST", -9*3600},
|
||||
{"AKDT", -8*3600},
|
||||
{"HST", -10*3600},
|
||||
{"AEST", 10*3600},
|
||||
{"AEDT", 11*3600},
|
||||
{"ACST", 9*3600+1800},
|
||||
{"ACDT", 10*3600+1800},
|
||||
{"AWST", 8*3600},
|
||||
{"AWDT", 9*3600}
|
||||
{"Z", 0, true},
|
||||
{"UT", 0, true},
|
||||
{"GMT", 0, true},
|
||||
{"BST", 1*3600, false},
|
||||
{"IST", 1*3600, false},
|
||||
{"WET", 0, false},
|
||||
{"WEST", 1*3600, false},
|
||||
{"CET", 1*3600, false},
|
||||
{"CEST", 2*3600, false},
|
||||
{"EET", 2*3600, false},
|
||||
{"EEST", 3*3600, false},
|
||||
{"MSK", 3*3600, false},
|
||||
{"MSD", 4*3600, false},
|
||||
{"NST", -3*3600-1800, false},
|
||||
{"NDT", -2*3600-1800, false},
|
||||
{"AST", -4*3600, false},
|
||||
{"ADT", -3*3600, false},
|
||||
{"EST", -5*3600, false},
|
||||
{"EDT", -4*3600, false},
|
||||
{"CST", -6*3600, false},
|
||||
{"CDT", -5*3600, false},
|
||||
{"MST", -7*3600, false},
|
||||
{"MDT", -6*3600, false},
|
||||
{"PST", -8*3600, false},
|
||||
{"PDT", -7*3600, false},
|
||||
{"AKST", -9*3600, false},
|
||||
{"AKDT", -8*3600, false},
|
||||
{"HST", -10*3600, false},
|
||||
{"AEST", 10*3600, false},
|
||||
{"AEDT", 11*3600, false},
|
||||
{"ACST", 9*3600+1800, false},
|
||||
{"ACDT", 10*3600+1800, false},
|
||||
{"AWST", 8*3600, false},
|
||||
{"AWDT", 9*3600, false}
|
||||
};
|
||||
|
||||
int tzd = 0;
|
||||
while (it != end && Ascii::isSpace(*it)) ++it;
|
||||
const Zone* zone = nullptr;
|
||||
std::string designator;
|
||||
if (it != end)
|
||||
{
|
||||
if (Ascii::isAlpha(*it))
|
||||
{
|
||||
std::string designator;
|
||||
designator += *it++;
|
||||
if (it != end && Ascii::isAlpha(*it)) designator += *it++;
|
||||
if (it != end && Ascii::isAlpha(*it)) designator += *it++;
|
||||
@ -300,20 +309,33 @@ int DateTimeParser::parseTZD(std::string::const_iterator& it, const std::string:
|
||||
{
|
||||
if (designator == zones[i].designator)
|
||||
{
|
||||
tzd = zones[i].timeZoneDifferential;
|
||||
zone = &(zones[i]);
|
||||
tzd = zone->timeZoneDifferential;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!designator.empty() && !zone)
|
||||
throw SyntaxException("Unknown timezone designator "s + designator);
|
||||
|
||||
if (it != end && (*it == '+' || *it == '-'))
|
||||
{
|
||||
// Time difference is allowed only for some timezone designators in general
|
||||
// Some formats prevent even that with regular expression
|
||||
if (zone && !zone->allowsDifference)
|
||||
throw SyntaxException("Timezone does not allow difference "s + zone->designator);
|
||||
|
||||
int sign = *it == '+' ? 1 : -1;
|
||||
++it;
|
||||
int hours = 0;
|
||||
PARSE_NUMBER_N(hours, 2);
|
||||
if (hours < 0 || hours > 23)
|
||||
throw SyntaxException("Timezone difference hours out of range");
|
||||
if (it != end && *it == ':') ++it;
|
||||
int minutes = 0;
|
||||
PARSE_NUMBER_N(minutes, 2);
|
||||
if (minutes < 0 || minutes > 59)
|
||||
throw SyntaxException("Timezone difference minutes out of range");
|
||||
tzd += sign*(hours*3600 + minutes*60);
|
||||
}
|
||||
}
|
||||
|
@ -64,7 +64,7 @@ namespace
|
||||
namespace Poco {
|
||||
|
||||
|
||||
RegularExpression::RegularExpression(const std::string& pattern, int options, bool /*study*/): _pcre(0)
|
||||
RegularExpression::RegularExpression(const std::string& pattern, int options, bool /*study*/): _pcre(nullptr)
|
||||
{
|
||||
int errorCode;
|
||||
PCRE2_SIZE errorOffset;
|
||||
|
@ -24,6 +24,7 @@ using Poco::DateTimeParser;
|
||||
using Poco::Timestamp;
|
||||
using Poco::SyntaxException;
|
||||
|
||||
using namespace std::string_literals;
|
||||
|
||||
DateTimeParserTest::DateTimeParserTest(const std::string& name): CppUnit::TestCase(name)
|
||||
{
|
||||
@ -46,6 +47,17 @@ void DateTimeParserTest::testISO8601()
|
||||
assertTrue (dt.minute() == 30);
|
||||
assertTrue (dt.second() == 0);
|
||||
assertTrue (tzd == 0);
|
||||
testBad(DateTimeFormat::ISO8601_FRAC_FORMAT, "2005-01-08T12.30:00Z", tzd);
|
||||
testBad(DateTimeFormat::ISO8601_FRAC_FORMAT, "2005-00-08T12:30:00Z", tzd);
|
||||
testBad(DateTimeFormat::ISO8601_FRAC_FORMAT, "2005-01-00T12:30:00Z", tzd);
|
||||
testBad(DateTimeFormat::ISO8601_FRAC_FORMAT, "2005-01-00T33:30:00Z", tzd);
|
||||
testBad(DateTimeFormat::ISO8601_FRAC_FORMAT, "2005-01-00T12:80:00Z", tzd);
|
||||
testBad(DateTimeFormat::ISO8601_FRAC_FORMAT, "2005-01-00T12:30:90Z", tzd);
|
||||
testBad(DateTimeFormat::ISO8601_FRAC_FORMAT, "2005-01-0012:30:90Z", tzd);
|
||||
testBad(DateTimeFormat::ISO8601_FRAC_FORMAT, "2005-01-00X12:30:90Z", tzd);
|
||||
testBad(DateTimeFormat::ISO8601_FRAC_FORMAT, "200501-00T12:30:90Z", tzd);
|
||||
testBad(DateTimeFormat::ISO8601_FRAC_FORMAT, "2005-0100T12:30:90Z", tzd);
|
||||
testBad(DateTimeFormat::ISO8601_FRAC_FORMAT, "2005_01+00T12:30:90Z", tzd);
|
||||
|
||||
dt = DateTimeParser::parse(DateTimeFormat::ISO8601_FORMAT, "2005-01-08T12:30:00+01:00", tzd);
|
||||
assertTrue (dt.year() == 2005);
|
||||
@ -55,6 +67,9 @@ void DateTimeParserTest::testISO8601()
|
||||
assertTrue (dt.minute() == 30);
|
||||
assertTrue (dt.second() == 0);
|
||||
assertTrue (tzd == 3600);
|
||||
testBad(DateTimeFormat::ISO8601_FRAC_FORMAT, "2005-01-8T12:30:00+01:00", tzd);
|
||||
testBad(DateTimeFormat::ISO8601_FRAC_FORMAT, "2005-01-08T12:30:00+41:00", tzd);
|
||||
testBad(DateTimeFormat::ISO8601_FRAC_FORMAT, "2005-01-08T12:30:00+01:70", tzd);
|
||||
|
||||
dt = DateTimeParser::parse(DateTimeFormat::ISO8601_FORMAT, "2005-01-08T12:30:00-01:00", tzd);
|
||||
assertTrue (dt.year() == 2005);
|
||||
@ -64,6 +79,7 @@ void DateTimeParserTest::testISO8601()
|
||||
assertTrue (dt.minute() == 30);
|
||||
assertTrue (dt.second() == 0);
|
||||
assertTrue (tzd == -3600);
|
||||
testBad(DateTimeFormat::ISO8601_FRAC_FORMAT, "2005-01-0812:30:00-01:00", tzd);
|
||||
|
||||
dt = DateTimeParser::parse(DateTimeFormat::ISO8601_FORMAT, "2005-01-08T12:30:00", tzd);
|
||||
assertTrue (dt.year() == 2005);
|
||||
@ -73,6 +89,7 @@ void DateTimeParserTest::testISO8601()
|
||||
assertTrue (dt.minute() == 30);
|
||||
assertTrue (dt.second() == 0);
|
||||
assertTrue (tzd == 0);
|
||||
testBad(DateTimeFormat::ISO8601_FRAC_FORMAT, "2005-01-08T12:30:0", tzd);
|
||||
|
||||
dt = DateTimeParser::parse(DateTimeFormat::ISO8601_FORMAT, "2005-01-08", tzd);
|
||||
assertTrue (dt.year() == 2005);
|
||||
@ -82,6 +99,7 @@ void DateTimeParserTest::testISO8601()
|
||||
assertTrue (dt.minute() == 0);
|
||||
assertTrue (dt.second() == 0);
|
||||
assertTrue (tzd == 0);
|
||||
testBad(DateTimeFormat::ISO8601_FRAC_FORMAT, "2005-01-8", tzd);
|
||||
}
|
||||
|
||||
|
||||
@ -98,6 +116,7 @@ void DateTimeParserTest::testISO8601Frac()
|
||||
assertTrue (dt.millisecond() == 0);
|
||||
assertTrue (dt.microsecond() == 0);
|
||||
assertTrue (tzd == 0);
|
||||
testBad(DateTimeFormat::ISO8601_FRAC_FORMAT, "2005-1-08T12:30:00Z", tzd);
|
||||
|
||||
dt = DateTimeParser::parse(DateTimeFormat::ISO8601_FRAC_FORMAT, "2005-01-08T12:30:00+01:00", tzd);
|
||||
assertTrue (dt.year() == 2005);
|
||||
@ -109,6 +128,7 @@ void DateTimeParserTest::testISO8601Frac()
|
||||
assertTrue (dt.millisecond() == 0);
|
||||
assertTrue (dt.microsecond() == 0);
|
||||
assertTrue (tzd == 3600);
|
||||
testBad(DateTimeFormat::ISO8601_FRAC_FORMAT, "2005-01-08Z12:30:00+01:00", tzd);
|
||||
|
||||
dt = DateTimeParser::parse(DateTimeFormat::ISO8601_FRAC_FORMAT, "2005-01-08T12:30:00-01:00", tzd);
|
||||
assertTrue (dt.year() == 2005);
|
||||
@ -120,6 +140,7 @@ void DateTimeParserTest::testISO8601Frac()
|
||||
assertTrue (dt.millisecond() == 0);
|
||||
assertTrue (dt.microsecond() == 0);
|
||||
assertTrue (tzd == -3600);
|
||||
testBad(DateTimeFormat::ISO8601_FRAC_FORMAT, "2005-01-08T12:30:00-01.00", tzd);
|
||||
|
||||
dt = DateTimeParser::parse(DateTimeFormat::ISO8601_FRAC_FORMAT, "2005-01-08T12:30:00", tzd);
|
||||
assertTrue (dt.year() == 2005);
|
||||
@ -131,6 +152,7 @@ void DateTimeParserTest::testISO8601Frac()
|
||||
assertTrue (dt.millisecond() == 0);
|
||||
assertTrue (dt.microsecond() == 0);
|
||||
assertTrue (tzd == 0);
|
||||
testBad(DateTimeFormat::ISO8601_FRAC_FORMAT, "2005-01-08T12;30:00", tzd);
|
||||
|
||||
dt = DateTimeParser::parse(DateTimeFormat::ISO8601_FRAC_FORMAT, "2005-01-08", tzd);
|
||||
assertTrue (dt.year() == 2005);
|
||||
@ -142,6 +164,7 @@ void DateTimeParserTest::testISO8601Frac()
|
||||
assertTrue (dt.millisecond() == 0);
|
||||
assertTrue (dt.microsecond() == 0);
|
||||
assertTrue (tzd == 0);
|
||||
testBad(DateTimeFormat::ISO8601_FRAC_FORMAT, "2005-01+08", tzd);
|
||||
|
||||
dt = DateTimeParser::parse(DateTimeFormat::ISO8601_FRAC_FORMAT, "2005-01-08T12:30:00.1Z", tzd);
|
||||
assertTrue (dt.year() == 2005);
|
||||
@ -153,6 +176,7 @@ void DateTimeParserTest::testISO8601Frac()
|
||||
assertTrue (dt.millisecond() == 100);
|
||||
assertTrue (dt.microsecond() == 0);
|
||||
assertTrue (tzd == 0);
|
||||
testBad(DateTimeFormat::ISO8601_FRAC_FORMAT, "2005-01-08T12:30:00.1J", tzd);
|
||||
|
||||
dt = DateTimeParser::parse(DateTimeFormat::ISO8601_FRAC_FORMAT, "2005-01-08T12:30:00.123+01:00", tzd);
|
||||
assertTrue (dt.year() == 2005);
|
||||
@ -164,6 +188,7 @@ void DateTimeParserTest::testISO8601Frac()
|
||||
assertTrue (dt.millisecond() == 123);
|
||||
assertTrue (dt.microsecond() == 0);
|
||||
assertTrue (tzd == 3600);
|
||||
testBad(DateTimeFormat::ISO8601_FRAC_FORMAT, "2005-01-08T12:30:00.123*01:00", tzd);
|
||||
|
||||
dt = DateTimeParser::parse(DateTimeFormat::ISO8601_FRAC_FORMAT, "2005-01-08T12:30:00.12345-01:00", tzd);
|
||||
assertTrue (dt.year() == 2005);
|
||||
@ -175,6 +200,7 @@ void DateTimeParserTest::testISO8601Frac()
|
||||
assertTrue (dt.millisecond() == 123);
|
||||
assertTrue (dt.microsecond() == 450);
|
||||
assertTrue (tzd == -3600);
|
||||
testBad(DateTimeFormat::ISO8601_FRAC_FORMAT, "2005-01+08T12:30:00.12345-01:00", tzd);
|
||||
|
||||
dt = DateTimeParser::parse(DateTimeFormat::ISO8601_FRAC_FORMAT, "2010-09-23T16:17:01.2817002+02:00", tzd);
|
||||
assertTrue (dt.year() == 2010);
|
||||
@ -186,6 +212,7 @@ void DateTimeParserTest::testISO8601Frac()
|
||||
assertTrue (dt.millisecond() == 281);
|
||||
assertTrue (dt.microsecond() == 700);
|
||||
assertTrue (tzd == 7200);
|
||||
testBad(DateTimeFormat::ISO8601_FRAC_FORMAT, "201009-23T16:17:01.2817002+02:00", tzd);
|
||||
|
||||
dt = DateTimeParser::parse(DateTimeFormat::ISO8601_FRAC_FORMAT, "2005-01-08T12:30:00", tzd);
|
||||
assertTrue (dt.year() == 2005);
|
||||
@ -197,6 +224,7 @@ void DateTimeParserTest::testISO8601Frac()
|
||||
assertTrue (dt.millisecond() == 0);
|
||||
assertTrue (dt.microsecond() == 0);
|
||||
assertTrue (tzd == 0);
|
||||
testBad(DateTimeFormat::ISO8601_FRAC_FORMAT, "2005-01-08T12:30:0", tzd);
|
||||
|
||||
dt = DateTimeParser::parse(DateTimeFormat::ISO8601_FRAC_FORMAT, "2005-01-08T12:30:00.123456", tzd);
|
||||
assertTrue (dt.year() == 2005);
|
||||
@ -208,6 +236,7 @@ void DateTimeParserTest::testISO8601Frac()
|
||||
assertTrue (dt.millisecond() == 123);
|
||||
assertTrue (dt.microsecond() == 456);
|
||||
assertTrue (tzd == 0);
|
||||
testBad(DateTimeFormat::ISO8601_FRAC_FORMAT, "005-01-08T12:30:00.123456", tzd);
|
||||
|
||||
dt = DateTimeParser::parse(DateTimeFormat::ISO8601_FRAC_FORMAT, "2005-01-08", tzd);
|
||||
assertTrue (dt.year() == 2005);
|
||||
@ -219,6 +248,10 @@ void DateTimeParserTest::testISO8601Frac()
|
||||
assertTrue (dt.millisecond() == 0);
|
||||
assertTrue (dt.microsecond() == 0);
|
||||
assertTrue (tzd == 0);
|
||||
testBad(DateTimeFormat::ISO8601_FRAC_FORMAT, "2005-01-0", tzd);
|
||||
|
||||
testBad(DateTimeFormat::ISO8601_FRAC_FORMAT, "jnghjgnbcfjb", tzd);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -233,6 +266,7 @@ void DateTimeParserTest::testRFC822()
|
||||
assertTrue (dt.minute() == 30);
|
||||
assertTrue (dt.second() == 0);
|
||||
assertTrue (tzd == 0);
|
||||
testBad(DateTimeFormat::RFC822_FORMAT, "at, 8 Jan 05 12:30:00 GMT", tzd);
|
||||
|
||||
dt = DateTimeParser::parse(DateTimeFormat::RFC822_FORMAT, "Sat, 8 Jan 05 12:30:00 +0100", tzd);
|
||||
assertTrue (dt.year() == 2005);
|
||||
@ -242,6 +276,7 @@ void DateTimeParserTest::testRFC822()
|
||||
assertTrue (dt.minute() == 30);
|
||||
assertTrue (dt.second() == 0);
|
||||
assertTrue (tzd == 3600);
|
||||
testBad(DateTimeFormat::RFC822_FORMAT, "Sat, x Jan 05 12:30:00 +0100", tzd);
|
||||
|
||||
dt = DateTimeParser::parse(DateTimeFormat::RFC822_FORMAT, "Sat, 8 Jan 05 12:30:00 -0100", tzd);
|
||||
assertTrue (dt.year() == 2005);
|
||||
@ -251,6 +286,7 @@ void DateTimeParserTest::testRFC822()
|
||||
assertTrue (dt.minute() == 30);
|
||||
assertTrue (dt.second() == 0);
|
||||
assertTrue (tzd == -3600);
|
||||
testBad(DateTimeFormat::RFC822_FORMAT, "Sat, 8 Jan 05 12:30:00 *0100", tzd);
|
||||
|
||||
dt = DateTimeParser::parse(DateTimeFormat::RFC822_FORMAT, "Tue, 18 Jan 05 12:30:00 CET", tzd);
|
||||
assertTrue (dt.year() == 2005);
|
||||
@ -260,6 +296,7 @@ void DateTimeParserTest::testRFC822()
|
||||
assertTrue (dt.minute() == 30);
|
||||
assertTrue (dt.second() == 0);
|
||||
assertTrue (tzd == 3600);
|
||||
testBad(DateTimeFormat::RFC822_FORMAT, "Tue, 18 Jan 05 12:30:00 abc", tzd);
|
||||
|
||||
dt = DateTimeParser::parse(DateTimeFormat::RFC822_FORMAT, "Wed, 12 Sep 73 02:01:12 CEST", tzd);
|
||||
assertTrue (dt.year() == 1973);
|
||||
@ -269,6 +306,7 @@ void DateTimeParserTest::testRFC822()
|
||||
assertTrue (dt.minute() == 1);
|
||||
assertTrue (dt.second() == 12);
|
||||
assertTrue (tzd == 7200);
|
||||
testBad(DateTimeFormat::RFC822_FORMAT, "Wed, 12 Sep 73 02:01:2 CST", tzd);
|
||||
|
||||
dt = DateTimeParser::parse(DateTimeFormat::RFC822_FORMAT, "12 Sep 73 02:01:12 CEST", tzd);
|
||||
assertTrue (dt.year() == 1973);
|
||||
@ -278,6 +316,8 @@ void DateTimeParserTest::testRFC822()
|
||||
assertTrue (dt.minute() == 1);
|
||||
assertTrue (dt.second() == 12);
|
||||
assertTrue (tzd == 7200);
|
||||
|
||||
testBad(DateTimeFormat::RFC822_FORMAT, "12 Sep 73 02.01:12 EST", tzd);
|
||||
}
|
||||
|
||||
|
||||
@ -292,6 +332,7 @@ void DateTimeParserTest::testRFC1123()
|
||||
assertTrue (dt.minute() == 30);
|
||||
assertTrue (dt.second() == 0);
|
||||
assertTrue (tzd == 0);
|
||||
testBad(DateTimeFormat::RFC1123_FORMAT, "Sat, 8 Jan 2005 12:30:00 GPX", tzd);
|
||||
|
||||
dt = DateTimeParser::parse(DateTimeFormat::RFC1123_FORMAT, "Sat, 8 Jan 2005 12:30:00 +0100", tzd);
|
||||
assertTrue (dt.year() == 2005);
|
||||
@ -301,6 +342,7 @@ void DateTimeParserTest::testRFC1123()
|
||||
assertTrue (dt.minute() == 30);
|
||||
assertTrue (dt.second() == 0);
|
||||
assertTrue (tzd == 3600);
|
||||
testBad(DateTimeFormat::RFC1123_FORMAT, "Sat, 8 Jan 2005 xy:30:00 +0100", tzd);
|
||||
|
||||
dt = DateTimeParser::parse(DateTimeFormat::RFC1123_FORMAT, "Sat, 8 Jan 2005 12:30:00 -0100", tzd);
|
||||
assertTrue (dt.year() == 2005);
|
||||
@ -310,6 +352,7 @@ void DateTimeParserTest::testRFC1123()
|
||||
assertTrue (dt.minute() == 30);
|
||||
assertTrue (dt.second() == 0);
|
||||
assertTrue (tzd == -3600);
|
||||
testBad(DateTimeFormat::RFC1123_FORMAT, "Sat, 8 Jan 205 12:30:00 -0100", tzd);
|
||||
|
||||
dt = DateTimeParser::parse(DateTimeFormat::RFC1123_FORMAT, "Sun, 20 Jul 1969 16:17:30 EDT", tzd);
|
||||
assertTrue (dt.year() == 1969);
|
||||
@ -319,15 +362,41 @@ void DateTimeParserTest::testRFC1123()
|
||||
assertTrue (dt.minute() == 17);
|
||||
assertTrue (dt.second() == 30);
|
||||
assertTrue (tzd == -14400);
|
||||
testBad(DateTimeFormat::RFC1123_FORMAT, "Hue, 18 Jan 2005 12:30:00 EDT", tzd);
|
||||
|
||||
dt = DateTimeParser::parse(DateTimeFormat::RFC1123_FORMAT, "Sun, 20 Jul 1969 16:17:30 GMT+01:00", tzd);
|
||||
assertTrue (dt.year() == 1969);
|
||||
assertTrue (dt.month() == 7);
|
||||
assertTrue (dt.day() == 20);
|
||||
assertTrue (dt.hour() == 16);
|
||||
assertTrue (dt.minute() == 17);
|
||||
assertTrue (dt.second() == 30);
|
||||
assertTrue (tzd == 3600);
|
||||
testBad(DateTimeFormat::RFC1123_FORMAT, "Sun, 20 Jul 1969 16:17:30 GMT+01:00", tzd);
|
||||
testBad(DateTimeFormat::RFC1123_FORMAT, "Sun, 20 Jul 1969 16:17:30 GMT+01?00", tzd);
|
||||
|
||||
dt = DateTimeParser::parse(DateTimeFormat::RFC1123_FORMAT, "Tue, 18 Jan 2005 12:30:00 CDT", tzd);
|
||||
assertTrue (dt.year() == 2005);
|
||||
assertTrue (dt.month() == 1);
|
||||
assertTrue (dt.day() == 18);
|
||||
assertTrue (dt.hour() == 12);
|
||||
assertTrue (dt.minute() == 30);
|
||||
assertTrue (dt.second() == 0);
|
||||
assertTrue (tzd == -18000);
|
||||
testBad(DateTimeFormat::RFC1123_FORMAT, "Hue, 18 Jan 2005 12:30:00 CDT", tzd);
|
||||
|
||||
dt = DateTimeParser::parse(DateTimeFormat::RFC1123_FORMAT, "Wed, 12 Sep 1973 02:01:12 CST", tzd);
|
||||
assertTrue (dt.year() == 1973);
|
||||
assertTrue (dt.month() == 9);
|
||||
assertTrue (dt.day() == 12);
|
||||
assertTrue (dt.hour() == 2);
|
||||
assertTrue (dt.minute() == 1);
|
||||
assertTrue (dt.second() == 12);
|
||||
assertTrue (tzd == -21600);
|
||||
testBad(DateTimeFormat::RFC1123_FORMAT, "Wed, 12 Sp 1973 02:01:12 CST", tzd);
|
||||
|
||||
dt = DateTimeParser::parse(DateTimeFormat::RFC1123_FORMAT, "12 Sep 1973 02:01:12 EST", tzd);
|
||||
assertTrue (dt.year() == 1973);
|
||||
assertTrue (dt.month() == 9);
|
||||
assertTrue (dt.day() == 12);
|
||||
assertTrue (dt.hour() == 2);
|
||||
assertTrue (dt.minute() == 1);
|
||||
assertTrue (dt.second() == 12);
|
||||
assertTrue (tzd == -18000);
|
||||
testBad(DateTimeFormat::RFC1123_FORMAT, "12 Sep 193 02:01:12 EST", tzd);
|
||||
testBad(DateTimeFormat::RFC1123_FORMAT, "12 Sep 1973 02:01:12 ABC", tzd);
|
||||
}
|
||||
|
||||
|
||||
@ -342,6 +411,7 @@ void DateTimeParserTest::testHTTP()
|
||||
assertTrue (dt.minute() == 30);
|
||||
assertTrue (dt.second() == 0);
|
||||
assertTrue (tzd == 0);
|
||||
testBad(DateTimeFormat::HTTP_FORMAT, "Sat, 08 Jn 2005 12:30:00 GMT", tzd);
|
||||
|
||||
dt = DateTimeParser::parse(DateTimeFormat::HTTP_FORMAT, "Sat, 08 Jan 2005 12:30:00 +0100", tzd);
|
||||
assertTrue (dt.year() == 2005);
|
||||
@ -351,6 +421,7 @@ void DateTimeParserTest::testHTTP()
|
||||
assertTrue (dt.minute() == 30);
|
||||
assertTrue (dt.second() == 0);
|
||||
assertTrue (tzd == 3600);
|
||||
testBad(DateTimeFormat::HTTP_FORMAT, "Sat, 08 Jan 2005 12:30:00 j0100", tzd);
|
||||
|
||||
dt = DateTimeParser::parse(DateTimeFormat::HTTP_FORMAT, "Sat, 08 Jan 2005 12:30:00 -0100", tzd);
|
||||
assertTrue (dt.year() == 2005);
|
||||
@ -360,6 +431,7 @@ void DateTimeParserTest::testHTTP()
|
||||
assertTrue (dt.minute() == 30);
|
||||
assertTrue (dt.second() == 0);
|
||||
assertTrue (tzd == -3600);
|
||||
testBad(DateTimeFormat::HTTP_FORMAT, "Sat 08 Jan 2005 12:30:00 -0100", tzd);
|
||||
}
|
||||
|
||||
|
||||
@ -374,6 +446,7 @@ void DateTimeParserTest::testRFC850()
|
||||
assertTrue (dt.minute() == 30);
|
||||
assertTrue (dt.second() == 0);
|
||||
assertTrue (tzd == 0);
|
||||
testBad(DateTimeFormat::RFC850_FORMAT, "Saturday, 8-Jan 05 12:30:00 GMT", tzd);
|
||||
|
||||
dt = DateTimeParser::parse(DateTimeFormat::RFC850_FORMAT, "Saturday, 8-Jan-05 12:30:00 +0100", tzd);
|
||||
assertTrue (dt.year() == 2005);
|
||||
@ -383,6 +456,7 @@ void DateTimeParserTest::testRFC850()
|
||||
assertTrue (dt.minute() == 30);
|
||||
assertTrue (dt.second() == 0);
|
||||
assertTrue (tzd == 3600);
|
||||
testBad(DateTimeFormat::RFC850_FORMAT, "Saturday, 8+Jan-05 12:30:00 +0100", tzd);
|
||||
|
||||
dt = DateTimeParser::parse(DateTimeFormat::RFC850_FORMAT, "Saturday, 8-Jan-05 12:30:00 -0100", tzd);
|
||||
assertTrue (dt.year() == 2005);
|
||||
@ -392,6 +466,7 @@ void DateTimeParserTest::testRFC850()
|
||||
assertTrue (dt.minute() == 30);
|
||||
assertTrue (dt.second() == 0);
|
||||
assertTrue (tzd == -3600);
|
||||
testBad(DateTimeFormat::RFC850_FORMAT, "Saturday 8-Jan-05 12:30:00 -0100", tzd);
|
||||
|
||||
dt = DateTimeParser::parse(DateTimeFormat::RFC850_FORMAT, "Wed, 12-Sep-73 02:01:12 CEST", tzd);
|
||||
assertTrue (dt.year() == 1973);
|
||||
@ -401,6 +476,7 @@ void DateTimeParserTest::testRFC850()
|
||||
assertTrue (dt.minute() == 1);
|
||||
assertTrue (dt.second() == 12);
|
||||
assertTrue (tzd == 7200);
|
||||
testBad(DateTimeFormat::RFC850_FORMAT, "Wed, 12-pep-73 02:01:12 CST", tzd);
|
||||
}
|
||||
|
||||
|
||||
@ -415,6 +491,7 @@ void DateTimeParserTest::testRFC1036()
|
||||
assertTrue (dt.minute() == 30);
|
||||
assertTrue (dt.second() == 0);
|
||||
assertTrue (tzd == 0);
|
||||
testBad(DateTimeFormat::RFC1036_FORMAT, "Saturday, 8 Jan 0512:30:00 GMT", tzd);
|
||||
|
||||
dt = DateTimeParser::parse(DateTimeFormat::RFC1036_FORMAT, "Saturday, 8 Jan 05 12:30:00 +0100", tzd);
|
||||
assertTrue (dt.year() == 2005);
|
||||
@ -424,6 +501,7 @@ void DateTimeParserTest::testRFC1036()
|
||||
assertTrue (dt.minute() == 30);
|
||||
assertTrue (dt.second() == 0);
|
||||
assertTrue (tzd == 3600);
|
||||
testBad(DateTimeFormat::RFC1036_FORMAT, "Saturday, 8 Jan 051 12:30:00 +0100", tzd);
|
||||
|
||||
dt = DateTimeParser::parse(DateTimeFormat::RFC1036_FORMAT, "Saturday, 8 Jan 05 12:30:00 -0100", tzd);
|
||||
assertTrue (dt.year() == 2005);
|
||||
@ -433,6 +511,7 @@ void DateTimeParserTest::testRFC1036()
|
||||
assertTrue (dt.minute() == 30);
|
||||
assertTrue (dt.second() == 0);
|
||||
assertTrue (tzd == -3600);
|
||||
testBad(DateTimeFormat::RFC1036_FORMAT, "Saturday, 8 Jan 05 12:30:00 -0100x", tzd);
|
||||
}
|
||||
|
||||
|
||||
@ -447,6 +526,7 @@ void DateTimeParserTest::testASCTIME()
|
||||
assertTrue (dt.minute() == 30);
|
||||
assertTrue (dt.second() == 0);
|
||||
assertTrue (tzd == 0);
|
||||
testBad(DateTimeFormat::ASCTIME_FORMAT, "Bat Jan 8 12:30:00 2005", tzd);
|
||||
}
|
||||
|
||||
|
||||
@ -461,6 +541,7 @@ void DateTimeParserTest::testSORTABLE()
|
||||
assertTrue (dt.minute() == 30);
|
||||
assertTrue (dt.second() == 0);
|
||||
assertTrue (tzd == 0);
|
||||
testBad(DateTimeFormat::SORTABLE_FORMAT, "2005-01-08 12:30;00", tzd);
|
||||
|
||||
dt = DateTimeParser::parse(DateTimeFormat::SORTABLE_FORMAT, "2005-01-08", tzd);
|
||||
assertTrue (dt.year() == 2005);
|
||||
@ -470,6 +551,7 @@ void DateTimeParserTest::testSORTABLE()
|
||||
assertTrue (dt.minute() == 0);
|
||||
assertTrue (dt.second() == 0);
|
||||
assertTrue (tzd == 0);
|
||||
testBad(DateTimeFormat::SORTABLE_FORMAT, "2005+01-08", tzd);
|
||||
}
|
||||
|
||||
|
||||
@ -758,6 +840,18 @@ void DateTimeParserTest::testParseDayOfWeek()
|
||||
}
|
||||
|
||||
|
||||
void DateTimeParserTest::testBad(const std::string& fmt, const std::string& dateStr, int tzd)
|
||||
{
|
||||
try
|
||||
{
|
||||
DateTime dt;
|
||||
DateTimeParser::parse(fmt, dateStr, dt, tzd);
|
||||
fail ("must fail: "s + fmt + ", " + dateStr);
|
||||
}
|
||||
catch(const Poco::Exception&) { }
|
||||
}
|
||||
|
||||
|
||||
void DateTimeParserTest::setUp()
|
||||
{
|
||||
}
|
||||
|
@ -44,6 +44,7 @@ public:
|
||||
static CppUnit::Test* suite();
|
||||
|
||||
private:
|
||||
void testBad(const std::string& fmt, const std::string& dateStr, int tzd);
|
||||
};
|
||||
|
||||
|
||||
|
@ -136,6 +136,15 @@ void RegularExpressionTest::testMatch6()
|
||||
}
|
||||
|
||||
|
||||
void RegularExpressionTest::testMatchDateTime()
|
||||
{
|
||||
RegularExpression re(
|
||||
R"(([\+-]?\d{4}(?!\d{2}\b))((-?)((0[1-9]|1[0-2])(\3([12]\d|0[1-9]|3[01]))?|W([0-4]\d|5[0-2])(-?[1-7])?|(00[1-9]|0[1-9]\d|[12]\d{2}|3([0-5]\d|6[1-6])))([T\s]((([01]\d|2[0-3])((:?)[0-5]\d)?|24\:?00)([\.,]\d+(?!:))?)?(\17[0-5]\d([\.,]\d+)?)?([zZ]|([\+-])([01]\d|2[0-3]):?([0-5]\d)?)?)?)?)"
|
||||
);
|
||||
assert (re.match("2005-01-08T12:30:00Z"));
|
||||
}
|
||||
|
||||
|
||||
void RegularExpressionTest::testExtract()
|
||||
{
|
||||
RegularExpression re("[0-9]+");
|
||||
@ -295,6 +304,7 @@ CppUnit::Test* RegularExpressionTest::suite()
|
||||
CppUnit_addTest(pSuite, RegularExpressionTest, testMatch4);
|
||||
CppUnit_addTest(pSuite, RegularExpressionTest, testMatch5);
|
||||
CppUnit_addTest(pSuite, RegularExpressionTest, testMatch6);
|
||||
CppUnit_addTest(pSuite, RegularExpressionTest, testMatchDateTime);
|
||||
CppUnit_addTest(pSuite, RegularExpressionTest, testExtract);
|
||||
CppUnit_addTest(pSuite, RegularExpressionTest, testSplit1);
|
||||
CppUnit_addTest(pSuite, RegularExpressionTest, testSplit2);
|
||||
|
@ -31,6 +31,7 @@ public:
|
||||
void testMatch4();
|
||||
void testMatch5();
|
||||
void testMatch6();
|
||||
void testMatchDateTime();
|
||||
void testExtract();
|
||||
void testSplit1();
|
||||
void testSplit2();
|
||||
|
Loading…
x
Reference in New Issue
Block a user