самый быстрый способ получить time_t из строки YYYYMMDDHHMMSS
Вопрос
Это законно?Я пытаюсь получить time_t как можно быстрее, учитывая строку в формате ГГГГММДДЧЧММСС.
static time_t ConvertToSecSince1970(char *szYYYYMMDDHHMMSS)
{
struct tm Tm;
memset(&Tm, 0, sizeof(Tm));
Tm.tm_year = makeInt(szYYYYMMDDHHMMSS + 0, 4) - 1900;
Tm.tm_mon = makeInt(szYYYYMMDDHHMMSS + 4, 2) - 1;
Tm.tm_mday = makeInt(szYYYYMMDDHHMMSS + 6, 2);
Tm.tm_hour = makeInt(szYYYYMMDDHHMMSS + 8, 2);
Tm.tm_min = makeInt(szYYYYMMDDHHMMSS + 10, 2);
Tm.tm_sec = makeInt(szYYYYMMDDHHMMSS + 12, 2);
return mktime(&Tm);
}
Кажется, я дал бы тот же ответ, если бы я создал TM, используя:
strptime(szYYYYMMDDHHMMSS, "%Y%m%d%H%M%S", &Tm);
Меня беспокоит, что tm_yday, tm_wday, tm_isdst, tm_gmtoff, tm_zone важны.Мои даты указаны в формате UTC, поэтому я решил, что gmtoff = 0 и tm_zone = 0 могут подойти.
Кстати, вот makeInt:
inline int makeInt(const char *p, int size)
{
const char *endp;
int intval = 0;
endp = p + size;
while (p < endp)
{
intval = intval * 10 + *p - '0';
p++;
}
return intval;
}
Решение
mktime()
игнорирует tm_wday
и tm_yday
поля и вычисляет для них новые значения на основе других полей.То же самое относится и к расширениям BSD. tm_gmtoff
и tm_zone
, за исключением того, что они рассчитываются по местному часовому поясу.
Однако обратите внимание, что mktime()
использует местный время, а не UTC, поэтому, если вы вводите даты в формате UTC, тогда ваш часовой пояс должен быть установлен в UTC.
Другие советы
Вероятно, вам лучше использовать получить дату если только ты не конечно это слишком медленно.В противном случае то, что вы делаете, выглядит вполне нормально, если не немного загадочно.
Обработка даты и времени в целом имеет множество сложных моментов, поэтому я настоятельно рекомендую использовать strptime(), а не создавать свой собственный.Если производительность strptime() является узким местом, обойдите это каким-либо другим способом, а не пытайтесь создать лучший strptime(), например:
Ваша строка, как и time_t (как она обычно используется), дает только секундную точность, поэтому вы можете кэшировать преобразованное значение и обновлять его только один раз в секунду.
Прежде всего, не работайте с временными метками в строковой форме.Например.Вместо этого передайте значение time_t (содержащее секунды с момента начала эпохи, возвращенные time()) и преобразуйте его в строку только тогда, когда/если вам нужно его распечатать/показать пользователю/.