C-将日期转换为忽略系统时区的日期



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

#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 rn", p); 
    return 0;
}

我可以将日期转换为时间戳。但是面临问题。时间戳被抵消5小时30分钟,这是我的Linux机器的时区。但是我不想要那个。有没有办法忽略系统时区?

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

即使timegm()不在POSIX中,它也由大多数Posixy系统提供。如果您希望代码在Posixy系统中可移植,则可以使用解决方案(如timegm MAN页面的某些版本中所述):

#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()(and timegm())函数可能会或可能不会在发生错误的情况下设置errno;它只是返回(time_t)-1。这意味着不可能可靠地确定(time_t)-1(对应于1969年第二年的UTC`))是实际的有效时间戳还是错误返回。

换句话说,如果errno != 0在致电parse_utc()后,则出现错误。(请注意,如果字符串或格式无效,parse_utc()返回NULL,则使用errno == EINVAL。)如果errno == 0但是*to == (time_t)-1,则取决于架构是否实际上是在UTC中的最后一年中提到的时间字符串,或错误;我们根本不知道。

相关内容

  • 没有找到相关文章

最新更新