mirror of
https://github.com/znc/znc.git
synced 2026-03-28 17:42:41 +01:00
Merge pull request #1455 from CyberShadow/timeval
Add sub-second precision for timestamp formatting
This commit is contained in:
@@ -498,6 +498,64 @@ CString CUtils::FormatTime(time_t t, const CString& sFormat,
|
||||
return s;
|
||||
}
|
||||
|
||||
CString CUtils::FormatTime(const timeval& tv, const CString& sFormat,
|
||||
const CString& sTimezone) {
|
||||
// Parse additional format specifiers before passing them to
|
||||
// strftime, since the way strftime treats unknown format
|
||||
// specifiers is undefined.
|
||||
CString sFormat2;
|
||||
|
||||
// Make sure %% is parsed correctly, i.e. %%f is passed through to
|
||||
// strftime to become %f, and not 123.
|
||||
bool bInFormat = false;
|
||||
int iDigits;
|
||||
CString::size_type uLastCopied = 0, uFormatStart;
|
||||
|
||||
for (CString::size_type i = 0; i < sFormat.length(); i++) {
|
||||
if (!bInFormat) {
|
||||
if (sFormat[i] == '%') {
|
||||
uFormatStart = i;
|
||||
bInFormat = true;
|
||||
iDigits = 3;
|
||||
}
|
||||
} else {
|
||||
switch (sFormat[i]) {
|
||||
case '0': case '1': case '2': case '3': case '4':
|
||||
case '5': case '6': case '7': case '8': case '9':
|
||||
iDigits = sFormat[i] - '0';
|
||||
break;
|
||||
case 'f': {
|
||||
int iVal = tv.tv_usec;
|
||||
int iDigitDelta = iDigits - 6; // tv_user is in 10^-6 seconds
|
||||
for (; iDigitDelta > 0; iDigitDelta--)
|
||||
iVal *= 10;
|
||||
for (; iDigitDelta < 0; iDigitDelta++)
|
||||
iVal /= 10;
|
||||
sFormat2 += sFormat.substr(uLastCopied,
|
||||
uFormatStart - uLastCopied);
|
||||
CString sVal = CString(iVal);
|
||||
sFormat2 += CString(iDigits - sVal.length(), '0');
|
||||
sFormat2 += sVal;
|
||||
uLastCopied = i + 1;
|
||||
bInFormat = false;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
bInFormat = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (uLastCopied) {
|
||||
sFormat2 += sFormat.substr(uLastCopied);
|
||||
return FormatTime(tv.tv_sec, sFormat2, sTimezone);
|
||||
} else {
|
||||
// If there are no extended format specifiers, avoid doing any
|
||||
// memory allocations entirely.
|
||||
return FormatTime(tv.tv_sec, sFormat, sTimezone);
|
||||
}
|
||||
}
|
||||
|
||||
CString CUtils::FormatServerTime(const timeval& tv) {
|
||||
CString s_msec(tv.tv_usec / 1000);
|
||||
while (s_msec.length() < 3) {
|
||||
|
||||
Reference in New Issue
Block a user