




Боюсь, что в Standard C / C++ их нет. Существует функция POSIX strptime, которая может преобразовывать в struct tm, который затем можно преобразовать в time_t с помощью mktime.
Если вы стремитесь к кросс-платформенной совместимости, лучше используйте boost::date_time, который имеет для этого сложные функции.
Используйте strptime() для анализа времени в struct tm, затем используйте mktime() для преобразования в time_t.
Не знаю, есть ли хорошая альтернатива для Windows, есть несколько реализаций с открытым исходным кодом, которые вы могли бы использовать. В качестве альтернативы, если вы знаете, что дата всегда будет в указанном вами формате, вы можете проанализировать ее в struct tm, возможно, используя sscanf, а затем использовать mktime для получения time_t.
вот пример stackoverflow.com/a/11213640/1115059
@ An̲̳̳drew strptime() часто доступен в Windows с компилятором gcc. Доступность - это проблема компилятора, а не ОС.
Библиотека даты и времени Boost должна помочь; в частности, вы можете посмотреть http://www.boost.org/doc/libs/1_37_0/doc/html/date_time/date_time_io.html
В отсутствие strptime вы можете использовать sscanf для синтаксического анализа данных в struct tm, а затем вызвать mktime. Не самое элегантное решение, но оно сработает.
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(...)
{
}
}
Обратите внимание, что strptime, упомянутый в принятом ответе, не переносится. Вот удобный код C++ 11, который я использую для преобразования строки в std :: time_t:
static std::time_t to_time_t(const std::string& str, bool is_dst = false, const std::string& format = "%Y-%b-%d %H:%M:%S")
{
std::tm t = {0};
t.tm_isdst = is_dst ? 1 : 0;
std::istringstream ss(str);
ss >> std::get_time(&t, format.c_str());
return mktime(&t);
}
Вы можете назвать это так:
std::time_t t = to_time_t("2018-February-12 23:12:34");
Вы можете найти параметры формата строки здесь.
1) Код не устанавливает член tm_isdst. Несоблюдение этого правила может привести к противоречивым результатам. 2) struct tm допускает добавление дополнительных членов, которые выигрывают при инициализации. Может, std::tm t = { 0 };? 3) Строка месяца OP является числовой, а не буквенной. Используйте "%m", а не "%b". 4) OP использовал другой порядок, чем YMD hms.
Я добавил опцию dst. Инициализация с 0 - хорошая идея. Остальное можно легко настроить в соответствии с индивидуальными требованиями.
best way to convert a date string, formatted as "MM-DD-YY HH:MM:SS", to a time_t
Ограничение кода стандартными функциями библиотеки C ищет инверсию strftime(). Чтобы расширить общую идею @ Роб, используется 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;
}
Дополнительный код может использоваться для защиты только двухзначных частей временной метки, положительных значений, интервалов и т. д.
Примечание: предполагается, что «ММ-ДД-ГГ ЧЧ: ММ: СС» - это время местный.
Интересно, что я так и не нашел варианта использования %n, так как всегда использовал возвращаемое значение *scanf, чтобы гарантировать, что все аргументы были просканированы. Однако похоже, что %n (как вы его используете) делает это. и гарантирует, что после ожидаемой строки не будет лишних gumpf. В настоящее время я не часто узнаю что-то новое о C, так что спасибо :-)
@paxdiablo Спасибо. " %n", как правило, помогает обнаруживать любой требуемый конечный текст, чего не различает возвращаемое значение. Например. "%d xyz %n".
strptime (), похоже, недоступен в Windows. Есть ли хорошая альтернатива?