Resolves: tdf#106956 CDateFromIso accept also YYYY-MM-DD form

Previous implementation was over-simplified and accepted all sort of malformed
input to yield some arbitrary date, including longer and shorter and not
strictly numeric strings.

Change-Id: I2158429aeff7431f5ec5a1c9125018a5455a4730
This commit is contained in:
Eike Rathke
2017-04-28 15:37:17 +02:00
parent 3d0cbe3e7b
commit cdcbdf88b7

View File

@@ -2045,31 +2045,64 @@ RTLFUNC(CDateToIso)
} }
} }
// Function to convert date from ISO 8601 date format // Function to convert date from ISO 8601 date format YYYYMMDD or YYYY-MM-DD
RTLFUNC(CDateFromIso) RTLFUNC(CDateFromIso)
{ {
(void)pBasic; (void)pBasic;
(void)bWrite; (void)bWrite;
if ( rPar.Count() == 2 ) do
{ {
if ( rPar.Count() != 2 )
break;
OUString aStr = rPar.Get(1)->GetOUString(); OUString aStr = rPar.Get(1)->GetOUString();
const sal_Int32 iMonthStart = aStr.getLength() - 4; const sal_Int32 nLen = aStr.getLength();
OUString aYearStr = aStr.copy( 0, iMonthStart ); if (nLen != 8 && nLen != 10)
OUString aMonthStr = aStr.copy( iMonthStart, 2 ); break;
OUString aDayStr = aStr.copy( iMonthStart+2, 2 );
OUString aYearStr, aMonthStr, aDayStr;
if (nLen == 8)
{
// YYYYMMDD
if (!comphelper::string::isdigitAsciiString(aStr))
break;
aYearStr = aStr.copy( 0, 4 );
aMonthStr = aStr.copy( 4, 2 );
aDayStr = aStr.copy( 6, 2 );
}
else
{
// YYYY-MM-DD
const sal_Int32 nSep1 = aStr.indexOf('-');
if (nSep1 != 4)
break;
const sal_Int32 nSep2 = aStr.indexOf('-', nSep1+1);
if (nSep2 != 7)
break;
aYearStr = aStr.copy( 0, 4 );
aMonthStr = aStr.copy( 5, 2 );
aDayStr = aStr.copy( 8, 2 );
if ( !comphelper::string::isdigitAsciiString(aYearStr) ||
!comphelper::string::isdigitAsciiString(aMonthStr) ||
!comphelper::string::isdigitAsciiString(aDayStr))
break;
}
double dDate; double dDate;
if( implDateSerial( (sal_Int16)aYearStr.toInt32(), if (!implDateSerial( (sal_Int16)aYearStr.toInt32(),
(sal_Int16)aMonthStr.toInt32(), (sal_Int16)aDayStr.toInt32(), dDate ) ) (sal_Int16)aMonthStr.toInt32(), (sal_Int16)aDayStr.toInt32(), dDate ))
{ break;
rPar.Get(0)->PutDate( dDate );
} rPar.Get(0)->PutDate( dDate );
}
else return;
{
StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT );
} }
while (false);
StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT );
} }
RTLFUNC(DateSerial) RTLFUNC(DateSerial)