mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
RiaDateStringParser: add option for day-first parsing of ambiguous date strings.
This commit is contained in:
parent
abc9e82ff5
commit
061e0d4688
@ -29,34 +29,27 @@ const std::string MONTH_NAMES[] =
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QDateTime RiaDateStringParser::parseDateString( const QString& dateString )
|
||||
QDateTime RiaDateStringParser::parseDateString( const QString& dateString, OrderPreference preference )
|
||||
{
|
||||
return RiaDateStringParser::parseDateString( dateString.toStdString() );
|
||||
return RiaDateStringParser::parseDateString( dateString.toStdString(), preference );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QDateTime RiaDateStringParser::parseDateString( const std::string& dateString )
|
||||
QDateTime RiaDateStringParser::parseDateString( const std::string& dateString, OrderPreference preference )
|
||||
{
|
||||
int year = -1, month = -1, day = -1;
|
||||
bool parsedOk = false;
|
||||
|
||||
if ( hasSeparators( dateString ) )
|
||||
{
|
||||
parsedOk = tryParseYearFirst( dateString, year, month, day ) ||
|
||||
tryParseDayFirst( dateString, year, month, day ) || tryParseMonthFirst( dateString, year, month, day );
|
||||
parsedOk = parseDateStringWithSeparators( dateString, year, month, day, preference );
|
||||
}
|
||||
|
||||
if ( !parsedOk )
|
||||
{
|
||||
auto firstNumerical = dateString.find_first_of( "0123456789" );
|
||||
if ( firstNumerical != std::string::npos )
|
||||
{
|
||||
std::string subString = dateString.substr( firstNumerical );
|
||||
|
||||
parsedOk = tryParseYearFirstNoSeparators( subString, year, month, day ) ||
|
||||
tryParseDayFirstNoSeparators( subString, year, month, day ) ||
|
||||
tryParseMonthFirstNoSeparators( subString, year, month, day );
|
||||
}
|
||||
parsedOk = parseDateStringWithoutSeparators( dateString, year, month, day, preference );
|
||||
}
|
||||
|
||||
QDateTime dt;
|
||||
@ -66,6 +59,63 @@ QDateTime RiaDateStringParser::parseDateString( const std::string& dateString )
|
||||
return dt;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RiaDateStringParser::parseDateStringWithSeparators( const std::string& dateString,
|
||||
int& year,
|
||||
int& month,
|
||||
int& day,
|
||||
OrderPreference preference )
|
||||
{
|
||||
auto tryParseAllYearFirst = []( const std::string& dateString, int& year, int& month, int& day ) {
|
||||
return tryParseYearFirst( dateString, year, month, day ) || tryParseDayFirst( dateString, year, month, day ) ||
|
||||
tryParseMonthFirst( dateString, year, month, day );
|
||||
};
|
||||
|
||||
auto tryParseAllDayFirst = []( const std::string& dateString, int& year, int& month, int& day ) {
|
||||
return tryParseDayFirst( dateString, year, month, day ) || tryParseYearFirst( dateString, year, month, day ) ||
|
||||
tryParseMonthFirst( dateString, year, month, day );
|
||||
};
|
||||
|
||||
return ( preference == OrderPreference::YEAR_FIRST ) ? tryParseAllYearFirst( dateString, year, month, day )
|
||||
: tryParseAllDayFirst( dateString, year, month, day );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RiaDateStringParser::parseDateStringWithoutSeparators( const std::string& dateString,
|
||||
int& year,
|
||||
int& month,
|
||||
int& day,
|
||||
OrderPreference preference )
|
||||
{
|
||||
auto tryParseAllYearFirstNoSeparators = []( const std::string& dateString, int& year, int& month, int& day ) {
|
||||
return tryParseYearFirstNoSeparators( dateString, year, month, day ) ||
|
||||
tryParseDayFirstNoSeparators( dateString, year, month, day ) ||
|
||||
tryParseMonthFirstNoSeparators( dateString, year, month, day );
|
||||
};
|
||||
|
||||
auto tryParseAllDayFirstNoSeparators = []( const std::string& dateString, int& year, int& month, int& day ) {
|
||||
return tryParseDayFirstNoSeparators( dateString, year, month, day ) ||
|
||||
tryParseYearFirstNoSeparators( dateString, year, month, day ) ||
|
||||
tryParseMonthFirstNoSeparators( dateString, year, month, day );
|
||||
};
|
||||
|
||||
auto firstNumerical = dateString.find_first_of( "0123456789" );
|
||||
if ( firstNumerical != std::string::npos )
|
||||
{
|
||||
std::string subString = dateString.substr( firstNumerical );
|
||||
|
||||
return ( preference == OrderPreference::YEAR_FIRST )
|
||||
? tryParseAllYearFirstNoSeparators( subString, year, month, day )
|
||||
: tryParseAllDayFirstNoSeparators( subString, year, month, day );
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Try parse formats
|
||||
/// 'yyyy mm dd'
|
||||
|
@ -30,10 +30,29 @@
|
||||
class RiaDateStringParser
|
||||
{
|
||||
public:
|
||||
static QDateTime parseDateString( const QString& dateString );
|
||||
static QDateTime parseDateString( const std::string& dateString );
|
||||
enum class OrderPreference
|
||||
{
|
||||
YEAR_FIRST,
|
||||
DAY_FIRST
|
||||
};
|
||||
|
||||
static QDateTime parseDateString( const QString& dateString, OrderPreference preference = OrderPreference::YEAR_FIRST );
|
||||
static QDateTime parseDateString( const std::string& dateStringString,
|
||||
OrderPreference preference = OrderPreference::YEAR_FIRST );
|
||||
|
||||
private:
|
||||
static bool parseDateStringWithSeparators( const std::string& dateString,
|
||||
int& year,
|
||||
int& month,
|
||||
int& day,
|
||||
OrderPreference preference );
|
||||
|
||||
static bool parseDateStringWithoutSeparators( const std::string& dateString,
|
||||
int& year,
|
||||
int& month,
|
||||
int& day,
|
||||
OrderPreference preference );
|
||||
|
||||
static bool tryParseYearFirst( const std::string& s, int& year, int& month, int& day );
|
||||
static bool tryParseDayFirst( const std::string& s, int& year, int& month, int& day );
|
||||
static bool tryParseMonthFirst( const std::string& s, int& year, int& month, int& day );
|
||||
|
@ -131,3 +131,27 @@ TEST( RiaDateStringParserTest, ParseWithoutSeparators )
|
||||
EXPECT_TRUE( nov24thDT == RiaDateStringParser::parseDateString( nov24thString ) );
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
TEST( RiaDateStringParserTest, ParseDayFirst )
|
||||
{
|
||||
std::vector<std::pair<QString, QDate>> dates = {
|
||||
{ "28-DEC-1985", QDate( 1985, 12, 28 ) },
|
||||
{ "15-jan-02", QDate( 2002, 1, 15 ) },
|
||||
{ "15-january-02", QDate( 2002, 1, 15 ) },
|
||||
{ "2023-january-17", QDate( 2023, 1, 17 ) },
|
||||
{ "150102", QDate( 2002, 1, 15 ) },
|
||||
{ "310102", QDate( 2002, 1, 31 ) },
|
||||
};
|
||||
|
||||
for ( auto [dateString, expected] : dates )
|
||||
{
|
||||
QDateTime actual =
|
||||
RiaDateStringParser::parseDateString( dateString, RiaDateStringParser::OrderPreference::DAY_FIRST );
|
||||
EXPECT_EQ( expected.day(), actual.date().day() );
|
||||
EXPECT_EQ( expected.month(), actual.date().month() );
|
||||
EXPECT_EQ( expected.year(), actual.date().year() );
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user