Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
File renamed without changes.
30 changes: 27 additions & 3 deletions src/common/CvtFormat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1194,6 +1194,31 @@ namespace
return std::string_view(str + startPoint, wordLen);
}

constexpr unsigned getFractionsFromString(const char* str, FB_SIZE_T length, FB_SIZE_T& offset, FB_SIZE_T parseLength)
{
constexpr unsigned pow10[] = {1, 10, 100, 1'000, 10'000};
static_assert(std::size(pow10) > -ISC_TIME_SECONDS_PRECISION_SCALE);

if (parseLength > -ISC_TIME_SECONDS_PRECISION_SCALE)
parseLength = -ISC_TIME_SECONDS_PRECISION_SCALE;
int currentPrecisionScale = -ISC_TIME_SECONDS_PRECISION_SCALE;
unsigned fractions = 0;

const FB_SIZE_T parseLengthWithOffset = offset + parseLength;
for (; offset < parseLengthWithOffset && offset < length; offset++)
{
const char symbol = str[offset];

if (!isDigit(symbol))
break;

fractions = fractions * 10 + (symbol - '0');
--currentPrecisionScale;
}

return fractions * pow10[currentPrecisionScale];
}

template <typename TIterator>
constexpr TIterator getPreviousOrCurrentIterator(TIterator it, TIterator begin)
{
Expand Down Expand Up @@ -1499,10 +1524,9 @@ namespace
case Format::FF3:
case Format::FF4:
{
const int number = patternStr.back() - '0';
const int precision = patternStr.back() - '0';

const int fractions = getIntFromString(str, strLength, strOffset, number);
outFractions = fractions * pow(10, -ISC_TIME_SECONDS_PRECISION_SCALE - number);
outFractions = getFractionsFromString(str, strLength, strOffset, precision);
break;
}

Expand Down
22 changes: 14 additions & 8 deletions src/common/tests/CvtTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -550,25 +550,31 @@ BOOST_AUTO_TEST_CASE(CVTStringToFormatDateTime_TIME)
testCVTStringToFormatDateTimeExpectTime("5", "FF1", createTimeStampTZ(0, 0, 0, 0, 0, 0, 0, 5000), cb);
testCVTStringToFormatDateTimeExpectTime("9", "FF1", createTimeStampTZ(0, 0, 0, 0, 0, 0, 0, 9000), cb);

testCVTStringToFormatDateTimeExpectTime("1", "FF2", createTimeStampTZ(0, 0, 0, 0, 0, 0, 0, 100), cb);
testCVTStringToFormatDateTimeExpectTime("01", "FF2", createTimeStampTZ(0, 0, 0, 0, 0, 0, 0, 100), cb);
testCVTStringToFormatDateTimeExpectTime("1", "FF2", createTimeStampTZ(0, 0, 0, 0, 0, 0, 0, 1000), cb);
testCVTStringToFormatDateTimeExpectTime("10", "FF2", createTimeStampTZ(0, 0, 0, 0, 0, 0, 0, 1000), cb);
testCVTStringToFormatDateTimeExpectTime("50", "FF2", createTimeStampTZ(0, 0, 0, 0, 0, 0, 0, 5000), cb);
testCVTStringToFormatDateTimeExpectTime("99", "FF2", createTimeStampTZ(0, 0, 0, 0, 0, 0, 0, 9900), cb);

testCVTStringToFormatDateTimeExpectTime("1", "FF3", createTimeStampTZ(0, 0, 0, 0, 0, 0, 0, 10), cb);
testCVTStringToFormatDateTimeExpectTime("10", "FF3", createTimeStampTZ(0, 0, 0, 0, 0, 0, 0, 100), cb);
testCVTStringToFormatDateTimeExpectTime("01", "FF3", createTimeStampTZ(0, 0, 0, 0, 0, 0, 0, 100), cb);
testCVTStringToFormatDateTimeExpectTime("001", "FF3", createTimeStampTZ(0, 0, 0, 0, 0, 0, 0, 10), cb);
testCVTStringToFormatDateTimeExpectTime("1", "FF3", createTimeStampTZ(0, 0, 0, 0, 0, 0, 0, 1000), cb);
testCVTStringToFormatDateTimeExpectTime("10", "FF3", createTimeStampTZ(0, 0, 0, 0, 0, 0, 0, 1000), cb);
testCVTStringToFormatDateTimeExpectTime("100", "FF3", createTimeStampTZ(0, 0, 0, 0, 0, 0, 0, 1000), cb);
testCVTStringToFormatDateTimeExpectTime("500", "FF3", createTimeStampTZ(0, 0, 0, 0, 0, 0, 0, 5000), cb);
testCVTStringToFormatDateTimeExpectTime("999", "FF3", createTimeStampTZ(0, 0, 0, 0, 0, 0, 0, 9990), cb);

testCVTStringToFormatDateTimeExpectTime("1", "FF4", createTimeStampTZ(0, 0, 0, 0, 0, 0, 0, 1), cb);
testCVTStringToFormatDateTimeExpectTime("10", "FF4", createTimeStampTZ(0, 0, 0, 0, 0, 0, 0, 10), cb);
testCVTStringToFormatDateTimeExpectTime("100", "FF4", createTimeStampTZ(0, 0, 0, 0, 0, 0, 0, 100), cb);
testCVTStringToFormatDateTimeExpectTime("01", "FF4", createTimeStampTZ(0, 0, 0, 0, 0, 0, 0, 100), cb);
testCVTStringToFormatDateTimeExpectTime("001", "FF4", createTimeStampTZ(0, 0, 0, 0, 0, 0, 0, 10), cb);
testCVTStringToFormatDateTimeExpectTime("0001", "FF4", createTimeStampTZ(0, 0, 0, 0, 0, 0, 0, 1), cb);
testCVTStringToFormatDateTimeExpectTime("1", "FF4", createTimeStampTZ(0, 0, 0, 0, 0, 0, 0, 1000), cb);
testCVTStringToFormatDateTimeExpectTime("10", "FF4", createTimeStampTZ(0, 0, 0, 0, 0, 0, 0, 1000), cb);
testCVTStringToFormatDateTimeExpectTime("100", "FF4", createTimeStampTZ(0, 0, 0, 0, 0, 0, 0, 1000), cb);
testCVTStringToFormatDateTimeExpectTime("1000", "FF4", createTimeStampTZ(0, 0, 0, 0, 0, 0, 0, 1000), cb);
testCVTStringToFormatDateTimeExpectTime("5000", "FF4", createTimeStampTZ(0, 0, 0, 0, 0, 0, 0, 5000), cb);
testCVTStringToFormatDateTimeExpectTime("9999", "FF4", createTimeStampTZ(0, 0, 0, 0, 0, 0, 0, 9999), cb);

testCVTStringToFormatDateTimeExpectTime("1 P.M. - 25 - 45 - 200", "HH P.M. MI.SS.FF4", createTimeStampTZ(0, 0, 0, 13, 25, 45, 0, 200), cb);
testCVTStringToFormatDateTimeExpectTime("1 P.M. - 25 - 45 - 2", "HH P.M. MI.SS.FF4", createTimeStampTZ(0, 0, 0, 13, 25, 45, 0, 2000), cb);
testCVTStringToFormatDateTimeExpectTime("15:0:15:2", "HH24.MI.SS.FF1", createTimeStampTZ(0, 0, 0, 15, 0, 15, 0, 2000), cb);
}

Expand All @@ -583,7 +589,7 @@ BOOST_AUTO_TEST_CASE(CVTStringToFormatDateTime_TZ)

BOOST_AUTO_TEST_CASE(CVTStringToFormatDateTime_SOLID_PATTERNS)
{
testCVTStringToFormatDateTimeExpectTime("1 P.M. - 25 - 45 - 200", "HHA.M.MISSFF4", createTimeStampTZ(0, 0, 0, 13, 25, 45, 0, 200), cb);
testCVTStringToFormatDateTimeExpectTime("1 P.M. - 25 - 45 - 2", "HHA.M.MISSFF4", createTimeStampTZ(0, 0, 0, 13, 25, 45, 0, 2000), cb);
testCVTStringToFormatDateTimeExpectDate("1981-8/13", "YEARMMDD", createTimeStampTZ(1981, 8, 13, 0, 0, 0, 0), cb);
}

Expand Down
Loading