gpt4 book ai didi

C:如何在特定时区(按偏移量)打印特定的 `time` 值?

转载 作者:太空狗 更新时间:2023-10-29 15:41:24 29 4
gpt4 key购买 nike

我正在用 C 语言编写一个应用程序来解析由外部程序(我无法控制)记录的数据文件。它存储二进制数据,其中一个字段是标准 UNIX“纪元”格式的时间(自 1970 年 1 月 1 日以来的秒数,UTC)。

另一个字段是时区,存储为与 UTC 的秒数偏移量。

太棒了,我已经拥有制作日期/时间字符串所需的一切,以在记录时区中表示该信息,对吗?好吧……似乎不是这样,和/或我不确定该怎么做。

我已经将事情归结为一个相当简单的测试用例:

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

int main(void)
{
time_t t;
struct tm *tm;
char buf[BUFSIZ];

int offset = 4980; /* slightly bizarre, just to test this - an hour
* and 23 minutes ahead of UTC */

t = time(NULL);
tm = localtime(&t);

strftime(buf, BUFSIZ, "%FT%T%z", tm);
printf("before: %s\n", buf);

/* since we're not telling localtime anything different,
* compensate here (by subtracting applied offset, and adding
* desired one): */
t += offset - tm->tm_gmtoff;
tm = localtime(&t);

tm->tm_zone = "XYZ"; // not used -- but it was in an earlier version
tm->tm_gmtoff = offset;

// on macos, I used to also have %+, which referenced tm_zone
strftime(buf, BUFSIZ, "%FT%T%z", tm);
printf("after: %s\n", buf);

return 0;
}

当我在 MacOS X 10.6 上运行它时,我得到:

before: 2011-02-23T00:53:04-0800
after: 2011-02-23T10:16:04-0800

我所期望的(事实上,在 Linux 机器上得到的)是:

before: 2011-02-23T00:53:04-0800
after: 2011-02-23T10:16:04+0123

我是否需要更改 TZ 环境变量(并且可能调用 tzset)?似乎应该有一种方法来操纵数据结构并获得正确的东西,但以上肯定不起作用(无论如何在 MacOS X 10.6 上——在 Linux 上工作得很好)。

作为解决方法,我想我可以从我的格式字符串中删除 %z 并自己创建该部分。

不过,理想情况下,我想要修改我的 struct tm,或者我可以使用的其他一些函数调用(比如 strftime,但带有额外的参数或其他东西,或者也许是本地时间的另一种形式),这将使事情做正确的事情。

因为 Linux 似乎表现良好(尽管即使在那里,上述解决方案也不是很理想,因为我在捏造我的 time_t 值;我更希望有一个参数来改变struct tm 被计算),这是我应该报告为针对 MacOS 的错误吗?

或者,有没有我可以调用的一组不同的库例程,即使最终需要第三方(我想是来自 GNU 人员的东西)库?我更愿意继续使用 C,尽管我会考虑 ObjC 或 C++ 选项。

最佳答案

我更喜欢使用mktime() 而不是修改time_t 值。但是,这会应用 TZ 偏移量(就像 localtime() 解决方案一样),因此需要 mkgmtime() 实现。

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

static void set_timezone(char *tz)
{
static char var[1024];

snprintf(var, sizeof(var), "TZ=%s", tz);
putenv(var);
tzset();
}

static time_t mkgmtime(struct tm *tm)
{
char var[1024];
time_t t;

snprintf(var, sizeof(var), "%s", getenv("TZ") ? getenv("TZ") : "");

set_timezone("GMT0");

t = mktime(tm);

set_timezone(var);

return t;
}

int main(void)
{
time_t t;
struct tm tm;
char buf[BUFSIZ];
int offset = 4980; /* slightly bizarre, just to test this - an hour
* and 23 minutes ahead of UTC */

t = time(NULL);
tm = *localtime(&t);
strftime(buf, BUFSIZ, "%FT%T%z", &tm);
printf("before: %s\n", buf);

tm = *gmtime(&t);
tm.tm_sec += offset;
mkgmtime(&tm);

strftime(buf, BUFSIZ, "%FT%T%z", &tm);
printf("after: %s\n", buf);

return 0;
}

关于C:如何在特定时区(按偏移量)打印特定的 `time` 值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5088836/

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