Strptime() в Windows?
Существует ли эквивалентная реализация strptime()
для Windows? К сожалению, эта функция POSIX недоступна.
Открыть групповое описание strptime - summary: он преобразует текстовую строку, такую как "MM-DD-YYYY HH:MM:SS"
, в tm struct
, противоположную strftime()
.
Ответы
Ответ 1
Версия с открытым исходным кодом (лицензия BSD) strptime()
можно найти здесь: http://cvsweb.netbsd.org/bsdweb.cgi/src/lib/libc/time/strptime.c?rev=HEAD
Вам нужно будет добавить следующее объявление:
char *strptime(const char * __restrict, const char * __restrict, struct tm * __restrict);
Ответ 2
Если вы не хотите передавать какой-либо код или осуждать проект, чтобы увеличить его, вы можете сделать это:
- проанализируйте дату, используя
sscanf
- затем скопируйте целые числа в
struct tm
(вычесть 1 из месяца и 1900 из года в месяц - 0-11 и годы начинаются в 1900 году).
- наконец, используйте
mktime
, чтобы получить целое число эпохи UTC
Не забудьте установить член isdst
struct tm
в -1, иначе у вас будут проблемы с летним временем.
Ответ 3
Это задание:
#include "stdafx.h"
#include "boost/date_time/posix_time/posix_time.hpp"
using namespace boost::posix_time;
int _tmain(int argc, _TCHAR* argv[])
{
std::string ts("2002-01-20 23:59:59.000");
ptime t(time_from_string(ts));
tm pt_tm = to_tm( t );
Обратите внимание, что входная строка YYYY-MM-DD
Ответ 4
Предполагая, что вы используете Visual Studio 2015 или выше, вы можете использовать это как замену для strptime:
#include <time.h>
#include <iomanip>
#include <sstream>
extern "C" char* strptime(const char* s,
const char* f,
struct tm* tm) {
// Isn't the C++ standard lib nice? std::get_time is defined such that its
// format parameters are the exact same as strptime. Of course, we have to
// create a string stream first, and imbue it with the current C locale, and
// we also have to make sure we return the right things if it fails, or
// if it succeeds, but this is still far simpler an implementation than any
// of the versions in any of the C standard libraries.
std::istringstream input(s);
input.imbue(std::locale(setlocale(LC_ALL, nullptr)));
input >> std::get_time(tm, f);
if (input.fail()) {
return nullptr;
}
return (char*)(s + input.tellg());
}
Просто имейте в виду, что для кросс-платформенных приложений std::get_time
не был реализован до GCC 5.1, поэтому напрямую переключиться на вызов std::get_time
не может быть.
Ответ 5
Один из вариантов - использовать GetSystemTime
и отправить информацию о времени функции, которая анализирует ее в соответствии с вашим форматом, используя vsnprintf_s
. в
пример ниже есть одна функция, которая создает временную строку с миллисекундой
точность. Затем он отправляет строку в функцию, которая форматирует ее в соответствии с требуемым форматом:
#include <string>
#include <cstdio>
#include <cstdarg>
#include <atlstr.h>
std::string FormatToISO8601 (const std::string FmtS, ...) {
CStringA BufferString;
try {
va_list VaList;
va_start (VaList, FmtS);
BufferString.FormatV (FmtS.c_str(), VaList);
} catch (...) {}
return std::string (BufferString);
}
void CreateISO8601String () {
SYSTEMTIME st;
GetSystemTime(&st);
std::string MyISO8601String = FormatToISO8601 ("%4u-%02u-%02uT%02u:%02u:%02u.%03u", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
}