【问题标题】:How to get local time in seconds (unix epoch)?如何以秒为单位获取本地时间(unix epoch)?
【发布时间】:2022-07-07 00:13:38
【问题描述】:

我试图在设置时区时以秒为单位(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 ...

【问题讨论】:

  • 像 1643371200 这样的 Unix 时间总是 UTC。当您调用 localtime 时,它会应用您的本地时区,作为从 1643371200 转换为本地、人类可读时间的一部分。当您拨打 mktime 时,它会取消您的本地时区。
  • @SteveSummit 我知道,但我怎样才能获得或将我的本地时间转换为秒?
  • 使用mktime,就像你做的那样。
  • @SteveSummit 但mktime 以UTC 给出,但我希望它是当地时间。
  • Re "我认为这会给我以秒为单位的本地时间。", mktime(&local_tv) 确实 以秒为单位给你本地时间。具体来说,自 Linux 上 1970-01-01T00:00:00+0000 以来的秒数。那你到底想要什么?

标签: c timezone localtime mktime gettimeofday


【解决方案1】:

那么为什么mktime() 与localtime_r() 一起使用时给我1643371200

2022-01-28T13:00:00+01:00 是 1970-01-01T00:00:00+00:00(Linux 上使用的纪元)之后的 1643371200 秒。

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

                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 开始的秒数。

这可以使用 time() - mktime(1970-01-01T00:00:00) 获得

#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 = 1643371200ul; // time( NULL );

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

【讨论】:

  • 好主意,但我会使用不同的技巧。如果今天的 DST 规则(或基本 GMT 偏移量)与 1970 年不同,这可能会给出错误的答案。
猜你喜欢
  • 1970-01-01
  • 2017-08-05
  • 1970-01-01
  • 2021-03-19
  • 2012-10-07
  • 2016-08-03
  • 2020-04-11
  • 2011-01-24
  • 1970-01-01
相关资源
最近更新 更多