diff options
author | Eike Rathke <erack@redhat.com> | 2016-07-08 17:08:47 +0200 |
---|---|---|
committer | Eike Rathke <erack@redhat.com> | 2016-07-08 20:41:02 +0000 |
commit | 6d4f2dcc7cbba771e9d9b00de50368db4a88ef1b (patch) | |
tree | 0301896941b955ffa79ef3e96b874ebdad78662c /include | |
parent | 06287b9c348281612854d67c4eb2e7a38dc722ca (diff) |
Resolves: tdf#100452 class Date full (BCE,CE) proleptic Gregorian calendar
... implementing signed years with year 0 gap.
Date(31,12,-1) last day BCE
Date(1,1,1) first day CE
New class Date member functions:
* AddYears(sal_Int16) to be used instead of
aDate.SetYear(aDate.GetYear()+sal_Int16) to handle year 0 gap.
* convenience GetNextYear() to be used insted of GetYear()+1
* convenience GetPrevYear() to be used insted of GetYear()-1
* AddMonths(sal_Int32)
* operator=(const css::util::Date&)
New class DateTime member functions:
* operator=(const css::util::DateTime&)
Made some conversion ctors explicit, specifically Date(sal_Int32)
Adapted hopefully all places that used a sal_uInt16 year to use
sal_Int16 where appropriate.
Eliminated some quirks in date handling found on the fly.
Added era handling to i18npool icu calendar setting interface, which
missing was responsible for 0001-01-01 entered in Calc being set as
-0001-01-01, hence subtracting one day resulted in -0002-12-31.
Change-Id: I77b39fba9599ebd5067d7864f6c9ebe01f6f578f
Reviewed-on: https://gerrit.libreoffice.org/27049
Reviewed-by: Eike Rathke <erack@redhat.com>
Tested-by: Jenkins <ci@libreoffice.org>
Diffstat (limited to 'include')
-rw-r--r-- | include/editeng/flditem.hxx | 4 | ||||
-rw-r--r-- | include/svl/zforlist.hxx | 2 | ||||
-rw-r--r-- | include/svtools/calendar.hxx | 10 | ||||
-rw-r--r-- | include/tools/date.hxx | 115 | ||||
-rw-r--r-- | include/tools/datetime.hxx | 6 | ||||
-rw-r--r-- | include/vcl/field.hxx | 4 |
6 files changed, 92 insertions, 49 deletions
diff --git a/include/editeng/flditem.hxx b/include/editeng/flditem.hxx index 649167a20118..fd01faed6d83 100644 --- a/include/editeng/flditem.hxx +++ b/include/editeng/flditem.hxx @@ -106,7 +106,7 @@ enum SvxDateFormat { SVXDATEFORMAT_APPDEFAULT = 0, // Set as in App class EDITENG_DLLPUBLIC SvxDateField : public SvxFieldData { - sal_uInt32 nFixDate; + sal_Int32 nFixDate; SvxDateType eType; SvxDateFormat eFormat; @@ -118,7 +118,7 @@ public: SvxDateType eType = SVXDATETYPE_VAR, SvxDateFormat eFormat = SVXDATEFORMAT_STDSMALL ); - sal_uInt32 GetFixDate() const { return nFixDate; } + sal_Int32 GetFixDate() const { return nFixDate; } void SetFixDate( const Date& rDate ) { nFixDate = rDate.GetDate(); } SvxDateType GetType() const { return eType; } diff --git a/include/svl/zforlist.hxx b/include/svl/zforlist.hxx index de78ae51b484..e28b4aeb2cfd 100644 --- a/include/svl/zforlist.hxx +++ b/include/svl/zforlist.hxx @@ -333,7 +333,7 @@ public: /// Change language/country, also input and format scanner void ChangeIntl( LanguageType eLnge ); /// Change the reference null date - void ChangeNullDate(sal_uInt16 nDay, sal_uInt16 nMonth, sal_uInt16 nYear); + void ChangeNullDate(sal_uInt16 nDay, sal_uInt16 nMonth, sal_Int16 nYear); /// Change standard precision void ChangeStandardPrec(short nPrec); /// Set zero value suppression diff --git a/include/svtools/calendar.hxx b/include/svtools/calendar.hxx index 144f78250821..3814d11a702b 100644 --- a/include/svtools/calendar.hxx +++ b/include/svtools/calendar.hxx @@ -146,7 +146,7 @@ calls or by ending a selection. #define DIB_BOLD ((sal_uInt16)0x0001) -typedef std::set<sal_uInt32> IntDateSet; +typedef std::set<sal_Int32> IntDateSet; class SVT_DLLPUBLIC Calendar : public Control @@ -188,8 +188,8 @@ private: long mnDayHeight; long mnWeekWidth; WinBits mnWinStyle; - sal_uInt16 mnFirstYear; - sal_uInt16 mnLastYear; + sal_Int16 mnFirstYear; + sal_Int16 mnLastYear; bool mbCalc:1, mbFormat:1, mbDrag:1, @@ -224,9 +224,9 @@ private: SVT_DLLPRIVATE sal_uInt16 ImplHitTest( const Point& rPos, Date& rDate ) const; SVT_DLLPRIVATE void ImplDrawSpin(vcl::RenderContext& rRenderContext); SVT_DLLPRIVATE void ImplDrawDate(vcl::RenderContext& rRenderContext, long nX, long nY, - sal_uInt16 nDay, sal_uInt16 nMonth, sal_uInt16 nYear, + sal_uInt16 nDay, sal_uInt16 nMonth, sal_Int16 nYear, DayOfWeek eDayOfWeek, - bool bOther, sal_uLong nToday); + bool bOther, sal_Int32 nToday); SVT_DLLPRIVATE void ImplDraw(vcl::RenderContext& rRenderContext); SVT_DLLPRIVATE void ImplUpdateDate( const Date& rDate ); SVT_DLLPRIVATE void ImplUpdateSelection( IntDateSet* pOld ); diff --git a/include/tools/date.hxx b/include/tools/date.hxx index 1dfb13098028..bab1efd833f8 100644 --- a/include/tools/date.hxx +++ b/include/tools/date.hxx @@ -27,15 +27,32 @@ enum DayOfWeek { MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY }; -// TODO FIXME: make it handle signed year? +/** Represents a date in the proleptic Gregorian calendar. + + Largest representable date is 32767-12-31 = 327671231 + + Smallest representable date is -32768-01-01 = -327680101 + + Due to possible conversions to css::util::Date, which has a short + Year member variable, these limits are fix. + + Year value 0 is unused. The year before year 1 CE is year 1 BCE, which is + the traditional proleptic Gregorian calendar. + + This is not how ISO 8601:2000 defines things (but ISO 8601:1998 Draft + Revision did), but it enables class Date to be used for writing XML files + as XML Schema Part 2 in D.3.2 No Year Zero says + "The year "0000" is an illegal year value.", see + https://www.w3.org/TR/2004/REC-xmlschema-2-20041028/#noYearZero + and furthermore the note for 3.2.7 dateTime + https://www.w3.org/TR/2004/REC-xmlschema-2-20041028/#dateTime + + */ class SAL_WARN_UNUSED TOOLS_DLLPUBLIC Date { private: - sal_uInt32 nDate; - void setDateFromDMY( sal_uInt16 nDay, sal_uInt16 nMonth, sal_uInt16 nYear ) - { nDate = ( sal_uInt32( nDay % 100 ) ) + - ( ( sal_uInt32( nMonth % 100 ) ) * 100 ) + - ( ( sal_uInt32( nYear % 10000 ) ) * 10000); } + sal_Int32 mnDate; + void setDateFromDMY( sal_uInt16 nDay, sal_uInt16 nMonth, sal_Int16 nYear ); public: enum DateInitSystem @@ -43,37 +60,61 @@ public: SYSTEM }; - // TODO temporary until all uses are inspected and resolved enum DateInitEmpty { EMPTY }; - Date( DateInitEmpty) - { nDate = 0; } - Date( DateInitSystem ); - Date( sal_uInt32 _nDate ) { Date::nDate = _nDate; } - Date( const Date& rDate ) - { nDate = rDate.nDate; } - Date( sal_uInt16 nDay, sal_uInt16 nMonth, sal_uInt16 nYear ) + explicit Date( DateInitEmpty ) : mnDate(0) {} + explicit Date( DateInitSystem ); + explicit Date( sal_Int32 nDate ) : mnDate(nDate) {} + Date( const Date& rDate ) : mnDate(rDate.mnDate) {} + Date( sal_uInt16 nDay, sal_uInt16 nMonth, sal_Int16 nYear ) { setDateFromDMY(nDay, nMonth, nYear); } - Date( const css::util::Date& _rDate ) + Date( const css::util::Date& rUDate ) { - SAL_WARN_IF(_rDate.Year < 0, "tools.datetime", "Negative year in css::util::Date to ::Date conversion"); - setDateFromDMY(_rDate.Day, _rDate.Month, _rDate.Year); + setDateFromDMY(rUDate.Day, rUDate.Month, rUDate.Year); } Date( const css::util::DateTime& _rDateTime ); - void SetDate( sal_uInt32 nNewDate ) { nDate = nNewDate; } - sal_uInt32 GetDate() const { return nDate; } + void SetDate( sal_Int32 nNewDate ); + sal_Int32 GetDate() const { return mnDate; } + /** Type safe access for values that are guaranteed to be unsigned, like Date::SYSTEM. */ + sal_uInt32 GetDateUnsigned() const { return static_cast<sal_uInt32>(mnDate < 0 ? -mnDate : mnDate); } css::util::Date GetUNODate() const { return css::util::Date(GetDay(), GetMonth(), GetYear()); } void SetDay( sal_uInt16 nNewDay ); void SetMonth( sal_uInt16 nNewMonth ); - void SetYear( sal_uInt16 nNewYear ); - sal_uInt16 GetDay() const { return (sal_uInt16)(nDate % 100); } - sal_uInt16 GetMonth() const { return (sal_uInt16)((nDate / 100) % 100); } - sal_uInt16 GetYear() const { return (sal_uInt16)(nDate / 10000); } + void SetYear( sal_Int16 nNewYear ); + sal_uInt16 GetDay() const + { + return mnDate < 0 ? + static_cast<sal_uInt16>(-mnDate % 100) : + static_cast<sal_uInt16>( mnDate % 100); + } + sal_uInt16 GetMonth() const + { + return mnDate < 0 ? + static_cast<sal_uInt16>((-mnDate / 100) % 100) : + static_cast<sal_uInt16>(( mnDate / 100) % 100); + } + sal_Int16 GetYear() const { return static_cast<sal_Int16>(mnDate / 10000); } + /** Type safe access for values that are guaranteed to be unsigned, like Date::SYSTEM. */ + sal_uInt16 GetYearUnsigned() const { return static_cast<sal_uInt16>((mnDate < 0 ? -mnDate : mnDate) / 10000); } + sal_Int16 GetNextYear() const { sal_Int16 nY = GetYear(); return nY == -1 ? 1 : nY + 1; } + sal_Int16 GetPrevYear() const { sal_Int16 nY = GetYear(); return nY == 1 ? -1 : nY - 1; } + + /** Add years skipping year 0 and truncating at limits. If the original + date was on Feb-29 and the resulting date is not a leap year, the + result is adjusted to Feb-28. + */ + void AddYears( sal_Int16 nAddYears ); + + /** Add months skipping year 0 and truncating at limits. If the original + date was on Feb-29 or day 31 and the resulting date is not a leap year + or a month with less days, the result is adjusted to Feb-28 or day 30. + */ + void AddMonths( sal_Int32 nAddMonths ); /** Obtain the day of the week for the date. @@ -146,24 +187,26 @@ public: bool Normalize(); bool IsBetween( const Date& rFrom, const Date& rTo ) const - { return ((nDate >= rFrom.nDate) && - (nDate <= rTo.nDate)); } + { return ((mnDate >= rFrom.mnDate) && + (mnDate <= rTo.mnDate)); } bool operator ==( const Date& rDate ) const - { return (nDate == rDate.nDate); } + { return (mnDate == rDate.mnDate); } bool operator !=( const Date& rDate ) const - { return (nDate != rDate.nDate); } + { return (mnDate != rDate.mnDate); } bool operator >( const Date& rDate ) const - { return (nDate > rDate.nDate); } + { return (mnDate > rDate.mnDate); } bool operator <( const Date& rDate ) const - { return (nDate < rDate.nDate); } + { return (mnDate < rDate.mnDate); } bool operator >=( const Date& rDate ) const - { return (nDate >= rDate.nDate); } + { return (mnDate >= rDate.mnDate); } bool operator <=( const Date& rDate ) const - { return (nDate <= rDate.nDate); } + { return (mnDate <= rDate.mnDate); } Date& operator =( const Date& rDate ) - { nDate = rDate.nDate; return *this; } + { mnDate = rDate.mnDate; return *this; } + Date& operator =( const css::util::Date& rUDate ) + { setDateFromDMY( rUDate.Day, rUDate.Month, rUDate.Year); return *this; } Date& operator +=( long nDays ); Date& operator -=( long nDays ); Date& operator ++(); @@ -178,14 +221,14 @@ public: Internally sanitizes nMonth to values 1 <= nMonth <= 12, does not normalize values. */ - static sal_uInt16 GetDaysInMonth( sal_uInt16 nMonth, sal_uInt16 nYear ); + static sal_uInt16 GetDaysInMonth( sal_uInt16 nMonth, sal_Int16 nYear ); /// Internally normalizes values. - static long DateToDays( sal_uInt16 nDay, sal_uInt16 nMonth, sal_uInt16 nYear ); + static long DateToDays( sal_uInt16 nDay, sal_uInt16 nMonth, sal_Int16 nYear ); /// Semantically identical to IsValidDate() member method. - static bool IsValidDate( sal_uInt16 nDay, sal_uInt16 nMonth, sal_uInt16 nYear ); + static bool IsValidDate( sal_uInt16 nDay, sal_uInt16 nMonth, sal_Int16 nYear ); /// Semantically identical to Normalize() member method. - static bool Normalize( sal_uInt16 & rDay, sal_uInt16 & rMonth, sal_uInt16 & rYear ); + static bool Normalize( sal_uInt16 & rDay, sal_uInt16 & rMonth, sal_Int16 & rYear ); private: /// An accelerated form of DateToDays on this date diff --git a/include/tools/datetime.hxx b/include/tools/datetime.hxx index 66826dff58e1..9e1f5f3fe6ea 100644 --- a/include/tools/datetime.hxx +++ b/include/tools/datetime.hxx @@ -34,14 +34,13 @@ public: SYSTEM }; - // TODO temporary until all uses are inspected and resolved enum DateTimeInitEmpty { EMPTY }; - DateTime( DateTimeInitEmpty ) : Date( Date::EMPTY ), Time( Time::EMPTY ) {} - DateTime( DateTimeInitSystem ) : Date( Date::SYSTEM ), Time( Time::SYSTEM ) {} + explicit DateTime( DateTimeInitEmpty ) : Date( Date::EMPTY ), Time( Time::EMPTY ) {} + explicit DateTime( DateTimeInitSystem ) : Date( Date::SYSTEM ), Time( Time::SYSTEM ) {} DateTime( const DateTime& rDateTime ) : Date( rDateTime ), Time( rDateTime ) {} DateTime( const Date& rDate ) : Date( rDate ), Time(0) {} @@ -103,6 +102,7 @@ public: { return (const Date&) rDateTime - rDate; } DateTime& operator =( const DateTime& rDateTime ); + DateTime& operator =( const css::util::DateTime& rUDateTime ); void GetWin32FileDateTime( sal_uInt32 & rLower, sal_uInt32 & rUpper ); static DateTime CreateFromWin32FileDateTime( sal_uInt32 rLower, sal_uInt32 rUpper ); diff --git a/include/vcl/field.hxx b/include/vcl/field.hxx index d07624e8a92c..d277a0a55b59 100644 --- a/include/vcl/field.hxx +++ b/include/vcl/field.hxx @@ -336,12 +336,12 @@ public: void SetEmptyDate(); bool IsEmptyDate() const; - void ResetLastDate() { maLastDate = Date( 0, 0, 0 ); } + void ResetLastDate() { maLastDate = Date( Date::EMPTY ); } static void ExpandCentury( Date& rDate ); static void ExpandCentury( Date& rDate, sal_uInt16 nTwoDigitYearStart ); - static Date GetInvalidDate() { return Date( 0, 0, 0 ); } + static Date GetInvalidDate() { return Date( Date::EMPTY ); } /** enables or disables the enforcement of valid values |