diff options
Diffstat (limited to '')
| -rw-r--r-- | project/dclib/dclib-numeric.c | 395 |
1 files changed, 303 insertions, 92 deletions
diff --git a/project/dclib/dclib-numeric.c b/project/dclib/dclib-numeric.c index 8be5cf6..138053d 100644 --- a/project/dclib/dclib-numeric.c +++ b/project/dclib/dclib-numeric.c @@ -1950,6 +1950,7 @@ mem_t EncodeByModeMem s64 timezone_adjust_sec = -1; s64 timezone_adjust_usec = -1; +s64 timezone_adjust_nsec = -1; int timezone_adjust_isdst = -1; /////////////////////////////////////////////////////////////////////////////// @@ -1959,10 +1960,11 @@ void SetupTimezone ( bool force ) if ( force || timezone_adjust_sec == -1 ) { timezone_adjust_sec = GetTimezoneAdjust(GetTimeSec(false)); - timezone_adjust_usec = 1000000ll * timezone_adjust_sec; - TRACE("TZ: %s,%s, %ld, %d => %lld %lld\n", + timezone_adjust_usec = USEC_PER_SEC * timezone_adjust_sec; + timezone_adjust_nsec = NSEC_PER_SEC * timezone_adjust_sec; + TRACE("TZ: %s,%s, %ld, %d => %lld %lld %lld\n", tzname[0], tzname[1], timezone, daylight, - timezone_adjust_sec, timezone_adjust_usec ); + timezone_adjust_sec, timezone_adjust_usec, timezone_adjust_nsec ); } } @@ -1993,41 +1995,76 @@ int GetTimezoneAdjust ( time_t tim ) /////////////////////////////////////////////////////////////////////////////// -struct timeval GetTimeOfDay ( bool localtime ) +static u_sec_t AdjustLocalTime ( u_sec_t sec ) { static uint last_hour = 0; + const uint hour = sec / 3600; + if ( last_hour != hour ) + { + last_hour = hour; + SetupTimezone(true); + } + return sec - timezone_adjust_sec; +} + +//----------------------------------------------------------------------------- + +struct timeval GetTimeOfDay ( bool localtime ) +{ struct timeval tval; gettimeofday(&tval,NULL); if (localtime) + tval.tv_sec = AdjustLocalTime(tval.tv_sec); + return tval; +} + +//----------------------------------------------------------------------------- + +struct timespec GetClockTime ( bool localtime ) +{ + struct timespec ts; + + #if HAVE_CLOCK_GETTIME + if (!clock_gettime(CLOCK_REALTIME,&ts)) { - const uint hour = tval.tv_sec / 3600; - if ( last_hour != hour ) - { - last_hour = hour; - SetupTimezone(true); - } - tval.tv_sec -= timezone_adjust_sec; + if (localtime) + ts.tv_sec = AdjustLocalTime(ts.tv_sec); + return ts; } - return tval; + #endif + + // fall back + struct timeval tval = GetTimeOfDay(localtime); + ts.tv_sec = tval.tv_sec; + ts.tv_nsec = tval.tv_usec * NSEC_PER_USEC; + return ts; } /////////////////////////////////////////////////////////////////////////////// DayTime_t GetDayTime ( bool localtime ) { - struct timeval tval = GetTimeOfDay(localtime); div_t d; - DayTime_t dt; - dt.time = tval.tv_sec; - d = div(tval.tv_sec,86400); + + #if HAVE_CLOCK_GETTIME + struct timespec tim = GetClockTime(localtime); + dt.usec = tim.tv_nsec / NSEC_PER_USEC; + dt.nsec = tim.tv_nsec; + #else + struct timeval tim = GetTimeOfDay(localtime); + dt.usec = tim.tv_usec; + dt.nsec = tim.tv_usec * NSEC_PER_USEC; + #endif + + dt.time = tim.tv_sec; + d = div(tim.tv_sec,86400); dt.day = d.quot; d = div(d.rem,3600); dt.hour = d.quot; d = div(d.rem,60); dt.min = d.quot; dt.sec = d.rem; - dt.usec = tval.tv_usec; return dt; } @@ -2045,7 +2082,7 @@ u_sec_t GetTimeSec ( bool localtime ) u_msec_t GetTimeMSec ( bool localtime ) { struct timeval tval = GetTimeOfDay(localtime); - return (u64)(tval.tv_sec) * 1000ll + tval.tv_usec/1000; + return (u_msec_t)(tval.tv_sec) * MSEC_PER_SEC + tval.tv_usec/USEC_PER_MSEC; } /////////////////////////////////////////////////////////////////////////////// @@ -2053,7 +2090,15 @@ u_msec_t GetTimeMSec ( bool localtime ) u_usec_t GetTimeUSec ( bool localtime ) { struct timeval tval = GetTimeOfDay(localtime); - return (u64)(tval.tv_sec) * 1000000ll + tval.tv_usec; + return (u_usec_t)(tval.tv_sec) * USEC_PER_SEC + tval.tv_usec; +} + +/////////////////////////////////////////////////////////////////////////////// + +u_nsec_t GetTimeNSec ( bool localtime ) +{ + struct timespec ts = GetClockTime(localtime); + return (u_nsec_t)(ts.tv_sec) * NSEC_PER_SEC + ts.tv_nsec; } // @@ -2067,24 +2112,36 @@ static time_t time_base = 0; u_msec_t GetTimerMSec() { - struct timeval tval; - gettimeofday(&tval,NULL); + struct timeval tv; + gettimeofday(&tv,NULL); if (!time_base) - time_base = tval.tv_sec; + time_base = tv.tv_sec; - return (u_msec_t)( tval.tv_sec - time_base ) * 1000 + tval.tv_usec/1000; + return (u_msec_t)( tv.tv_sec - time_base ) * MSEC_PER_SEC + + tv.tv_usec/USEC_PER_MSEC; } /////////////////////////////////////////////////////////////////////////////// u_usec_t GetTimerUSec() { - struct timeval tval; - gettimeofday(&tval,NULL); + struct timeval tv; + gettimeofday(&tv,NULL); if (!time_base) - time_base = tval.tv_sec; + time_base = tv.tv_sec; - return (u_usec_t)( tval.tv_sec - time_base ) * 1000000 + tval.tv_usec; + return (u_usec_t)( tv.tv_sec - time_base ) * USEC_PER_SEC + tv.tv_usec; +} + +/////////////////////////////////////////////////////////////////////////////// + +u_usec_t GetTimerNSec() +{ + struct timespec ts = GetClockTime(false); + if (!time_base) + time_base = ts.tv_sec; + + return (u_usec_t)( ts.tv_sec - time_base ) * NSEC_PER_SEC + ts.tv_nsec; } /////////////////////////////////////////////////////////////////////////////// @@ -2128,14 +2185,14 @@ ccp PrintTimeByFormatUTC /////////////////////////////////////////////////////////////////////////////// -ccp PrintUsecByFormat +ccp PrintNSecByFormat ( // returns temporary buffer by GetCircBuf(); ccp format, // format string for strftime() - // 1-6 '@' in row replaced by digits of 'usec' + // 1-9 '@' in row replaced by digits of 'nsec' time_t tim, // seconds since epoch - uint usec // micro second of second + uint nsec // nanosecond of second ) { char buf[100]; @@ -2144,9 +2201,9 @@ ccp PrintUsecByFormat char *at = strchr(buf,'@'); if (at) { - char ubuf[8]; - snprintf(ubuf,sizeof(ubuf),"%06u",usec); - ccp src = ubuf; + char nbuf[10]; + snprintf(nbuf,sizeof(nbuf),"%09u",nsec); + ccp src = nbuf; while ( *at == '@' && *src ) *at++ = *src++; } @@ -2156,14 +2213,14 @@ ccp PrintUsecByFormat //----------------------------------------------------------------------------- -ccp PrintUsecByFormatUTC +ccp PrintNSecByFormatUTC ( // returns temporary buffer by GetCircBuf(); ccp format, // format string for strftime() - // 1-6 '@' in row replaced by digits of 'usec' + // 1-9 '@' in row replaced by digits of 'nsec' time_t tim, // seconds since epoch - uint usec // micro second of second + uint nsec // nanosecond of second ) { char buf[100]; @@ -2172,9 +2229,9 @@ ccp PrintUsecByFormatUTC char *at = strchr(buf,'@'); if (at) { - char ubuf[8]; - snprintf(ubuf,sizeof(ubuf),"%06u",usec); - ccp src = ubuf; + char nbuf[10]; + snprintf(nbuf,sizeof(nbuf),"%09u",nsec); + ccp src = nbuf; while ( *at == '@' && *src ) *at++ = *src++; } @@ -2199,7 +2256,7 @@ ccp PrintTimevalByFormat tv = &temp; } - return PrintUsecByFormat(format,tv->tv_sec,tv->tv_usec); + return PrintUSecByFormat(format,tv->tv_sec,tv->tv_usec); } //----------------------------------------------------------------------------- @@ -2219,7 +2276,47 @@ ccp PrintTimevalByFormatUTC tv = &temp; } - return PrintUsecByFormatUTC(format,tv->tv_sec,tv->tv_usec); + return PrintUSecByFormatUTC(format,tv->tv_sec,tv->tv_usec); +} + +/////////////////////////////////////////////////////////////////////////////// + +ccp PrintTimespecByFormat +( + // returns temporary buffer by GetCircBuf(); + + ccp format, // format string for strftime() + const struct timespec *ts // time to print, if NULL use GetClockTime(false) +) +{ + struct timespec temp; + if (!ts) + { + temp = GetClockTime(true); + ts = &temp; + } + + return PrintNSecByFormat(format,ts->tv_sec,ts->tv_nsec); +} + +//----------------------------------------------------------------------------- + +ccp PrintTimespecByFormatUTC +( + // returns temporary buffer by GetCircBuf(); + + ccp format, // format string for strftime() + const struct timespec *ts // time to print, if NULL use GetClockTime(false) +) +{ + struct timespec temp; + if (!ts) + { + temp = GetClockTime(false); + ts = &temp; + } + + return PrintNSecByFormatUTC(format,ts->tv_sec,ts->tv_nsec); } /////////////////////////////////////////////////////////////////////////////// @@ -2256,13 +2353,13 @@ ccp PrintTimeMSec if (!buf) buf = GetCircBuf( buf_size = 24 ); - time_t time = msec / 1000; + time_t time = msec / MSEC_PER_SEC; struct tm *tm = localtime(&time); uint len = strftime(buf,buf_size,"%F %T",tm); if ( fraction && len + 4 < buf_size ) { - len += snprintf(buf+len, buf_size-len, ".%03llu", msec % 1000 ); + len += snprintf(buf+len, buf_size-len, ".%03llu", msec % MSEC_PER_SEC ); const uint pos = len - 3 + ( fraction < 3 ? fraction : 3 ); if ( pos < buf_size ) buf[pos] = 0; @@ -2285,13 +2382,13 @@ ccp PrintTimeUSec if (!buf) buf = GetCircBuf( buf_size = 28 ); - time_t time = usec / 1000000; + time_t time = usec / USEC_PER_SEC; struct tm *tm = localtime(&time); uint len = strftime(buf,buf_size,"%F %T",tm); if ( fraction && len + 7 < buf_size ) { - len += snprintf(buf+len, buf_size-len, ".%06llu", usec % 1000000 ); + len += snprintf(buf+len, buf_size-len, ".%06llu", usec % USEC_PER_SEC ); const uint pos = len - 6 + ( fraction < 6 ? fraction : 6 ); if ( pos < buf_size ) buf[pos] = 0; @@ -2301,6 +2398,35 @@ ccp PrintTimeUSec } /////////////////////////////////////////////////////////////////////////////// + +ccp PrintTimeNSec +( + char * buf, // result buffer (>26 bytes are good) + // If NULL, a local circulary static buffer is used + size_t buf_size, // size of 'buf', ignored if buf==NULL + u_nsec_t nsec, // nanoseconds to print + uint fraction // number of digits (0-9) to print as fraction +) +{ + if (!buf) + buf = GetCircBuf( buf_size = 32 ); + + time_t time = nsec / NSEC_PER_SEC; + struct tm *tm = localtime(&time); + uint len = strftime(buf,buf_size,"%F %T",tm); + + if ( fraction && len + 10 < buf_size ) + { + len += snprintf(buf+len, buf_size-len, ".%09llu", nsec % NSEC_PER_SEC ); + const uint pos = len - 9 + ( fraction < 9 ? fraction : 9 ); + if ( pos < buf_size ) + buf[pos] = 0; + } + + return buf; +} + +/////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// ccp PrintTimerMSec @@ -2345,7 +2471,7 @@ ccp PrintTimerUSec // If NULL, a local circulary static buffer is used size_t buf_size, // size of 'buf', ignored if buf==NULL s_usec_t usec, // microseconds to print - uint fraction // number of digits (0-3) to print as fraction + uint fraction // number of digits (0-6) to print as fraction ) { if ( !buf || buf_size < 4 ) @@ -2355,12 +2481,12 @@ ccp PrintTimerUSec if (minus) usec = -usec; - u32 sec = (u64)usec / 1000000; + u32 sec = usec / USEC_PER_SEC; if (fraction) { const uint len = snprintf(buf+1,buf_size-1,"%02d:%02d:%02d.%06lld", - sec/3600, sec/60%60, sec%60, (u64)usec%1000000 ); + sec/3600, sec/60%60, sec%60, (u64)usec%USEC_PER_SEC ); if ( len > 6 && fraction < 6 ) { const uint pos = len - 6 + fraction; @@ -2383,7 +2509,54 @@ ccp PrintTimerUSec } /////////////////////////////////////////////////////////////////////////////// + +ccp PrintTimerNSec +( + char * buf, // result buffer (>16 bytes are good) + // If NULL, a local circulary static buffer is used + size_t buf_size, // size of 'buf', ignored if buf==NULL + s_nsec_t nsec, // nanoseconds to print + uint fraction // number of digits (0-9) to print as fraction +) +{ + if ( !buf || buf_size < 4 ) + buf = GetCircBuf( buf_size = 24 ); + + const bool minus = nsec < 0; + if (minus) + nsec = -nsec; + + u32 sec = nsec / NSEC_PER_SEC; + + if (fraction) + { + const uint len = snprintf(buf+1,buf_size-1,"%02d:%02d:%02d.%09lld", + sec/3600, sec/60%60, sec%60, (u64)nsec%NSEC_PER_SEC ); + if ( len > 9 && fraction < 9 ) + { + const uint pos = len - 9 + fraction; + if ( pos < buf_size ) + buf[pos] = 0; + } + } + else + snprintf(buf+1,buf_size-1,"%02d:%02d:%02d", + sec/3600, sec/60%60, sec%60 ); + + char *ptr = buf+1; + while ( *ptr == '0' || *ptr == ':' ) + ptr++; + if ( *ptr == '.' ) + ptr--; + if (minus) + *--ptr = '-'; + return ptr; +} + /////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + +// [[nsec]] -> PrintTimer3U(), PrintTimer3N() ccp PrintTimer3 ( @@ -2440,6 +2613,8 @@ ccp PrintTimer3 /////////////////////////////////////////////////////////////////////////////// +// [[nsec]] -> PrintTimer4U(), PrintTimer4N() + ccp PrintTimer4 ( char * buf, // result buffer (>4 bytes) @@ -2495,6 +2670,8 @@ ccp PrintTimer4 /////////////////////////////////////////////////////////////////////////////// +// [[nsec]] -> PrintTimer6U(), PrintTimer6N() + ccp PrintTimer6 ( char * buf, // result buffer (>6 bytes) @@ -2635,6 +2812,8 @@ ccp PrintTimer6 /////////////////////////////////////////////////////////////////////////////// +// [[nsec]] -> PrintTimer4Us(), PrintTimer4Ns() + ccp PrintTimerUSec4s ( char * buf, // result buffer (>4 bytes) @@ -2673,6 +2852,8 @@ ccp PrintTimerUSec4s /////////////////////////////////////////////////////////////////////////////// +// [[nsec]] -> PrintTimer7Us(), PrintTimer7Ns() + ccp PrintTimerUSec7s ( char * buf, // result buffer (>7 bytes) @@ -2709,45 +2890,18 @@ ccp PrintTimerUSec7s return buf; } -/////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// - -#if 0 -u64 GetXTime ( xtime_t * xtime ) -{ - struct timeval tval; - gettimeofday(&tval,0); - if (!time_base) - time_base = tval.tv_sec; - if (!rel_usec_base) - rel_usec_base = (u64)( tval.tv_sec - time_base ) * 1000000 + tval.tv_usec; - - const ull total_usec = 1000000ull * tval.tv_sec + tval.tv_usec; - - if (xtime) - { - xtime->time = tval.tv_sec; - xtime->usec = tval.tv_usec; - xtime->total_usec = total_usec; - xtime->rel_usec = total_usec - rel_usec_base; - } - return total_usec; -} -#endif - // /////////////////////////////////////////////////////////////////////////////// /////////////// scan date & time /////////////// /////////////////////////////////////////////////////////////////////////////// -char * ScanInterval +char * ScanIntervalTS ( - time_t *res_time, // not NULL: store seconds - u32 *res_usec, // not NULL: store micro seconds of second + struct timespec *res_ts, // not NULL: store result here ccp source // source text ) { - uint days = 0, sec = 0, usec = 0; + uint days = 0, sec = 0, nsec = 0; bool day_possible = true; uint colon_count = 0; char *src = source ? (char*)source : ""; @@ -2757,7 +2911,7 @@ char * ScanInterval for(;;) { - if ( *src < '0' || *src >='9' ) + if ( *src < '0' || *src >= '9' ) break; ulong num = strtoul(src,&src,10); if ( *src == 'd' && day_possible ) @@ -2779,11 +2933,11 @@ char * ScanInterval { src++; uint i; - for ( i = 0; i < 6; i++ ) + for ( i = 0; i < 9; i++ ) { - usec *= 10; + nsec *= 10; if ( *src >= '0' && *src <= '9' ) - usec += *src++ - '0'; + nsec += *src++ - '0'; } while ( *src >= '0' && *src <= '9' ) src++; @@ -2793,32 +2947,87 @@ char * ScanInterval } } + if (res_ts) + { + res_ts->tv_sec = days * SEC_PER_DAY + sec; + res_ts->tv_nsec = nsec; + } + + return src; +} + +/////////////////////////////////////////////////////////////////////////////// + +char * ScanIntervalUSec +( + u_usec_t *res_usec, // not NULL: store total microseconds + ccp source // source text +) +{ + struct timespec ts; + char *res = ScanIntervalTS(&ts,source); + + if (res_usec) + *res_usec = ts.tv_sec * USEC_PER_SEC + ts.tv_nsec / NSEC_PER_USEC; + return res; +} + +/////////////////////////////////////////////////////////////////////////////// + +char * ScanIntervalNSec +( + u_nsec_t *res_nsec, // not NULL: store total nanoseconds + ccp source // source text +) +{ + struct timespec ts; + char *res = ScanIntervalTS(&ts,source); + + if (res_nsec) + *res_nsec = ts.tv_sec * NSEC_PER_SEC + ts.tv_nsec; + return res; +} + +/////////////////////////////////////////////////////////////////////////////// + +char * ScanInterval +( + time_t *res_time, // not NULL: store seconds + u32 *res_usec, // not NULL: store microseconds of second + ccp source // source text +) +{ + struct timespec ts; + char *res = ScanIntervalTS(&ts,source); + if (res_time) - *res_time = days * 86400 + sec; + *res_time = ts.tv_sec; if (res_usec) - *res_usec = usec; - return src; + *res_usec = ts.tv_nsec / NSEC_PER_USEC; + + return res; } /////////////////////////////////////////////////////////////////////////////// char * ScanInterval64 ( - u64 *res_usec, // not NULL: store total micro seconds + u64 *res_usec, // not NULL: store total microseconds ccp source // source text ) { - time_t time; - u32 usec; - char *src = ScanInterval(&time,&usec,source); + u_usec_t usec; + char *res = ScanIntervalUSec(&usec,source); if (res_usec) - *res_usec = time * 1000000ull + usec; - return src; + *res_usec = usec; + return res; } /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// +// [[nsec]] + char * ScanDateTime ( time_t *res_time, // not NULL: store seconds here @@ -2938,9 +3147,11 @@ char * ScanDateTime /////////////////////////////////////////////////////////////////////////////// +// [[nsec]] + char * ScanDateTime64 ( - u64 *res_usec, // not NULL: store total micro seconds + u64 *res_usec, // not NULL: store total microseconds ccp source, // source text bool allow_delta // true: allow +|- interval ) |
