【问题标题】:how to parse syslog timestamp如何解析系统日志时间戳
【发布时间】:2011-10-30 04:35:27
【问题描述】:

http://www.syslog.cc/ietf/drafts/draft-ietf-syslog-protocol-23.txt

6.2.3.1。上述链接中的示例 提供了不同时间戳格式的示例。

如何解析C 中的这些时间戳?

即时,任何类型的消息都可以到达,我希望能够解析它。

【问题讨论】:

    标签: c unix timestamp syslog


    【解决方案1】:

    日期格式是更严格的 RFC3339 版本,给出一个字符串,例如 '2011-08-18T23:31:42Z'

    我不确定 strptime 函数可以处理时区说明符(上面时间字符串中的 Z),因此在您自己的函数中处理它可能更容易。它绝对不能处理小数秒,因为 struct tm 不处理它们。如果需要,您可以使用 struct timespec 来存储小数秒。

    您可以使用 strptime 解析出大部分格式:

    struct tm tm;
    time_t t
    char *extra;
    extra = strptime( tmstr, "%C%y-%m-%dT%H:%M:%S", &tm );
    tm.tm_isdst = -1;
    t = mktime( &tm );
    

    在此之后,extra 将是输入 tmstr 的剩余部分。这可能包括小数秒,然后将包含时区格式。如果 extra 以 '.' 开头只需使用 strtod 函数解析数字即可:

    if( extra && extra[0] == '.' )
    {
      char *endptr;
      fraction = strtod( extra, &endptr );
      extra = endptr;
    
      /* use timespec if fractional seconds required */
      struct timespec ts;
      ts.tv_sec = t;
      ts.tv_nsec = fraction * 1000000000;
    }
    

    那么 extra 现在将只包含时区说明符。如果它是“Z”,那么我们就完成了,因为 mktime 无论如何都会给你 UTC 时间。否则你会有一个偏移量,例如+03:00,因此您需要将时间修改为该小时/分钟数。

    【讨论】:

    • 非常感谢。太棒了。我只需要找出如何将+03:00 添加到我保留为time_t 的时间。
    • 知道了。非常感谢您的帮助。
    • struct timespec 将是比double 更好的存储时间戳的方式。后者随着时间的推移而失去精度,并且无法存储“原始值”的精确表示,这些表示几乎可以肯定是以微秒或纳秒为单位,而不是某种以 2 为底的小数形式。
    • 也同意这一点! 9 年后,我刚刚习惯了我们的做法,实际上它对于我们的目的来说已经足够好了(我们只需要毫秒精度)。我将编辑我的答案,以便未来的访问者得到更好的答案......
    • 在时区调整之前执行 mktime() 不是错误的来源(当调整将时间移入或移出“节省”时间时)?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-29
    • 1970-01-01
    • 2021-09-25
    • 2017-02-09
    相关资源
    最近更新 更多