UTC time and LOCAL time - yuhannah/skills_map GitHub Wiki

in mrpt, test datetime.h

测试UTC时间和LOCAL时间

接口代码:

mrpt::system::TTimeStamp  mrpt::system::getCurrentTime( )
{
#ifdef MRPT_OS_WINDOWS
    FILETIME		t;
    GetSystemTimeAsFileTime(&t);
    return (((uint64_t)t.dwHighDateTime) << 32) | ((uint64_t)t.dwLowDateTime);
#elif defined(MRPT_OS_APPLE)

    /* Jerome Monceaux 2011/03/08: [email protected]
     * comment the next line because it does not compile
     * under snow osx and an exception was thrown systematically
     */
    struct timeval tv;
    timespec  tim;

    gettimeofday(&tv, NULL);
    tim.tv_sec = tv.tv_sec;
    tim.tv_nsec = tv.tv_usec*1000;

    return time_tToTimestamp( tim.tv_sec ) + tim.tv_nsec/100;
#else
    timespec  tim;
    clock_gettime(CLOCK_REALTIME, &tim); /// 这里的区别,此处使用 CLOCK_REALTIME

    return time_tToTimestamp( tim.tv_sec ) + tim.tv_nsec/100;
#endif
}
mrpt::system::TTimeStamp  mrpt::system::getCurrentLocalTime()
{
#ifdef MRPT_OS_WINDOWS
    FILETIME		tt,t;
    GetSystemTimeAsFileTime(&tt);
    FileTimeToLocalFileTime(&tt,&t);

    return (((uint64_t)t.dwHighDateTime) << 32) | ((uint64_t)t.dwLowDateTime);
#elif defined(MRPT_OS_APPLE)
    // See: http://www.wand.net.nz/~smr26/wordpress/2009/01/19/monotonic-time-in-mac-os-x/
    THROW_EXCEPTION("to do")
#else
    timespec  tim;
    clock_gettime(CLOCK_REALTIME, &tim); /// 这里的区别,此处使用 CLOCK_REALTIME

    time_t  tt;
    struct tm * timeinfo;
    time(&tt);
    timeinfo = localtime( &tt );

    return time_tToTimestamp( mktime(timeinfo) ) + tim.tv_nsec/100;
#endif
}

测试代码:

auto timeUTC = mrpt::system::getCurrentTime();
YUH_WARN << "     getCurrentTime = " << timeUTC;
mrpt::system::TTimeParts timeParts;
mrpt::system::timestampToParts(timeUTC, timeParts, false);
YUH_WARN << "  UTC time = " << (unsigned int)timeParts.year << " year " << (unsigned int)timeParts.month << " month " << (unsigned int)timeParts.day << " day " << (unsigned int)timeParts.hour << " hour " << (unsigned int)timeParts.minute << " minute " << timeParts.second << " second " << (unsigned int)timeParts.day_of_week << " dayOfWeek" << endl;
auto timeLocal = mrpt::system::getCurrentLocalTime();
YUH_WARN << "getCurrentLocalTime = " << timeLocal;
mrpt::system::timestampToParts(timeLocal, timeParts, true);
YUH_WARN << "LOCAL time = " << (unsigned int)timeParts.year << " year " << (unsigned int)timeParts.month << " month " << (unsigned int)timeParts.day << " day " << (unsigned int)timeParts.hour << " hour " << (unsigned int)timeParts.minute << " minute " << timeParts.second << " second " << (unsigned int)timeParts.day_of_week << " dayOfWeek" << endl;

测试结果:

W 2021-03-19 09:51:34.973664606 2681 SlamActor.cpp:2087  YUH:      getCurrentTime = 132605922949736608
W 2021-03-19 09:51:34.973757356 2681 SlamActor.cpp:2090  YUH:   UTC time = 2021 year 3 month 19 day 1 hour 51 minute 34.9737 second 6 dayOfWeek
W 2021-03-19 09:51:34.973992148 2681 SlamActor.cpp:2092  YUH: getCurrentLocalTime = 132605922949738865
W 2021-03-19 09:51:34.974144106 2681 SlamActor.cpp:2094  YUH: LOCAL time = 2021 year 3 month 19 day 9 hour 51 minute 34.9739 second 6 dayOfWeek

