如何以秒为单位获取本地时间(unix epoch)?

How to get local time in seconds (unix epoch)?

提问人:ddomnik 提问时间:7/6/2022 更新时间:7/7/2022 访问量:644

问:

当设置时区时,我正在尝试以秒为单位获取本地时间(unix 纪元)。 例如

1643371200是 2022-01-28 12:00:00 和UTC0

这可以通过 gettimeofday(tv, NULL) 使用 timeval 结构读取为秒。
现在假设我通过 setenv(“TZ”,“CET-1CEST,M3.5.0,M10.5.0/3”,1) 将我的本地时区设置为欧洲/柏林。

当我使用

localtime_r(&now, &local_tv);
char strftime_buf[64];
strftime(strftime_buf, sizeof(strftime_buf), "%c", &local_tv);
printf("get local time: %s", strftime_buf);

这将按预期打印 2022-01-28 13:00:00 (+1h)。
现在我使用了 mktime(&local_tv),因为我认为这会以秒为单位给我本地时间。但它仍然1643371200 (12:00:00)。当我将 mktime()gettimeofday() 一起使用时,我少了 1 小时,所以 11:00:00 ...

C 时区 本地时间 MKTim getTimeOfDay

评论

1赞 Steve Summit 7/6/2022
像 1643371200 这样的 Unix 时间始终是 UTC。当您调用时,它会应用您的本地时区,作为从 1643371200 转换为本地人类可读时间的一部分。当您拨打 时,它会剥离您的本地时区。localtimemktime
0赞 ddomnik 7/6/2022
@SteveSummit我知道,但是如何获取本地时间或将本地时间转换为秒?
0赞 Steve Summit 7/6/2022
使用 ,就像你一样。mktime
0赞 ddomnik 7/6/2022
@SteveSummit但以UTC格式提供,但我希望以当地时间提供。mktime
0赞 ikegami 7/6/2022
回复“我以为这会给我以秒为单位的本地时间”,确实会给你以秒为单位的本地时间。具体来说,自 Linux 上 1970-01-01T00:00:00+0000 以来的秒数。那么你到底想要什么呢?mktime(&local_tv)

答:

1赞 ikegami 7/6/2022 #1

那么为什么在使用时给我mktime()1643371200localtime_r()

2022-01-28T13:00:00+01:00 比 Linux 上使用的纪元 1970-01-01T00:00:00+00:00 晚 1643371200 秒。

mktime从字面上看是 的逆运算,所以当然 mktime(localtime(time)) 给出了时间。localtime

                time /
             gettimeofday
                  |
+-----------------+-----------------+
|                 |                 |
|                 v                 |
|             Epoch time            |
|                 |                 |
|          +------+------+          |
|          |             |          |
|          v             v          |
|      localtime       gmtime       |
|          |             |          |
|          v             v          |
|     Broken down     Broken down   |
|     local time      UTC+0 time    |
|          |             |          |
|          v             v          |
|       mktime /     _mkgmtime* /   |
|      timelocal*     timegm*       |
|          |             |          |
+----------+             +----------+

我如何获得1643374800?

您似乎需要自 1970-01-01T00:00:00 本地时间以来的秒数。

如果你想要这个,你就做错了什么。不需要此值。[1]

要查找两次之间的秒数,请首先将它们转换为纪元时间(如果尚未转换为纪元时间)。然后简单地从另一个中减去一个。

#include <inttypes.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <time.h>

int main( void ) {
   setenv( "TZ", "Europe/Berlin", 1 );
   tzset();

   struct tm base_tm = {
      .tm_sec    = 0,             /* Seconds (0-60) */
      .tm_min    = 0,             /* Minutes (0-59) */
      .tm_hour   = 0,             /* Hours (0-23) */
      .tm_mday   = 1,             /* Day of the month (1-31) */
      .tm_mon    = 1 - 1,         /* Month (0-11) */
      .tm_year   = 1970 - 1900,   /* Year - 1900 */
      //.tm_wday = ,              /* Day of the week (0-6, Sunday = 0) */
      //.tm_yday = ,              /* Day in the year (0-365, 1 Jan = 0) */
      .tm_isdst  = -1             /* Daylight saving time */
   };

   time_t base_epoch = mktime( &base_tm );

   time_t now_epoch = 1643371200l;  // time( NULL );

   printf( "%" PRIi64 "\n", (int64_t)( now_epoch - base_epoch ) );  // 1643374800
}

  1. 它可能有助于纠正错误执行的某些操作。