diff options
Diffstat (limited to 'include/tools/date.hxx')
-rw-r--r-- | include/tools/date.hxx | 115 |
1 files changed, 79 insertions, 36 deletions
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 |