现象的结论: 使用 clock_gettime(CLOCK_REALTIME, &tim); 对应的参数为 CLOCK_REALTIME ,结果显示:

  • UTC时间与当前格林尼治时间GMT相同
  • LOCAL时间与北京时间相同
  • 两者的区别在于北京时间比GMT时间多8小时时差

测试 CLOCK_REALTIME 参数和 CLOCK_MONOTONIC 参数

接口代码:

mrpt::system::TTimeStamp  mrpt::system::getCurrentTime( )
{
#ifdef MRPT_OS_WINDOWS
    FILETIME		t;
    GetSystemTimeAsFileTime(&t);
    return (((uint64_t)t.dwHighDateTime) << 32) | ((uint64_t)t.dwLowDateTime);
#elif defined(MRPT_OS_APPLE)

    /* Jerome Monceaux 2011/03/08: [email protected]
     * comment the next line because it does not compile
     * under snow osx and an exception was thrown systematically
     */
    struct timeval tv;
    timespec  tim;

    gettimeofday(&tv, NULL);
    tim.tv_sec = tv.tv_sec;
    tim.tv_nsec = tv.tv_usec*1000;

    return time_tToTimestamp( tim.tv_sec ) + tim.tv_nsec/100;
#else
    timespec  tim;
    clock_gettime(CLOCK_MONOTONIC, &tim); /// 这里的区别,此处使用 CLOCK_MONOTONIC

    return time_tToTimestamp( tim.tv_sec ) + tim.tv_nsec/100;
#endif
}
mrpt::system::TTimeStamp  mrpt::system::getCurrentLocalTime()
{
#ifdef MRPT_OS_WINDOWS
    FILETIME		tt,t;
    GetSystemTimeAsFileTime(&tt);
    FileTimeToLocalFileTime(&tt,&t);

    return (((uint64_t)t.dwHighDateTime) << 32) | ((uint64_t)t.dwLowDateTime);
#elif defined(MRPT_OS_APPLE)
    // See: http://www.wand.net.nz/~smr26/wordpress/2009/01/19/monotonic-time-in-mac-os-x/
    THROW_EXCEPTION("to do")
#else
    timespec  tim;
    clock_gettime(CLOCK_MONOTONIC, &tim); /// 这里的区别,此处使用 CLOCK_MONOTONIC

    time_t  tt;
    struct tm * timeinfo;
    time(&tt);
    timeinfo = localtime( &tt );

    return time_tToTimestamp( mktime(timeinfo) ) + tim.tv_nsec/100;
#endif
}

测试代码:

auto timeUTC = mrpt::system::getCurrentTime();
YUH_WARN << "     getCurrentTime = " << timeUTC;
mrpt::system::TTimeParts timeParts;
mrpt::system::timestampToParts(timeUTC, timeParts, false);
YUH_WARN << "  UTC time = " << (unsigned int)timeParts.year << " year " << (unsigned int)timeParts.month << " month " << (unsigned int)timeParts.day << " day " << (unsigned int)timeParts.hour << " hour " << (unsigned int)timeParts.minute << " minute " << timeParts.second << " second " << (unsigned int)timeParts.day_of_week << " dayOfWeek" << endl;
auto timeLocal = mrpt::system::getCurrentLocalTime();
YUH_WARN << "getCurrentLocalTime = " << timeLocal;
mrpt::system::timestampToParts(timeLocal, timeParts, true);
YUH_WARN << "LOCAL time = " << (unsigned int)timeParts.year << " year " << (unsigned int)timeParts.month << " month " << (unsigned int)timeParts.day << " day " << (unsigned int)timeParts.hour << " hour " << (unsigned int)timeParts.minute << " minute " << timeParts.second << " second " << (unsigned int)timeParts.day_of_week << " dayOfWeek" << endl;

测试结果:

W 2021-03-19 10:02:05.97702782 2747 SlamActor.cpp:2087  YUH:      getCurrentTime = 116444772819093503
W 2021-03-19 10:02:05.97794657 2747 SlamActor.cpp:2090  YUH:   UTC time = 1970 year 1 month 1 day 1 hour 1 minute 21.9094 second 5 dayOfWeek
W 2021-03-19 10:02:05.98008448 2747 SlamActor.cpp:2092  YUH: getCurrentLocalTime = 132605929259095606
W 2021-03-19 10:02:05.98095948 2747 SlamActor.cpp:2094  YUH: LOCAL time = 2021 year 3 month 19 day 10 hour 2 minute 5.90956 second 6 dayOfWeek

