From 91cb01b1e6f898b5a1c1934f60b2b43653a12044 Mon Sep 17 00:00:00 2001 From: Eike Rathke Date: Thu, 30 Aug 2018 20:27:14 +0200 Subject: The never ending rounding and scaling of tools::Time::GetClock() Change-Id: Idab1c49730e10a806d7aeecb1d9b2676b3cc51e5 Reviewed-on: https://gerrit.libreoffice.org/59839 Reviewed-by: Eike Rathke Tested-by: Jenkins --- tools/source/datetime/ttime.cxx | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) (limited to 'tools') diff --git a/tools/source/datetime/ttime.cxx b/tools/source/datetime/ttime.cxx index 7f058cf2ac6d..0adde9acfe0b 100644 --- a/tools/source/datetime/ttime.cxx +++ b/tools/source/datetime/ttime.cxx @@ -294,9 +294,22 @@ void tools::Time::GetClock( double fTimeInDays, // In seconds, including milli and nano. const double fRawSeconds = fTime * tools::Time::secondPerDay; - // Round to nanoseconds, which is the highest resolution this could be - // influenced by. - double fSeconds = rtl::math::round( fRawSeconds, 9); + // Round to nanoseconds most, which is the highest resolution this could be + // influenced by, but if the original value included a date round to at + // most 14 significant digits (including adding 4 for *86400), otherwise we + // might end up with a fake precision of h:m:s.999999986 which in fact + // should had been h:m:s+1 + // BUT, leave at least 2 decimals to round. Which shouldn't be a problem in + // practice because class Date can calculate only 8-digit days for it's + // sal_Int16 year range, which exactly leaves us with 14-4-8=2. + int nDec = 9; + const double fAbsTimeInDays = fabs( fTimeInDays); + if (fAbsTimeInDays >= 1.0) + { + const int nDig = static_cast(ceil( log10( fAbsTimeInDays))); + nDec = std::max( std::min( nDig, 9), 2); + } + double fSeconds = rtl::math::round( fRawSeconds, nDec); // If this ended up as a full day the original value was very very close // but not quite. Take that. -- cgit