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.kaganski@collabora.com>
This commit is contained in:
Mike Kaganski 2022-11-24 09:55:08 +03:00
parent 4dc372c87b
commit febf6795f6
2 changed files with 38 additions and 65 deletions

View file

@ -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);
}

View file

@ -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.