29#include <rtl/math.hxx>
33#include <com/sun/star/i18n/CalendarFieldIndex.hpp>
34#include <com/sun/star/i18n/CalendarDisplayIndex.hpp>
35#include <com/sun/star/i18n/CalendarDisplayCode.hpp>
36#include <com/sun/star/i18n/AmPmValue.hpp>
37#include <com/sun/star/i18n/NativeNumberMode.hpp>
38#include <com/sun/star/i18n/NativeNumberXmlAttributes2.hpp>
55constexpr OUStringLiteral GREGORIAN =
u"gregorian";
57const sal_uInt16 UPPER_PRECISION = 300;
58const double EXP_LOWER_BOUND = 1.0E-4;
59const double EXP_ABS_UPPER_BOUND = 1.0E15;
65constexpr sal_Int32 kTimeSignificantRound = 7;
76 1,1,1,2,2,3,2,1,1,1,1,2,1,1,1,1,
77 2,2,2,2,2,2,2,2,2,2,1,1,2,2,2,2,
78 3,2,2,2,2,2,2,3,2,1,2,2,2,3,3,3,
79 2,3,2,2,2,2,2,3,2,2,2,1,1,1,2,2,
80 1,2,2,2,2,2,1,2,2,1,1,2,1,3,2,2,
81 2,2,1,2,1,2,2,2,2,2,2,1,1,1,2,1
96 r.insert(
nPos++,
' ');
104 DBG_ASSERT( fAbsVal > 0.0,
"GetPrecExp: fAbsVal <= 0.0" );
105 if ( fAbsVal < 1e-7 || fAbsVal > 1e7 )
108 return static_cast<tools::Long>(floor( log10( fAbsVal ) )) + 1;
118 while( fAbsVal >= 10 )
133 for (sal_uInt16
i = 0;
i < nCnt; ++
i)
163 else if ( nDBNum <= 3 )
170 if (1 <= nDBNum && nDBNum <= 4)
174 nNatNum = it->second[nDBNum - 1];
182 = { {
primary(
LANGUAGE_CHINESE), { 1, 0, 0, 1, 2, 3, 0, 0, 0 } },
183 {
primary(
LANGUAGE_JAPANESE), { 1, 2, 3, 1, 2, 3, 1, 2, 0 } },
209 nDBNum = it->second[
nNatNum - 1];
274 OUString& rExtension )
const
302enum BracketFormatSymbolType
304 BRACKET_SYMBOLTYPE_FORMAT = -1,
305 BRACKET_SYMBOLTYPE_COLOR = -2,
306 BRACKET_SYMBOLTYPE_ERROR = -3,
307 BRACKET_SYMBOLTYPE_DBNUM1 = -4,
308 BRACKET_SYMBOLTYPE_DBNUM2 = -5,
309 BRACKET_SYMBOLTYPE_DBNUM3 = -6,
310 BRACKET_SYMBOLTYPE_DBNUM4 = -7,
311 BRACKET_SYMBOLTYPE_DBNUM5 = -8,
312 BRACKET_SYMBOLTYPE_DBNUM6 = -9,
313 BRACKET_SYMBOLTYPE_DBNUM7 = -10,
314 BRACKET_SYMBOLTYPE_DBNUM8 = -11,
315 BRACKET_SYMBOLTYPE_DBNUM9 = -12,
316 BRACKET_SYMBOLTYPE_LOCALE = -13,
317 BRACKET_SYMBOLTYPE_NATNUM0 = -14,
318 BRACKET_SYMBOLTYPE_NATNUM1 = -15,
319 BRACKET_SYMBOLTYPE_NATNUM2 = -16,
320 BRACKET_SYMBOLTYPE_NATNUM3 = -17,
321 BRACKET_SYMBOLTYPE_NATNUM4 = -18,
322 BRACKET_SYMBOLTYPE_NATNUM5 = -19,
323 BRACKET_SYMBOLTYPE_NATNUM6 = -20,
324 BRACKET_SYMBOLTYPE_NATNUM7 = -21,
325 BRACKET_SYMBOLTYPE_NATNUM8 = -22,
326 BRACKET_SYMBOLTYPE_NATNUM9 = -23,
327 BRACKET_SYMBOLTYPE_NATNUM10 = -24,
328 BRACKET_SYMBOLTYPE_NATNUM11 = -25,
329 BRACKET_SYMBOLTYPE_NATNUM12 = -26,
330 BRACKET_SYMBOLTYPE_NATNUM13 = -27,
331 BRACKET_SYMBOLTYPE_NATNUM14 = -28,
332 BRACKET_SYMBOLTYPE_NATNUM15 = -29,
333 BRACKET_SYMBOLTYPE_NATNUM16 = -30,
334 BRACKET_SYMBOLTYPE_NATNUM17 = -31,
335 BRACKET_SYMBOLTYPE_NATNUM18 = -32,
336 BRACKET_SYMBOLTYPE_NATNUM19 = -33
358 for (sal_uInt16
i = 0;
i < 4;
i++)
365 : rScan(rFormat.rScan), bStarFlag( rFormat.bStarFlag )
372 , bStarFlag( rFormat.bStarFlag )
379 if ( nSymbolType > 0 )
383 switch ( nSymbolType )
385 case BRACKET_SYMBOLTYPE_COLOR :
386 case BRACKET_SYMBOLTYPE_DBNUM1 :
387 case BRACKET_SYMBOLTYPE_DBNUM2 :
388 case BRACKET_SYMBOLTYPE_DBNUM3 :
389 case BRACKET_SYMBOLTYPE_DBNUM4 :
390 case BRACKET_SYMBOLTYPE_DBNUM5 :
391 case BRACKET_SYMBOLTYPE_DBNUM6 :
392 case BRACKET_SYMBOLTYPE_DBNUM7 :
393 case BRACKET_SYMBOLTYPE_DBNUM8 :
394 case BRACKET_SYMBOLTYPE_DBNUM9 :
395 case BRACKET_SYMBOLTYPE_LOCALE :
396 case BRACKET_SYMBOLTYPE_NATNUM0 :
397 case BRACKET_SYMBOLTYPE_NATNUM1 :
398 case BRACKET_SYMBOLTYPE_NATNUM2 :
399 case BRACKET_SYMBOLTYPE_NATNUM3 :
400 case BRACKET_SYMBOLTYPE_NATNUM4 :
401 case BRACKET_SYMBOLTYPE_NATNUM5 :
402 case BRACKET_SYMBOLTYPE_NATNUM6 :
403 case BRACKET_SYMBOLTYPE_NATNUM7 :
404 case BRACKET_SYMBOLTYPE_NATNUM8 :
405 case BRACKET_SYMBOLTYPE_NATNUM9 :
406 case BRACKET_SYMBOLTYPE_NATNUM10 :
407 case BRACKET_SYMBOLTYPE_NATNUM11 :
408 case BRACKET_SYMBOLTYPE_NATNUM12 :
409 case BRACKET_SYMBOLTYPE_NATNUM13 :
410 case BRACKET_SYMBOLTYPE_NATNUM14 :
411 case BRACKET_SYMBOLTYPE_NATNUM15 :
412 case BRACKET_SYMBOLTYPE_NATNUM16 :
413 case BRACKET_SYMBOLTYPE_NATNUM17 :
414 case BRACKET_SYMBOLTYPE_NATNUM18 :
415 case BRACKET_SYMBOLTYPE_NATNUM19 :
458 sCalendar =
"[~dangi]";
467 sCalendar =
"[~hijri]";
484 sCalendar=
"[~buddhist]";
499 sCalendar =
"[~jewish]";
560 switch ( nNumeralID )
668 nNatNum = nNumeralID == 0x27 ? 9 : ( ( nNumeralID - 0x1B ) % 3 ) + 1;
709 if ( nNumeralID >= 0x02 && nNumeralID <= 0x13 )
712 rString.insert(
nPos,
"[NatNum" + OUString::number(
nNatNum) +
"]");
718bool NatNumTakesParameters(sal_Int16 nNum)
720 return (nNum == css::i18n::NativeNumberMode::NATNUM12);
728 sal_Int32 nUpper = 0;
729 sal_Int32 nLen = sParam.getLength();
730 for (sal_Int32
n = 0;
n < nLen; ++
n)
733 if (
'A' <= c && c <=
'Z' )
737 else if ( c ==
' ' && nUpper == 3 && (
n == 3 || sParam[
n - 4] ==
' ') )
747 return nUpper == 3 && (nLen == 3 || sParam[nLen - 4] ==
' ');
753 sal_Int32& nCheckPos,
755 bool bReplaceBooleanEquivalent)
757 , bAdditionalBuiltin( false )
760 if (bReplaceBooleanEquivalent)
763 OUStringBuffer sBuff(rString);
770 if ( rThSep.getLength() == 1)
774 if (rThSep[0] == cNBSp )
775 sBuff.replace( cNBSp,
' ');
776 else if (rThSep[0] == cNNBSp )
777 sBuff.replace( cNNBSp,
' ');
780 OUString aConvertFromDecSep;
781 OUString aConvertToDecSep;
800 bool bCancel =
false;
801 bool bCondition =
false;
816 OUString sInsertCalendar;
825 if (
nIndex == 0 && !bCondition )
830 else if (
nIndex == 1 && bCondition )
853 sBuff.remove(
nPos, nCntChars);
854 sBuff.insert(
nPos,
'0');
859 if (aConvertToDecSep.isEmpty())
861 if (aConvertToDecSep != aConvertFromDecSep)
863 const OUString
aStr( sStr.replaceAt( nDecPos,
864 aConvertFromDecSep.getLength(), aConvertToDecSep));
866 sBuff.remove(
nPos, nCntChars);
875 sBuff.insert(
nPos++,
'0');
885 if (
nPos < sBuff.getLength() && sBuff[
nPos] ==
']' )
899 OUString sSymbol( sStr);
900 switch ( eSymbolType )
902 case BRACKET_SYMBOLTYPE_COLOR :
912 if (pColor ==
nullptr)
919 case BRACKET_SYMBOLTYPE_NATNUM0 :
920 case BRACKET_SYMBOLTYPE_NATNUM1 :
921 case BRACKET_SYMBOLTYPE_NATNUM2 :
922 case BRACKET_SYMBOLTYPE_NATNUM3 :
923 case BRACKET_SYMBOLTYPE_NATNUM4 :
924 case BRACKET_SYMBOLTYPE_NATNUM5 :
925 case BRACKET_SYMBOLTYPE_NATNUM6 :
926 case BRACKET_SYMBOLTYPE_NATNUM7 :
927 case BRACKET_SYMBOLTYPE_NATNUM8 :
928 case BRACKET_SYMBOLTYPE_NATNUM9 :
929 case BRACKET_SYMBOLTYPE_NATNUM10 :
930 case BRACKET_SYMBOLTYPE_NATNUM11 :
931 case BRACKET_SYMBOLTYPE_NATNUM12 :
932 case BRACKET_SYMBOLTYPE_NATNUM13 :
933 case BRACKET_SYMBOLTYPE_NATNUM14 :
934 case BRACKET_SYMBOLTYPE_NATNUM15 :
935 case BRACKET_SYMBOLTYPE_NATNUM16 :
936 case BRACKET_SYMBOLTYPE_NATNUM17 :
937 case BRACKET_SYMBOLTYPE_NATNUM18 :
938 case BRACKET_SYMBOLTYPE_NATNUM19 :
947 sal_Int32 nSpacePos = sStr.indexOf(
' ');
950 sParams =
o3tl::trim(sStr.subView(nSpacePos+1));
953 sal_uInt8 nNum =
static_cast<sal_uInt8>(0 - (eSymbolType - BRACKET_SYMBOLTYPE_NATNUM0));
954 if (!sParams.isEmpty() && !NatNumTakesParameters(nNum))
960 sStr =
"NatNum" + OUString::number(nNum);
965 if (sParams.isEmpty())
966 sParams =
"cardinal";
967 else if (sParams.indexOf(
"CURRENCY") >= 0)
968 sParams = sParams.replaceAll(
"CURRENCY",
969 rLoc().getCurrBankSymbol());
971 sStr +=
" " + sParams;
975 case BRACKET_SYMBOLTYPE_DBNUM1 :
976 case BRACKET_SYMBOLTYPE_DBNUM2 :
977 case BRACKET_SYMBOLTYPE_DBNUM3 :
978 case BRACKET_SYMBOLTYPE_DBNUM4 :
979 case BRACKET_SYMBOLTYPE_DBNUM5 :
980 case BRACKET_SYMBOLTYPE_DBNUM6 :
981 case BRACKET_SYMBOLTYPE_DBNUM7 :
982 case BRACKET_SYMBOLTYPE_DBNUM8 :
983 case BRACKET_SYMBOLTYPE_DBNUM9 :
992 sal_uInt8 nNum =
static_cast<sal_uInt8>(1 - (eSymbolType - BRACKET_SYMBOLTYPE_DBNUM1));
993 sStr =
"DBNum" + OUStringChar(
sal_Unicode(
'0' + nNum));
997 case BRACKET_SYMBOLTYPE_LOCALE :
999 sBuff[
nPos-1] !=
']' )
1005 nCheckPos = nPosOld;
1014 nCheckPos = nPosOld;
1080 if (sSymbol.getLength() > 6)
1095 if (sStr == sSymbol)
1101 sBuff.remove(nPosOld,
nPos - nPosOld);
1102 if (!sStr.isEmpty())
1104 sBuff.insert(nPosOld,
"[" + sStr +
"]");
1105 nPos = nPosOld + sStr.getLength() + 2;
1121 if (eSymbolType == BRACKET_SYMBOLTYPE_FORMAT)
1138 if (!sInsertCalendar.isEmpty())
1140 sStr = sInsertCalendar + sStr;
1144 if (nCnt == 0 && nStrPos == 0)
1173 sStr =
"[$-" + OUString::number( sal_uInt16(eLanguage), 16 ).toAsciiUpperCase() +
"]" + sStr;
1176 sBuff.remove(nPosOld,
nPos - nPosOld);
1177 sBuff.insert(nPosOld, sStr);
1178 nPos = nPosOld + sStr.getLength();
1179 if (
nPos < sBuff.getLength())
1181 sBuff.insert(
nPos,
";");
1222 nCheckPos = nPosOld + nStrPos;
1227 else if (eSymbolType == BRACKET_SYMBOLTYPE_ERROR)
1229 nCheckPos = nPosOld;
1234 nCheckPos = nPosOld + 1;
1238 if ( bCancel && !nCheckPos )
1250 if (sBuff.getLength() ==
nPos)
1252 if (
nIndex < 3 && rString[rString.getLength()-1] ==
';')
1268 if (sBuff[
nPos-1] !=
';')
1269 sBuff.insert(
nPos++,
';');
1271 if (
nIndex == 2 && eSymbolType == BRACKET_SYMBOLTYPE_FORMAT && sBuff[
nPos-1] ==
';')
1292 nCheckPos = std::max<sal_Int32>( sBuff.indexOf(
']') + 1, 1);
1297 nCheckPos = std::max<sal_Int32>( sBuff.indexOf(
']') + 1, 1);
1300 assert(!
"unhandled substitute");
1303 if ( bCondition && !nCheckPos )
1306 sBuff[sBuff.getLength() - 1] !=
';' )
1322 sBuff[sBuff.getLength() - 1] !=
';' &&
1337 sBuff.append(
";" + aAdd);
1342 sBuff[sBuff.getLength() - 1] !=
';' &&
1354 sBuff.append(
";" + aAdd);
1359 rString = sBuff.makeStringAndClear();
1362 if (
NumFor[2].GetCount() == 0 &&
1440 sal_Int32 nStartPos =
nPos;
1442 sal_Int32 nLen = rString.getLength();
1443 OUStringBuffer sBuffSymbol;
1444 while (
nPos < nLen )
1446 cToken = rString[
nPos];
1451 rString.remove(
nPos,1);
1457 sBuffSymbol.append(cToken);
1460 sSymbol = sBuffSymbol.makeStringAndClear();
1461 return nPos - nStartPos;
1480bool IsCombiningSymbol( OUStringBuffer& rStringBuffer, sal_Int32 nPos )
1485 switch (rStringBuffer[nPos])
1504 OUStringBuffer
aBuf;
1513 if (
n ||
aBuf.getLength())
1515 aBuf.append(toUniChar(
n));
1527 if (
n ||
aBuf.getLength())
1529 aBuf.append(toUniChar(
n));
1536 sal_uInt16 n16 =
static_cast<sal_uInt16
>(
1558 if (
n || !
aBuf.isEmpty() ||
i == 3)
1560 aBuf.append(toUniChar(
n));
1565 return aBuf.makeStringAndClear();
1595 nRawNum = (nRawNum >> 16);
1597 nRawNum = (nRawNum >> 8);
1603 return meSubstitute == Substitute::NONE && !mnCalendarType && !mnNumeralShape;
1609 sal_uInt32 nNum = 0;
1611 sal_Int32 nStart =
nPos;
1612 sal_Int32 nLen = rString.size();
1613 while (
nPos < nLen && (
nPos - nStart < 8) )
1615 cToken = rString[
nPos];
1618 if (
'0' <= cToken && cToken <=
'9' )
1621 nNum += cToken -
'0';
1623 else if (
'a' <= cToken && cToken <=
'f' )
1626 nNum += cToken -
'a' + 10;
1628 else if (
'A' <= cToken && cToken <=
'F' )
1631 nNum += cToken -
'A' + 10;
1644 std::u16string_view rKeyword, sal_Int32 & nNumber )
1660 OUString& sSymbol)
const
1662 short eSymbolType = BRACKET_SYMBOLTYPE_FORMAT;
1665 sal_Int32 nLen = rString.getLength();
1666 ScanState eState = SsStart;
1667 OUStringBuffer sBuffSymbol(128);
1670 while (
nPos < nLen && eState != SsStop)
1672 cToken = rString[
nPos];
1679 eState = SsGetQuoted;
1680 sBuffSymbol.append(cToken);
1682 else if (cToken ==
'[')
1684 eState = SsGetBracketed;
1685 sBuffSymbol.append(cToken);
1687 else if (cToken ==
';')
1689 eState = SsGetString;
1691 eSymbolType = BRACKET_SYMBOLTYPE_FORMAT;
1693 else if (cToken ==
']')
1696 eSymbolType = BRACKET_SYMBOLTYPE_ERROR;
1698 else if (cToken ==
' ')
1701 rString.remove(
nPos, 1);
1706 sBuffSymbol.append(cToken);
1707 eState = SsGetString;
1708 eSymbolType = BRACKET_SYMBOLTYPE_FORMAT;
1711 case SsGetBracketed:
1717 sBuffSymbol.stripStart(
'[');
1718 sBuffSymbol.append(cToken);
1736 rString.remove(
nPos, 1);
1740 if (
nPos < nLen && rString[
nPos] ==
'-' )
1743 sBuffSymbol.stripStart(
'[');
1744 eSymbolType = BRACKET_SYMBOLTYPE_LOCALE;
1745 eState = SsGetPrefix;
1749 eSymbolType = BRACKET_SYMBOLTYPE_FORMAT;
1750 eState = SsGetString;
1752 sBuffSymbol.append(cToken);
1756 eSymbolType = BRACKET_SYMBOLTYPE_FORMAT;
1757 sBuffSymbol.append(cToken);
1758 eState = SsGetString;
1762 static constexpr OUStringLiteral aNatNum(
u"NATNUM");
1763 static constexpr OUStringLiteral aDBNum(
u"DBNUM");
1764 const OUString aBufStr( rString.toString());
1765 sal_Int32 nNatNumNum;
1768 0 <= nNatNumNum && nNatNumNum <= 19 )
1770 sBuffSymbol.stripStart(
'[');
1771 sBuffSymbol.append( aBufStr.subView(--
nPos, aNatNum.getLength()+1) );
1772 nPos += aNatNum.getLength()+1;
1774 eSymbolType =
static_cast<short>(BRACKET_SYMBOLTYPE_NATNUM0 - nNatNumNum);
1775 eState = SsGetPrefix;
1778 1 <= nDBNum && nDBNum <= 9 )
1780 sBuffSymbol.stripStart(
'[');
1781 sBuffSymbol.append( aBufStr.subView(--
nPos, aDBNum.getLength()+1) );
1782 nPos += aDBNum.getLength()+1;
1784 eSymbolType = sal::static_int_cast< short >( BRACKET_SYMBOLTYPE_DBNUM1 - (nDBNum - 1) );
1785 eState = SsGetPrefix;
1790 if ( cUpper == rKeywords[
NF_KEY_H][0] ||
1794 sBuffSymbol.append(cToken);
1800 sBuffSymbol.stripStart(
'[');
1801 sBuffSymbol.append(cToken);
1802 eSymbolType = BRACKET_SYMBOLTYPE_COLOR;
1803 eState = SsGetPrefix;
1812 eState = SsGetQuoted;
1813 sBuffSymbol.append(cToken);
1815 else if (cToken ==
';' && (
nPos < 2 || !IsCombiningSymbol( rString,
nPos-2)))
1821 sBuffSymbol.append(cToken);
1827 eState = SsGetString;
1828 sBuffSymbol.append(cToken);
1832 sBuffSymbol.append(cToken);
1838 sBuffSymbol.append(cToken);
1839 eState = SsGetString;
1840 eSymbolType = BRACKET_SYMBOLTYPE_FORMAT;
1845 if (cUpper == rKeywords[
NF_KEY_H][0] ||
1849 if (cLetter == cToken)
1851 sBuffSymbol.append(cToken);
1856 sBuffSymbol.stripStart(
'[');
1857 sBuffSymbol.append(cToken);
1858 eState = SsGetPrefix;
1863 sBuffSymbol.stripStart(
'[');
1864 sBuffSymbol.append(cToken);
1865 eSymbolType = BRACKET_SYMBOLTYPE_COLOR;
1866 eState = SsGetPrefix;
1875 eSymbolType = BRACKET_SYMBOLTYPE_ERROR;
1880 sBuffSymbol.append(cToken);
1888 eSymbolType = BRACKET_SYMBOLTYPE_ERROR;
1894 sBuffSymbol.append(cToken);
1898 else if (cLetter ==
'>')
1900 sBuffSymbol.append(cToken);
1907 eSymbolType = BRACKET_SYMBOLTYPE_ERROR;
1912 rString.remove(
nPos,1);
1928 sBuffSymbol.append(cToken);
1935 sSymbol = sBuffSymbol.makeStringAndClear();
1943 sal_Int32 nCheckPos;
1948 nKey, eConvertFrom, eConvertTo,
false);
1950 DBG_ASSERT( pFormat,
"SvNumberformat::ConvertLanguage: Conversion without format" );
1958 OUString aColorName = rFormatter.GetColorName();
1960 rFormatter.SetColor( pColor, aColorName );
1967 for (
const auto & j :
NumFor)
1969 if ( j.HasNewCurrency() )
1978 OUString& rExtension )
const
1980 for (
const auto & j :
NumFor)
1982 if ( j.GetNewCurrencySymbol( rSymbol, rExtension ) )
1995 OUStringBuffer aTmp(rStr.getLength());
1996 sal_Int32 nStartPos,
nPos, nLen;
1997 nLen = rStr.getLength();
1999 while ( (
nPos = rStr.indexOf(
"[$", nStartPos )) >= 0 )
2004 aTmp.append(rStr.subView( nStartPos, ++nEnd - nStartPos ));
2009 aTmp.append(rStr.subView(nStartPos,
nPos - nStartPos) );
2010 nStartPos =
nPos + 2;
2012 nEnd = nStartPos - 1;
2015 nDash = rStr.indexOf(
'-', ++nEnd );
2018 while ( nEnd >= 0 );
2020 nEnd = nStartPos - 1;
2023 nClose = rStr.indexOf(
']', ++nEnd );
2026 while ( nEnd >= 0 );
2038 if(nDash >= 0 && nDash < nClose)
2042 aTmp.append(rStr.subView(nStartPos,
nPos - nStartPos) );
2043 nStartPos = nClose + 1;
2046 if ( nLen > nStartPos )
2048 aTmp.append(rStr.subView(nStartPos, nLen - nStartPos) );
2050 return aTmp.makeStringAndClear();
2064 if ( fabs(fNumber) > EXP_ABS_UPPER_BOUND )
2066 nStandardPrec = ::std::min(nStandardPrec,
static_cast<sal_uInt16
>(14));
2067 rOutString = ::rtl::math::doubleToUString( fNumber,
2068 rtl_math_StringFormat_E2, nStandardPrec ,
2081bool checkForAll0s(
const T& rString, sal_Int32 nIdx=0)
2083 if (nIdx>=rString.getLength())
2088 if (rString[nIdx]!=
'0')
2091 while (++nIdx<rString.getLength());
2101 nPrecision = ::std::min(UPPER_PRECISION, nPrecision);
2108 rOutString = ::rtl::math::doubleToUString( rNumber,
2109 rtl_math_StringFormat_F, nPrecision ,
2111 if (rOutString[0] ==
'-' && checkForAll0s(rOutString, 1))
2120 bool bModified =
false;
2138 OutString = ::rtl::math::doubleToUString( fNumber,
2139 rtl_math_StringFormat_Automatic,
2140 rtl_math_DecimalPlaces_Max,
2158 return static_cast<short>(fNumber == fLimit);
2160 return static_cast<short>(fNumber != fLimit);
2162 return static_cast<short>(fNumber < fLimit);
2164 return static_cast<short>(fNumber <= fLimit);
2166 return static_cast<short>(fNumber > fLimit);
2168 return static_cast<short>(fNumber >= fLimit);
2178 if (rStr.size() > 1)
2180 rBuf.append(
u'\x001B');
2181 rBuf.append(rStr[1]);
2189 if (rStr.size() > 1)
2191 rBuf.insert(
nPos, rStr[1]);
2192 rBuf.insert(
nPos,
u'\x001B');
2199 OUString& OutString,
2200 const Color** ppColor)
2202 OUStringBuffer sOutBuff;
2208 else if (
NumFor[3].GetCount() > 0)
2222 for (sal_uInt16
i = 0;
i < nCnt;
i++)
2238 sOutBuff.append(sString);
2245 OutString = sOutBuff.makeStringAndClear();
2250void lcl_GetOutputStringScientific(
double fNumber, sal_uInt16 nCharCount,
2253 bool bSign = std::signbit(fNumber);
2257 double fExp = log10( fabs(fNumber) );
2260 sal_uInt16 nCharFormat = 6 + (fExp >= 100.0 ? 1 : 0);
2261 sal_uInt16 nPrec = nCharCount > nCharFormat ? nCharCount - nCharFormat : 0;
2267 nPrec = ::std::min(nPrec,
static_cast<sal_uInt16
>(14));
2269 rOutString = ::rtl::math::doubleToUString(fNumber, rtl_math_StringFormat_E2,
2276 OUStringBuffer aPercentString;
2277 for( i = 0;
i < nCnt;
i++ )
2281 aPercentString.append( rInfo.
sStrArray[i] );
2282 bool bStringFound =
false;
2287 bStringFound =
true;
2288 aPercentString.insert( 0,
"\"" );
2290 aPercentString.insert( 0, rInfo.
sStrArray[i] );
2294 aPercentString.insert( 0,
"\"" );
2297 return aPercentString.makeStringAndClear();
2303 OUStringBuffer aDenominatorString;
2304 for( i = 0;
i < nCnt;
i++ )
2310 for( ;
i < nCnt;
i++ )
2313 aDenominatorString.append( rInfo.
sStrArray[i] );
2319 return aDenominatorString.makeStringAndClear();
2325 OUStringBuffer aNumeratorString;
2326 for( i = 0;
i < nCnt;
i++ )
2332 aNumeratorString.insert( 0, rInfo.
sStrArray[i] );
2337 return aNumeratorString.makeStringAndClear();
2343 OUStringBuffer aIntegerString;
2344 for( i = 0;
i < nCnt;
i++ )
2351 aIntegerString.insert( 0, rInfo.
sStrArray[i] );
2356 return aIntegerString.makeStringAndClear();
2362 for( i = 0;
i < nCnt;
i++ )
2378 return lcl_GetPercentString( rInfo, nCnt );
2385 return lcl_GetDenominatorString( rInfo, nCnt );
2392 return lcl_GetNumeratorString( rInfo, nCnt );
2399 return lcl_GetIntegerFractionDelimiterString( rInfo, nCnt );
2408 double fTestNum = fNumber;
2409 bool bSign = std::signbit(fTestNum);
2412 fTestNum = -fTestNum;
2414 if (fTestNum < EXP_LOWER_BOUND)
2416 lcl_GetOutputStringScientific(fNumber, nCharCount,
GetFormatter(), rOutString);
2420 double fExp = log10(fTestNum);
2422 sal_uInt16 nDigitPre = fExp >= 0.0 ?
static_cast<sal_uInt16
>(ceil(fExp)) : 1;
2426 lcl_GetOutputStringScientific(fNumber, nCharCount,
GetFormatter(), rOutString);
2430 sal_uInt16 nPrec = nCharCount >= nDigitPre ? nCharCount - nDigitPre : 0;
2442 if (rOutString.getLength() > nCharCount)
2445 lcl_GetOutputStringScientific(fNumber, nCharCount,
GetFormatter(), rOutString);
2455 if (nCheck == -1 || nCheck == 1)
2463 if (nCheck == -1 || nCheck == 1)
2476 OUString& OutString,
2477 const Color** ppColor)
2494 OUStringBuffer sBuff(64);
2501 bool bHadStandard =
false;
2514 if (std::signbit(fNumber))
2516 if (!(fNumber < 0.0))
2523 else if (fNumber < 1.0 && fNumber > -1.0)
2526 bool bFix = (fNumber < -EXP_LOWER_BOUND || EXP_LOWER_BOUND < fNumber);
2530 constexpr sal_Int32 kMaxExp = 9;
2531 const sal_Int32 nExp =
static_cast<sal_Int32
>(ceil( -log10( fabs( fNumber))));
2532 if (nExp <= kMaxExp && rtl::math::approxEqual(
2533 rtl::math::round( fNumber, 16), rtl::math::round( fNumber, nExp + 16)))
2542 OutString = ::rtl::math::doubleToUString( fNumber,
2543 rtl_math_StringFormat_F,
2544 rtl_math_DecimalPlaces_Max,
2547 OutString = ::rtl::math::doubleToUString( fNumber,
2548 rtl_math_StringFormat_E2,
2549 rtl_math_DecimalPlaces_Max,
2554 OutString = ::rtl::math::doubleToUString( fNumber,
2555 rtl_math_StringFormat_Automatic,
2556 rtl_math_DecimalPlaces_Max,
2562 bHadStandard =
true;
2566 bHadStandard =
true;
2570 bHadStandard =
true;
2574 bHadStandard =
true;
2579 if ( !bHadStandard )
2582 if (fNumber < 0.0 &&
2605 for (sal_uInt16
i = 0;
i < nCnt;
i++)
2666 OUStringBuffer& sStr)
2683 sStr = ::rtl::math::doubleToUString( fNumber,
2684 rtl_math_StringFormat_E,
2686 OUStringBuffer ExpStr;
2688 sal_Int32 nExPos = sStr.indexOf(
'E');
2689 sal_Int32 nDecPos = -1;
2694 sal_Int32 nExpStart = nExPos + 1;
2696 switch ( sStr[ nExpStart ] )
2705 ExpStr = sStr.subView( nExpStart );
2706 sStr.truncate( nExPos );
2710 sal_Int32 nExp = OUString::unacquired(ExpStr).toInt32() * nExpSign;
2711 sal_Int32 nRescale = (rInfo.
nCntPre != 0) ? nExp %
static_cast<sal_Int32
>(rInfo.
nCntPre) : -1;
2712 if( nRescale < 0 && rInfo.
nCntPre != 0 )
2713 nRescale +=
static_cast<sal_Int32
>(rInfo.
nCntPre);
2724 ExpStr = OUString::number( nExp );
2727 sStr = ::rtl::math::doubleToUString( fNumber,
2728 rtl_math_StringFormat_E,
2738 sStr.truncate( sStr.indexOf(
'E') );
2739 if (sStr[0] ==
'1' && cFirstDigit !=
'1')
2744 sal_Int32
index = 0;
2746 while((
index = sStr.indexOf(
'.',
index)) >= 0)
2750 sStr.remove(
index, 1);
2754 sal_uInt16 j = nCnt-1;
2756 sal_Int32 nZeros = 0;
2760 while (nZeros < k && ExpStr[nZeros] ==
'0')
2766 ExpStr.remove( 0, nZeros);
2773 const OUString& rStr = rInfo.
sStrArray[j];
2776 ExpStr.insert(0,
'-');
2778 else if (rStr.getLength() > 1 && rStr[1] ==
'+')
2780 ExpStr.insert(0,
'+');
2782 ExpStr.insert(0, rStr[0]);
2804 sStr.insert(0,
'-');
2806 sStr.append(ExpStr);
2814 double fIntPart = 0.0;
2815 sal_Int64 nFrac = 0, nDiv = 1;
2816 double fSign = (fNumber < 0.0) ? -1.0 : 1.0;
2820 return fSign * ( fIntPart +
static_cast<double>(nFrac) /
static_cast<double>(nDiv) );
2822 return fSign * fIntPart;
2826 double& fIntPart, sal_Int64& nFrac, sal_Int64& nDiv )
const
2828 if ( fNumber < 0.0 )
2830 fIntPart = floor(fNumber);
2831 fNumber -= fIntPart;
2833 sal_Int64 nForcedDiv = lcl_GetDenominatorString( rInfo,
NumFor[nIx].GetCount() ).toInt32();
2834 if( nForcedDiv > 0 )
2837 nFrac =
static_cast<sal_Int64
>(floor ( fNumber * nDiv ));
2838 double fFracNew =
static_cast<double>(nFrac) /
static_cast<double>(nDiv);
2839 double fFracNew1 =
static_cast<double>(nFrac + 1) /
static_cast<double>(nDiv);
2840 double fDiff = fNumber - fFracNew;
2841 if( fDiff > ( fFracNew1 - fNumber ) )
2849 sal_Int64 nBasis =
static_cast<sal_Int64
>(floor( pow(10.0,rInfo.
nCntExp))) - 1;
2850 sal_Int64 nFracPrev = 1, nDivPrev = 0, nFracNext, nDivNext, nPartialDenom;
2851 double fRemainder = fNumber;
2855 while ( fRemainder > 0.0 )
2857 double fTemp = 1.0 / fRemainder;
2858 nPartialDenom =
static_cast<sal_Int64
>(floor(fTemp));
2859 fRemainder = fTemp -
static_cast<double>(nPartialDenom);
2860 nDivNext = nPartialDenom * nDiv + nDivPrev;
2861 if ( nDivNext <= nBasis )
2863 nFracNext = nPartialDenom * nFrac + nFracPrev;
2871 sal_Int64 nCollat = (nBasis - nDivPrev) / nDiv;
2872 if ( 2 * nCollat >= nPartialDenom )
2874 sal_Int64 nFracTest = nCollat * nFrac + nFracPrev;
2875 sal_Int64 nDivTest = nCollat * nDiv + nDivPrev;
2876 double fSign = (
static_cast<double>(nFrac) > fNumber *
static_cast<double>(nDiv))?1.0:-1.0;
2877 if ( fSign * (
double(nFrac * nDivTest + nDiv * nFracTest) - 2.0 * double(nDiv * nDivTest) * fNumber ) > 0.0 )
2891 nDiv = ( nForcedDiv > 0 ) ? nForcedDiv : 1;
2897 OUStringBuffer& sBuff)
2902 OUStringBuffer sStr, sFrac, sDiv;
2903 bool bSign = ( (fNumber < 0) && (nIx == 0) );
2904 const OUString sIntegerFormat = lcl_GetFractionIntegerString(rInfo, nCnt);
2905 const OUString sNumeratorFormat = lcl_GetNumeratorString(rInfo, nCnt);
2906 const OUString sDenominatorFormat = lcl_GetDenominatorString(rInfo, nCnt);
2908 sal_Int64 nFrac = 0, nDiv = 1;
2909 double fNum = floor(fNumber);
2918 SAL_WARN(
"svl.numbers",
"SvNumberformat:: Fraction, nCntExp == 0");
2927 double fNum1 = fNum *
static_cast<double>(nDiv) +
static_cast<double>(nFrac);
2934 nFrac =
static_cast<sal_Int64
>(floor(fNum1));
2936 else if (fNum == 0.0 && nFrac != 0)
2943 sStr.appendAscii(
aBuf );
2946 bool bHideFraction = (rInfo.
nCntPre > 0 && nFrac == 0
2947 && (sNumeratorFormat.indexOf(
'0') < 0)
2948 && (sDenominatorFormat.indexOf(
'0') < 0
2949 || sDenominatorFormat.toInt32() > 0) );
2950 if ( bHideFraction )
2960 sal_uInt16 j = nCnt-1;
2968 if ( bHideFraction )
2970 if ( sNumeratorFormat.indexOf(
'?') >= 0
2971 || sDenominatorFormat.indexOf(
'?') >= 0 )
2972 sDiv.insert(0,
' ');
3000 if ( bHideFraction )
3002 if ( sIntegerFormat.indexOf(
'?') >= 0
3003 || sNumeratorFormat.indexOf(
'?') >= 0
3004 || sDenominatorFormat.indexOf(
'?') >= 0 )
3006 for (sal_Int32
i = 0;
i < rInfo.
sStrArray[j].getLength();
i++)
3007 sFrac.insert(0,
' ');
3012 if ( fNum != 0.0 || sIntegerFormat.indexOf(
'0') >= 0 )
3016 if ( sIntegerFormat.indexOf(
'?') >= 0
3017 || sNumeratorFormat.indexOf(
'?') >= 0 )
3019 for (sal_Int32
i = 0;
i < rInfo.
sStrArray[j].getLength();
i++)
3020 sFrac.insert(0,
' ');
3038 k = sStr.getLength();
3042 if (bSign && (nFrac != 0 || fNum != 0.0))
3044 sBuff.insert(0,
'-');
3047 sBuff.append(sFrac);
3053 int nFractionDecimals,
bool bAddOneRoundingDecimal, sal_uInt16 nIx, sal_uInt16 nMinimumInputLineDecimals )
3055 if (!nFractionDecimals)
3060 rBuf.append( rtl::math::doubleToUString( fFractionOfSecond, rtl_math_StringFormat_F,
3061 (bAddOneRoundingDecimal ? nFractionDecimals + 1 : nFractionDecimals),
'.'));
3062 rBuf.stripStart(
'0');
3063 rBuf.stripStart(
'.');
3064 if (bAddOneRoundingDecimal && rBuf.getLength() > nFractionDecimals)
3065 rBuf.truncate( nFractionDecimals);
3066 if (nMinimumInputLineDecimals)
3069 for (sal_Int32
index = rBuf.getLength();
index < nMinimumInputLineDecimals; ++
index)
3074 nFractionDecimals = rBuf.getLength();
3080 return static_cast<sal_uInt16
>(nFractionDecimals);
3085 OUStringBuffer& sBuff)
3088 bool bCalendarSet =
false;
3089 const double fNumberOrig = fNumber;
3107 nCntPost = kTimeSignificantRound;
3115 OUStringBuffer sSecStr;
3116 sal_Int32 nSecPos = 0;
3117 sal_uInt32 nHour, nMin, nSec;
3120 sal_uInt16 nCHour, nCMinute, nCSecond;
3121 double fFractionOfSecond;
3127 (bInputLine ? rInfo.
nCntPost : 0));
3131 const double fTime = rtl::math::round( fNumber * 86400.0,
int(nCntPost));
3132 if (bSign && fTime == 0.0)
3141 sal_uInt32 nSeconds =
static_cast<sal_uInt32
>(fTime);
3144 (bInputLine ? rInfo.
nCntPost : 0));
3155 nMin = nSeconds / 60;
3156 nSec = nSeconds % 60;
3160 nHour = nSeconds / 3600;
3161 nMin = (nSeconds%3600) / 60;
3181 else if (nHour < 12)
3195 for (sal_uInt16
i = 0;
i < nCnt;
i++)
3218 nLen = ( bInputLine &&
i > 0 &&
3222 for (sal_Int32 j = 0; j < nLen && nSecPos < nCntPost && nSecPos < sSecStr.getLength(); ++j)
3224 sBuff.append(sSecStr[nSecPos]);
3229 if ( !bCalendarSet )
3232 fDiff += fNumberOrig;
3234 bCalendarSet =
true;
3238 sBuff.append(
GetCal().getDisplayName(
3239 CalendarDisplayIndex::AM_PM, AmPmValue::AM, 0 ));
3243 sBuff.append(
GetCal().getDisplayName(
3244 CalendarDisplayIndex::AM_PM, AmPmValue::PM, 0 ));
3281 sBuff.insert(0,
'-');
3305 bool bMonthSeen =
false;
3306 bool bDaySeen =
false;
3309 for (sal_uInt16
i = 0;
i <
nCount && io_nState == 0; ++
i)
3334 ((nLen = rInfo.
sStrArray[
i-1].getLength()) > 0) &&
3363 return CalendarDisplayCode::SHORT_MONTH_NAME;
3365 return CalendarDisplayCode::LONG_MONTH_NAME;
3367 return CalendarDisplayCode::NARROW_MONTH_NAME;
3377 return CalendarDisplayCode::SHORT_GENITIVE_MONTH_NAME;
3379 return CalendarDisplayCode::LONG_GENITIVE_MONTH_NAME;
3381 return CalendarDisplayCode::NARROW_GENITIVE_MONTH_NAME;
3391 return CalendarDisplayCode::SHORT_PARTITIVE_MONTH_NAME;
3393 return CalendarDisplayCode::LONG_PARTITIVE_MONTH_NAME;
3395 return CalendarDisplayCode::NARROW_PARTITIVE_MONTH_NAME;
3401 SAL_WARN(
"svl.numbers",
"ImpUseMonthCase: unhandled keyword index eCodeType");
3402 return CalendarDisplayCode::LONG_MONTH_NAME;
3408 if (
GetCal().getUniqueID() != GREGORIAN )
3413 const sal_uInt16 nCnt = rNumFor.
GetCount();
3415 for (
i = 0;
i < nCnt;
i++ )
3437 double& fOrgDateTime )
const
3446 sal_Int32 nCnt = xCals.getLength();
3450 auto pCal = std::find_if(xCals.begin(), xCals.end(),
3451 [](
const OUString& rCalName) { return rCalName != GREGORIAN; });
3452 if (pCal == xCals.end())
3455 if ( !rOrgCalendar.getLength() )
3465 double fOrgDateTime )
const
3468 if ( rOrgCalendar.size() && rCal.
getUniqueID() != GREGORIAN )
3481 sal_Int16 nVal = rCal.
getValue( CalendarFieldIndex::ERA );
3484 if ( !rOrgCalendar.getLength() )
3489 else if ( rOrgCalendar == GREGORIAN )
3491 rOrgCalendar.clear();
3508bool SvNumberformat::ImpSwitchToSpecifiedCalendar( OUString& rOrgCalendar,
3509 double& fOrgDateTime,
3513 const sal_uInt16 nCnt = rNumFor.
GetCount();
3514 for ( sal_uInt16 i = 0;
i < nCnt;
i++ )
3519 if ( !rOrgCalendar.getLength() )
3542 sal_Int16 nVal = rCal.
getValue( CalendarFieldIndex::ERA );
3574 bool bIsIso =
false;
3586 State eState = eNone;
3588 sal_uInt16 nCnt = rNumFor.
GetCount();
3589 for (sal_uInt16
i=0;
i < nCnt && !bIsIso && eState != eNotIso; ++
i)
3591 switch ( rTypeArray[
i] )
3595 if (eState != eNone)
3606 if (eState != eAtSep1)
3617 if (eState != eAtSep2)
3630 if (eState == eAtYear)
3634 else if (eState == eAtMonth)
3655 SAL_WARN(
"svl.numbers",
"SvNumberformat::ImpIsIso8601: no date" );
3663 const sal_uInt16 nCnt = rNumFor.
GetCount();
3664 for ( sal_uInt16
i = 0;
i < nCnt;
i++ )
3680 return rCal.
getValue( css::i18n::CalendarFieldIndex::ERA ) == 0 &&
3695 const double fOff =
DateTime::Sub( rNullDate, aCE) + fNumber;
3697 const double fDiff =
DateTime::Sub( rNullDate, rEpochStart);
3699 return fMin <= fOff && fOff <= fMax;
3704 OUStringBuffer& sBuff)
3716 int nUseMonthCase = 0;
3717 OUString aOrgCalendar;
3719 double fOrgDateTime(0.0);
3721 if ( bOtherCalendar )
3727 bOtherCalendar =
false;
3749 bool bUseSpellout = NatNumTakesParameters(
nNatNum) &&
3752 for (sal_uInt16
i = 0;
i < nCnt;
i++)
3757 if ( !aOrgCalendar.getLength() )
3833 if ( bOtherCalendar )
3844 if ( bOtherCalendar )
3850 if ( bOtherCalendar )
3861 if ( bOtherCalendar )
3867 if ( bOtherCalendar )
3877 if ( bOtherCalendar )
3883 if ( bOtherCalendar )
3899 OUStringBuffer
aBuf;
3911 if ( bOtherCalendar )
3945 sBuff.append(
rLoc().getLongDateDayOfWeekSep());
3949 rCal.
getValue( CalendarFieldIndex::WEEK_OF_YEAR )));
3965 if ( aOrgCalendar.getLength() )
3974 OUStringBuffer& sBuff)
3988 sal_Int32 nCntPost, nFirstRounding;
3993 nCntPost = nFirstRounding = kTimeSignificantRound;
4000 nFirstRounding = (rInfo.
bThousand ? nCntPost : kTimeSignificantRound);
4002 double fTime = (fNumber - floor( fNumber )) * 86400.0;
4003 fTime = ::rtl::math::round( fTime,
int(nFirstRounding) );
4004 if (fTime >= 86400.0)
4008 fNumber = floor( fNumber + 0.5) + fTime;
4012 int nUseMonthCase = 0;
4013 OUString aOrgCalendar;
4014 double fOrgDateTime(0.0);
4016 if ( bOtherCalendar )
4022 bOtherCalendar =
false;
4026 OUStringBuffer sSecStr;
4027 sal_Int32 nSecPos = 0;
4028 sal_uInt32 nHour, nMin, nSec;
4031 sal_uInt16 nCHour, nCMinute, nCSecond;
4032 double fFractionOfSecond;
4038 (bInputLine ? rInfo.
nCntPost : 0));
4042 sal_uInt32 nSeconds =
static_cast<sal_uInt32
>(floor( fTime ));
4045 (bInputLine ? rInfo.
nCntPost : 0));
4056 nMin = nSeconds / 60;
4057 nSec = nSeconds % 60;
4061 nHour = nSeconds / 3600;
4062 nMin = (nSeconds%3600) / 60;
4080 else if (nHour < 12)
4096 for (sal_uInt16
i = 0;
i < nCnt;
i++)
4101 if ( !aOrgCalendar.getLength() )
4128 nLen = ( bInputLine &&
i > 0 &&
4132 for (sal_Int32 j = 0; j < nLen && nSecPos < nCntPost && nSecPos < sSecStr.getLength(); ++j)
4134 sBuff.append(sSecStr[ nSecPos ]);
4142 AmPmValue::AM, 0 ));
4147 AmPmValue::PM, 0 ));
4180 CalendarDisplayCode::SHORT_MONTH,
nNatNum ));
4184 CalendarDisplayCode::LONG_MONTH,
nNatNum ));
4214 if ( bOtherCalendar )
4219 if ( bOtherCalendar )
4225 if ( bOtherCalendar )
4230 if ( bOtherCalendar )
4236 if ( bOtherCalendar )
4246 if ( bOtherCalendar )
4252 if ( bOtherCalendar )
4268 OUStringBuffer
aBuf;
4276 sBuff.append(aYear);
4278 if ( bOtherCalendar )
4300 sBuff.append(
rLoc().getLongDateDayOfWeekSep());
4319 if ( aOrgCalendar.getLength() )
4328 OUStringBuffer& sStr)
4333 for (sal_uInt16 j = 0; j < nCnt; ++j)
4351 OUStringBuffer& sStr)
4363 if ( std::signbit( fNumber ) )
4382 sal_Int32 nDecPos = -1;
4383 bool bInteger =
false;
4387 const sal_uInt16 nThousand = rInfo.
nThousand;
4389 for (
i = 0;
i < nThousand;
i++)
4410 if ((rInfo.
nCntPost + nPrecExp) > 15 && nPrecExp < 15)
4412 sStr = ::rtl::math::doubleToUString( fNumber, rtl_math_StringFormat_F, 15-nPrecExp,
'.');
4420 sStr = ::rtl::math::doubleToUString( fNumber, rtl_math_StringFormat_F, rInfo.
nCntPost,
'.' );
4422 sStr.stripStart(
'0');
4424 else if (fNumber == 0.0)
4431 sStr = ::rtl::math::doubleToUString( fNumber, rtl_math_StringFormat_F, 0,
'.');
4432 sStr.stripStart(
'0');
4434 nDecPos = sStr.indexOf(
'.' );
4438 while ( *++
p ==
'0' )
4444 sStr.remove( nDecPos, 1 );
4446 if (bSign && (sStr.isEmpty() || checkForAll0s(sStr)))
4455 bRes |=
ImpDecimalFill( sStr, fNumber, nDecPos, j, nIx, bInteger );
4458 sStr.insert(0,
'-');
4472 bool bFilled =
false;
4474 sal_Int32 k = sStr.getLength();
4478 bool bTrailing =
true;
4492 if (rInfo.
sStrArray[j].getLength() >= 2)
4508 const OUString& rStr = rInfo.
sStrArray[j];
4517 if (nDecPos >= 0 && nDecPos <= k)
4519 sal_Int32 nAppend = rStr.getLength() - (k - nDecPos);
4520 while (nAppend-- > 0)
4522 sStr.insert( k++,
'0');
4525 while (k && p1 <
p--)
4529 if ( sStr[k] !=
'0' )
4540 else if ( c ==
'-' )
4548 else if ( c ==
'?' )
4553 else if ( !bFilled )
4566 OUStringBuffer sNum;
4568 sNum.stripStart(
'-');
4569 sStr.insert(k, sNum);
4594 sal_Int32 nLeadingStringChars = 0;
4595 sal_Int32 nDigitCount = 0;
4599 bool bDoThousands = (rInfo.
nThousand == 0);
4620 nLeadingStringChars = nLeadingStringChars + rInfo.
sStrArray[j].getLength();
4630 if (rInfo.
sStrArray[j].getLength() >= 2)
4643 if ( !bDoThousands && j <
NumFor[nIx].GetCount()-1 )
4645 bDoThousands = ((j == 0) ||
4656 else if (nDigitCount < nDigCnt)
4666 const OUString& rStr = rInfo.
sStrArray[j-1];
4667 sal_Int32 nLen = rStr.getLength();
4670 cLeader = rStr[ nLen - 1 ];
4680 sBuff.insert(k,
' ');
4691 const OUString& rStr = rInfo.
sStrArray[j];
4706 sBuff.insert(0,
'0');
4709 sBuff.insert(0,
' ');
4713 if (nDigitCount == nDigCnt && k > 0)
4716 ImpDigitFill(sBuff, 0, k, nIx, nDigitCount, aGrouping);
4726 OUStringBuffer sNum;
4728 sNum.stripStart(
'-');
4729 sBuff.insert(k, sNum);
4738 k = k + nLeadingStringChars;
4739 if (k > nLeadingStringChars)
4741 ImpDigitFill(sBuff, nLeadingStringChars, k, nIx, nDigitCount, aGrouping);
4750 sal_Int32 & nDigitCount,
4758 if (nDigitCount == rGrouping.
getPos())
4760 sStr.insert( k, rThousandSep );
4779 bool bInsertRightBlank)
4785 bool bDoThousands = (rInfo.
nThousand == 0);
4786 bool bFoundNumber =
false;
4789 k = sBuff.getLength();
4804 if (rInfo.
sStrArray[j].getLength() >= 2)
4816 if ( !bDoThousands && j <
NumFor[nIx].GetCount()-1 )
4818 bDoThousands = ((j == 0) ||
4823 if ( bDoThousands && k > 0 )
4830 bFoundNumber =
true;
4831 sal_uInt16 nPosInsertBlank = bInsertRightBlank ? k : 0;
4832 const OUString& rStr = rInfo.
sStrArray[j];
4846 sBuff.insert(0,
'0');
4849 sBuff.insert(nPosInsertBlank,
' ');
4861 OUStringBuffer sNum;
4862 bFoundNumber =
true;
4864 sNum.stripStart(
'-');
4865 sBuff.insert(k, sNum);
4891 sal_uInt16& nPrecision,
4892 sal_uInt16& nLeadingCnt)
const
4897 GetNumForInfo( 0, nDummyType, bThousand, nPrecision, nLeadingCnt );
4907 bool& bThousand, sal_uInt16& nPrecision, sal_uInt16& nLeadingCnt )
const
4922 sal_Int32 nPosHash = 1;
4925 nPrecision -= nPosHash;
4937 while (!bStop &&
i < nCnt)
4947 while ( *
p ==
'0' || *
p ==
'?' )
4965 bool bString )
const
4976 if (
nPos == 0xFFFF )
4994 else if (
nPos > nCnt - 1 )
5028 if (
nPos == 0xFFFF )
5032 else if (
nPos > nCnt - 1 )
5060 return tmp[0] ==
"(" && tmp[nCnt-1] ==
")";
5075 for ( sal_uInt16 j=0; j<nCnt; j++ )
5077 switch ( rTypeArray[j] )
5081 return DateOrder::DMY;
5087 return DateOrder::MDY;
5094 return DateOrder::YMD;
5100 SAL_WARN(
"svl.numbers",
"SvNumberformat::GetDateOrder: no date" );
5107 sal_uInt32 nRet = 0;
5110 SAL_WARN(
"svl.numbers",
"SvNumberformat::GetExactDateOrder: no date" );
5116 for ( sal_uInt16 j=0; j<nCnt && nShift < 3; j++ )
5118 switch ( rTypeArray[j] )
5122 nRet = (nRet << 8) |
'D';
5130 nRet = (nRet << 8) |
'M';
5139 nRet = (nRet << 8) |
'Y';
5167 double fLimit, std::u16string_view rDecSep )
5193 SAL_WARN(
"svl.numbers",
"unsupported number format" );
5196 rStr += ::rtl::math::doubleToUString( fLimit,
5197 rtl_math_StringFormat_Automatic, rtl_math_DecimalPlaces_Max,
5202static void lcl_insertLCID( OUStringBuffer& rFormatStr, sal_uInt32 nLCID, sal_Int32 nPosInsertLCID,
bool bDBNumInserted )
5206 if (nPosInsertLCID == rFormatStr.getLength() && !bDBNumInserted)
5210 auto aLCIDString = OUString::number( nLCID , 16 ).toAsciiUpperCase();
5212 if ( bDBNumInserted && nPosInsertLCID >= 8
5213 && aLCIDString.length > 4
5214 && OUString::unacquired(rFormatStr).match(
"[DBNum", nPosInsertLCID-8) )
5216 nPosInsertLCID -= 8;
5217 rFormatStr.remove( nPosInsertLCID, 8 );
5219 rFormatStr.insert( nPosInsertLCID,
"[$-" + aLCIDString +
"]" );
5232 nAlphabetID = nAlphabetID << 24;
5238 bool bSystemLanguage )
const
5240 OUStringBuffer
aStr;
5258 bDefault[2] = ( !bDefault[0] && !bDefault[1] &&
5261 bool bDefaults = bDefault[0] || bDefault[1] || bDefault[2];
5263 bDefault[3] =
false;
5269 bDefault[0] = bDefault[1] =
true;
5272 NumFor[2].GetCount() == 0 )
5274 bDefault[0] = bDefault[1] = bDefault[2] = bDefault[3] =
true;
5278 else if ( bDefault[0] )
5280 bDefault[0] =
false;
5288 for (
int i=0;
i<3 && !bDefault[
i]; ++
i )
5295 for (
int n=0;
n<4;
n++ )
5319 if ( !rColorName.isEmpty() )
5324 if ( rKey[j] == rColorName )
5326 aPrefix +=
"[" + rKeywords[j] +
"]";
5333 bool bDBNumInserted =
false;
5337 aNatNum.
SetLang( nOriginalLang );
5340 aPrefix +=
"[DBNum" + OUString::number( aNatNum.
GetDBNum() ) +
"]";
5341 bDBNumInserted =
true;
5346 if ( nSem && (nCnt || !aPrefix.isEmpty()) )
5348 for ( ; nSem; --nSem )
5352 for ( ; nSub <=
n; ++nSub )
5354 bDefault[nSub] =
false;
5358 if ( !aPrefix.isEmpty() )
5360 aStr.append( aPrefix );
5362 sal_Int32 nPosHaveLCID = -1;
5363 sal_Int32 nPosInsertLCID =
aStr.getLength();
5364 sal_uInt32 nCalendarID = 0x0000000;
5365 constexpr sal_uInt32 kCalGengou = 0x0030000;
5370 for ( sal_uInt16 j=0; j<nCnt; j++ )
5374 aStr.append( rKeywords[rTypeArray[j]] );
5379 switch (rTypeArray[j])
5394 nCalendarID = kCalGengou;
5403 switch ( rTypeArray[j] )
5413 if ( rStrArray[j].
getLength() > 1 && rStrArray[j][1] ==
'+' )
5433 aStr.append(
'\\' );
5434 aStr.append( rStrArray[j] );
5438 aStr.append(
"\"" + rStrArray[j] +
"\"" );
5444 if ( rStrArray[j+1] ==
"gengou" )
5446 nCalendarID = kCalGengou;
5448 else if ( rStrArray[j+1] ==
"hijri" )
5450 nCalendarID = 0x0060000;
5452 else if ( rStrArray[j+1] ==
"buddhist" )
5454 nCalendarID = 0x0070000;
5456 else if ( rStrArray[j+1] ==
"jewish" )
5458 nCalendarID = 0x0080000;
5466 nPosHaveLCID =
aStr.getLength();
5467 aStr.append( rStrArray[j] );
5470 aStr.append( rStrArray[j] );
5475 sal_uInt32 nAlphabetID = 0x0000000;
5482 nAlphabetID = 0x01000000;
5490 nAlphabetID = 0x02000000;
5492 nAlphabetID = 0x03000000;
5493 else if ( pri.
anyOf(
5497 nAlphabetID = 0x04000000;
5499 nAlphabetID = 0x05000000;
5503 nAlphabetID = 0x02000000;
5505 nAlphabetID = 0x06000000;
5508 nAlphabetID = 0x07000000;
5510 nAlphabetID = 0x08000000;
5512 nAlphabetID = 0x09000000;
5514 nAlphabetID = 0x0A000000;
5516 nAlphabetID = 0x0B000000;
5518 nAlphabetID = 0x0C000000;
5523 nAlphabetID = 0x0D000000;
5526 nAlphabetID = 0x0E000000;
5528 nAlphabetID = 0x0F000000;
5530 nAlphabetID = 0x10000000;
5532 nAlphabetID = 0x11000000;
5534 nAlphabetID = 0x12000000;
5539 nAlphabetID = 0x13000000;
5566 nAlphabetID = 0x27000000;
5579 else if (nPosHaveLCID < 0)
5598 if ( nCalendarID > 0 )
5600 if ( nAlphabetID == 0 )
5601 nAlphabetID = 0x01000000;
5603 nLanguageID = nOriginalLang;
5605 lcl_insertLCID(
aStr, nAlphabetID + nCalendarID +
static_cast<sal_uInt16
>(nLanguageID), nPosInsertLCID,
5608 for ( ; nSub<4 && bDefault[nSub]; ++nSub )
5612 return aStr.makeStringAndClear();
5616 sal_Int64 nVal, sal_uInt16 nMinDigits )
const
5621 if ( nMinDigits == 2 )
5624 if ( 0 <= nVal && nVal < 10 )
5628 aBuf[1] =
'0' + nVal;
5633 aStr = OUString::number( nVal );
5638 OUString aValStr( OUString::number( nVal ) );
5639 if ( aValStr.getLength() >= nMinDigits )
5645 OUStringBuffer
aBuf;
5646 for(sal_Int32
index = 0;
index < nMinDigits - aValStr.getLength(); ++
index)
5650 aBuf.append(aValStr);
5657 aStr = OUString::number( nVal );
5681 const sal_uInt16 nDateKey)
const
5684 if (rNum.
GetParams().indexOf(
'=') == -1)
5691 sal_Int32 nField = -1;
5694 nField = rNum.
GetParams().indexOf(Concat2View(rKeywords[nDateKey] +
"="), ++nField);
5696 while (nField != -1 && nField != 0 &&
5704 sal_Int32 nKeywordLen = rKeywords[nDateKey].getLength() + 1;
5705 sal_Int32 nFieldEnd = rNum.
GetParams().indexOf(
',', nField);
5707 if (nFieldEnd == -1)
5708 nFieldEnd = rNum.
GetParams().getLength();
5714 rNum.
GetParams().copy(nField + nKeywordLen, nFieldEnd - nField - nKeywordLen));
5718 sal_uInt16 nNumFor )
const
5725 css::lang::Locale aLocale(
5732 css::i18n::NativeNumberXmlAttributes aTmp(
5735 rAttr.Locale = aTmp.Locale;
5736 rAttr.Format = aTmp.Format;
5737 rAttr.Style = aTmp.Style;
5738 if ( NatNumTakesParameters(rNum.
GetNatNum()) )
5743 rAttr.Format.clear();
5744 rAttr.Style.clear();
5748 rAttr.Spellout.clear();
5753 rAttr = css::i18n::NativeNumberXmlAttributes2();
5758 rAttr = css::i18n::NativeNumberXmlAttributes2();
5767 if ( !rNum.
IsSet() )
5769 const sal_Int32 nNum = rNum.
GetNatNum();
5770 OUStringBuffer sNatNumModifier =
"[NatNum" + OUString::number( nNum );
5771 if ( NatNumTakesParameters( nNum ) )
5773 sNatNumModifier.append(
" " + rNum.
GetParams() );
5775 sNatNumModifier.append(
"]" );
5777 return sNatNumModifier.makeStringAndClear();
5784 sal_Int32 nLen = rStr.getLength();
5799 while ( *
p ==
' ' && ++
p < pEnd );
5810 while ( *
p ==
' ' && pBeg < --
p );
5818 sal_Int32 nLen = rStr.getLength();
5826 bool bQuoted =
false;
5837 if ( *(
p-1) != cEscIn )
5844 if ( *(
p-1) != cEscOut )
5863 sal_Int32 nLen = rStr.getLength();
5870 if ( rStr[
nPos ] == cQuote )
5881 if ( *
p == cQuote &&
p > p0 && *(
p-1) != cEscIn )
5883 return sal::static_int_cast< sal_Int32 >(
p - p0);
5902 sal_uInt16 nCnt = 0;
5905 for ( sal_uInt16 j=0; j<nNumForCnt; ++j )
5907 switch ( rTypeArray[j] )
5927 constexpr sal_uInt16 k00 = 0x00;
5928 constexpr sal_uInt16 kLB = 0x01;
5929 constexpr sal_uInt16 kRB = 0x02;
5930 constexpr sal_uInt16 kMM = 0x04;
5931 constexpr sal_uInt16 kTS = 0x08;
5932 constexpr sal_uInt16 kSS = 0x10;
5933#define HAS_MINUTE_SECOND(state) ((state) == (kMM|kTS|kSS) || (state) == (kLB|kMM|kRB|kTS|kSS))
5940 for (sal_uInt16 j=0; j < nNumForCnt; ++j)
5942 switch (rTypeArray[j])
5954 else if (rStr ==
"]")
5956 if (
nState != (kLB|kMM) &&
nState != (kMM|kTS|kLB|kSS))
5999#undef HAS_MINUTE_SECOND
6004 OUStringBuffer sString;
6009 for (sal_uInt16 j=0; j < nNumForCnt; ++j)
6011 switch (rTypeArray[j])
6015 sString.append(
NumFor[0].
Info().sStrArray[j] );
6019 sString.append(
NumFor[0].
Info().sStrArray[j] );
6023 sString.append(
rLoc().getTime100SecSep() );
6024 padToLength(sString, sString.getLength() + nPrecision,
'0');
6031 sString.append(
"\"" );
6034 sString.append(
NumFor[0].
Info().sStrArray[j] );
6037 sString.append(
"\"" );
6042 return sString.makeStringAndClear();
void loadCalendar(const OUString &rUniqueID, const css::lang::Locale &rLocale, bool bTimeZoneUTC=true)
void setLocalDateTime(double fTimeInDays)
sal_Int16 getValue(sal_Int16 nFieldIndex) const
OUString getDisplayName(sal_Int16 nCalendarDisplayIndex, sal_Int16 nIdx, sal_Int16 nNameType) const
void setDateTime(double fTimeInDays)
OUString getDisplayString(sal_Int32 nCalendarDisplayCode, sal_Int16 nNativeNumberMode) const
double getDateTime() const
OUString getUniqueID() const
css::i18n::Calendar2 getLoadedCalendar() const
css::uno::Sequence< OUString > getAllCalendars(const css::lang::Locale &rLocale) const
const DateTime & getEpochStart() const
OUString uppercase(const OUString &rStr, sal_Int32 nPos, sal_Int32 nCount) const
static double Sub(const DateTime &rDateTime1, const DateTime &rDateTime2)
void SetColor(const Color *pCol, OUString const &rName)
const SvNumberNatNum & GetNatNum() const
bool HasNewCurrency() const
void SetNatNumParams(const OUString &sParams)
const OUString & GetColorName() const
void SetNatNumDate(bool bDate)
const Color * GetColor() const
ImpSvNumberformatInfo & Info()
void Copy(const ImpSvNumFor &rNumFor, const ImpSvNumberformatScan *pSc)
void Enlarge(sal_uInt16 nCount)
bool GetNewCurrencySymbol(OUString &rSymbol, OUString &rExtension) const
void SetNatNumNum(sal_uInt8 nNum, bool bDBNum)
sal_uInt16 GetCount() const
void SetNatNumLang(LanguageType eLang)
const css::lang::Locale & getLocale(bool bResolveSystem=true) const
const OUString & getDateSep() const
const OUString & getTime100SecSep() const
const OUString & getTimeSep() const
const OUString & getNumThousandSep() const
DateOrder getDateOrder() const
const OUString & getNumDecimalSep() const
const LanguageTag & getLanguageTag() const
const OUString & getLongDateDayOfWeekSep() const
static LanguageType getRealLanguage(LanguageType nLang)
void SetLang(LanguageType e)
sal_uInt8 GetNatNum() const
sal_uInt8 GetDBNum() const
static sal_uInt8 MapNatNumToDBNum(sal_uInt8 nNatNum, LanguageType eLang, bool bDate)
OUString const & GetParams() const
LanguageType GetLang() const
static sal_uInt8 MapDBNumToNatNum(sal_uInt8 nDBNum, LanguageType eLang, bool bDate)
DigitGroupingIterator & advance()
#define DBG_ASSERT(sCon, aError)
#define LANGUAGE_ARABIC_PRIMARY_ONLY
#define LANGUAGE_CHINESE_LSO
#define LANGUAGE_MONGOLIAN_MONGOLIAN_CHINA
#define LANGUAGE_MONGOLIAN_CYRILLIC_LSO
#define LANGUAGE_MONGOLIAN_MONGOLIAN_MONGOLIA
#define LANGUAGE_NF_SYSTEM_TIME
#define LANGUAGE_CHINESE_TRADITIONAL
#define LANGUAGE_CHINESE_SIMPLIFIED
#define LANGUAGE_NF_SYSTEM_DATE
#define LANGUAGE_JAPANESE
#define LANGUAGE_CHINESE_SINGAPORE
#define LANGUAGE_CHINESE_MACAU
#define LANGUAGE_PUNJABI_ARABIC_LSO
#define LANGUAGE_CHINESE_HONGKONG
#define LANGUAGE_ARABIC_SAUDI_ARABIA
#define LANGUAGE_DONTKNOW
#define LANGUAGE_MALAYALAM
constexpr LanguageType primary(LanguageType lt)
#define LANGUAGE_GUJARATI
#define LANGUAGE_MONGOLIAN_CYRILLIC_MONGOLIA
#define LANGUAGE_ENGLISH_US
#define LANGUAGE_TIGRIGNA_ETHIOPIA
#define LANGUAGE_MONGOLIAN_MONGOLIAN_LSO
#define SAL_WARN(area, stream)
#define SAL_N_ELEMENTS(arr)
if(aStr !=aBuf) UpdateName_Impl(m_xFollowLb.get()
double getLength(const B2DPolygon &rCandidate)
const LanguageTag & getLocale()
const LanguageTag & getLanguageTag()
B & padToLength(B &rBuffer, sal_Int32 nLen, U cFill)
OStringBuffer & padToLength(OStringBuffer &rBuffer, sal_Int32 nLength, char cFill='\0')
OString stripStart(const OString &rIn, char c)
OString OutString(std::u16string_view rStr, rtl_TextEncoding eDestEnc, bool bUnicode=true)
std::basic_string_view< charT, traits > trim(std::basic_string_view< charT, traits > str)
sal_Int32 toInt32(std::u16string_view str, sal_Int16 radix=10)
int sprintf(char(&s)[N], char const *format, T &&... arguments)
bool matchIgnoreAsciiCase(std::u16string_view s1, std::u16string_view s2, sal_Int32 fromIndex=0)
@ NF_SYMBOLTYPE_FRACBLANK
@ NF_SYMBOLTYPE_TIME100SECSEP
@ NF_SYMBOLTYPE_FRAC_FDIV
const LocaleDataWrapper & GetLocaleData()
::std::array< OUString, NF_KEYWORD_ENTRIES_COUNT > NfKeywordTable
NfKeywordIndex
For ImpSvNumberformatScan: first the short symbols, then the long symbols! e.g.
@ NF_KEYWORD_ENTRIES_COUNT
bool anyOf(strong_int v) const
SvNumFormatType
MAX_ULONG.
@ UNDEFINED
is used as a return value if no format exists.
@ TIME
selects time formats.
@ NUMBER
selects decimal number formats.
@ LOGICAL
selects boolean number formats.
@ CURRENCY
selects currency formats.
@ FRACTION
selects number formats for fractions.
@ TEXT
selects text number formats.
@ DATE
selects date formats.
@ PERCENT
selects percentage number formats.
@ DATETIME
selects number formats which contain date and time.
@ SCIENTIFIC
selects scientific number formats.
@ DEFINED
selects only user-defined number formats.
const sal_uInt16 FLAG_STANDARD_IN_FORMAT