我正在用 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
环境变量(可能还有 call tzset
)?似乎应该有一种方法来操纵数据结构并获得正确的东西,但上面肯定行不通(无论如何,在 MacOS X 10.6 上——在 Linux 上工作得很好)。
作为一种解决方法,我想我可以从格式字符串中删除 %z 并自己创建该部分。
不过,理想情况下,我希望修改 mystruct tm
或其他一些我可以使用的函数调用(如 strftime,但带有额外的参数或其他东西,或者可能是 localtime 的替代形式),这将让事情做正确的事。
由于 Linux 似乎表现良好(即使在那里,上述解决方案也不是很理想,因为我在捏造我的time_t
价值;我更喜欢有一个参数来改变struct tm
计算的方式),这是我应该报告的吗作为针对 MacOS 的错误?
或者,我可以调用一组不同的库例程,即使最终需要第三方(我想是来自 GNU 的人)库?尽管我会考虑使用 ObjC 或 C++ 选项,但我更愿意继续使用 C。