enh(DateTimeParser): option to cleanup input string before parsing (#569).

This commit is contained in:
Matej Kenda 2024-01-08 11:19:37 +01:00
parent 233c1f771f
commit bbd07b6cb7
4 changed files with 45 additions and 5 deletions

View File

@ -59,24 +59,28 @@ class Foundation_API DateTimeParser
public:
static void parse(const std::string& fmt, const std::string& str, DateTime& dateTime, int& timeZoneDifferential);
/// Parses a date and time in the given format from the given string.
/// Performs cleanup of the input string (trims spaces).
/// Throws a SyntaxException if the string cannot be successfully parsed.
/// Please see DateTimeFormatter::format() for a description of the format string.
/// Class DateTimeFormat defines format strings for various standard date/time formats.
static DateTime parse(const std::string& fmt, const std::string& str, int& timeZoneDifferential);
/// Parses a date and time in the given format from the given string.
/// Performs cleanup of the input string (trims spaces).
/// Throws a SyntaxException if the string cannot be successfully parsed.
/// Please see DateTimeFormatter::format() for a description of the format string.
/// Class DateTimeFormat defines format strings for various standard date/time formats.
static bool tryParse(const std::string& fmt, const std::string& str, DateTime& dateTime, int& timeZoneDifferential);
/// Parses a date and time in the given format from the given string.
/// Performs cleanup of the input string (trims spaces).
/// Returns true if the string has been successfully parsed, false otherwise.
/// Please see DateTimeFormatter::format() for a description of the format string.
/// Class DateTimeFormat defines format strings for various standard date/time formats.
static void parse(const std::string& str, DateTime& dateTime, int& timeZoneDifferential);
/// Parses a date and time from the given dateTime string. Before parsing, the method
/// performs cleanup of the input string (trims spaces) when cleanup is true and
/// examines the dateTime string for a known date/time format.
/// Throws a SyntaxException if the string cannot be successfully parsed.
/// Please see DateTimeFormatter::format() for a description of the format string.
@ -84,12 +88,14 @@ public:
static DateTime parse(const std::string& str, int& timeZoneDifferential);
/// Parses a date and time from the given dateTime string. Before parsing, the method
/// performs cleanup of the input string (trims spaces) and
/// examines the dateTime string for a known date/time format.
/// Please see DateTimeFormatter::format() for a description of the format string.
/// Class DateTimeFormat defines format strings for various standard date/time formats.
static bool tryParse(const std::string& str, DateTime& dateTime, int& timeZoneDifferential);
/// Parses a date and time from the given dateTime string. Before parsing, the method
/// performs cleanup of the input string (trims spaces) and
/// examines the dateTime string for a known date/time format.
/// Please see DateTimeFormatter::format() for a description of the format string.
/// Class DateTimeFormat defines format strings for various standard date/time formats.

View File

@ -17,6 +17,7 @@
#include "Poco/DateTime.h"
#include "Poco/Exception.h"
#include "Poco/Ascii.h"
#include "Poco/String.h"
namespace Poco {
@ -42,10 +43,17 @@ namespace Poco {
{ int i = 0; while (i < n && it != end && Ascii::isDigit(*it)) { var = var*10 + ((*it++) - '0'); i++; } while (i++ < n) var *= 10; }
void DateTimeParser::parse(const std::string& fmt, const std::string& str, DateTime& dateTime, int& timeZoneDifferential)
inline std::string cleanedInputString(const std::string& str)
{
return Poco::trim(str);
}
void DateTimeParser::parse(const std::string& fmt, const std::string& dtStr, DateTime& dateTime, int& timeZoneDifferential)
{
const auto str = cleanedInputString(dtStr);
if (fmt.empty() || str.empty() || (DateTimeFormat::hasFormat(fmt) && !DateTimeFormat::isValid(str)))
throw SyntaxException("Invalid DateTimeString:" + str);
throw SyntaxException("Invalid DateTimeString:" + dtStr);
int year = 0;
int month = 0;
@ -223,8 +231,10 @@ DateTime DateTimeParser::parse(const std::string& str, int& timeZoneDifferential
}
bool DateTimeParser::tryParse(const std::string& str, DateTime& dateTime, int& timeZoneDifferential)
bool DateTimeParser::tryParse(const std::string& dtStr, DateTime& dateTime, int& timeZoneDifferential)
{
const auto str = cleanedInputString(dtStr);
if (str.length() < 4) return false;
if (str[3] == ',')

View File

@ -751,6 +751,28 @@ void DateTimeParserTest::testGuess()
assertTrue (tzd == 0);
}
void DateTimeParserTest::testCleanup()
{
int tzd;
DateTime dt = DateTimeParser::parse("2005-01-08T12:30:00Z", tzd);
DateTime dt2 = DateTimeParser::parse(" 2005-01-08T12:30:00Z ", tzd);
assertTrue (dt == dt2);
assertTrue(DateTimeParser::tryParse(" 2005-01-08T12:30:00Z ", dt, tzd));
dt = DateTimeParser::parse(DateTimeFormat::ISO8601_FRAC_FORMAT, "2005-01-08T12:30:00.1Z", tzd);
dt2 = DateTimeParser::parse(DateTimeFormat::ISO8601_FRAC_FORMAT, "2005-01-08T12:30:00.1Z ", tzd);
assertTrue (dt == dt2);
assertTrue(DateTimeParser::tryParse(DateTimeFormat::ISO8601_FRAC_FORMAT, " 2005-01-08T12:30:00Z ", dt, tzd));
assertFalse(DateTimeParser::tryParse(DateTimeFormat::ISO8601_FRAC_FORMAT, " ", dt, tzd));
}
void DateTimeParserTest::testParseMonth()
{
@ -790,7 +812,7 @@ void DateTimeParserTest::testParseMonth()
month = DateTimeParser::parseMonth(it, str.end());
fail("Not a valid month name - must throw");
}
catch (SyntaxException&)
catch (const SyntaxException&)
{
}
}
@ -834,7 +856,7 @@ void DateTimeParserTest::testParseDayOfWeek()
dow = DateTimeParser::parseDayOfWeek(it, str.end());
fail("Not a valid weekday name - must throw");
}
catch (SyntaxException&)
catch (const SyntaxException&)
{
}
}
@ -877,6 +899,7 @@ CppUnit::Test* DateTimeParserTest::suite()
CppUnit_addTest(pSuite, DateTimeParserTest, testSORTABLE);
CppUnit_addTest(pSuite, DateTimeParserTest, testCustom);
CppUnit_addTest(pSuite, DateTimeParserTest, testGuess);
CppUnit_addTest(pSuite, DateTimeParserTest, testCleanup);
CppUnit_addTest(pSuite, DateTimeParserTest, testParseMonth);
CppUnit_addTest(pSuite, DateTimeParserTest, testParseDayOfWeek);

View File

@ -35,6 +35,7 @@ public:
void testSORTABLE();
void testCustom();
void testGuess();
void testCleanup();
void testParseMonth();
void testParseDayOfWeek();