libCom: Fix epicsTime::strftime() roll-over bug
Fractional seconds could round-up to .000 without incrementing the integer seconds. We can't actually do the latter, so we prevent the roll-over and clamp at all 9's instead. Idea from Eric Norum.
This commit is contained in:
@@ -554,9 +554,11 @@ size_t epicsTime::strftime (
|
||||
static_cast < unsigned long > ( 1e1 ),
|
||||
static_cast < unsigned long > ( 1e0 )
|
||||
};
|
||||
// round and convert nanosecs to integer of correct range
|
||||
// round without overflowing into whole seconds
|
||||
unsigned long frac = tmns.nSec + div[fracWid] / 2;
|
||||
frac %= static_cast < unsigned long > ( 1e9 );
|
||||
if (frac >= nSecPerSec)
|
||||
frac = nSecPerSec - 1;
|
||||
// convert nanosecs to integer of correct range
|
||||
frac /= div[fracWid];
|
||||
char fracFormat[32];
|
||||
sprintf ( fracFormat, "%%0%lulu", fracWid );
|
||||
|
||||
@@ -48,7 +48,7 @@ MAIN(epicsTimeTest)
|
||||
const int wasteTime = 100000;
|
||||
const int nTimes = 10;
|
||||
|
||||
testPlan(12 + nTimes * 18);
|
||||
testPlan(15 + nTimes * 18);
|
||||
|
||||
try {
|
||||
const epicsTimeStamp epochTS = {0, 0};
|
||||
@@ -96,6 +96,10 @@ MAIN(epicsTimeTest)
|
||||
et.strftime(buf, sizeof(buf), pFormat);
|
||||
testOk(strcmp(buf, "1990-01-01 00.098765432") == 0, "'%s' => '%s'", pFormat, buf);
|
||||
|
||||
pFormat = "%S.%03f";
|
||||
et.strftime(buf, sizeof(buf), pFormat);
|
||||
testOk(strcmp(buf, "00.099") == 0, "'%s' => '%s'", pFormat, buf);
|
||||
|
||||
pFormat = "%S.%04f";
|
||||
et.strftime(buf, sizeof(buf), pFormat);
|
||||
testOk(strcmp(buf, "00.0988") == 0, "'%s' => '%s'", pFormat, buf);
|
||||
@@ -113,6 +117,14 @@ MAIN(epicsTimeTest)
|
||||
et.strftime(smbuf, sizeof(smbuf), pFormat);
|
||||
testOk(strcmp(smbuf, "00.*") == 0, "'%s' => '%s'", pFormat, smbuf);
|
||||
|
||||
pFormat = "%S.%03f";
|
||||
(et + 0.9).strftime(buf, sizeof(buf), pFormat);
|
||||
testOk(strcmp(buf, "00.999") == 0, "0.998765 => '%s'", buf);
|
||||
|
||||
pFormat = "%S.%03f";
|
||||
(et + 0.901).strftime(buf, sizeof(buf), pFormat);
|
||||
testOk(strcmp(buf, "00.999") == 0, "0.999765 => '%s'", buf);
|
||||
|
||||
pFormat = "%%S.%%05f";
|
||||
et.strftime(buf, sizeof(buf), pFormat);
|
||||
testOk(strcmp(buf, "%S.%05f") == 0, "'%s' => '%s'", pFormat, buf);
|
||||
|
||||
Reference in New Issue
Block a user