27#include <rtl/math.hxx>
28#include <rtl/character.hxx>
32#include <com/sun/star/i18n/CalendarFieldIndex.hpp>
33#include <com/sun/star/i18n/LocaleCalendar2.hpp>
46#define NF_TEST_CALENDAR 0
48#define NF_TEST_CALENDAR 0
52#include <com/sun/star/i18n/XCalendar4.hpp>
69#define NF_RECOGNIZE_ISO8601_TIMEZONES 0
77 bTextInitialized( false ),
78 bScanGenitiveMonths( false ),
79 bScanPartitiveMonths( false ),
135 sal_Int32
nPos, nLen;
136 for (
nPos = 0, nLen = rStr.getLength();
nPos < nLen; ++
nPos )
138 if ( 256 <= rStr[
nPos ] &&
146 rStr = pFormatter->
GetNatNum()->getNativeNumberString( rStr,
158 std::unique_ptr<char[]> bufInHeap;
159 constexpr int bufOnStackSize = 256;
160 char bufOnStack[bufOnStackSize];
161 char* buf = bufOnStack;
162 const sal_Int32 bufsize =
aStr.size() + (bForceFraction ? 2 : 1);
163 if (bufsize > bufOnStackSize)
165 bufInHeap = std::make_unique<char[]>(bufsize);
166 buf = bufInHeap.get();
174 if (c ==
'.' || (c >=
'0' && c <=
'9'))
175 *
p++ =
static_cast<char>(c);
181 return strtod_nolocale(buf,
nullptr);
219 ScanState eState = SsStart;
221 sal_Int32 nChars = 0;
226 if (cToken == 0 || eState == SsStop)
232 if ( rtl::isAsciiDigit( cToken ) )
239 eState = SsGetString;
244 if ( rtl::isAsciiDigit( cToken ) )
255 if ( !rtl::isAsciiDigit( cToken ) )
272 rSymbol = OUString( pStr, nChars );
289 OUString& rSymbol )
const
292 OUStringBuffer sBuff(rSymbol);
296 ScanState eState = SsStart;
297 sal_Int32 nCounter = 0;
302 if (cToken == 0 || eState == SsStop)
312 pHere += rThSep.getLength() - 1;
321 if ( rtl::isAsciiDigit( cToken ) )
323 sBuff.append(cToken);
342 if (eState == SsGetValue)
346 sBuff.remove( sBuff.getLength() - nCounter, nCounter );
348 pHere -= nCounter + rThSep.getLength();
350 rSymbol = sBuff.makeStringAndClear();
360 const sal_Unicode*
const pEnd = pStr + rString.getLength();
390 const OUString& rString, sal_Int32 nPos )
392 if (
nPos + rWhat.getLength() <= rString.getLength() )
406 if ( rWhat.isEmpty() )
411 const sal_Unicode*
const pEnd = pWhat + rWhat.getLength();
413 while ( pWhat < pEnd )
415 if ( *pWhat != *pStr )
430 const OUString& rString, sal_Int32 nPos )
const
432 if (rWhat.isEmpty() || rString.getLength() <
nPos + rWhat.getLength())
437 nPos += rWhat.getLength();
438 if (
nPos == rString.getLength())
461 if (rtl::isAsciiAlphanumeric( c ))
465 rString.iterateCodePoints( &
nIndex);
472 if ((
nType & (KCharacterType::UPPER | KCharacterType::LOWER | KCharacterType::DIGIT)) != 0)
475 if (
nType & KCharacterType::LETTER)
491 if ((
nPos <
static_cast<sal_Int32
>(rString.size())) && (rString[
nPos] == c))
506 sal_Int32 nHere =
nPos;
507 if (
nPos < rString.getLength() )
524 const OUString& rString, sal_Int32& nPos )
540 sal_uInt16 nStringPos )
const
545 rString[0] ==
u' ' &&
546 rSep.getLength() == 1 && rString.size() == 1;
547 if (!((rString == rSep || bSpaceBreak) &&
549 IsNum[ nStringPos + 1 ] ))
561 sal_Int32 nLen =
sStrArray[ nStringPos + 1 ].getLength();
562 if (nLen == aGrouping.
get() ||
608 if (rString.getLength() >
nPos)
615 for ( sal_Int16
i = 0;
i < nMonths;
i++ )
626 res = sal::static_int_cast< short >(-(
i+1));
638 res = sal::static_int_cast< short >(-(
i+1));
650 res = sal::static_int_cast< short >(-(
i+1));
658 res = sal::static_int_cast< short >(-(
i+1));
664 res = sal::static_int_cast< short >(-(
i+1));
676 res = sal::static_int_cast< short >(-(
i+1));
682 res = sal::static_int_cast< short >(-(
i+1));
741 if (rString.getLength() >
nPos)
748 for ( sal_Int16
i = 0;
i < nDays;
i++ )
776 if ( rString.getLength() >
nPos )
792 OUString aSymbol, aExtension;
795 if ( aSymbol.getLength() <= rString.getLength() -
nPos )
827 if ( rString.getLength() >
nPos )
856 if (
static_cast<sal_Int32
>(rString.size()) >
nPos )
880 if (
static_cast<sal_Int32
>(rString.size()) >
nPos )
886 if (rString[
nPos] ==
'.' || rString[
nPos] ==
',')
915 if (
static_cast<sal_Int32
>(rString.size()) >
nPos)
916 switch (rString[
nPos ])
945 if (
static_cast<sal_Int32
>(rString.size()) >
nPos)
947 switch (rString[
nPos])
987 sal_uInt16 nMinute = 0;
988 sal_uInt16 nSecond = 0;
989 double fSecond100 = 0.0;
990 sal_uInt16 nStartIndex =
nIndex;
992 if (
nDecPos == 2 && (nCnt == 3 || nCnt == 2))
1001 else if (
nIndex - nStartIndex < nCnt)
1009 SAL_WARN(
"svl.numbers",
"ImpSvNumberInputScan::GetTimeRef: bad number index");
1013 bool bAllowDuration = (nHour == 0 && !
nAmPm);
1015 if (
nAmPm && nHour > 12)
1019 else if (
nAmPm == -1 && nHour != 12)
1023 else if (
nAmPm == 1 && nHour == 12)
1028 if (
nDecPos == 2 && nCnt == 2)
1032 else if (
nIndex - nStartIndex < nCnt)
1036 &&
nIndex > 1 && nMinute > 59)
1039 bAllowDuration = (nMinute == 0);
1041 if (
nIndex - nStartIndex < nCnt)
1045 &&
nIndex > 1 && nSecond > 59 && !(nHour == 23 && nMinute == 59 && nSecond == 60))
1048 if (
nIndex - nStartIndex < nCnt)
1052 fOutNumber = (
static_cast<double>(nHour)*3600 +
1053 static_cast<double>(nMinute)*60 +
1054 static_cast<double>(nSecond) +
1055 fSecond100)/86400.0;
1062 sal_uInt16 nRes = 0;
1085 if ( 0 < nNum && nNum <= nRes )
1100 sal_uInt16 nYear = 0;
1138 nMayBeIso8601 = (nLen >= 4 ? 4 : (nLen == 3 ? 3 : (nLen > 0 ? 2 : 1)));
1148 int nCanForceToIso8601 = 0;
1159 if (eDateOrder == DateOrder::Invalid)
1168 nCanForceToIso8601 = 1;
1174 case DateOrder::DMY:
1176 if (n < 1 || n > 31)
1178 nCanForceToIso8601 = 2;
1181 case DateOrder::MDY:
1183 if (n < 1 || n > 12)
1185 nCanForceToIso8601 = 2;
1188 case DateOrder::YMD:
1189 nCanForceToIso8601 = 2;
1193 return nCanForceToIso8601 > 1;
1224 if (rM.getLength() >= 3 && rM[0] ==
'-' && rM[ rM.getLength() - 1] ==
'-')
1232 bool bDay1 = !bYear1;
1236 bDay1 =
n >= 1 &&
n <= 31;
1238 bool bDay2 = !bYear2;
1242 bDay2 =
n >= 1 &&
n <= 31;
1245 if (bDay1 && !bDay2)
1249 else if (!bDay1 && bDay2)
1253 else if (bDay1 && bDay2)
1272 sal_Int32 nLen = rStr.size();
1273 if (nLen > 1 && rStr[nLen-1] ==
'-')
1276 if (nPat + nLen <
static_cast<sal_Int32
>(rPat.size()) && rPat[nPat+nLen] ==
'Y')
1279 bOk = (rPat.find( rStr.substr( 0, nLen), nPat) ==
static_cast<size_t>(nPat));
1289 sal_Int32 nSep = nPat;
1291 while (nSep <
static_cast<sal_Int32
>(rPat.size()) && (c = rPat[nSep]) !=
'D' && c !=
'M' && c !=
'Y')
1332 assert(!
"shouldn't reach here");
1364 if (rPat.getLength() == 3)
1372 SAL_WARN(
"svl.numbers",
"ignoring date acceptance pattern with decimal separator ambiguity: " << rPat);
1380 for ( ; nPat < rPat.getLength() && bOk && nNext <
nStringsCnt; ++nPat, ++nNext)
1389 if (bOk && (c ==
'M' || c ==
'D'))
1396 sal_Int32 nMaxLen, nMaxVal;
1401 nMaxVal = nMonthsInYear;
1415 bOk = (
sStrArray[nNext].getLength() <= nMaxLen);
1418 sal_Int32 nNum =
sStrArray[nNext].toInt32();
1419 bOk = (1 <= nNum && nNum <= nMaxVal);
1426 bOk = !
IsNum[nNext];
1432 const sal_Int32 nLen =
sStrArray[nNext].getLength();
1433 bOk = (nLen == nSepLen && rPat.indexOf(
sStrArray[nNext], nPat) == nPat);
1442 else if (nPat + nLen > rPat.getLength() &&
sStrArray[nNext][ nLen - 1 ] ==
' ')
1451 bOk = (rPat.indexOf(
aBuf, nPat) == nPat);
1454 nPat +=
aBuf.getLength() - 1;
1473 if (nPat > 0 && nNext > 0)
1476 sal_Int32 nPatCheck = nPat - 1;
1477 switch (rPat[nPatCheck])
1493 c = rPat[--nPatCheck];
1494 }
while (c !=
'Y' && c !=
'M' && c !=
'D' && nPatCheck > 0);
1514 else if (nPat == rPat.getLength())
1535 if (nParticle < nDatePatternStart || nParticle >=
nStringsCnt ||
IsNum[nParticle])
1541 for (sal_Int32 nPat = 0; nPat < rPat.getLength() && nNext <
nStringsCnt; ++nPat, ++nNext)
1550 if (nNext == nParticle)
1553 const sal_Int32 nLen =
sStrArray[nNext].getLength();
1554 bool bOk = (nLen == nSepLen && rPat.indexOf(
sStrArray[nNext], nPat) == nPat);
1561 if (!bOk && (nPat + nLen > rPat.getLength() &&
sStrArray[nNext][ nLen - 1 ] ==
' '))
1569 bOk = (rPat.indexOf(
aBuf, nPat) == nPat);
1579 nPat +=
sStrArray[nNext].getLength() - 1;
1603 sal_uInt16 nNum = 0;
1605 for (sal_Int32 nPat = 0; nPat < rPat.getLength(); ++nPat)
1612 if (nNum == nNumber)
1613 return rPat[nPat] == cType;
1629 sal_uInt32 nOrder = 0;
1631 for (sal_Int32 nPat = 0; nPat < rPat.getLength() && !(nOrder & 0xff0000); ++nPat)
1638 nOrder = (nOrder << 8) | rPat[nPat];
1651 if (bFromFormatIfNoPattern &&
mpFormat)
1656 switch ((nOrder & 0xff0000) >> 16)
1659 if ((((nOrder & 0xff00) >> 8) ==
'M') && ((nOrder & 0xff) ==
'D'))
1661 return DateOrder::YMD;
1665 if ((((nOrder & 0xff00) >> 8) ==
'D') && ((nOrder & 0xff) ==
'Y'))
1667 return DateOrder::MDY;
1671 if ((((nOrder & 0xff00) >> 8) ==
'M') && ((nOrder & 0xff) ==
'Y'))
1673 return DateOrder::DMY;
1678 switch ((nOrder & 0xff00) >> 8)
1681 switch (nOrder & 0xff)
1684 return DateOrder::YMD;
1688 switch (nOrder & 0xff)
1691 return DateOrder::DMY;
1693 return DateOrder::MDY;
1697 switch (nOrder & 0xff)
1700 return DateOrder::MDY;
1702 return DateOrder::DMY;
1707 switch (nOrder & 0xff)
1710 return DateOrder::YMD;
1712 return DateOrder::MDY;
1714 return DateOrder::DMY;
1719 SAL_WARN(
"svl.numbers",
"ImpSvNumberInputScan::GetDateOrder: undefined, falling back to locale's default");
1728 return (
nMayBeMonthDate == 2) ? LongDateOrder::DMY : LongDateOrder::YMD;
1732 if (!nExactDateOrder)
1734 else if ((((nExactDateOrder >> 16) & 0xff) ==
'Y') && ((nExactDateOrder & 0xff) ==
'D'))
1735 eLDO = LongDateOrder::YMD;
1736 else if ((((nExactDateOrder >> 16) & 0xff) ==
'D') && ((nExactDateOrder & 0xff) ==
'Y'))
1737 eLDO = LongDateOrder::DMY;
1740 if (eLDO != LongDateOrder::YMD && eLDO != LongDateOrder::DMY)
1744 case DateOrder::YMD:
1745 eLDO = LongDateOrder::YMD;
1747 case DateOrder::DMY:
1748 eLDO = LongDateOrder::DMY;
1754 else if (eLDO == LongDateOrder::DMY && eDateOrder == DateOrder::YMD)
1758 eLDO = LongDateOrder::YMD;
1760 else if (eLDO == LongDateOrder::YMD && eDateOrder == DateOrder::DMY)
1764 eLDO = LongDateOrder::DMY;
1801 for (
int nTryOrder = 1; nTryOrder <= nFormatOrder; nTryOrder++ )
1804 OUString aOrgCalendar;
1810 bFormatTurn =
false;
1818 if ( nTryOrder == 1 )
1820 bFormatTurn =
false;
1830 if ( nTryOrder == 2 )
1832 bFormatTurn =
false;
1853 SAL_WARN(
"svl.numbers",
"ImpSvNumberInputScan::GetDateRef: unknown NfEvalDateFormat" );
1854 DateFmt = DateOrder::YMD;
1855 bFormatTurn =
false;
1892 mpFormat->SwitchToSpecifiedCalendar( aOrgCalendar, fOrgDateTime,
1901 pCal->
setValue( CalendarFieldIndex::DAY_OF_MONTH, 1 );
1927 sal_uInt32 nDateOrder = (bFormatTurn ?
1949 case DateOrder::MDY:
1950 case DateOrder::YMD:
1954 if (nDay == 0 || nDay > 32)
1956 pCal->
setValue( CalendarFieldIndex::YEAR, nYear);
1964 case DateOrder::DMY:
1976 case DateOrder::DMY:
1979 case DateOrder::YMD:
1999 sal_uInt32 nExactDateOrder = (bFormatTurn ?
2002 bool bIsExact = (0xff < nExactDateOrder && nExactDateOrder <= 0xffff);
2011 bIsExact = (0xff < nExactDateOrder && nExactDateOrder <= 0xffff);
2018 switch ( (nExactDateOrder >> 8) & 0xff )
2032 switch ( nExactDateOrder & 0xff )
2046 SAL_WARN_IF( !bHadExact,
"svl.numbers",
"ImpSvNumberInputScan::GetDateRef: error in exact date order");
2055 if ((bFormatTurn || !bIsExact) && (!bHadExact || !pCal->
isValid()))
2057 if ( !bHadExact && nExactDateOrder )
2063 case DateOrder::MDY:
2069 pCal->
setValue( CalendarFieldIndex::DAY_OF_MONTH, 1 );
2074 case DateOrder::DMY:
2080 pCal->
setValue( CalendarFieldIndex::DAY_OF_MONTH, 1 );
2085 case DateOrder::YMD:
2091 pCal->
setValue( CalendarFieldIndex::DAY_OF_MONTH, 1 );
2110 if ((((nExactDateOrder >> 8) & 0xff) ==
'Y') && ((nExactDateOrder & 0xff) ==
'D'))
2128 case LongDateOrder::DMY:
2132 case LongDateOrder::YMD:
2179 case DateOrder::MDY:
2185 case DateOrder::DMY:
2191 case DateOrder::YMD:
2211 if ((((nExactDateOrder >> 8) & 0xff) ==
'Y') && ((nExactDateOrder & 0xff) ==
'D'))
2230 case LongDateOrder::DMY:
2234 case LongDateOrder::YMD:
2271 nTryOrder = nFormatOrder;
2277 if ( aOrgCalendar.getLength() )
2284 struct entry {
const char* lan;
const char* cou;
const char* cal; };
2285 const entry cals[] = {
2286 {
"en",
"US",
"gregorian" },
2287 {
"ar",
"TN",
"hijri" },
2288 {
"he",
"IL",
"jewish" },
2289 {
"ja",
"JP",
"gengou" },
2290 {
"ko",
"KR",
"hanja_yoil" },
2291 {
"th",
"TH",
"buddhist" },
2292 {
"zh",
"TW",
"ROC" },
2295 lang::Locale aLocale;
2297 sal_Int16 nDay, nMyMonth, nYear, nHour, nMinute, nSecond;
2298 sal_Int16 nDaySet, nMonthSet, nYearSet, nHourSet, nMinuteSet, nSecondSet;
2299 sal_Int16 nZO, nDST1, nDST2, nDST, nZOmillis, nDST1millis, nDST2millis, nDSTmillis;
2300 sal_Int32 nZoneInMillis, nDST1InMillis, nDST2InMillis;
2301 uno::Reference< uno::XComponentContext > xContext =
2302 ::comphelper::getProcessComponentContext();
2303 uno::Reference< i18n::XCalendar4 > xCal = i18n::LocaleCalendar2::create(xContext);
2304 for (
const entry*
p = cals;
p->lan; ++
p )
2306 aLocale.Language = OUString::createFromAscii(
p->lan );
2307 aLocale.Country = OUString::createFromAscii(
p->cou );
2308 xCal->loadCalendar( OUString::createFromAscii(
p->cal ),
2310 double nDateTime = 0.0;
2311 nZO = xCal->getValue( i18n::CalendarFieldIndex::ZONE_OFFSET );
2312 nZOmillis = xCal->getValue( i18n::CalendarFieldIndex::ZONE_OFFSET_SECOND_MILLIS );
2313 nZoneInMillis =
static_cast<sal_Int32
>(nZO) * 60000 +
2314 (nZO < 0 ? -1 : 1) *
static_cast<sal_uInt16
>(nZOmillis);
2315 nDST1 = xCal->getValue( i18n::CalendarFieldIndex::DST_OFFSET );
2316 nDST1millis = xCal->getValue( i18n::CalendarFieldIndex::DST_OFFSET_SECOND_MILLIS );
2317 nDST1InMillis =
static_cast<sal_Int32
>(nDST1) * 60000 +
2318 (nDST1 < 0 ? -1 : 1) *
static_cast<sal_uInt16
>(nDST1millis);
2319 nDateTime -= (double)(nZoneInMillis + nDST1InMillis) / 1000.0 / 60.0 / 60.0 / 24.0;
2320 xCal->setDateTime( nDateTime );
2321 nDST2 = xCal->getValue( i18n::CalendarFieldIndex::DST_OFFSET );
2322 nDST2millis = xCal->getValue( i18n::CalendarFieldIndex::DST_OFFSET_SECOND_MILLIS );
2323 nDST2InMillis =
static_cast<sal_Int32
>(nDST2) * 60000 +
2324 (nDST2 < 0 ? -1 : 1) *
static_cast<sal_uInt16
>(nDST2millis);
2325 if ( nDST1InMillis != nDST2InMillis )
2327 nDateTime = 0.0 - (double)(nZoneInMillis + nDST2InMillis) / 1000.0 / 60.0 / 60.0 / 24.0;
2328 xCal->setDateTime( nDateTime );
2330 nDaySet = xCal->getValue( i18n::CalendarFieldIndex::DAY_OF_MONTH );
2331 nMonthSet = xCal->getValue( i18n::CalendarFieldIndex::MONTH );
2332 nYearSet = xCal->getValue( i18n::CalendarFieldIndex::YEAR );
2333 nHourSet = xCal->getValue( i18n::CalendarFieldIndex::HOUR );
2334 nMinuteSet = xCal->getValue( i18n::CalendarFieldIndex::MINUTE );
2335 nSecondSet = xCal->getValue( i18n::CalendarFieldIndex::SECOND );
2336 nZO = xCal->getValue( i18n::CalendarFieldIndex::ZONE_OFFSET );
2337 nZOmillis = xCal->getValue( i18n::CalendarFieldIndex::ZONE_OFFSET_SECOND_MILLIS );
2338 nDST = xCal->getValue( i18n::CalendarFieldIndex::DST_OFFSET );
2339 nDSTmillis = xCal->getValue( i18n::CalendarFieldIndex::DST_OFFSET_SECOND_MILLIS );
2340 xCal->setValue( i18n::CalendarFieldIndex::DAY_OF_MONTH, nDaySet );
2341 xCal->setValue( i18n::CalendarFieldIndex::MONTH, nMonthSet );
2342 xCal->setValue( i18n::CalendarFieldIndex::YEAR, nYearSet );
2343 xCal->setValue( i18n::CalendarFieldIndex::HOUR, nHourSet );
2344 xCal->setValue( i18n::CalendarFieldIndex::MINUTE, nMinuteSet );
2345 xCal->setValue( i18n::CalendarFieldIndex::SECOND, nSecondSet );
2346 bValid = xCal->isValid();
2347 nDay = xCal->getValue( i18n::CalendarFieldIndex::DAY_OF_MONTH );
2348 nMyMonth= xCal->getValue( i18n::CalendarFieldIndex::MONTH );
2349 nYear = xCal->getValue( i18n::CalendarFieldIndex::YEAR );
2350 nHour = xCal->getValue( i18n::CalendarFieldIndex::HOUR );
2351 nMinute = xCal->getValue( i18n::CalendarFieldIndex::MINUTE );
2352 nSecond = xCal->getValue( i18n::CalendarFieldIndex::SECOND );
2353 bValid = bValid && nDay == nDaySet && nMyMonth == nMonthSet && nYear ==
2354 nYearSet && nHour == nHourSet && nMinute == nMinuteSet && nSecond
2401 if (
nSign &&
nPos == rString.getLength())
2404 const sal_Int32 nStartBlanks =
nPos;
2408 nPos = nStartBlanks;
2428 nPos = nStartBlanks;
2437 const sal_Int32 nMonthStart =
nPos;
2448 sal_Int32 nTempPos = nMonthStart;
2452 SkipChar(
'.', rString, nTempPos );
2455 short nTempTempMonth =
GetMonth( rString, nTempPos);
2489 if ( nTempDayOfWeek )
2493 if (
nPos < rString.getLength() )
2495 if ( nTempDayOfWeek < 0 )
2498 if ( rString[
nPos ] ==
'.' )
2539 if (
nMonth &&
nPos + 1 == rString.getLength())
2545 if (
nPos < rString.getLength())
2583 const sal_Int32 nStartBlanks =
nPos;
2593 bool bSignedYear =
false;
2617 nPos = nStartBlanks;
2622 nPos = nStartBlanks;
2659 (nStringPos == 4 &&
nSign)) &&
2660 sStrArray[nStringPos-2].indexOf(
'/') == -1)))
2664 if (
nPos == rString.getLength())
2670 (nStringPos == 2 &&
nSign)))
2693 bool bSignedYear =
false;
2713 if (((nExactDateOrder & 0xff) ==
'Y') && (((nExactDateOrder >> 8) & 0xff) ==
'M')
2714 && (((nExactDateOrder >> 16) & 0xff) ==
'D'))
2716 const sal_Int32 nTmpPos =
nPos;
2763 const sal_Int32 nMonthStart =
nPos;
2776 if (nMonthStart > 0 &&
nPos < rString.getLength())
2780 if (nCurNumCount <= 1)
2862 if (
nPos < rString.getLength())
2877 if ( (nStringPos == 5 && rString[0] ==
'T') ||
2878 (nStringPos == 6 && rString[0] ==
'T' &&
sStrArray[0] ==
"-"))
2884 else if (nStringPos == 7 && rString[0] ==
':')
2898 if (nStringPos == 9 && rString[0] ==
':')
2904#if NF_RECOGNIZE_ISO8601_TIMEZONES
2905 else if (
nPos == 0 && rString.getLength() == 1 && nStringPos >= 9 &&
MayBeIso8601())
2908 switch (rString[ 0 ])
2919 nTimezonePos = nStringPos + 1;
2924 if (nTimezonePos && nStringPos >= 11 &&
2938 if (
nPos < rString.getLength())
2977 const sal_Int32 nStartBlanks =
nPos;
2987 bool bSignedYear =
false;
3011 nPos = nStartBlanks;
3020 bool bSignDetectedHere =
false;
3032 bSignDetectedHere =
true;
3110 bool bSignedYear =
false;
3117 if (bDate && bSignDetectedHere)
3151 const sal_Int32 nMonthStart =
nPos;
3164 if (nMonthStart > 0)
3181 sal_Int32 nOrigPos =
nPos;
3222 if (
nPos < rString.getLength() &&
3227 sal_Int32 nOldPos =
nPos;
3235 if ( nTempDayOfWeek )
3237 if (
nPos < rString.getLength() )
3239 if ( nTempDayOfWeek < 0 )
3241 if ( rString[
nPos ] ==
'.' )
3255#if NF_RECOGNIZE_ISO8601_TIMEZONES
3257 rString.getLength() == 1 && rString[ 0 ] ==
'Z' &&
MayBeIso8601())
3264 if (
nPos < rString.getLength())
3280 bool bDontDetectNegation)
3287 const OUString* pStr;
3288 OUString aString( rString );
3289 bool bFound =
false;
3291 bool bContinue =
true;
3302 if ( pStr && pTransliteration->isEqual( aString, *pStr ) )
3307 else if ( nSub < 2 )
3316 while ( bContinue );
3317 if ( !bFound && bFirst &&
nPos )
3321 aString = aString.copy(
nPos);
3325 while ( bContinue );
3329 if ( !bDontDetectNegation && (nString == 0) &&
3333 aString = aString.replaceAll(
" ",
"");
3334 if ( (aString.getLength() == 1) && (aString[0] ==
'-') )
3346 else if ( !bDontDetectNegation && (nSub == 1) &&
3362 if ( (nString == 0) && !bFirst &&
3576 sal_uInt16 nThOld = 10;
3662 else if ( bDidMatch )
3703 else if ( bWasReturn )
3735 sal_Int32 j, nElems;
3741 css::uno::Sequence< css::i18n::CalendarItem2 > xElems = pCal->
getMonths();
3742 nElems = xElems.getLength();
3745 for ( j = 0; j < nElems; j++ )
3755 nElems = xElems.getLength();
3758 for ( j = 0; j < nElems; j++ )
3774 nElems = xElems.getLength();
3777 for ( j = 0; j < nElems; j++ )
3792 nElems = xElems.getLength();
3795 for ( j = 0; j < nElems; j++ )
3834 const sal_uInt16 Month,
3835 const sal_Int16 Year )
3854 if ( !rString.getLength() )
3858 else if (rString.getLength() > 308)
3885 if (c ==
'-' || c ==
'+')
4036 if (
nMonth < 0 && nDayOfWeek < 0 && nNumericsCnt >= 5)
4091 OUStringBuffer sResString;
4119 sResString.append(
"0.");
4128 sResString.append(
'.');
4131 for ( ; k < nStop; k++)
4143 sResString.append(
'E');
4146 sResString.append(
'-');
4149 rtl_math_ConversionStatus eStatus;
4150 fOutNumber = ::rtl::math::stringToDouble( sResString,
'.',
',', &eStatus );
4151 if ( eStatus == rtl_math_ConversionStatus_OutOfRange )
4160 fOutNumber = DBL_MAX;
4179 fOutNumber = -fOutNumber;
4205 if (fDenominator != 0.0)
4207 fOutNumber = fNumerator/fDenominator;
4232 if (fDenominator != 0.0)
4234 fOutNumber += fNumerator/fDenominator;
4256 fOutNumber = -fOutNumber;
4264 fOutNumber = -fOutNumber;
4278 fOutNumber += fTime;
4283 SAL_WARN(
"svl.numbers",
"Some number recognized but what's it?" );
4291 if (fOutNumber < -DBL_MAX)
4294 fOutNumber = -DBL_MAX;
4297 else if (fOutNumber > DBL_MAX)
4300 fOutNumber = DBL_MAX;
void loadCalendar(const OUString &rUniqueID, const css::lang::Locale &rLocale, bool bTimeZoneUTC=true)
css::uno::Sequence< css::i18n::CalendarItem2 > getDays() const
sal_Int16 getNumberOfDaysInWeek() const
css::uno::Sequence< css::i18n::CalendarItem2 > getGenitiveMonths() const
css::uno::Sequence< css::i18n::CalendarItem2 > getMonths() const
void setValue(sal_Int16 nFieldIndex, sal_Int16 nValue)
void setGregorianDateTime(const DateTime &rDateTime)
double getLocalDateTime() const
const DateTime & getEpochStart() const
css::uno::Sequence< css::i18n::CalendarItem2 > getPartitiveMonths() const
sal_Int16 getNumberOfMonthsInYear() const
OUString uppercase(const OUString &rStr, sal_Int32 nPos, sal_Int32 nCount) const
sal_Int32 getCharacterType(const OUString &rStr, sal_Int32 nPos) const
bool isDigit(const OUString &rStr, sal_Int32 nPos) const
static double Sub(const DateTime &rDateTime1, const DateTime &rDateTime2)
LanguageType getLanguageType(bool bResolveSystem=true) const
const css::lang::Locale & getLocale(bool bResolveSystem=true) const
OUString getLanguage() const
OUString getCountry() const
const OUString & getLongDateMonthSep() const
const OUString & getTime100SecSep() const
const OUString & getTimeSep() const
const OUString & getTimeAM() const
const OUString & getNumDecimalSepAlt() const
const OUString & getLongDateDaySep() const
const css::uno::Sequence< OUString > & getDateAcceptancePatterns() const
DateOrder getDateOrder() const
const OUString & getTimePM() const
const OUString & getNumDecimalSep() const
LongDateOrder getLongDateOrder() const
const css::uno::Sequence< sal_Int32 > & getDigitGrouping() const
const LanguageTag & getLanguageTag() const
const OUString & getLongDateDayOfWeekSep() const
Switch between LANGUAGE_SYSTEM and LANGUAGE_ENGLISH_US and any other LocaleDataWrapper.
void changeLocale(const LanguageTag &rLanguageTag)
DigitGroupingIterator & advance()
#define SAL_WARN_IF(condition, area, stream)
#define SAL_WARN(area, stream)
double getLength(const B2DPolygon &rCandidate)
B & padToLength(B &rBuffer, sal_Int32 nLen, U cFill)
OString strip(const OString &rIn, char c)
css::uno::Sequence< T > concatSequences(const css::uno::Sequence< T > &rS1, const Ss &... rSn)
constexpr bool starts_with(std::basic_string_view< charT, traits > sv, std::basic_string_view< charT, traits > x) noexcept
sal_Int32 toInt32(std::u16string_view rStr)
static bool lcl_IsSignedYearSep(std::u16string_view rStr, std::u16string_view rPat, sal_Int32 nPat)
If a string is a separator plus '-' minus sign preceding a 'Y' year in a date pattern at position nPa...
const sal_Unicode cNoBreakSpace
const sal_Unicode cNarrowNoBreakSpace
static void TransformInput(SvNumberFormatter const *pFormatter, OUString &rStr)
static sal_Int32 lcl_getPatternSeparatorLength(std::u16string_view rPat, sal_Int32 nPat)
Length of separator usually is 1 but theoretically could be anything.
#define SV_MAX_COUNT_INPUT_STRINGS
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.
NfEvalDateFormat
enum values for <method>SvNumberFormatter::SetEvalDateFormat</method>
@ NF_EVALDATEFORMAT_INTL_FORMAT
First try the DateFormat from International.
@ NF_EVALDATEFORMAT_INTL
DateFormat only from International, default.
@ NF_EVALDATEFORMAT_FORMAT
DateFormat only from date format passed to function (if any).
@ NF_EVALDATEFORMAT_FORMAT_INTL
First try the DateFormat from the date format passed.
SvNumInputOptions
Input options to be used with IsNumberFormat()
@ LAX_TIME
allow input of minutes or seconds >59