English 中文(简体)
正在使用 strftime () 取得 utc 时间戳
原标题:getting utc timestamp using strftime()

我试图使用 strftime 函数将当前的 UTC 时间编码为字符串 :

time_t now;
struct tm nowLocal;
struct tm nowUtc;

now = time(NULL);
localtime_r(&now, &nowLocal);
gmtime_r(&now, &nowUtc);

迄今为止良好 : nowlocal 包含我时区(CET)的当前时间, nowUtc 包含UTC时间, 差额与 tm_gmtoff 值完全吻合 :

nowLocal: {tm_sec = 28, tm_min = 27, tm_hour = 13, tm_mday = 23,
   tm_mon = 4, tm_year = 112, tm_wday = 3, tm_yday = 143,
   tm_isdst = 1, tm_gmtoff = 7200, tm_zone = 0x8127a38 "CEST"}

nowUtc:   {tm_sec = 28, tm_min = 27, tm_hour = 11, tm_mday = 23,
   tm_mon = 4, tm_year = 112, tm_wday = 3, tm_yday = 143,
   tm_isdst = 0, tm_gmtoff = 0, tm_zone = 0x3e9907 "GMT"}

然后我打电话给 strftime () () with "%s" 格式的 "%s" 格式,以获得自时代以来的秒数:

char tsFromLocal[32];
char tsFromUtc[32];

strftime(tsFromLocal, sizeof(tsFromLocal), "%s", &nowLocal);
strftime(tsFromUtc, sizeof(tsFromUtc), "%s", &nowUtc);

结果对我来说似乎很奇怪。 我期望从两个 strftime () 调来与 s 格式完全相同的字符串, 被描述为 :

自此时代以来的秒数, 即自 < code> 1970-01- 01-0 00: 00: 00 UTC 开始的秒数。 除非有跳跃第二支持, 否则跳行秒数不会计算 。

但我有两个不同的价值:

tsFromLocal: "1337772448"

tsFromUtc:   "1337768848"

此外,区别不在于 7200 ( tm_gmtoff ),而在于 3600 < /genger{%/em>。 任何人都能解释这种行为吗? 或者说这是个错误?

我之所以这样做,是因为我需要将时间价值转移到整个网络上,并将其与目标机器上的时间进行比较,因为目标机器上的时间可能在不同的时间区。

struct tm restoredUtc;
time_t restored;

strptime(tsFromUtc, "%s", &restoredUtc);
restored = timegm(&restoredUtc);

但我有:

restoredUtc:{tm_sec = 28, tm_min = 27, tm_hour = 12, tm_mday = 23,
   tm_mon = 4, tm_year = 112, tm_wday = 3, tm_yday = 143,
   tm_isdst = 1, tm_gmtoff = 7200, tm_zone = 0x8127a38 "CEST"}

因此, strptime () () tm_zone ) 根据当前时区设置 tm_zone > 。 但是,即使我使用 timegm () 而不是 timegm () , 我也不会得到正确的值, 因为它应该是 11: 27: 28 CEST > 12: 27:28 CEST 。 这个错误是否与 strftime () 的不同结果有关?

对这一后半部分有何评论?

问题回答

最好还是使用格林尼治标准( GMT), 因为有 < code> gmtime_r < / code >, 到处都会有相同的答案。 如果一台机器想在本地时间显示, 稍后可以完成, 但坚持一个存储和网络传输时区是一个好主意, 并且 GMT 值很容易实现 。

我怀疑评论是正确的 : strftime () 正在将时间解释为本地时间 。 请注意 tm_ gmtoff 不是一个标准字段; 不知道 strftime () 是否正在查看它。 但我找不到任何具体信息可以确认这一点 。

然而,在回答您的问题的第二部分时, 为什么不直接将 time( NULL) (NULL) 的结果传输到网络上呢? 或者, 如果您已经有时间使用 struct tm 的形式, 请使用 mktime () 转换为 time_t , 然后传输到? printf ("%lu"), (未签名的长时间) 要比尝试使用 strftime ("%s") 简单得多, 而C99 或 POSIX 则没有标准化。

问题1:有人能解释这种行为吗?

