gpt4 book ai didi

将日期转换为纪元时间忽略系统时区

转载 作者:行者123 更新时间:2023-11-30 16:49:32 43 4
gpt4 key购买 nike

我编写了以下代码来将日期转换为时间戳。

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

int main()
{
struct tm date_time;
char date_time_buf[255];
char date_time_hdr[255]={0};
strncpy(date_time_hdr,"Thu, 02 Mar 2017 05:54:28 GMT",255);
memset(&date_time, 0, sizeof(struct tm));
strptime(date_time_hdr, "%a, %d %b %Y %H:%M:%S %Z", &date_time);
memset(date_time_buf, 0, 255);
strftime(date_time_buf, 255, "%s", &date_time);
int p=atoi(date_time_buf);
printf("time is %d \r\n", p);
return 0;
}

我能够将日期转换为时间戳。但面临一个问题。时间戳偏移 5 小时 30 分钟,这是我的 Linux 机器的时区。但我不想要这样。有没有办法忽略系统时区?

最佳答案

不要使用 strftime() 将分解时间 struct tm 格式化为整数,并使用 atoi() 对其进行解析,您可以使用简单但非标准的 timegm()功能。

尽管 timegm() 不在 POSIX 中,但大多数 POSIXy 系统都提供它。如果您希望代码能够跨 POSIXy 系统移植,可以使用解决方法(如 timegm 手册页的某些版本中所述):

#define _POSIX_C_SOURCE 200809L
#define _XOPEN_SOURCE
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <errno.h>

time_t alt_timegm(struct tm *from)
{
char *tz;
time_t result;
int saved_errno;

tz = getenv("TZ");
if (tz)
tz = strdup(tz);

setenv("TZ", "", 1); /* TZ empty refers to UTC */
tzset();

errno = 0;
result = mktime(from);
saved_errno = errno;

setenv("TZ", tz, 1);
free(tz);

errno = saved_errno;
return result;
}

此解决方法确实有一个缺点,即它会临时修改当前时区,这会影响执行任何时区相关函数的其他线程。在单线程进程中,这不是问题(因为与时区相关的函数不是异步信号安全的,因此它们不能在信号处理程序中使用)。

在多线程程序中,应该序列化对时区相关函数的所有访问 - 上面的 alt_timegm()mktime()localtime() 等 --,以确保每个函数都在正确的时区设置下运行。

Linux 和 BSD 中的 timegm() 实现是线程安全的;也就是说,它们不会修改时区。

使用上面的内容,使用 strptime() 格式将字符串解析为 Unix 时间戳很容易:

const char *parse_utc(const char *s, const char *format, time_t *to)
{
char *result;
struct tm t_parts;
time_t t;

if (!s || !format) {
errno = EINVAL;
return NULL;
}

result = strptime(s, format, &t_parts);
if (!result) {
errno = EINVAL;
return NULL;
}

errno = 0;
t = alt_timegm(&t_parts);
if (to)
*to = result;

return (const char *)result;
}

上面的parse_utc()使用strptime()格式format解析字符串s,将UTC时间戳保存到to 如果不为 NULL,则返回指向字符串 s 中第一个未解析字符的指针。

在上述函数中设置errno = 0可能看起来很奇怪,但这是因为mktime()(和timegm())如果发生错误,函数可能会也可能不会设置errno;它只返回(time_t)-1。这意味着无法可靠地确定 (time_t)-1(对应于 UTC` 1969 年的最后一秒)是实际有效的时间戳,还是错误返回。

换句话说,如果在调用 parse_utc() 后出现 errno != 0,则表示出现错误。 (请注意,如果字符串或格式无效,parse_utc() 将返回 NULL,且 errno == EINVAL。)如果 errno == 0*to == (time_t)-1,这取决于体系结构,时间字符串是否实际引用 UTC 1969 年的最后一秒,或者是否是一个错误;我们根本不知道。

关于将日期转换为纪元时间忽略系统时区,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42548454/

43 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com