strptime в c со смещением часового пояса - PullRequest
5 голосов
/ 07 сентября 2011

У меня возникают проблемы с поиском способа разбора часового пояса по строкам, например: «Четверг, 1 сентября 2011 г. 09:06:03 -0400 (EDT)»

Что мне нужно сделатьв более крупной схеме моей программы взять char * и преобразовать его в time_t.Ниже приведена простая тестовая программа, которую я написал, чтобы попытаться выяснить, учитывал ли strptime часовой пояс вообще, и это не так (когда эта тестовая программа выполняет все напечатанные числа, они должны совпадать, когда они должны отличаться).Предложения?

Я также пытался использовать GNU getdate и getdate_r, потому что это выглядит как лучший вариант для возможных гибких форматов, но я получил предупреждение «неявного объявления функции» от компилятора, подразумевая, что я не включалправильные библиотеки.Есть ли что-то еще, что я должен # включить, чтобы использовать getdate?

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

#ifndef __USE_XOPEN
#define __USE_XOPEN
#endif
#include <time.h>

int main (int argc, char** argv){

char *timestr1, *timestr2, *timestr3;
struct tm time1, time2, time3;
time_t timestamp1, timestamp2, timestamp3;

timestr1 = "Thu, 1 Sep 2011 09:06:03 -0400 (EDT)"; // -4, and with timezone name
timestr2 = "Thu, 1 Sep 2011 09:06:03 -0000"; // -0

strptime(timestr1, "%a, %d %b %Y %H:%M:%S %Z", &time1); //includes UTC offset
strptime(timestr2, "%a, %d %b %Y %H:%M:%S %Z", &time2); //different UTC offset
strptime(timestr1, "%a, %d %b %Y %H:%M:%S", &time3); //ignores UTC offset

time1.tm_isdst = -1;
timestamp1 = mktime(&time1);
time2.tm_isdst = -1;
timestamp2 = mktime(&time2);
time3.tm_isdst = -1;
timestamp3 = mktime(&time3);

printf("Hello \n");
printf("%d\n%d\n%d\n", timestamp1, timestamp2, timestamp3);
printf("Check the numbers \n");
return 0;
}

1 Ответ

3 голосов
/ 08 сентября 2011

В MacOS X (10.7.1) одна из «ошибок», перечисленных в справочной странице strptime(3):

Спецификатор формата% Z принимает только сокращения часового пояса местного часового пояса или значение "ВРЕМЯ ПО ГРИНВИЧУ". Это ограничение вызвано неоднозначностью из-за перегрузки сокращений часовых поясов. Одним из таких примеров является EST, который является восточным стандартным временем и летним временем Восточной Австралии.

Некоторое время назад я написал пару команд - timestamp (май 1989 г. для редакции 1.1) и strptime (июль 2007 г. для редакции 1.1). Это относительно тонкие обложки над функциями strftime() и strptime().

Запустив их на MacOS X, я получаю:

$ strptime -T '%Y-%m-%dT%H:%M:%S %Z' 2011-09-08T21:00:00PDT
1315540800 = 2011-09-08T21:00:00PDT
$ timestamp 1315540800
1315540800 = Thu Sep 08 21:00:00 2011
$ timestamp -u 1315540800
1315540800 = Fri Sep 09 04:00:00 2011
$ strptime -T '%Y-%m-%dT%H:%M:%S %Z' 2011-09-08T21:00:00GMT
1315515600 = 2011-09-08T21:00:00GMT
$ timestamp 1315515600
1315515600 = Thu Sep 08 14:00:00 2011
$ timestamp -T '%Y-%m-%dT%H:%M:%S %z' 1315515600
1315515600 = 2011-09-08T14:00:00 -0700
$

Я нахожусь в США / Тихоокеанском регионе (или в Америке / Лос-Анджелесе, или по тихоокеанскому летнему времени; UTC-07: 00), поэтому эти команды показывают, что (как указано на странице руководства) strptime() распознает PDT и GMT и дает соответствующие ответы для каждого. Параметр -u для timestamp указывает «печатать время UTC (или GMT)», а не местное время. И 9 часов вечера в UTC - это действительно 2 часа дня в PDT.

Свяжитесь со мной, если вам нужен источник - смотрите мой профиль.

...