⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 utctools.c

📁 Open DMT Client C Source code
💻 C
字号:
// ----------------------------------------------------------------------------// Copyright 2006-2007, Martin D. Flynn// All rights reserved// ----------------------------------------------------------------------------//// Licensed under the Apache License, Version 2.0 (the "License");// you may not use this file except in compliance with the License.// You may obtain a copy of the License at// // http://www.apache.org/licenses/LICENSE-2.0// // Unless required by applicable law or agreed to in writing, software// distributed under the License is distributed on an "AS IS" BASIS,// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.// See the License for the specific language governing permissions and// limitations under the License.//// ----------------------------------------------------------------------------// Description://  Timer tools//  Various timer based tools.// ---// Change History://  2006/01/04  Martin D. Flynn//      -Initial release//  2007/01/28  Martin D. Flynn//      -WindowsCE port//      -Added 'utcGetTimestampDelta'//      -If ENABLE_SET_TIME is not defined, 'utcSetTimeSec' will instead save the//      time offset between the local system time and UTC so that 'utcGetTimeSec'//      will now return the corrected UTC time.// ----------------------------------------------------------------------------#include "stdafx.h" // TARGET_WINCE#define SKIP_TRANSPORT_MEDIA_CHECK // only if TRANSPORT_MEDIA not used in this file #include "custom/defaults.h"#include <stdlib.h>#include <stdio.h>#include <string.h>#include <ctype.h>#include <time.h>#include "custom/log.h"#include "tools/threads.h"#include "tools/utctools.h"// ----------------------------------------------------------------------------// 1 second == 1000 milliseconds == 1000,000 microseconds = 1000,000,000 nanoseconds// ----------------------------------------------------------------------------/* offset from system clock time and UTC time */#if !defined(ENABLE_SET_TIME)// utcSec = now + systemTimeOffet;static Int32 systemTimeOffet = 0L;#endif/* system startup time */static UInt32 startupTime = 0L;void utcMarkStartupTime(){    // this could set time startup time to '0' (or near zero) if the system    // clock hasn't been updated by GPS yet.    startupTime = utcGetTimeSec();    // We back up one second so that all timer initialized right at the startup of the    // program will not be zero.    if (startupTime > 0L) { startupTime--; }}UInt32 utcGetStartupTimeSec(){    return startupTime;}// ----------------------------------------------------------------------------/* convert YMDHMS to UTC seconds since Epoch */UInt32 utcYmdHmsToSeconds(YMDHMS_t *yh){    long TOD = (yh->wHour * 3600L) + (yh->wMinute * 60L) + yh->wSecond;    long yr  = ((long)yh->wYear * 1000L) + (long)(((yh->wMonth - 3) * 1000) / 12);    long dd  = yh->wDay;    long DAY = ((367L * yr + 625L) / 1000L) - (2L * (yr / 1000L))             + (yr / 4000L) - (yr / 100000L) + (yr / 400000L)             + (long)dd - 719469L; // offset to 'Epoch'    return (UInt32)((DAY * 24L * 60L * 60L) + TOD);}/* convert UTC EPoch seconds to YMDHMS */YMDHMS_t *utcSecondsToYmdHms(YMDHMS_t *yh, UInt32 utcSec){    memset(yh, 0, sizeof(YMDHMS_t));    Int32 TOD    = utcSec % (24L * 60L * 60L); // in seconds    yh->wHour    = (int)(TOD / (60L * 60L));    yh->wMinute  = (int)((TOD % (60L * 60L)) / 60L);    yh->wSecond  = (int)((TOD % (60L * 60L)) % 60L);    Int32 N      = (utcSec / (24L * 60L * 60L)) + 719469L;    Int32 C      = ((N * 1000L) - 200L) / 36524250L;    Int32 N1     = N + C - (C / 4L);    Int32 Y1     = ((N1 * 1000L) - 200L) / 365250L;    Int32 N2     = N1 - ((365250L * Y1) / 1000L);    Int32 M1     = ((N2 * 1000L) - 500L) / 30600L;    yh->wDay     = (int)(((N2 * 1000L) - (30600L * M1) + 500L) / 1000L);    yh->wMonth   = (int)((M1 <= 9L)? (M1 + 3L) : (M1 - 9L));    yh->wYear    = (int)((M1 <= 9L)? Y1 : (Y1 + 1));    return yh;}/* format date/time */// The destination buffer is assumed to be at least 20 bytes in length// the output format will be: "YYYY/MM/DD hh:mm:ss" (with a terminating null)const char *utcFormatDateTime(char *dt, UInt32 utcSec){    if (dt) {        YMDHMS_t yh;        utcSecondsToYmdHms(&yh, utcSec);        sprintf(dt, "%04d/%02d/%02d %02d:%02d:%02d",             yh.wYear, yh.wMonth , yh.wDay, yh.wHour, yh.wMinute, yh.wSecond);    }    return dt;}// ----------------------------------------------------------------------------/* get a timestamp with millisecond resolution (based on actual current system clock) */// This may not provide an accurate UTC time!static struct timeval *_utcGetTimestamp(struct timeval *tv){    if (tv) {        // struct timeval:        //   tv_sec     - seconds        //   tv_usec    - microseconds#if defined(TARGET_WINCE)        SYSTEMTIME st;        GetSystemTime(&st); // UTC        long TOD = (st.wHour * 3600L) + (st.wMinute * 60L) + st.wSecond;        long yr  = ((long)st.wYear * 1000L) + (long)(((st.wMonth - 3) * 1000) / 12);        long dd  = st.wDay;        long DAY = ((367L * yr + 625L) / 1000L) - (2L * (yr / 1000L))                 + (yr / 4000L) - (yr / 100000L) + (yr / 400000L)                 + (long)dd - 719469L; // offset to 'Epoch'        long sec = (DAY * 24L * 60L * 60L) + TOD;        tv->tv_usec = (UInt32)st.wMilliseconds * 1000L;        tv->tv_sec  = (UInt32)sec;#else        gettimeofday(tv, 0);#endif    }    return tv;}/* get a timestamp with millisecond resolution (adjusted for UTC time) */struct timeval *utcGetTimestamp(struct timeval *tv){    if (tv) {        _utcGetTimestamp(tv);#if !defined(ENABLE_SET_TIME)        // apply offset to UTC time        tv->tv_sec = tv->tv_sec + systemTimeOffet;#endif    }    return tv;}/* get a timestamp with the specified number of millisecond in the future */struct timeval *utcGetTimestampDelta(struct timeval *tv, Int32 deltaMS){    if (tv) {        utcGetTimestamp(tv);        Int32 sec    = (Int32)tv->tv_sec  + deltaMS / 1000L;        Int32 usec   = (Int32)tv->tv_usec + (deltaMS % 1000L) * 1000L;        if (usec > 1000000L) {            usec -= 1000000L;            sec  += 1L;        } else        if (usec < 0L) {            usec += 1000000L;            sec  -= 1L;        }        tv->tv_sec  = sec;        tv->tv_usec = usec;    }    return tv;}/* return the difference between two timestamps in milliseconds */UInt32 utcGetDeltaMillis(struct timeval *ts1, struct timeval *ts2){    if (ts1 == ts2) {        // if they point to the same structure, or are both null        return 0L;    } else {        struct timeval now;        if (!ts1) {            utcGetTimestamp(&now);            ts1 = &now;        }        if (!ts2) {            utcGetTimestamp(&now);            ts2 = &now;        }        Int32 delta = ((ts1->tv_sec - ts2->tv_sec) * 1000L) + ((ts1->tv_usec - ts2->tv_usec) / 1000L);        return (UInt32)((delta >= 0L)? delta : -delta); // absolute value    }}// ----------------------------------------------------------------------------/* return current time in seconds */static UInt32 _utcGetTimeSec(){#if defined(TARGET_WINCE)    struct timeval tv;    _utcGetTimestamp(&tv);    return (UInt32)tv.tv_sec;#else    return (UInt32)time((time_t*)0);#endif}/* return current time in seconds (adjusted for UTC) */UInt32 utcGetTimeSec(){    UInt32 ts = _utcGetTimeSec();#if !defined(ENABLE_SET_TIME)    ts = ts + systemTimeOffet;#endif    if (ts < MIN_CLOCK_TIME) {        // the time has not yet been initialized by the GPS!    }    return ts;}/* set current time in seconds */utBool utcSetTimeSec(UInt32 utcSec){    // Notes:    // - This implementation is platform specific.  On Linux systems, this can be    //   accomplished with the 'settimeofday' function.    // - IMPORTANT: When setting this time, it is very important that the value of    //   'startupTime' also be adjusted accordingly so that time deltas will still    //   be calculated properly!    // - This time can be set to the latest time aquired from the GPS fix.  However,    //   It shouldn't be set on every new GPS fix, but rather only when the current    //   system clock has drifted beyond some acceptable tolarance (eg. 5 seconds).    /* get the elapsed time since startup */    UInt32 preAdjustedTime = utcGetTimeSec();    UInt32 startupTimeDeltaSec = preAdjustedTime - startupTime;#if defined(ENABLE_SET_TIME)    /* set current clock time */#if defined(TARGET_WINCE)    // this may not actually work on all WinCE platforms!  Test it!    SYSTEMTIME st;    utcSecondsToYmdHms((YMDHMS_t*)&st, utcSec);    //logINFO(LOGSRC,"UTC: %d/%d/%d %d:%d:%d", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);    SetSystemTime(&st); // UTC#else    //int settimeofday(const struct timeval *tv , const struct timezone *tz);    struct timeval tv;    tv.tv_sec         = utcSec;    tv.tv_usec        = 0;    struct timezone tz;    tz.tz_minuteswest = 0;    tz.tz_dsttime     = 0;    settimeofday(&tv, &tz);#endif // defined(TARGET_WINCE)    #else    /* reset system time offset */    UInt32 now = _utcGetTimeSec(); // unadjusted    systemTimeOffet = (Int32)(utcSec - now);#endif // defined(ENABLE_SET_TIME)    /* print new time */    char ts[32];    utcFormatDateTime(ts, utcGetTimeSec());    logINFO(LOGSRC,"Synchronized clock: %s UTC\n", ts);    /* adjust startup time */    UInt32 postAdjustedTime = utcGetTimeSec();    if (postAdjustedTime > startupTimeDeltaSec) {        // This should ALWAYS be true        startupTime = postAdjustedTime - startupTimeDeltaSec;        // 'startupTime' now still reflects that startup occured 'startupTimeDeltaSec'         // seconds ago.    } else {        // This means that the 'startupTime' was previously initialized to some         // terribly erroneous value.  Reset the startup time to the current time.        // All initialized timers will be effected.        startupTime = postAdjustedTime;    }    /* return successful */    return utTrue;}// ----------------------------------------------------------------------------// Timers:// These functions exist to eliminate the inaccuracy on the system clock// (that is, when the current system clock does not, or cannot, provide an // accurate current UTC time)./* get a timer base on the current time */TimerSec_t utcGetTimer(){    UInt32 time = utcGetTimeSec();    TimerSec_t upTime = UTC_TO_TIMER(time);    return upTime;}/* return the age of the timer in seconds */Int32 utcGetTimerAgeSec(TimerSec_t timerSec){    TimerSec_t baseTimeSec = utcGetTimer();    Int32 delta = (Int32)baseTimeSec - (Int32)timerSec;    return delta;}/* return true if the timer has elapsed beyond the specified interval */utBool utcIsTimerExpired(TimerSec_t timerSec, Int32 intervalSec){    /* return true if the timer has not yet been initialized */    if (timerSec <= 0L) {        return utTrue;    }    /* return true if there is no timeout interval */    if (intervalSec <= 0L) {        return utTrue;    }    /* return true if 'intervalSec' has passed */    if (utcGetTimerAgeSec(timerSec) > intervalSec) {        return utTrue;    } else {        return utFalse;    }}// ----------------------------------------------------------------------------/* get an absolute time 'offsetMS' milliseconds into the future */struct timespec *utcGetAbsoluteTimespec(struct timespec *ts, UInt32 offsetMS){    if (ts) {        struct timeval tv;        utcGetTimestamp(&tv);        ts->tv_sec  = tv.tv_sec;        ts->tv_nsec = tv.tv_usec * 1000L;               // micro -> nano        if (offsetMS >= 1000L) {                        // at least 1 second?            ts->tv_sec += offsetMS / 1000L;             // milli -> sec            offsetMS %= 1000L;                          // strip seconds        }        ts->tv_nsec += offsetMS * 1000000L;             // milli -> nano        if (ts->tv_nsec >= 1000000000L) {               // at least 1 second?            ts->tv_sec += ts->tv_nsec / 1000000000L;    // nano-> sec            ts->tv_nsec %= 1000000000L;                 // strip seconds        }    }    return ts;}// ----------------------------------------------------------------------------

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -