SvXMLUnitConverter::convertDateTime: use tools::Time::GetClock()

... to not round up to the next magnitude.

Change-Id: Ibda6e014ae3bdbe021e208c8781f619b112bee21
Reviewed-on: https://gerrit.libreoffice.org/59887
Reviewed-by: Eike Rathke <erack@redhat.com>
Tested-by: Eike Rathke <erack@redhat.com>
This commit is contained in:
Eike Rathke
2018-09-03 08:37:50 +02:00
parent 89b47b5eb2
commit 238f180e08
+36 -65
View File
@@ -319,61 +319,12 @@ void SvXMLUnitConverter::convertDateTime( OUStringBuffer& rBuffer,
bool bAddTimeIf0AM )
{
double fValue = fDateTime;
sal_Int32 nValue = static_cast <sal_Int32> (::rtl::math::approxFloor (fValue));
const sal_Int32 nDays = static_cast <sal_Int32> (::rtl::math::approxFloor (fValue));
Date aDate (aTempNullDate.Day, aTempNullDate.Month, aTempNullDate.Year);
aDate.AddDays( nValue);
fValue -= nValue;
double fCount;
if (nValue > 0)
fCount = ::rtl::math::approxFloor (log10(static_cast<double>(nValue))) + 1;
else if (nValue < 0)
fCount = ::rtl::math::approxFloor (log10(static_cast<double>(nValue * -1))) + 1;
else
fCount = 0.0;
sal_Int16 nCount = sal_Int16(fCount);
bool bHasTime(false);
double fHoursValue = 0;
double fMinsValue = 0;
double fSecsValue = 0;
double f100SecsValue = 0;
if (fValue > 0.0)
{
bHasTime = true;
fValue *= 24;
fHoursValue = ::rtl::math::approxFloor (fValue);
fValue -= fHoursValue;
fValue *= 60;
fMinsValue = ::rtl::math::approxFloor (fValue);
fValue -= fMinsValue;
fValue *= 60;
fSecsValue = ::rtl::math::approxFloor (fValue);
fValue -= fSecsValue;
if (fValue > 0.0)
f100SecsValue = ::rtl::math::round( fValue, XML_MAXDIGITSCOUNT_TIME - nCount);
else
f100SecsValue = 0.0;
aDate.AddDays( nDays);
fValue -= nDays;
const bool bHasTime = (fValue > 0.0);
if (f100SecsValue == 1.0)
{
f100SecsValue = 0.0;
fSecsValue += 1.0;
}
if (fSecsValue >= 60.0)
{
fSecsValue -= 60.0;
fMinsValue += 1.0;
}
if (fMinsValue >= 60.0)
{
fMinsValue -= 60.0;
fHoursValue += 1.0;
}
if (fHoursValue >= 24.0)
{
fHoursValue -= 24.0;
aDate.AddDays(1);
}
}
sal_Int16 nTempYear = aDate.GetYear();
assert(nTempYear != 0);
if (nTempYear < 0)
@@ -400,29 +351,49 @@ void SvXMLUnitConverter::convertDateTime( OUStringBuffer& rBuffer,
if (nTemp < 10)
rBuffer.append( '0');
rBuffer.append( sal_Int32( nTemp));
if(bHasTime || bAddTimeIf0AM)
if (bHasTime || bAddTimeIf0AM)
{
double fCount;
if (nDays > 0)
fCount = ::rtl::math::approxFloor (log10(static_cast<double>(nDays))) + 1;
else if (nDays < 0)
fCount = ::rtl::math::approxFloor (log10(static_cast<double>(nDays * -1))) + 1;
else
fCount = 0.0;
const int nDigits = sal_Int16(fCount) + 4; // +4 for *86400 in seconds
const int nFractionDecimals = std::max( XML_MAXDIGITSCOUNT_TIME - nDigits, 0);
sal_uInt16 nHour, nMinute, nSecond;
double fFractionOfSecond;
// Pass the original date+time value for proper scaling and rounding.
tools::Time::GetClock( fDateTime, nHour, nMinute, nSecond, fFractionOfSecond, nFractionDecimals);
rBuffer.append( 'T');
if (fHoursValue < 10)
if (nHour < 10)
rBuffer.append( '0');
rBuffer.append( sal_Int32( fHoursValue));
rBuffer.append( sal_Int32( nHour));
rBuffer.append( ':');
if (fMinsValue < 10)
if (nMinute < 10)
rBuffer.append( '0');
rBuffer.append( sal_Int32( fMinsValue));
rBuffer.append( sal_Int32( nMinute));
rBuffer.append( ':');
if (fSecsValue < 10)
if (nSecond < 10)
rBuffer.append( '0');
rBuffer.append( sal_Int32( fSecsValue));
if (f100SecsValue > 0.0)
rBuffer.append( sal_Int32( nSecond));
if (nFractionDecimals)
{
OUString a100th( ::rtl::math::doubleToUString( fValue,
// nFractionDecimals+1 to not round up what GetClock() carefully
// truncated.
OUString aFraction( ::rtl::math::doubleToUString( fFractionOfSecond,
rtl_math_StringFormat_F,
XML_MAXDIGITSCOUNT_TIME - nCount, '.', true));
if ( a100th.getLength() > 2 )
nFractionDecimals + 1, '.', true));
const sal_Int32 nLen = aFraction.getLength();
if ( nLen > 2 )
{
// Truncate nFractionDecimals+1 digit if it was not rounded to zero.
const sal_Int32 nCount = nLen - 2 - static_cast<int>(nLen > nFractionDecimals + 2);
rBuffer.append( '.');
rBuffer.appendCopy( a100th, 2 ); // strip 0.
rBuffer.appendCopy( aFraction, 2, nCount); // strip 0.
}
}
}