summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorEike Rathke <erack@redhat.com>2023-06-21 21:56:56 +0200
committerEike Rathke <erack@redhat.com>2023-06-22 01:40:00 +0200
commit986c2d86a7b53a6599d014db7327f47cb33d4fea (patch)
tree0cc09933466809d9a606171fecaa25ae76807012 /tools
parent5435c1b80e93811c851878768bb3d2f4b5bc66a7 (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.cxx17
-rw-r--r--tools/source/datetime/duration.cxx58
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)