2016-05-05 3 views
1

У меня есть следующая функция для преобразования строки типа ISO в формат std::chrono::time_point с точностью до миллисекунды. Код всегда работал отлично в Linux, но теперь мне нужно преобразовать его в Windows.Преобразование времени ISO в std :: chrono :: time_point

Чтобы использовать тот же код, я скомпилировал его с флагом _WIN32 для Windows и изменил код strptime, который не поддерживается на VS2010, компилятор, который я использую.

В окнах он не преобразуется должным образом - для единственной строки времени evey введите следующий неверный результат. Я не могу узнать, что я делаю неправильно:

 std::chrono::time_point<std::chrono::system_clock> convertISOStringToTimePoint(std::string isoString) 
     { 
      struct tm timeDate; 

#ifdef _WIN32 
      timeDate.tm_year = std::stoi(isoString.substr(0, 4)); 
      timeDate.tm_mon = std::stoi(isoString.substr(5, 2)) - 1; 
      timeDate.tm_mday = std::stoi(isoString.substr(8, 2)); 
      timeDate.tm_hour = std::stoi(isoString.substr(11, 2)); 
      timeDate.tm_min = std::stoi(isoString.substr(14, 2)); 
      timeDate.tm_sec = std::stoi(isoString.substr(17, 2)); 
      timeDate.tm_isdst = -1; 
#else 
      strptime(isoString.c_str(), "%FT%TZ", &timeDate); 
#endif 
      time_t t = mktime(&timeDate); 

      std::chrono::time_point<std::chrono::system_clock> time; 
      time = std::chrono::system_clock::from_time_t(t); 

      auto timeMs = std::chrono::time_point_cast<std::chrono::milliseconds>(time); 

      int value = std::stoi(isoString.substr(20,3)); 

      timeMs += std::chrono::milliseconds(value); 

      return timeMs; 
     } 

оцененной помощи, чтобы узнать, как там происходит здесь ....

+1

Какой компилятор вы используете на окнах? – NathanOliver

+0

Вы расплывчаты. Представьте свой [MCVE]. –

+0

На окнах VS2010. – Mendes

ответ

0

I've нашел проблему и опубликовать решение:

struct tm основана на многолетнем с 1900 года, так что линия:

timeDate.tm_year = std::stoi(isoString.substr(0, 4));

должно быть:

timeDate.tm_year = std::stoi(isoString.substr(0, 4)) - 1900;

Также необходимо очистить struct tm перед использованием:

struct tm timeDate 
memset(&timeDate, 0, sizeof(timeDate)); 

Это решило проблему.

3

Поскольку mktime использует текущую локальную временную зону, мои психические навыки отладки сказать мне что временная метка ISO, которую вы указали, вероятно, находится в формате UTC, а не по местному времени.

Смежные вопросы