Эквивалент strptime () в Windows? - PullRequest
37 голосов
/ 26 ноября 2008

Есть ли хорошая эквивалентная реализация strptime() для Windows? К сожалению, эта функция POSIX недоступна.

Описание открытой группы strptime - сводка: она преобразует текстовую строку, например "MM-DD-YYYY HH:MM:SS", в tm struct, противоположную strftime().

Ответы [ 5 ]

30 голосов
/ 29 июня 2010

Если вы не хотите переносить какой-либо код или осуждать ваш проект для повышения, вы можете сделать это:

  1. разобрать дату с помощью sscanf
  2. затем скопируйте целые числа в struct tm (вычтите 1 из месяца и 1900 из года - месяцы 0-11, а годы начинаются с 1900 года)
  3. наконец, используйте mktime, чтобы получить целое число эпохи UTC

Просто не забудьте установить для isdst члена struct tm значение -1, иначе у вас возникнут проблемы с переходом на летнее время.

20 голосов
/ 26 ноября 2008

Версию с открытым исходным кодом (лицензия 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);
15 голосов
/ 05 ноября 2015

Предполагая, что вы используете 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 напрямую не может быть вариантом.

14 голосов
/ 26 ноября 2008

Это делает работу:

#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

0 голосов
/ 06 марта 2015

Одной из альтернатив является использование 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);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...