是的, 本地端 < code> tts: "1337772448" ! = tsFromUtc: "1337768848" 。 但错误在 < strong> tsFromUtc 中。 它们应该相同, 并且都应该是 1337772448 。

1337772448%( 24 < em> 60 60 60 > ) - & gt; 41248; 是一天的 UTC 秒或 11: 27: 28, 它符合您的 < code> nowUtc 结构, 是您认为( 在 UTC) 的时间

问题2:... 此错误是否与 strftime () 的不同结果有关?

我同意使用 time_t 作为网络通信的整数。

是的,看起来是这样。

如果您想要在此文章上更进一步 : 考虑在 < code> time( & amp; now) < / code > 之后贴上 < code> 的数值值 < code> 现在 , 并明确说明当时预计的时间 。

正如其他人提到的那样,您试图使用的函数会给您带来取决于每台计算机当前设置的结果。

然而, Linux 系统极有可能使用 UTC 来显示时钟, 并将其转换为显示日期所需的本地时间。 因此, 最好的办法是在您的计算机之间共享 UTC 值, 以确保它们拥有相同时间 。 如果没有, 则使用 NTP 或类似方法来纠正每台计算机的时间( 大多数 VPS 使用主机的时间, 因为主机已经运行了 NTP 服务器, 所以在这类机器上你几乎不必这样做 ) 。

现在,如果你想知道每台计算机的时区, 我建议您将该信息作为单独的变量共享。 这意味着您需要检索所述时区信息。 这样做有几种方法。

确定一个偏移 : 在 time_t 中转换 time_t 的 C 函数可用于定义一个偏移。 如果 struct tm 尚未包含一个偏移, 您可以使用 localtime () gmtime () 函数, 然后根据结果( 不完全是微不足道, 但不是那么困难) 或更好的计算抵消, 使用 gettimeday () , 并给您一个 struct timezone , 并在分钟内抵消, DST (日标准时间) 是否适用( 即夏天对冬季时间) 。

确定名称:总是有可能确定使用中时区的名称;可能难以找到所有功能来获取这些信息。

C+++ (C+/ 20及以上) 新版本的 C+++ (C+/ 20及以上) 具有为此目的而设的功能 : < code>std:: chrono:::: purent_zone ()- & gt; name () , 返回一个字符串, 如“ America/ Los_ Angeles ” 。 在 / usr/share/zoneinfo 目录下发现的名称 。

在 C 中, 您可以使用 strftime () () , 并使用 %z > >\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

还有一些图书馆可以实施这些功能:C++、Unicode、C++、Unicode、C+++、Unicode...所有图书馆都将使用较低层次的功能,您可以随时下载它们的代码,并查找关于它们如何使用代码的信息,以便了解如果您不想使用这些图书馆,如何自行实施。

在使用系统的 Linux 上,您也可以运行以下命令:

timedatectl show --va -p Timezone

所以在 C 中,您可以使用 popen () 并读取该命令的输出。

另见:





相关问题
Fastest method for running a binary search on a file in C?

For example, let s say I want to find a particular word or number in a file. The contents are in sorted order (obviously). Since I want to run a binary search on the file, it seems like a real waste ...

Print possible strings created from a Number

Given a 10 digit Telephone Number, we have to print all possible strings created from that. The mapping of the numbers is the one as exactly on a phone s keypad. i.e. for 1,0-> No Letter for 2->...

Tips for debugging a made-for-linux application on windows?

I m trying to find the source of a bug I have found in an open-source application. I have managed to get a build up and running on my Windows machine, but I m having trouble finding the spot in the ...

Trying to split by two delimiters and it doesn t work - C

I wrote below code to readin line by line from stdin ex. city=Boston;city=New York;city=Chicago and then split each line by ; delimiter and print each record. Then in yet another loop I try to ...

Good, free, easy-to-use C graphics libraries? [closed]

I was wondering if there were any good free graphics libraries for C that are easy to use? It s for plotting 2d and 3d graphs and then saving to a file. It s on a Linux system and there s no gnuplot ...

Encoding, decoding an integer to a char array

Please note that this is not homework and i did search before starting this new thread. I got Store an int in a char array? I was looking for an answer but didn t get any satisfactory answer in the ...