【发布时间】:2011-07-02 14:37:51
【问题描述】:
我正在用 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 人的东西)库?尽管我会考虑使用 ObjC 或 C++ 选项,但我更愿意继续使用 C。
【问题讨论】:
标签: c unix strftime localtime ctime