Преобразование даты и времени: представление строки в time_t

Как преобразовать строку даты, отформатированную как "MM-DD-YY HH:MM:SS", в значение time_t в C или С++?

7 ответов

Используйте strptime() для разбора времени в struct tm, затем используйте mktime() для преобразования в time_t.


В отсутствие strptime вы можете использовать sscanf для анализа данных в struct tm, а затем вызвать mktime. Не самое элегантное решение, но оно будет работать.


Должна помогать библиотека времени времени увеличения; в частности, вы можете посмотреть http://www.boost.org/doc/libs/1_37_0/doc/html/date_time/date_time_io.html


Я боюсь, что в Standard C/С++ нет никого. Существует функция POSIX strptime, которая может преобразовываться в struct tm, которая затем может быть преобразована в time_t с помощью mktime.

Если вы нацелены на совместимость между платформами, лучше используйте boost::date_time, у которого есть сложные функции для этого.


лучший способ конвертировать строку даты, отформатированную как "MM-DD-YY HH: MM: SS", к time_t

Ограничение кода на стандартные функции библиотеки C ищет обратное значение strftime(). Чтобы расширить общую идею @Rob, используется sscanf().

Используйте "%n" для обнаружения завершенной проверки

time_t date_string_to_time(const char *date) {
 struct tm tm = { 0 }; // Important, initialize all members
 int n = 0;
 sscanf(date, "%d-%d-%d %d:%d:%d %n", &tm.tm_mon, &tm.tm_mday, &tm.tm_year,
 &tm.tm_hour, &tm.tm_min, &tm.tm_sec, &n);
 // If scan did not completely succeed or extra junk
 if (n == 0 || date[n]) {
 return (time_t) -1;
 }
 tm.tm_isdst = -1; // Assume local daylight setting per date/time
 tm.tm_mon--; // Months since January
 // Assume 2 digit year if in the range 2000-2099, else assume year as given
 if (tm.tm_year >= 0 && tm.tm_year < 100) {
 tm.tm_year += 2000;
 }
 tm.tm_year -= 1900; // Years since 1900
 time_t t = mktime(&tm);
 return t;
}

Дополнительный код может использоваться для обеспечения только двухзначных элементов временной метки, положительных значений, интервалов и т.д.

Примечание: это предполагает, что "MM-DD-YY HH: MM: SS" является местным временем.


Обратите внимание, что strptime, упомянутый в принятом ответе, не переносится. Здесь удобный код С++ 11, который я использую для преобразования строки в std:: time_t:

static std::time_t to_time_t(const std::string& str, const std::string& format = "%Y-%b-%d %H:%M:%S")
{
 std::tm t = {};
 std::istringstream(str) >> std::get_time(&t, format.c_str());
 return mktime(&t);
}

Вы можете называть это следующим образом:

std::time_t t = to_time_t("2018-February-12 23:12:34");

Здесь можно найти параметры формата строки здесь.


static time_t MKTimestamp(int year, int month, int day, int hour, int min, int sec)
{
 time_t rawtime;
 struct tm * timeinfo;
 time ( &rawtime );
 timeinfo = gmtime ( &rawtime );
 timeinfo->tm_year = year-1900 ;
 timeinfo->tm_mon = month-1;
 timeinfo->tm_mday = day;
 timeinfo->tm_hour = hour;
 timeinfo->tm_min = min;
 timeinfo->tm_sec = sec;
 timeinfo->tm_isdst = 0; // disable daylight saving time
 time_t ret = mktime ( timeinfo );
 return ret;
}
 static time_t GetDateTime(const std::string pstr)
{
 try 
 {
 // yyyy-mm-dd
 int m, d, y, h, min;
 std::istringstream istr (pstr);
 istr >> y;
 istr.ignore();
 istr >> m;
 istr.ignore();
 istr >> d;
 istr.ignore();
 istr >> h;
 istr.ignore();
 istr >> min;
 time_t t;
 t=MKTimestamp(y,m,d,h-1,min,0);
 return t;
 }
 catch(...)
 {
 }
}

licensed under cc by-sa 3.0 with attribution.