comphelper/source/misc/date.cxx | 65 +++------------------------------------- include/comphelper/date.hxx | 38 ++++++++++++++++++++--- 2 files changed, 38 insertions(+), 65 deletions(-)
New commits: commit febf6795f68efcdc05a4bcb19a2b6636226b026d Author: Mike Kaganski <mike.kagan...@collabora.com> AuthorDate: Thu Nov 24 09:55:08 2022 +0300 Commit: Mike Kaganski <mike.kagan...@collabora.com> CommitDate: Thu Nov 24 11:49:02 2022 +0100 Make some date functions inline constexpr Change-Id: Ibef0f650ce66030f28b59e4818f549d86415e2d1 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/143198 Tested-by: Jenkins Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com> diff --git a/comphelper/source/misc/date.cxx b/comphelper/source/misc/date.cxx index b14ef501d331..b95f63f75c97 100644 --- a/comphelper/source/misc/date.cxx +++ b/comphelper/source/misc/date.cxx @@ -42,70 +42,15 @@ constexpr sal_Int32 MAX_DAYS = 11967900; // 32767-12-31 constexpr sal_Int16 kYearMax = SAL_MAX_INT16; constexpr sal_Int16 kYearMin = SAL_MIN_INT16; -sal_Int32 YearToDays(sal_Int16 nYear) -{ - assert(nYear != 0); - sal_Int32 nOffset; - sal_Int32 nYr; - if (nYear < 0) - { - nOffset = -366; - nYr = nYear + 1; - } - else - { - nOffset = 0; - nYr = nYear - 1; - } - return nOffset + nYr * 365 + nYr / 4 - nYr / 100 + nYr / 400; -} - -bool isLeapYear(sal_Int16 nYear) -{ - assert(nYear != 0); - if (nYear < 0) - nYear = -nYear - 1; - return (((nYear % 4) == 0) && ((nYear % 100) != 0)) || ((nYear % 400) == 0); -} - -sal_uInt16 getDaysInMonth(sal_uInt16 nMonth, sal_Int16 nYear) -{ - assert(1 <= nMonth && nMonth <= 12); - if (nMonth < 1 || 12 < nMonth) - return 0; - - constexpr sal_uInt16 aDaysInMonth[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; - if (nMonth != 2) - return aDaysInMonth[nMonth - 1]; - else - { - if (isLeapYear(nYear)) - return aDaysInMonth[nMonth - 1] + 1; - else - return aDaysInMonth[nMonth - 1]; - } -} - -sal_Int32 convertDateToDays(sal_uInt16 nDay, sal_uInt16 nMonth, sal_Int16 nYear) -{ - sal_Int32 nDays = YearToDays(nYear); - for (sal_uInt16 i = 1; i < nMonth; ++i) - nDays += getDaysInMonth(i, nYear); - nDays += nDay; - return nDays; -} +constexpr sal_Int32 nNullDateDays = convertDateToDays(30, 12, 1899); +static_assert(nNullDateDays == 693594); sal_Int32 convertDateToDaysNormalizing(sal_uInt16 nDay, sal_uInt16 nMonth, sal_Int16 nYear) { // Speed-up the common null-date 1899-12-30. - if (nYear == 1899 && nDay == 30 && nMonth == 12) - { -#ifndef NDEBUG - static sal_Int32 nDays = convertDateToDays(nDay, nMonth, nYear); - assert(nDays == 693594); -#endif - return 693594; - } + if (nYear == 1899 && nMonth == 12 && nDay == 30) + return nNullDateDays; + normalize(nDay, nMonth, nYear); return convertDateToDays(nDay, nMonth, nYear); } diff --git a/include/comphelper/date.hxx b/include/comphelper/date.hxx index 7dbe9589690e..22247f71fe5d 100644 --- a/include/comphelper/date.hxx +++ b/include/comphelper/date.hxx @@ -22,6 +22,8 @@ #include <sal/types.h> #include <comphelper/comphelperdllapi.h> +#include <cassert> + namespace comphelper::date { /** Days until start of year from zero, so month and day of month can be added. @@ -32,7 +34,12 @@ namespace comphelper::date @param nYear MUST be != 0. */ -COMPHELPER_DLLPUBLIC sal_Int32 YearToDays(sal_Int16 nYear); +constexpr inline sal_Int32 YearToDays(sal_Int16 nYear) +{ + assert(nYear != 0); + auto val = [](int off, int y) { return off + y * 365 + y / 4 - y / 100 + y / 400; }; + return nYear < 0 ? val(-366, nYear + 1) : val(0, nYear - 1); +} /** Whether year is a leap year. @@ -44,21 +51,42 @@ COMPHELPER_DLLPUBLIC sal_Int32 YearToDays(sal_Int16 nYear); @param nYear MUST be != 0. */ -COMPHELPER_DLLPUBLIC bool isLeapYear(sal_Int16 nYear); +constexpr inline bool isLeapYear(sal_Int16 nYear) +{ + assert(nYear != 0); + if (nYear < 0) + nYear = -nYear - 1; + return (((nYear % 4) == 0) && ((nYear % 100) != 0)) || ((nYear % 400) == 0); +} /** Get number of days in month of year. @param nYear MUST be != 0. */ -COMPHELPER_DLLPUBLIC sal_uInt16 getDaysInMonth(sal_uInt16 nMonth, sal_Int16 nYear); +constexpr inline sal_uInt16 getDaysInMonth(sal_uInt16 nMonth, sal_Int16 nYear) +{ + assert(1 <= nMonth && nMonth <= 12); + if (nMonth < 1 || 12 < nMonth) + return 0; + + constexpr sal_uInt16 aDaysInMonth[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; + sal_uInt16 n = aDaysInMonth[nMonth - 1]; + return nMonth == 2 && isLeapYear(nYear) ? n + 1 : n; +} /** Obtain days from zero for a given date, without normalizing. nDay, nMonth, nYear MUST form a valid proleptic Gregorian calendar date. */ -COMPHELPER_DLLPUBLIC sal_Int32 convertDateToDays(sal_uInt16 nDay, sal_uInt16 nMonth, - sal_Int16 nYear); +constexpr inline sal_Int32 convertDateToDays(sal_uInt16 nDay, sal_uInt16 nMonth, sal_Int16 nYear) +{ + sal_Int32 nDays = YearToDays(nYear); + for (sal_uInt16 i = 1; i < nMonth; ++i) + nDays += getDaysInMonth(i, nYear); + nDays += nDay; + return nDays; +} /** Obtain days from zero for a given date, with normalizing.