现象的结论:

  • 使用 clock_gettime(CLOCK_REALTIME, &tim); 对应的参数为 CLOCK_REALTIME ,结果显示:
    • UTC时间与当前格林尼治时间GMT相同
    • LOCAL时间与北京时间相同
    • 两者的区别在于北京时间比GMT时间多8小时时差
  • 使用 clock_gettime(CLOCK_MONOTONIC, &tim); 对应的参数为 CLOCK_MONOTONIC ,结果显示:
    • UTC时间是从1970年1月1日其计时,加上打印日志时程序运行的时间段
    • LOCAL时间与北京时间相同
    • 两者的区别在于UTC时间的起点为1970年1月1日,时长为程序运行时间,而LOCAL时间为当前时区的时间

测试 clock_gettime() 和 time()

接口代码:

timespec  tim;
clock_gettime(CLOCK_REALTIME, &tim);
YUH_WARN << "clock_gettime(CLOCK_REALTIME)  tim.tv_sec = " << tim.tv_sec << " tim.tv_nsec = " << tim.tv_nsec << endl;
clock_gettime(CLOCK_MONOTONIC, &tim);
YUH_WARN << "clock_gettime(CLOCK_MONOTONIC)  tim.tv_sec = " << tim.tv_sec << " tim.tv_nsec = " << tim.tv_nsec << endl;
time_t time3 = time(NULL);
YUH_WARN << "                                    time() = " << time3 << endl;

测试结果:

W 2021-03-19 11:38:06.322630862 2943 SlamActor.cpp:2083  YUH: clock_gettime(CLOCK_REALTIME)  tim.tv_sec = 1616125086 tim.tv_nsec = 322615695
W 2021-03-19 11:38:06.322895987 2943 SlamActor.cpp:2085  YUH: clock_gettime(CLOCK_MONOTONIC)  tim.tv_sec = 9443 tim.tv_nsec = 134544418
W 2021-03-19 11:38:06.323008279 2943 SlamActor.cpp:2087  YUH:                                     time() = 1616125086

现象的结论:

  • 使用 clock_gettime(CLOCK_REALTIME, &tim); 对应的参数为 CLOCK_REALTIME ,结果显示:
    • 秒的数据与使用 time(NULL); 接口获取的秒相同
  • 使用 clock_gettime(CLOCK_MONOTONIC, &tim); 对应的参数为 CLOCK_MONOTONIC ,结果显示:
    • 没有相同的部分
  • 使用 time(NULL); 对应的参数为 NULL ,结果显示:
    • 秒的数据与使用 clock_gettime(CLOCK_REALTIME, &tim); 接口获取的秒相同
  • clock_gettime(CLOCK_REALTIME, &tim); 接口的精度最高,为ns级
  • time(NULL); 接口的精度最低,为s级
/* Identifier for system-wide realtime clock.  
   系统实时时间,随系统实时时间改变而改变,即从UTC1970-1-1 0:0:0开始计时,
   中间时刻如果系统时间被用户改成其他,则对应的时间相应改变 */
# define CLOCK_REALTIME			0
/* Monotonic system-wide clock. 
   从系统启动这一刻起开始计时,不受系统时间被用户改变的影响 */
# define CLOCK_MONOTONIC		1

相关的理解

  • 传感器算法板上一般使用的是 clock_gettime(CLOCK_MONOTONIC, &tim); ,所以只能记录传感器启动后的从1970年1月1日起的时间戳,不受系统时间改变的影响
  • 传感器算法板上记录的时间,无法直接用于寻找实际时刻,需要将传感器数据及时传回总算法板,并及时在算法板统一打时间戳
  • 传感器数据传回算法板有一定的传输时间,需要校正
  • 传感器数据获取到打包传输的时间,不可知
  • 如果数据传输过程发生阻塞,要及时抛弃数据,获取最新数据,防止时间延迟