Я пишу приложение на C, которое анализирует файлы данных, записанные внешней программой (над которыми у меня нет контроля).Он хранит двоичные данные, одно поле которых представляет собой время в стандартном формате «эпохи» UNIX (секунды с 1 января 1970 года, 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 fолкс, я представляю) библиотека?Я бы предпочел придерживаться C, хотя я бы рассмотрел параметры ObjC или C ++.