diff options
author | Eike Rathke <erack@redhat.com> | 2023-06-21 21:56:56 +0200 |
---|---|---|
committer | Eike Rathke <erack@redhat.com> | 2023-06-22 01:40:00 +0200 |
commit | 986c2d86a7b53a6599d014db7327f47cb33d4fea (patch) | |
tree | 0cc09933466809d9a606171fecaa25ae76807012 /tools | |
parent | 5435c1b80e93811c851878768bb3d2f4b5bc66a7 (diff) |
Introduce tools::Duration(sal_Int32 nDays, const Time& rTime) ctor
Change-Id: If002e04536149b49b2249103ac914d17dec3fae6
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/153409
Reviewed-by: Eike Rathke <erack@redhat.com>
Tested-by: Jenkins
Diffstat (limited to 'tools')
-rw-r--r-- | tools/qa/cppunit/test_duration.cxx | 17 | ||||
-rw-r--r-- | tools/source/datetime/duration.cxx | 58 |
2 files changed, 75 insertions, 0 deletions
diff --git a/tools/qa/cppunit/test_duration.cxx b/tools/qa/cppunit/test_duration.cxx index 0f5a4e002219..c328db7cec38 100644 --- a/tools/qa/cppunit/test_duration.cxx +++ b/tools/qa/cppunit/test_duration.cxx @@ -104,6 +104,23 @@ void DurationTest::testDuration() const Duration aN = -aD; CPPUNIT_ASSERT_EQUAL(1.5, aN.GetInDays()); } + { + const Duration aD(1, Time(2, 3, 4, 5)); + CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1), aD.GetDays()); + CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt16>(2), aD.GetTime().GetHour()); + CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt16>(3), aD.GetTime().GetMin()); + CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt16>(4), aD.GetTime().GetSec()); + CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt32>(5), aD.GetTime().GetNanoSec()); + } + { + // 235929599 seconds == SAL_MAX_UINT16 hours + 59 minutes + 59 seconds + const Duration aD(0, Time(0, 0, 235929599)); + CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(2730), aD.GetDays()); + CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt16>(15), aD.GetTime().GetHour()); + CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt16>(59), aD.GetTime().GetMin()); + CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt16>(59), aD.GetTime().GetSec()); + CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt32>(0), aD.GetTime().GetNanoSec()); + } { // Add() const DateTime aS(Date(23, 11, 1999), Time(0, 0, 0)); const DateTime aE(Date(23, 11, 1999), Time(1, 23, 45)); diff --git a/tools/source/datetime/duration.cxx b/tools/source/datetime/duration.cxx index 3aa195cfbda5..255706f0486a 100644 --- a/tools/source/datetime/duration.cxx +++ b/tools/source/datetime/duration.cxx @@ -86,6 +86,64 @@ Duration::Duration(double fTimeInDays) } } +Duration::Duration(sal_Int32 nDays, const Time& rTime) + : mnDays(nDays) +{ + assert(nDays == 0 || rTime.GetTime() == 0 || (nDays < 0) == (rTime.GetTime() < 0)); + sal_uInt64 nN = rTime.GetNanoSec(); + sal_uInt64 nS = rTime.GetSec(); + if (nN >= Time::nanoSecPerSec) + { + nS += nN / Time::nanoSecPerSec; + nN %= Time::nanoSecPerSec; + } + sal_uInt64 nM = rTime.GetMin(); + if (nS >= Time::secondPerMinute) + { + nM += nS / Time::secondPerMinute; + nS %= Time::secondPerMinute; + } + sal_uInt64 nH = rTime.GetHour(); + if (nM >= Time::minutePerHour) + { + nH += nM / Time::minutePerHour; + nM %= Time::minutePerHour; + } + if (nH >= Time::hourPerDay) + { + sal_Int64 nDiff = nH / Time::hourPerDay; + nH %= Time::hourPerDay; + bool bOverflow = false; + if (rTime.GetTime() < 0) + { + nDiff = -nDiff; + bOverflow = (nDiff < SAL_MIN_INT32); + bOverflow |= o3tl::checked_add(mnDays, static_cast<sal_Int32>(nDiff), mnDays); + if (bOverflow) + mnDays = SAL_MIN_INT32; + } + else + { + bOverflow = (nDiff > SAL_MAX_INT32); + bOverflow |= o3tl::checked_add(mnDays, static_cast<sal_Int32>(nDiff), mnDays); + if (bOverflow) + mnDays = SAL_MAX_INT32; + } + assert(!bOverflow); + if (bOverflow) + { + nH = Time::hourPerDay - 1; + nM = Time::minutePerHour - 1; + nS = Time::secondPerMinute - 1; + nN = Time::nanoSecPerSec - 1; + } + } + maTime = Time(nH, nM, nS, nN); + if (rTime.GetTime() < 0) + maTime = -maTime; + assert(mnDays == 0 || maTime.GetTime() == 0 || (mnDays < 0) == (maTime.GetTime() < 0)); +} + Duration::Duration(sal_Int32 nDays, sal_Int64 nTime) : maTime(nTime) , mnDays(nDays) |