summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEike Rathke <erack@redhat.com>2012-01-10 16:42:01 +0100
committerEike Rathke <erack@redhat.com>2012-01-11 13:18:45 +0100
commit958cdbdcf5e35c04e259a69e972684060f1b3d12 (patch)
tree3ef304d9abb0c5efac583bcadc33f8bad49caea8
parent8ca1557b85188b7708930468d77412f51356e34c (diff)
accept and display years < 100
+ Years < 100 without being hit by the 2 digits year magic can be entered by preceding them with a leading 0 if at least 3 digits are present, e.g. 099-1-1 is year 99, not 1999. + Years < 100 in an yyyy format are always displayed as 0099.
-rw-r--r--svl/source/numbers/zforfind.cxx29
-rw-r--r--svl/source/numbers/zforfind.hxx19
-rw-r--r--svl/source/numbers/zformat.cxx26
3 files changed, 61 insertions, 13 deletions
diff --git a/svl/source/numbers/zforfind.cxx b/svl/source/numbers/zforfind.cxx
index ef76faca7763..3df9232c3b56 100644
--- a/svl/source/numbers/zforfind.cxx
+++ b/svl/source/numbers/zforfind.cxx
@@ -957,10 +957,14 @@ sal_uInt16 ImpSvNumberInputScan::ImplGetYear( sal_uInt16 nIndex )
{
sal_uInt16 nYear = 0;
- if (sStrArray[nNums[nIndex]].Len() <= 4)
+ xub_StrLen nLen = sStrArray[nNums[nIndex]].Len();
+ if (nLen <= 4)
{
nYear = (sal_uInt16) sStrArray[nNums[nIndex]].ToInt32();
- nYear = SvNumberFormatter::ExpandTwoDigitYear( nYear, nYear2000 );
+ // A year < 100 entered with at least 3 digits with leading 0 is taken
+ // as is without expansion.
+ if (nYear < 100 && nLen < 3)
+ nYear = SvNumberFormatter::ExpandTwoDigitYear( nYear, nYear2000 );
}
return nYear;
@@ -972,13 +976,22 @@ bool ImpSvNumberInputScan::MayBeIso8601()
{
if (nMayBeIso8601 == 0)
{
- if (nAnzNums >= 3 && nNums[0] < nAnzStrings &&
- sStrArray[nNums[0]].ToInt32() > 31)
- nMayBeIso8601 = 1;
- else
- nMayBeIso8601 = 2;
+ nMayBeIso8601 = 1;
+ xub_StrLen nLen = ((nAnzNums >= 1 && nNums[0] < nAnzStrings) ? sStrArray[nNums[0]].Len() : 0);
+ if (nLen)
+ {
+ sal_Int32 n;
+ if (nAnzNums >= 3 && nNums[2] < nAnzStrings &&
+ sStrArray[nNums[0]+1] == '-' && // separator year-month
+ (n = sStrArray[nNums[1]].ToInt32()) >= 1 && n <= 12 && // month
+ sStrArray[nNums[1]+1] == '-' && // separator month-day
+ (n = sStrArray[nNums[2]].ToInt32()) >= 1 && n <= 31) // day
+ // Year (nNums[0]) value not checked, may be anything, but
+ // length (number of digits) is checked.
+ nMayBeIso8601 = (nLen >= 4 ? 4 : (nLen == 3 ? 3 : (nLen > 0 ? 2 : 0)));
+ }
}
- return nMayBeIso8601 == 1;
+ return nMayBeIso8601 > 1;
}
//---------------------------------------------------------------------------
diff --git a/svl/source/numbers/zforfind.hxx b/svl/source/numbers/zforfind.hxx
index 9c557b7e8303..02e08d4b31a3 100644
--- a/svl/source/numbers/zforfind.hxx
+++ b/svl/source/numbers/zforfind.hxx
@@ -69,8 +69,13 @@ 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
+ /** Whether input may be an ISO 8601 date format, yyyy-mm-dd...
+
+ Checks if input has at least 3 numbers for yyyy-mm-dd and the separator
+ is '-', and 1<=mm<=12 and 1<=dd<=31.
+
+ @see nMayBeIso8601
+ */
bool MayBeIso8601();
private:
@@ -129,7 +134,15 @@ private:
// number <= nYear2000 => 20xx
// number > nYear2000 => 19xx
sal_uInt16 nTimezonePos; // Index of timezone separator (+1)
- sal_uInt8 nMayBeIso8601; // 0:=dontknowyet, 1:=yes, 2:=no
+
+ /** State of ISO 8601 detection.
+ 0:= don't know yet
+ 1:= no
+ 2:= yes, <=2 digits in year
+ 3:= yes, 3 digits in year
+ 4:= yes, >=4 digits in year
+ */
+ sal_uInt8 nMayBeIso8601;
#ifdef _ZFORFIND_CXX // methods private to implementation
void Reset(); // Reset all variables before start of analysis
diff --git a/svl/source/numbers/zformat.cxx b/svl/source/numbers/zformat.cxx
index d7969803459d..1976ec90afca 100644
--- a/svl/source/numbers/zformat.cxx
+++ b/svl/source/numbers/zformat.cxx
@@ -3387,8 +3387,19 @@ bool SvNumberformat::ImpGetDateOutput(double fNumber,
{
if ( bOtherCalendar )
SwitchToGregorianCalendar( aOrgCalendar, fOrgDateTime );
- OutString += rCal.getDisplayString(
+ String aYear = rCal.getDisplayString(
CalendarDisplayCode::LONG_YEAR, nNatNum );
+ if (aYear.Len() < 4)
+ {
+ // Ensure that year consists of at least 4 digits, so it
+ // can be distinguished from 2 digits display and edited
+ // without suddenly being hit by the 2-digit year magic.
+ String aZero;
+ aZero.Fill( 4 - aYear.Len(), sal_Unicode('0'));
+ ImpTransliterate( aZero, NumFor[nIx].GetNatNum());
+ aYear.Insert( aZero, 0);
+ }
+ OutString += aYear;
if ( bOtherCalendar )
SwitchToOtherCalendar( aOrgCalendar, fOrgDateTime );
}
@@ -3710,8 +3721,19 @@ bool SvNumberformat::ImpGetDateTimeOutput(double fNumber,
{
if ( bOtherCalendar )
SwitchToGregorianCalendar( aOrgCalendar, fOrgDateTime );
- OutString += rCal.getDisplayString(
+ String aYear = rCal.getDisplayString(
CalendarDisplayCode::LONG_YEAR, nNatNum );
+ if (aYear.Len() < 4)
+ {
+ // Ensure that year consists of at least 4 digits, so it
+ // can be distinguished from 2 digits display and edited
+ // without suddenly being hit by the 2-digit year magic.
+ String aZero;
+ aZero.Fill( 4 - aYear.Len(), sal_Unicode('0'));
+ ImpTransliterate( aZero, NumFor[nIx].GetNatNum());
+ aYear.Insert( aZero, 0);
+ }
+ OutString += aYear;
if ( bOtherCalendar )
SwitchToOtherCalendar( aOrgCalendar, fOrgDateTime );
}