diff options
-rw-r--r-- | xmloff/source/core/xmluconv.cxx | 101 |
1 files changed, 36 insertions, 65 deletions
diff --git a/xmloff/source/core/xmluconv.cxx b/xmloff/source/core/xmluconv.cxx index 76f9467b9fe4..237c041e92cc 100644 --- a/xmloff/source/core/xmluconv.cxx +++ b/xmloff/source/core/xmluconv.cxx @@ -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. } } } |