【问题标题】:Getting the localtime in milliseconds以毫秒为单位获取本地时间
【发布时间】:2017-08-05 04:20:36
【问题描述】:

我需要最快的方法来获取本地时间(因此考虑到当前时区),至少以毫秒为单位,如果可以在十分之一毫秒内获取它会更好。

我想避免使用 gettimeofday(),因为它现在是一个过时的函数。

所以,我似乎需要使用clock_gettime(CLOCK_REALTIME, ...) 并将小时调整为当前时区,但是如何?这样做的最佳点在哪里?在存储使用clock_gettime获得的时间戳之前,还是在将其转换为当前时区的公历之前?

编辑:我加入 get_clock 和 localtime 的原始示例 - 有更好的方法来实现吗?

#include <time.h>
#include <stdio.h>

int main() {
    struct timespec ts;
    clock_gettime(CLOCK_REALTIME, &ts);

    struct tm* ptm;
    ptm = localtime(&(ts.tv_sec));

    // Tenths of milliseconds (4 decimal digits)
    int tenths_ms = ts.tv_nsec / (100000L);

    printf("%04d-%02d-%02d %02d:%02d:%02d.%04d\n", 
        1900 + ptm->tm_year, ptm->tm_mon + 1, ptm->tm_mday, 
        ptm->tm_hour, ptm->tm_min, ptm->tm_sec, tenths_ms);
}

【问题讨论】:

    标签: c datetime time


    【解决方案1】:

    我认为没有比clock_gettime()localtime() 更好的方法了。但是,您需要正确舍入返回的纳秒,并考虑将时间向上舍入到下一秒的情况。要格式化时间,您可以使用 strftime() 而不是手动格式化 tm 结构:

    #include <time.h>
    #include <stdio.h>
    
    int main(void) {
        struct timespec ts;
        long msec;
        int err = clock_gettime(CLOCK_REALTIME, &ts);
        if (err) {
            perror("clock_gettime");
            return 1;
        }
    
        // round nanoseconds to milliseconds
        if (ts.tv_nsec >= 999500000) {
            ts.tv_sec++;
            msec = 0;
        } else {
            msec = (ts.tv_nsec + 500000) / 1000000;
        }
    
        struct tm* ptm = localtime(&ts.tv_sec);
        if (ptm == NULL) {
            perror("localtime");
            return 1;
        }
    
        char time_str[sizeof("1900-01-01 23:59:59")];
        time_str[strftime(time_str, sizeof(time_str),
                "%Y-%m-%d %H:%M:%S", ptm)] = '\0';
    
        printf("%s.%03li\n", time_str, msec);
    }
    

    【讨论】:

      【解决方案2】:

      是的,这可以使用clock_gettime() 函数来实现。在当前版本的 POSIX 中,gettimeofday() 被标记为已过时。这意味着它可能会从规范的未来版本中删除。鼓励应用程序编写者使用clock_gettime() 函数而不是gettimeofday()

      长话短说,这里有一个如何使用clock_gettime()的例子:

      #define _POSIX_C_SOURCE 200809L
      
      #include <inttypes.h>
      #include <math.h>
      #include <stdio.h>
      #include <time.h>
      
      void print_current_time_in_ms (void)
      {
          long            ms; // Milliseconds
          time_t          s;  // Seconds
          struct timespec spec;
      
          clock_gettime(CLOCK_REALTIME, &spec);
      
          s  = spec.tv_sec;
          ms = round(spec.tv_nsec / 1.0e6); // Convert nanoseconds to milliseconds
      
          printf("Current time: %"PRIdMAX".%03ld seconds since the Epoch\n",
                 (intmax_t)s, ms);
      }
      

      如果您的目标是测量经过的时间,并且您的系统支持“单调时钟”选项,那么您应该考虑使用CLOCK_MONOTONIC 而不是CLOCK_REALTIME

      还有一点,请记住在尝试编译代码时包含-lm 标志。

      要获取时区,只需执行以下操作:

      #define _GNU_SOURCE /* for tm_gmtoff and tm_zone */
      
      #include <stdio.h>
      #include <time.h>
      
      int main(void)
      {
        time_t t = time(NULL);
        struct tm lt = {0};
      
        localtime_r(&t, &lt);
      
        printf("Offset to GMT is %lds.\n", lt.tm_gmtoff);
        printf("The time zone is '%s'.\n", lt.tm_zone);
      
        return 0;
      }
      

      注意:time() 返回的纪元以来的秒数按照 GMT(格林威治标准时间)进行测量。

      【讨论】:

      • 但是,现在的时区调整呢?
      • 我已经编辑了我对您与时区相关的查询的回答。它为您提供了获取时区的代码。现在如何根据您的要求调整它作为练习留给您。
      • 谢谢。我已经编辑了问题以显示我的原始测试,这促使我提出这个问题,我真的需要知道如何更推荐(快速)的方法来达到这个目标。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-26
      • 2013-05-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-09
      相关资源
      最近更新 更多