diff options
author | Eike Rathke <erack@redhat.com> | 2017-04-28 15:37:17 +0200 |
---|---|---|
committer | Eike Rathke <erack@redhat.com> | 2017-04-28 15:46:33 +0200 |
commit | cdcbdf88b7f74184b532925eaf140dbf65a2cd21 (patch) | |
tree | 9b59a29bb065f1173ae38a631c8cac20538dca49 /basic | |
parent | 3d0cbe3e7bff402f2626deb94274c0fef40e4bde (diff) |
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
Diffstat (limited to 'basic')
-rw-r--r-- | basic/source/runtime/methods.cxx | 61 |
1 files changed, 47 insertions, 14 deletions
diff --git a/basic/source/runtime/methods.cxx b/basic/source/runtime/methods.cxx index a8468a61b908..1bb3a474bc60 100644 --- a/basic/source/runtime/methods.cxx +++ b/basic/source/runtime/methods.cxx @@ -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) { (void)pBasic; (void)bWrite; - if ( rPar.Count() == 2 ) + do { + if ( rPar.Count() != 2 ) + break; + OUString aStr = rPar.Get(1)->GetOUString(); - const sal_Int32 iMonthStart = aStr.getLength() - 4; - OUString aYearStr = aStr.copy( 0, iMonthStart ); - OUString aMonthStr = aStr.copy( iMonthStart, 2 ); - OUString aDayStr = aStr.copy( iMonthStart+2, 2 ); + const sal_Int32 nLen = aStr.getLength(); + if (nLen != 8 && nLen != 10) + break; - double dDate; - if( implDateSerial( (sal_Int16)aYearStr.toInt32(), - (sal_Int16)aMonthStr.toInt32(), (sal_Int16)aDayStr.toInt32(), dDate ) ) + OUString aYearStr, aMonthStr, aDayStr; + if (nLen == 8) { - rPar.Get(0)->PutDate( dDate ); + // 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; + if (!implDateSerial( (sal_Int16)aYearStr.toInt32(), + (sal_Int16)aMonthStr.toInt32(), (sal_Int16)aDayStr.toInt32(), dDate )) + break; + + rPar.Get(0)->PutDate( dDate ); + + return; } - else - { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); - } + while (false); + + StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); } RTLFUNC(DateSerial) |