Kaydet (Commit) f2851a27 authored tarafından Eike Rathke's avatar Eike Rathke

resolved fdo#54336 accept abbreviated combined date/time input

Abbreviated combined date/time input was not accepted if the date
acceptance pattern ended in a separator, like "D.M." with input
"D.M. hh:mm".

Additionally check that for "D.M. #" input against a "D.M." pattern the
'#' (any number) is not interpreted as year if the input so far was
recognized to possibly match a date without time, in which case the
count of numbers in input must match the count of numbers in pattern and
input here is not a date.

Change-Id: I3b123b872fbab9dab58afe3b6754b8ad70a61356
üst d6308705
...@@ -140,6 +140,7 @@ void ImpSvNumberInputScan::Reset() ...@@ -140,6 +140,7 @@ void ImpSvNumberInputScan::Reset()
nMayBeMonthDate = 0; nMayBeMonthDate = 0;
nAcceptedDatePattern = -2; nAcceptedDatePattern = -2;
nDatePatternStart = 0; nDatePatternStart = 0;
nDatePatternNumbers = 0;
nCanForceToIso8601 = 0; nCanForceToIso8601 = 0;
} }
...@@ -1179,6 +1180,7 @@ bool ImpSvNumberInputScan::IsAcceptedDatePattern( sal_uInt16 nStartPatternAt ) ...@@ -1179,6 +1180,7 @@ bool ImpSvNumberInputScan::IsAcceptedDatePattern( sal_uInt16 nStartPatternAt )
for (sal_Int32 nPattern=0; nPattern < sDateAcceptancePatterns.getLength(); ++nPattern) for (sal_Int32 nPattern=0; nPattern < sDateAcceptancePatterns.getLength(); ++nPattern)
{ {
sal_uInt16 nNext = nDatePatternStart; sal_uInt16 nNext = nDatePatternStart;
nDatePatternNumbers = 0;
bool bOk = true; bool bOk = true;
const OUString& rPat = sDateAcceptancePatterns[nPattern]; const OUString& rPat = sDateAcceptancePatterns[nPattern];
sal_Int32 nPat = 0; sal_Int32 nPat = 0;
...@@ -1190,6 +1192,8 @@ bool ImpSvNumberInputScan::IsAcceptedDatePattern( sal_uInt16 nStartPatternAt ) ...@@ -1190,6 +1192,8 @@ bool ImpSvNumberInputScan::IsAcceptedDatePattern( sal_uInt16 nStartPatternAt )
case 'M': case 'M':
case 'D': case 'D':
bOk = IsNum[nNext]; bOk = IsNum[nNext];
if (bOk)
++nDatePatternNumbers;
break; break;
default: default:
bOk = !IsNum[nNext]; bOk = !IsNum[nNext];
...@@ -1227,12 +1231,45 @@ bool ImpSvNumberInputScan::IsAcceptedDatePattern( sal_uInt16 nStartPatternAt ) ...@@ -1227,12 +1231,45 @@ bool ImpSvNumberInputScan::IsAcceptedDatePattern( sal_uInt16 nStartPatternAt )
if (nNext < nAnzStrings) if (nNext < nAnzStrings)
{ {
// Pattern end but not input end. // Pattern end but not input end.
if (!IsNum[nNext]) // A trailing blank may be part of the current pattern input,
// if pattern is "D.M." and input is "D.M. hh:mm" last was
// ". ", or may be following the current pattern input, if
// pattern is "D.M" and input is "D.M hh:mm" last was "M".
sal_Int32 nPos = 0;
sal_uInt16 nCheck;
if (nPat > 0 && nNext > 0)
{
// nPat is one behind after the for loop.
sal_Int32 nPatCheck = nPat - 1;
switch (rPat[nPatCheck])
{
case 'Y':
case 'M':
case 'D':
nCheck = nNext;
break;
default:
{
nCheck = nNext - 1;
// Advance position in input to match length of
// non-YMD (separator) characters in pattern.
sal_Unicode c;
do
{
++nPos;
} while ((c = rPat[--nPatCheck]) != 'Y' && c != 'M' && c != 'D');
}
}
}
else
{
nCheck = nNext;
}
if (!IsNum[nCheck])
{ {
// Trailing (or separating if time follows) blanks are ok. // Trailing (or separating if time follows) blanks are ok.
sal_Int32 nPos = 0; SkipBlanks( sStrArray[nCheck], nPos);
SkipBlanks( sStrArray[nNext], nPos); if (nPos == sStrArray[nCheck].getLength())
if (nPos == sStrArray[nNext].getLength())
{ {
nAcceptedDatePattern = nPattern; nAcceptedDatePattern = nPattern;
return true; return true;
...@@ -1307,6 +1344,18 @@ bool ImpSvNumberInputScan::SkipDatePatternSeparator( sal_uInt16 nParticle, sal_I ...@@ -1307,6 +1344,18 @@ bool ImpSvNumberInputScan::SkipDatePatternSeparator( sal_uInt16 nParticle, sal_I
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
sal_uInt16 ImpSvNumberInputScan::GetDatePatternNumbers()
{
// If not initialized yet start with first number, if any.
if (!IsAcceptedDatePattern( (nAnzNums ? nNums[0] : 0)))
{
return 0;
}
return nDatePatternNumbers;
}
//---------------------------------------------------------------------------
sal_uInt32 ImpSvNumberInputScan::GetDatePatternOrder() sal_uInt32 ImpSvNumberInputScan::GetDatePatternOrder()
{ {
// If not initialized yet start with first number, if any. // If not initialized yet start with first number, if any.
...@@ -3392,7 +3441,15 @@ bool ImpSvNumberInputScan::IsNumberFormat( const OUString& rString, ...@@ -3392,7 +3441,15 @@ bool ImpSvNumberInputScan::IsNumberFormat( const OUString& rString,
} }
else else
{ {
res = IsAcceptedDatePattern( nNums[0]) || MayBeIso8601() || nMatchedAllStrings; // Even if a date pattern was matched, for abbreviated
// pattern like "D.M." an input of "D.M. #" was
// accepted because # could had been a time. Here we do
// not have a combined date/time input though and #
// would be taken as Year in this example, which it is
// not. The count of numbers in pattern must match the
// count of numbers in input.
res = (GetDatePatternNumbers() == nAnzNums)
|| MayBeIso8601() || nMatchedAllStrings;
} }
} }
break; break;
......
...@@ -177,6 +177,12 @@ private: ...@@ -177,6 +177,12 @@ private:
*/ */
sal_uInt16 nDatePatternStart; sal_uInt16 nDatePatternStart;
/** Count of numbers that matched the accepted pattern, if any, else 0.
@see GetDatePatternNumbers()
*/
sal_uInt16 nDatePatternNumbers;
#ifdef _ZFORFIND_CXX // methods private to implementation #ifdef _ZFORFIND_CXX // methods private to implementation
void Reset(); // Reset all variables before start of analysis void Reset(); // Reset all variables before start of analysis
...@@ -375,6 +381,10 @@ private: ...@@ -375,6 +381,10 @@ private:
*/ */
bool SkipDatePatternSeparator( sal_uInt16 nParticle, sal_Int32 & rPos ); bool SkipDatePatternSeparator( sal_uInt16 nParticle, sal_Int32 & rPos );
/** Returns count of numbers in accepted date pattern.
*/
sal_uInt16 GetDatePatternNumbers();
/** Obtain order of accepted date pattern coded as, for example, /** Obtain order of accepted date pattern coded as, for example,
('D'<<16)|('M'<<8)|'Y' ('D'<<16)|('M'<<8)|'Y'
*/ */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment