resolved fdo#37978 - Date formatting in Spreadsheet is inconsistent
* SvNumberFormatter::IsNumberFormat() ISO 8601 date input results in yyyy-mm-dd format if no other date format was set. * SvNumberFormatter::GetInputLineString() preserves ISO 8601 date format for editing if such was set.
This commit is contained in:
parent
98d75b3506
commit
6c37252eb9
3 changed files with 73 additions and 47 deletions
|
@ -595,6 +595,9 @@ public:
|
|||
/// Whether nFIndex is a special builtin format
|
||||
bool IsSpecialStandardFormat( sal_uInt32 nFIndex, LanguageType eLnge );
|
||||
|
||||
/** Return the corresponding edit format of a format. */
|
||||
sal_uInt32 GetEditFormat( double fNumber, sal_uInt32 nFIndex, short eType, LanguageType eLnge );
|
||||
|
||||
/// Return the reference date
|
||||
Date* GetNullDate();
|
||||
/// Return the standard decimal precision
|
||||
|
|
|
@ -69,6 +69,10 @@ public:
|
|||
/// get threshold of two-digit year input
|
||||
sal_uInt16 GetYear2000() const { return nYear2000; }
|
||||
|
||||
// Whether input may be a ISO 8601 date format, yyyy-mm-dd...
|
||||
// checks if at least 3 numbers and first number>31
|
||||
bool MayBeIso8601();
|
||||
|
||||
private:
|
||||
SvNumberFormatter* pFormatter;
|
||||
String* pUpperMonthText; // Array of month names, uppercase
|
||||
|
@ -256,10 +260,6 @@ private:
|
|||
const String& rString,
|
||||
const SvNumberformat* pFormat = NULL );
|
||||
|
||||
// Whether input may be a ISO 8601 date format, yyyy-mm-dd...
|
||||
// checks if at least 3 numbers and first number>31
|
||||
bool MayBeIso8601();
|
||||
|
||||
// Compare rString to substring of array indexed by nString
|
||||
// nString == 0xFFFF => last substring
|
||||
bool ScanStringNumFor(
|
||||
|
|
|
@ -1155,7 +1155,6 @@ bool SvNumberFormatter::IsNumberFormat(const String& sString,
|
|||
const SvNumberformat* pFormat = (SvNumberformat*) aFTable.Get(F_Index);
|
||||
if (!pFormat)
|
||||
{
|
||||
// OSL_FAIL("SvNumberFormatter:: Unbekanntes altes Zahlformat (2)");
|
||||
ChangeIntl(IniLnge);
|
||||
FType = NUMBERFORMAT_NUMBER;
|
||||
}
|
||||
|
@ -1168,21 +1167,25 @@ bool SvNumberFormatter::IsNumberFormat(const String& sString,
|
|||
}
|
||||
bool res;
|
||||
short RType = FType;
|
||||
// Ergebnistyp
|
||||
// ohne def-Kennung
|
||||
if (RType == NUMBERFORMAT_TEXT) // Zahlzelle ->Stringz.
|
||||
res = false;
|
||||
if (RType == NUMBERFORMAT_TEXT)
|
||||
res = false; // type text preset => no conversion to number
|
||||
else
|
||||
res = pStringScanner->IsNumberFormat(sString, RType, fOutNumber, pFormat);
|
||||
|
||||
if (res && !IsCompatible(FType, RType)) // unpassender Typ
|
||||
if (res && !IsCompatible(FType, RType)) // non-matching type
|
||||
{
|
||||
switch ( RType )
|
||||
{
|
||||
case NUMBERFORMAT_DATE :
|
||||
// Preserve ISO 8601 input.
|
||||
if (pStringScanner->MayBeIso8601())
|
||||
F_Index = GetFormatIndex( NF_DATE_DIN_YYYYMMDD, ActLnge );
|
||||
else
|
||||
F_Index = GetStandardFormat( RType, ActLnge );
|
||||
break;
|
||||
case NUMBERFORMAT_TIME :
|
||||
{
|
||||
if ( pStringScanner->GetDecPos() )
|
||||
{ // 100stel Sekunden
|
||||
{ // 100th seconds
|
||||
if ( pStringScanner->GetAnzNums() > 3 || fOutNumber < 0.0 )
|
||||
F_Index = GetFormatIndex( NF_TIME_HH_MMSS00, ActLnge );
|
||||
else
|
||||
|
@ -1192,7 +1195,6 @@ bool SvNumberFormatter::IsNumberFormat(const String& sString,
|
|||
F_Index = GetFormatIndex( NF_TIME_HH_MMSS, ActLnge );
|
||||
else
|
||||
F_Index = GetStandardFormat( RType, ActLnge );
|
||||
}
|
||||
break;
|
||||
default:
|
||||
F_Index = GetStandardFormat( RType, ActLnge );
|
||||
|
@ -1435,6 +1437,60 @@ sal_uInt32 SvNumberFormatter::GetStandardFormat( double fNumber, sal_uInt32 nFIn
|
|||
}
|
||||
}
|
||||
|
||||
sal_uInt32 SvNumberFormatter::GetEditFormat( double fNumber, sal_uInt32 nFIndex, short eType, LanguageType eLang )
|
||||
{
|
||||
sal_uInt32 nKey = nFIndex;
|
||||
switch ( eType )
|
||||
{ // #61619# always edit using 4-digit year
|
||||
case NUMBERFORMAT_DATE :
|
||||
if (::rtl::math::approxFloor( fNumber) != fNumber)
|
||||
nKey = GetFormatIndex( NF_DATETIME_SYS_DDMMYYYY_HHMMSS, eLang );
|
||||
// fdo#34977 preserve time when editing even if only date was
|
||||
// displayed.
|
||||
/* FIXME: in case an ISO 8601 format was used, editing should
|
||||
* also use such. Unfortunately we have no builtin combined
|
||||
* date+time ISO format defined. Needs also locale data work.
|
||||
* */
|
||||
else
|
||||
{
|
||||
// Preserve ISO 8601 format.
|
||||
if ( nFIndex == GetFormatIndex( NF_DATE_DIN_YYYYMMDD, eLang) ||
|
||||
nFIndex == GetFormatIndex( NF_DATE_DIN_YYMMDD, eLang) ||
|
||||
nFIndex == GetFormatIndex( NF_DATE_DIN_MMDD, eLang))
|
||||
nKey = GetFormatIndex( NF_DATE_DIN_YYYYMMDD, eLang);
|
||||
else
|
||||
nKey = GetFormatIndex( NF_DATE_SYS_DDMMYYYY, eLang );
|
||||
}
|
||||
break;
|
||||
case NUMBERFORMAT_TIME :
|
||||
if (fNumber < 0.0 || fNumber >= 1.0)
|
||||
{
|
||||
/* XXX NOTE: this is a purely arbitrary value within the limits
|
||||
* of a signed 16-bit. 32k hours are 3.7 years ... or
|
||||
* 1903-09-26 if date. */
|
||||
if (fabs( fNumber) * 24 < 0x7fff)
|
||||
nKey = GetFormatIndex( NF_TIME_HH_MMSS, eLang );
|
||||
// Preserve duration, use [HH]:MM:SS instead of time.
|
||||
else
|
||||
nKey = GetFormatIndex( NF_DATETIME_SYS_DDMMYYYY_HHMMSS, eLang );
|
||||
// Assume that a large value is a datetime with only time
|
||||
// displayed.
|
||||
}
|
||||
else
|
||||
nKey = GetStandardFormat( fNumber, nFIndex, eType, eLang );
|
||||
break;
|
||||
case NUMBERFORMAT_DATETIME :
|
||||
nKey = GetFormatIndex( NF_DATETIME_SYS_DDMMYYYY_HHMMSS, eLang );
|
||||
/* FIXME: in case an ISO 8601 format was used, editing should
|
||||
* also use such. Unfortunately we have no builtin combined
|
||||
* date+time ISO format defined. Needs also locale data work. */
|
||||
break;
|
||||
default:
|
||||
nKey = GetStandardFormat( fNumber, nFIndex, eType, eLang );
|
||||
}
|
||||
return nKey;
|
||||
}
|
||||
|
||||
void SvNumberFormatter::GetInputLineString(const double& fOutNumber,
|
||||
sal_uInt32 nFIndex,
|
||||
String& sOutString)
|
||||
|
@ -1461,40 +1517,7 @@ void SvNumberFormatter::GetInputLineString(const double& fOutNumber,
|
|||
ChangeStandardPrec(INPUTSTRING_PRECISION);
|
||||
bPrecChanged = true;
|
||||
}
|
||||
sal_uInt32 nKey = nFIndex;
|
||||
switch ( eType )
|
||||
{ // #61619# always edit using 4-digit year
|
||||
case NUMBERFORMAT_DATE :
|
||||
if (::rtl::math::approxFloor( fOutNumber) != fOutNumber)
|
||||
nKey = GetFormatIndex( NF_DATETIME_SYS_DDMMYYYY_HHMMSS, eLang );
|
||||
// fdo#34977 preserve time when editing even if only date was
|
||||
// displayed.
|
||||
else
|
||||
nKey = GetFormatIndex( NF_DATE_SYS_DDMMYYYY, eLang );
|
||||
break;
|
||||
case NUMBERFORMAT_TIME :
|
||||
if (fOutNumber < 0.0 || fOutNumber >= 1.0)
|
||||
{
|
||||
/* XXX NOTE: this is a purely arbitrary value within the limits
|
||||
* of a signed 16-bit. 32k hours are 3.7 years ... or
|
||||
* 1903-09-26 if date. */
|
||||
if (fabs( fOutNumber) * 24 < 0x7fff)
|
||||
nKey = GetFormatIndex( NF_TIME_HH_MMSS, eLang );
|
||||
// Preserve duration, use [HH]:MM:SS instead of time.
|
||||
else
|
||||
nKey = GetFormatIndex( NF_DATETIME_SYS_DDMMYYYY_HHMMSS, eLang );
|
||||
// Assume that a large value is a datetime with only time
|
||||
// displayed.
|
||||
}
|
||||
else
|
||||
nKey = GetStandardFormat( fOutNumber, nFIndex, eType, eLang );
|
||||
break;
|
||||
case NUMBERFORMAT_DATETIME :
|
||||
nKey = GetFormatIndex( NF_DATETIME_SYS_DDMMYYYY_HHMMSS, eLang );
|
||||
break;
|
||||
default:
|
||||
nKey = GetStandardFormat( fOutNumber, nFIndex, eType, eLang );
|
||||
}
|
||||
sal_uInt32 nKey = GetEditFormat( fOutNumber, nFIndex, eType, eLang);
|
||||
if ( nKey != nFIndex )
|
||||
pFormat = (SvNumberformat*) aFTable.Get( nKey );
|
||||
if (pFormat)
|
||||
|
|
Loading…
Reference in a new issue