#5162 Support reading of LAS-file dates without separators

This commit is contained in:
Gaute Lindkvist
2020-01-21 15:14:17 +01:00
parent 5e68adc099
commit 024f3d020a
4 changed files with 263 additions and 12 deletions

View File

@@ -39,10 +39,20 @@ QDateTime RiaDateStringParser::parseDateString( const QString& dateString )
//--------------------------------------------------------------------------------------------------
QDateTime RiaDateStringParser::parseDateString( const std::string& dateString )
{
int year, month, day;
bool parsedOk = tryParseYearFirst( dateString, year, month, day ) ||
tryParseDayFirst( dateString, year, month, day ) ||
tryParseMonthFirst( dateString, year, month, day );
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 );
}
else if ( !RiaStdStringTools::containsAlphabetic( dateString ) )
{
parsedOk = tryParseYearFirstNoSeparators( dateString, year, month, day ) ||
tryParseDayFirstNoSeparators( dateString, year, month, day ) ||
tryParseMonthFirstNoSeparators( dateString, year, month, day );
}
QDateTime dt;
dt.setTimeSpec( RiaQDateTimeTools::currentTimeSpec() );
@@ -60,13 +70,12 @@ QDateTime RiaDateStringParser::parseDateString( const std::string& dateString )
/// 'yyyy-mm-dd'
/// 'yyyy-MMM-dd'
/// 'yyyy.MMM.dd'
/// 'yyyy.MMM.dd'
/// MMM is month name (shortened)
//--------------------------------------------------------------------------------------------------
bool RiaDateStringParser::tryParseYearFirst( const std::string& s, int& year, int& month, int& day )
{
auto firstSep = s.find_first_of( " -_." );
auto lastSep = s.find_first_of( " -_.", firstSep + 1 );
auto firstSep = s.find_first_of( separators() );
auto lastSep = s.find_first_of( separators(), firstSep + 1 );
if ( firstSep == std::string::npos || lastSep == std::string::npos ) return false;
@@ -91,8 +100,8 @@ bool RiaDateStringParser::tryParseYearFirst( const std::string& s, int& year, in
//--------------------------------------------------------------------------------------------------
bool RiaDateStringParser::tryParseDayFirst( const std::string& s, int& year, int& month, int& day )
{
auto firstSep = s.find_first_of( " -_." );
auto lastSep = s.find_first_of( " -_.", firstSep + 1 );
auto firstSep = s.find_first_of( separators() );
auto lastSep = s.find_first_of( separators(), firstSep + 1 );
if ( firstSep == std::string::npos || lastSep == std::string::npos ) return false;
@@ -108,8 +117,8 @@ bool RiaDateStringParser::tryParseDayFirst( const std::string& s, int& year, int
//--------------------------------------------------------------------------------------------------
bool RiaDateStringParser::tryParseMonthFirst( const std::string& s, int& year, int& month, int& day )
{
auto firstSep = s.find_first_of( " -_." );
auto lastSep = s.find_first_of( " -_.", firstSep + 1 );
auto firstSep = s.find_first_of( separators() );
auto lastSep = s.find_first_of( separators(), firstSep + 1 );
if ( firstSep == std::string::npos || lastSep == std::string::npos ) return false;
@@ -120,6 +129,83 @@ bool RiaDateStringParser::tryParseMonthFirst( const std::string& s, int& year, i
return tryParseYear( sYear, year ) && tryParseMonth( sMonth, month ) && tryParseDay( sDay, day );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RiaDateStringParser::tryParseYearFirstNoSeparators( const std::string& s, int& year, int& month, int& day )
{
if ( s.length() == 8 )
{
// Four digit year
auto sYear = s.substr( 0, 4 );
auto sMonth = s.substr( 4, 2 );
auto sDay = s.substr( 6, 2 );
return tryParseYear( sYear, year ) && tryParseMonth( sMonth, month ) && tryParseDay( sDay, day );
}
else if ( s.length() == 6 )
{
// Two digit year
auto sYear = s.substr( 0, 2 );
auto sMonth = s.substr( 2, 2 );
auto sDay = s.substr( 4, 2 );
return tryParseYear( sYear, year ) && tryParseMonth( sMonth, month ) && tryParseDay( sDay, day );
}
return false;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RiaDateStringParser::tryParseDayFirstNoSeparators( const std::string& s, int& year, int& month, int& day )
{
if ( s.length() == 8 )
{
// Four digit year
auto sDay = s.substr( 0, 2 );
auto sMonth = s.substr( 2, 2 );
auto sYear = s.substr( 4, 4 );
return tryParseYear( sYear, year ) && tryParseMonth( sMonth, month ) && tryParseDay( sDay, day );
}
else if ( s.length() == 6 )
{
// Two digit year
auto sDay = s.substr( 0, 2 );
auto sMonth = s.substr( 2, 2 );
auto sYear = s.substr( 4, 2 );
return tryParseYear( sYear, year ) && tryParseMonth( sMonth, month ) && tryParseDay( sDay, day );
}
return false;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RiaDateStringParser::tryParseMonthFirstNoSeparators( const std::string& s, int& year, int& month, int& day )
{
if ( s.length() == 8 )
{
// Four digit year
auto sMonth = s.substr( 0, 2 );
auto sDay = s.substr( 2, 2 );
auto sYear = s.substr( 4, 4 );
return tryParseYear( sYear, year ) && tryParseMonth( sMonth, month ) && tryParseDay( sDay, day );
}
else if ( s.length() == 6 )
{
// Two digit year
auto sMonth = s.substr( 0, 2 );
auto sDay = s.substr( 2, 2 );
auto sYear = s.substr( 4, 2 );
return tryParseYear( sYear, year ) && tryParseMonth( sMonth, month ) && tryParseDay( sDay, day );
}
return false;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -129,7 +215,15 @@ bool RiaDateStringParser::tryParseYear( const std::string& s, int& year )
auto today = QDate::currentDate();
int y = RiaStdStringTools::toInt( s );
if ( y > 1970 && y <= today.year() )
if ( y < 100 )
{
if ( y > 70 )
y += 1900;
else
y += 2000;
}
if ( y > 1970 && y <= today.year() + 50 ) // Support dates 50 years into the future.
{
year = y;
@@ -193,6 +287,23 @@ bool RiaDateStringParser::tryParseDay( const std::string& s, int& day )
return false;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::string RiaDateStringParser::separators()
{
return " -_.";
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RiaDateStringParser::hasSeparators( const std::string& s )
{
auto firstSep = s.find_first_of( separators() );
return firstSep != std::string::npos;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@@ -38,9 +38,15 @@ private:
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 );
static bool tryParseYearFirstNoSeparators( const std::string& s, int& year, int& month, int& day );
static bool tryParseDayFirstNoSeparators( const std::string& s, int& year, int& month, int& day );
static bool tryParseMonthFirstNoSeparators( const std::string& s, int& year, int& month, int& day );
static bool tryParseYear( const std::string& s, int& year );
static bool tryParseMonth( const std::string& s, int& month );
static bool tryParseDay( const std::string& s, int& day );
static std::string separators();
static bool hasSeparators( const std::string& s );
static std::string trimString( const std::string& s );
};