[Libreoffice-commits] .: 4 commits - chart2/source sax/qa sax/source sc/source sd/source sfx2/source svl/source svtools/source sw/source tools/inc tools/source vcl/source xmloff/source
Eike Rathke
erack at kemper.freedesktop.org
Tue Nov 29 17:07:05 PST 2011
chart2/source/view/axes/DateHelper.cxx | 6 -
sax/qa/cppunit/test_converter.cxx | 9 +-
sax/source/tools/converter.cxx | 19 +++-
sc/source/core/tool/interpr2.cxx | 2
sd/source/ui/annotations/annotationmanager.cxx | 2
sfx2/source/doc/docfile.cxx | 2
sfx2/source/doc/oleprops.cxx | 2
svl/source/items/dateitem.cxx | 2
svtools/source/contnr/templwin.cxx | 2
svtools/source/control/calendar.cxx | 8 -
sw/source/core/fields/docufld.cxx | 2
sw/source/ui/docvw/SidebarWin.cxx | 2
tools/inc/tools/date.hxx | 6 +
tools/source/datetime/tdate.cxx | 111 +++++++++++++++++++++++--
tools/source/inet/inetmsg.cxx | 2
vcl/source/control/field2.cxx | 2
xmloff/source/core/xmluconv.cxx | 11 ++
17 files changed, 158 insertions(+), 32 deletions(-)
New commits:
commit 7613359985a89a42417a746bcdbb25f072784733
Author: Eike Rathke <erack at redhat.com>
Date: Wed Nov 30 02:05:25 2011 +0100
handle dates with year < 1000
* Read dates with years consisting of less than 4 digits.
ISO 8601 specifies that years are to be written with a minimum of 4 digits.
However, be lenient in what we accept.
* Write years < 1000 with leading zeros to comply with ISO 8601 YYYY.
diff --git a/sax/qa/cppunit/test_converter.cxx b/sax/qa/cppunit/test_converter.cxx
index 923c7eb..17d1303 100644
--- a/sax/qa/cppunit/test_converter.cxx
+++ b/sax/qa/cppunit/test_converter.cxx
@@ -215,8 +215,13 @@ void ConverterTest::testDateTime()
doTest( util::DateTime(0, 0, 0, 24, 1, 1, 333)
/*(0, 0, 0, 0, 2, 1, 333)*/,
"0333-01-01T24:00:00"/*, "0333-01-02T00:00:00"*/ );
- doTestDateTimeF( "+0001-01-01T00:00:00" ); // invalid: ^+
- doTestDateTimeF( "1-01-01T00:00:00" ); // invalid: < 4 Y
+ // A leading ^+ is NOT invalid, ISO 8601 specifies this for explicit AD/CE.
+ doTest( util::DateTime(0, 0, 0, 0, 1, 1, 1),
+ "+0001-01-01T00:00:00", "0001-01-01T00:00:00" );
+ // While ISO 8601 specifies a minimum of 4 year digits we are lenient in
+ // what we accept.
+ doTest( util::DateTime(0, 0, 0, 0, 1, 1, 1),
+ "1-01-01T00:00:00", "0001-01-01T00:00:00" );
doTestDateTimeF( "0001-1-01T00:00:00" ); // invalid: < 2 M
doTestDateTimeF( "0001-01-1T00:00:00" ); // invalid: < 2 D
doTestDateTimeF( "0001-01-01T0:00:00" ); // invalid: < 2 H
diff --git a/sax/source/tools/converter.cxx b/sax/source/tools/converter.cxx
index b1629c8..0c0779b 100644
--- a/sax/source/tools/converter.cxx
+++ b/sax/source/tools/converter.cxx
@@ -1345,15 +1345,26 @@ bool Converter::convertDateOrDateTime(
const ::rtl::OUString string = rString.trim().toAsciiUpperCase();
sal_Int32 nPos(0);
- if ((string.getLength() > nPos) && (sal_Unicode('-') == string[nPos]))
+ if (string.getLength() > nPos)
{
- //Negative Number
- ++nPos;
+ if (sal_Unicode('-') == string[nPos])
+ {
+ //Negative Number
+ ++nPos;
+ }
+ else if (sal_Unicode('+') == string[nPos])
+ {
+ //Positive Number, explicit AD/CE
+ ++nPos;
+ }
}
sal_Int32 nYear(0);
{
- bSuccess = readDateTimeComponent(string, nPos, nYear, 4, false);
+ // While ISO 8601 specifies years with a minimum of 4 digits, be
+ // leninent in what we accept for years < 1000. One digit is acceptable
+ // if the remainders match.
+ bSuccess = readDateTimeComponent(string, nPos, nYear, 1, false);
bSuccess &= (0 < nYear);
bSuccess &= (nPos < string.getLength()); // not last token
}
diff --git a/xmloff/source/core/xmluconv.cxx b/xmloff/source/core/xmluconv.cxx
index 5ea85f1..6ceb885 100644
--- a/xmloff/source/core/xmluconv.cxx
+++ b/xmloff/source/core/xmluconv.cxx
@@ -436,9 +436,16 @@ void SvXMLUnitConverter::convertDateTime( OUStringBuffer& rBuffer,
aDate += 1;
}
}
- rBuffer.append( sal_Int32( aDate.GetYear()));
+ sal_uInt16 nTemp = aDate.GetYear();
+ if (nTemp < 1000)
+ rBuffer.append( sal_Unicode('0'));
+ if (nTemp < 100)
+ rBuffer.append( sal_Unicode('0'));
+ if (nTemp < 10)
+ rBuffer.append( sal_Unicode('0'));
+ rBuffer.append( sal_Int32( nTemp));
rBuffer.append( sal_Unicode('-'));
- sal_uInt16 nTemp = aDate.GetMonth();
+ nTemp = aDate.GetMonth();
if (nTemp < 10)
rBuffer.append( sal_Unicode('0'));
rBuffer.append( sal_Int32( nTemp));
commit 07a7b2937a9427b2feb3307804ec0f527091bb92
Author: Eike Rathke <erack at redhat.com>
Date: Wed Nov 30 02:05:24 2011 +0100
fixed fdo#40363 freeze chart wizard with non-gregorian date
Use the newly introduced Date::Normalize() instead of a never ending
while(!date.IsValid())
diff --git a/chart2/source/view/axes/DateHelper.cxx b/chart2/source/view/axes/DateHelper.cxx
index 6749e74..247e0f6 100644
--- a/chart2/source/view/axes/DateHelper.cxx
+++ b/chart2/source/view/axes/DateHelper.cxx
@@ -73,8 +73,7 @@ Date DateHelper::GetDateSomeMonthsAway( const Date& rD, long nMonthDistance )
nNewMonth += 12;
aRet.SetMonth( sal_uInt16(nNewMonth) );
aRet.SetYear( sal_uInt16(nNewYear) );
- while(!aRet.IsValidAndGregorian())
- aRet--;
+ aRet.Normalize();
return aRet;
}
@@ -82,8 +81,7 @@ Date DateHelper::GetDateSomeYearsAway( const Date& rD, long nYearDistance )
{
Date aRet(rD);
aRet.SetYear( static_cast<sal_uInt16>(rD.GetYear()+nYearDistance) );
- while(!aRet.IsValidAndGregorian())
- aRet--;
+ aRet.Normalize();
return aRet;
}
commit 6619955e72c1c2f29a32e82478d19147c0d7610a
Author: Eike Rathke <erack at redhat.com>
Date: Wed Nov 30 02:05:23 2011 +0100
introduced Date::IsValidDate() and Date::Normalize()
+ IsValidDate() checks only day and month regarding the year, not Gregorian
cut-off date as now does IsValidAndGregorian().
+ Normalize() carries over invalid day and month values to next months and
years.
* All methods that return or internally use a day count now internally
normalize the date values, without modifying the actual Date instance. So,
if the date is not valid you may get unexpected results.
* Previously, a date with month>12 would had accessed the days-of-month
array out of bounds on all such methods. So you would had gotten
unexpected results anyway..
* Affected methods are:
GetDayOfYear()
GetWeekOfYear()
GetDaysInMonth()
static DateToDays()
diff --git a/tools/source/datetime/tdate.cxx b/tools/source/datetime/tdate.cxx
index 06b0bc4..5deef52 100644
--- a/tools/source/datetime/tdate.cxx
+++ b/tools/source/datetime/tdate.cxx
@@ -60,6 +60,8 @@ inline sal_Bool ImpIsLeapYear( sal_uInt16 nYear )
// -----------------------------------------------------------------------
+// All callers must have sanitized or normalized month and year values!
+
inline sal_uInt16 DaysInMonth( sal_uInt16 nMonth, sal_uInt16 nYear )
{
if ( nMonth != 2 )
@@ -79,6 +81,8 @@ long Date::DateToDays( sal_uInt16 nDay, sal_uInt16 nMonth, sal_uInt16 nYear )
{
long nDays;
+ Normalize( nDay, nMonth, nYear);
+
nDays = ((sal_uIntPtr)nYear-1) * 365;
nDays += ((nYear-1) / 4) - ((nYear-1) / 100) + ((nYear-1) / 400);
for( sal_uInt16 i = 1; i < nMonth; i++ )
@@ -203,9 +207,13 @@ DayOfWeek Date::GetDayOfWeek() const
sal_uInt16 Date::GetDayOfYear() const
{
- sal_uInt16 nDay = GetDay();
- for( sal_uInt16 i = 1; i < GetMonth(); i++ )
- nDay = nDay + ::DaysInMonth( i, GetYear() ); // += yields a warning on MSVC, so don't use it
+ sal_uInt16 nDay = GetDay();
+ sal_uInt16 nMonth = GetMonth();
+ sal_uInt16 nYear = GetYear();
+ Normalize( nDay, nMonth, nYear);
+
+ for( sal_uInt16 i = 1; i < nMonth; i++ )
+ nDay = nDay + ::DaysInMonth( i, nYear ); // += yields a warning on MSVC, so don't use it
return nDay;
}
@@ -305,7 +313,12 @@ sal_uInt16 Date::GetWeekOfYear( DayOfWeek eStartDay,
sal_uInt16 Date::GetDaysInMonth() const
{
- return DaysInMonth( GetMonth(), GetYear() );
+ sal_uInt16 nDay = GetDay();
+ sal_uInt16 nMonth = GetMonth();
+ sal_uInt16 nYear = GetYear();
+ Normalize( nDay, nMonth, nYear);
+
+ return DaysInMonth( nMonth, nYear );
}
// -----------------------------------------------------------------------
@@ -343,6 +356,94 @@ sal_Bool Date::IsValidAndGregorian() const
// -----------------------------------------------------------------------
+bool Date::IsValidDate() const
+{
+ return IsValidDate( GetDay(), GetMonth(), GetYear());
+}
+
+// -----------------------------------------------------------------------
+
+//static
+bool Date::IsValidDate( sal_uInt16 nDay, sal_uInt16 nMonth, sal_uInt16 nYear )
+{
+ if ( !nMonth || (nMonth > 12) )
+ return false;
+ if ( !nDay || (nDay > DaysInMonth( nMonth, nYear )) )
+ return false;
+ return true;
+}
+
+// -----------------------------------------------------------------------
+
+bool Date::Normalize()
+{
+ sal_uInt16 nDay = GetDay();
+ sal_uInt16 nMonth = GetMonth();
+ sal_uInt16 nYear = GetYear();
+
+ if (!Normalize( nDay, nMonth, nYear))
+ return false;
+
+ SetDay( nDay);
+ SetMonth( nMonth);
+ SetYear( nYear);
+
+ return true;
+}
+
+// -----------------------------------------------------------------------
+
+//static
+bool Date::Normalize( sal_uInt16 & rDay, sal_uInt16 & rMonth, sal_uInt16 & rYear )
+{
+ if (IsValidDate( rDay, rMonth, rYear))
+ return false;
+
+ if (rMonth > 12)
+ {
+ rYear += rMonth / 12;
+ rMonth = rMonth % 12;
+ }
+ if (!rMonth)
+ {
+ if (!rYear)
+ {
+ rYear = 0;
+ rMonth = 1;
+ if (rDay > 31)
+ rDay -= 31;
+ else
+ rDay = 1;
+ }
+ else
+ {
+ --rYear;
+ rMonth = 12;
+ }
+ }
+ sal_uInt16 nDays;
+ while (rDay > (nDays = DaysInMonth( rMonth, rYear)))
+ {
+ rDay -= nDays;
+ if (rMonth < 12)
+ ++rMonth;
+ else
+ {
+ ++rYear;
+ rMonth = 1;
+ }
+ }
+ if (rYear > 9999)
+ {
+ rDay = 31;
+ rMonth = 12;
+ rYear = 9999;
+ }
+ return true;
+}
+
+// -----------------------------------------------------------------------
+
Date& Date::operator +=( long nDays )
{
sal_uInt16 nDay;
commit dca69d5bb2d0e542de26624dd9f71fb87e1533f2
Author: Eike Rathke <erack at redhat.com>
Date: Wed Nov 30 02:05:22 2011 +0100
renamed Date::IsValid() to IsValidAndGregorian() to prevent misassumptions
Once smaller than 1582-10-15 decrementing a Date will not produce a valid date.
diff --git a/chart2/source/view/axes/DateHelper.cxx b/chart2/source/view/axes/DateHelper.cxx
index 142dd60..6749e74 100644
--- a/chart2/source/view/axes/DateHelper.cxx
+++ b/chart2/source/view/axes/DateHelper.cxx
@@ -73,7 +73,7 @@ Date DateHelper::GetDateSomeMonthsAway( const Date& rD, long nMonthDistance )
nNewMonth += 12;
aRet.SetMonth( sal_uInt16(nNewMonth) );
aRet.SetYear( sal_uInt16(nNewYear) );
- while(!aRet.IsValid())
+ while(!aRet.IsValidAndGregorian())
aRet--;
return aRet;
}
@@ -82,7 +82,7 @@ Date DateHelper::GetDateSomeYearsAway( const Date& rD, long nYearDistance )
{
Date aRet(rD);
aRet.SetYear( static_cast<sal_uInt16>(rD.GetYear()+nYearDistance) );
- while(!aRet.IsValid())
+ while(!aRet.IsValidAndGregorian())
aRet--;
return aRet;
}
diff --git a/sc/source/core/tool/interpr2.cxx b/sc/source/core/tool/interpr2.cxx
index be38e1f..ef42258 100644
--- a/sc/source/core/tool/interpr2.cxx
+++ b/sc/source/core/tool/interpr2.cxx
@@ -93,7 +93,7 @@ double ScInterpreter::GetDateSerial( sal_Int16 nYear, sal_Int16 nMonth, sal_Int1
Date aDate( nD, nM, nY);
if (!bStrict)
aDate += nDay - 1;
- if (aDate.IsValid())
+ if (aDate.IsValidAndGregorian())
return (double) (aDate - *(pFormatter->GetNullDate()));
else
{
diff --git a/sd/source/ui/annotations/annotationmanager.cxx b/sd/source/ui/annotations/annotationmanager.cxx
index 772a428..625ecd4 100644
--- a/sd/source/ui/annotations/annotationmanager.cxx
+++ b/sd/source/ui/annotations/annotationmanager.cxx
@@ -175,7 +175,7 @@ OUString getAnnotationDateTimeString( const Reference< XAnnotation >& xAnnotatio
if (aDate == Date(Date()-1))
sRet = sRet + String(SdResId(STR_ANNOTATION_YESTERDAY));
else
- if (aDate.IsValid() )
+ if (aDate.IsValidAndGregorian() )
sRet = sRet + rLocalData.getDate(aDate);
Time aTime( aDateTime.Hours, aDateTime.Minutes, aDateTime.Seconds, aDateTime.HundredthSeconds );
diff --git a/sfx2/source/doc/docfile.cxx b/sfx2/source/doc/docfile.cxx
index ab3cbfc..097eba9 100644
--- a/sfx2/source/doc/docfile.cxx
+++ b/sfx2/source/doc/docfile.cxx
@@ -2969,7 +2969,7 @@ void SfxMedium::SetExpired_Impl( const DateTime& rDateTime )
sal_Bool SfxMedium::IsExpired() const
{
- return pImp->aExpireTime.IsValid() && pImp->aExpireTime < DateTime();
+ return pImp->aExpireTime.IsValidAndGregorian() && pImp->aExpireTime < DateTime();
}
//----------------------------------------------------------------
diff --git a/sfx2/source/doc/oleprops.cxx b/sfx2/source/doc/oleprops.cxx
index b7d56b0..f42ed87 100644
--- a/sfx2/source/doc/oleprops.cxx
+++ b/sfx2/source/doc/oleprops.cxx
@@ -634,7 +634,7 @@ void SfxOleFileTimeProperty::ImplSave( SvStream& rStrm )
// invalid time stamp is not converted to UTC
// heuristic to detect editing durations (which we assume to be < 1 year):
// check only the year, not the entire date
- if( aDateTimeUtc.IsValid()
+ if( aDateTimeUtc.IsValidAndGregorian()
&& aDateTimeUtc.GetYear() != TIMESTAMP_INVALID_DATETIME.GetYear() ) {
aDateTimeUtc.ConvertToUTC();
}
diff --git a/svl/source/items/dateitem.cxx b/svl/source/items/dateitem.cxx
index 1df6b62..accd1cf 100644
--- a/svl/source/items/dateitem.cxx
+++ b/svl/source/items/dateitem.cxx
@@ -148,7 +148,7 @@ SfxItemPresentation SfxDateTimeItem::GetPresentation
) const
{
DBG_CHKTHIS(SfxDateTimeItem, 0);
- if (aDateTime.IsValid())
+ if (aDateTime.IsValidAndGregorian())
if (pIntlWrapper)
{
rText = pIntlWrapper->getLocaleData()->getDate(aDateTime);
diff --git a/svtools/source/contnr/templwin.cxx b/svtools/source/contnr/templwin.cxx
index 3792826..c2daae8 100644
--- a/svtools/source/contnr/templwin.cxx
+++ b/svtools/source/contnr/templwin.cxx
@@ -164,7 +164,7 @@ void lcl_insertDateTimeEntry(SvtExtendedMultiLineEdit_Impl* i_pEditWin,
DateTime( Date( i_rUDT.Day, i_rUDT.Month, i_rUDT.Year ),
Time( i_rUDT.Hours, i_rUDT.Minutes,
i_rUDT.Seconds, i_rUDT.HundredthSeconds ) );
- if ( aToolsDT.IsValid() )
+ if ( aToolsDT.IsValidAndGregorian() )
{
LocaleDataWrapper aLocaleWrapper(
::comphelper::getProcessServiceFactory(),
diff --git a/svtools/source/control/calendar.cxx b/svtools/source/control/calendar.cxx
index 7b4bf57..4ff76c3 100644
--- a/svtools/source/control/calendar.cxx
+++ b/svtools/source/control/calendar.cxx
@@ -1974,7 +1974,7 @@ void Calendar::Select()
void Calendar::SelectDate( const Date& rDate, sal_Bool bSelect )
{
- if ( !rDate.IsValid() )
+ if ( !rDate.IsValidAndGregorian() )
return;
Table* pOldSel;
@@ -2037,7 +2037,7 @@ Date Calendar::GetSelectDate( sal_uLong nIndex ) const
void Calendar::SetCurDate( const Date& rNewDate )
{
- if ( !rNewDate.IsValid() )
+ if ( !rNewDate.IsValidAndGregorian() )
return;
if ( maCurDate != rNewDate )
@@ -2638,9 +2638,9 @@ sal_Bool CalendarField::ShowDropDown( sal_Bool bShow )
Calendar* pCalendar = GetCalendar();
Date aDate = GetDate();
- if ( IsEmptyDate() || !aDate.IsValid() )
+ if ( IsEmptyDate() || !aDate.IsValidAndGregorian() )
{
- if ( maDefaultDate.IsValid() )
+ if ( maDefaultDate.IsValidAndGregorian() )
aDate = maDefaultDate;
else
aDate = Date();
diff --git a/sw/source/core/fields/docufld.cxx b/sw/source/core/fields/docufld.cxx
index f950016..74366ea 100644
--- a/sw/source/core/fields/docufld.cxx
+++ b/sw/source/core/fields/docufld.cxx
@@ -994,7 +994,7 @@ String SwDocInfoFieldType::Expand( sal_uInt16 nSub, sal_uInt32 nFormat,
else
break;
- if (aDate.IsValid())
+ if (aDate.IsValidAndGregorian())
{
switch (nExtSub & ~DI_SUB_FIXED)
{
diff --git a/sw/source/ui/docvw/SidebarWin.cxx b/sw/source/ui/docvw/SidebarWin.cxx
index fe2b53c..311e5bd 100644
--- a/sw/source/ui/docvw/SidebarWin.cxx
+++ b/sw/source/ui/docvw/SidebarWin.cxx
@@ -415,7 +415,7 @@ void SwSidebarWin::CheckMetaText()
{
sMeta = String(SW_RES(STR_POSTIT_YESTERDAY));
}
- else if (aDate.IsValid() )
+ else if (aDate.IsValidAndGregorian() )
{
sMeta = rLocalData.getDate(aDate);
}
diff --git a/tools/inc/tools/date.hxx b/tools/inc/tools/date.hxx
index 183f6af..a9d0e0d 100644
--- a/tools/inc/tools/date.hxx
+++ b/tools/inc/tools/date.hxx
@@ -80,7 +80,11 @@ public:
sal_uInt16 GetDaysInMonth() const;
sal_uInt16 GetDaysInYear() const { return (IsLeapYear()) ? 366 : 365; }
sal_Bool IsLeapYear() const;
- sal_Bool IsValid() const;
+ /** If the represented date is valid (1<=month<=12, 1<=day<=(28,29,30,31)
+ depending on month/year) AND is of the Gregorian calendar (1582-10-15
+ <= date) (AND implicitly date <= 9999-12-31 due to internal
+ representation) */
+ sal_Bool IsValidAndGregorian() const;
sal_Bool IsBetween( const Date& rFrom, const Date& rTo ) const
{ return ((nDate >= rFrom.nDate) &&
diff --git a/tools/source/datetime/tdate.cxx b/tools/source/datetime/tdate.cxx
index 47af8c0..06b0bc4 100644
--- a/tools/source/datetime/tdate.cxx
+++ b/tools/source/datetime/tdate.cxx
@@ -318,7 +318,7 @@ sal_Bool Date::IsLeapYear() const
// -----------------------------------------------------------------------
-sal_Bool Date::IsValid() const
+sal_Bool Date::IsValidAndGregorian() const
{
sal_uInt16 nDay = GetDay();
sal_uInt16 nMonth = GetMonth();
diff --git a/tools/source/inet/inetmsg.cxx b/tools/source/inet/inetmsg.cxx
index 42ab896..e0db594 100644
--- a/tools/source/inet/inetmsg.cxx
+++ b/tools/source/inet/inetmsg.cxx
@@ -431,7 +431,7 @@ sal_Bool INetRFC822Message::ParseDateField (
return sal_False;
}
- return (rDateTime.IsValid() &&
+ return (rDateTime.IsValidAndGregorian() &&
!((rDateTime.GetSec() > 59) ||
(rDateTime.GetMin() > 59) ||
(rDateTime.GetHour() > 23) ));
diff --git a/vcl/source/control/field2.cxx b/vcl/source/control/field2.cxx
index 31e9403..5fadf7e 100644
--- a/vcl/source/control/field2.cxx
+++ b/vcl/source/control/field2.cxx
@@ -1309,7 +1309,7 @@ static sal_Bool ImplDateGetValue( const XubString& rStr, Date& rDate, ExtDateFie
Date aNewDate( nDay, nMonth, nYear );
DateFormatter::ExpandCentury( aNewDate, utl::MiscCfg().GetYear2000() );
- if ( aNewDate.IsValid() )
+ if ( aNewDate.IsValidAndGregorian() )
{
rDate = aNewDate;
return sal_True;
More information about the Libreoffice-commits
mailing list