C++11 фактическое системное время с миллисекундами
У меня проблема с получением реального системного времени за миллисекунды. Единственный хороший метод, который я нашел в Windows.h
, но я не могу это использовать. Я должен использовать std::chrono
, Как я могу это сделать?
Я потратил много времени, пытаясь найти его в Google, но нашел только примеры второй точности.
Я пытаюсь получить строку, как это:
[2014-11-25 22:15:38:449]
4 ответа
Используя код из этого ответа:
#include <chrono>
#include <ctime>
#include <iostream>
template <typename Duration>
void print_time(tm t, Duration fraction) {
using namespace std::chrono;
std::printf("[%04u-%02u-%02u %02u:%02u:%02u.%03u]\n", t.tm_year + 1900,
t.tm_mon + 1, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec,
static_cast<unsigned>(fraction / milliseconds(1)));
// VS2013's library has a bug which may require you to replace
// "fraction / milliseconds(1)" with
// "duration_cast<milliseconds>(fraction).count()"
}
int main() {
using namespace std;
using namespace std::chrono;
system_clock::time_point now = system_clock::now();
system_clock::duration tp = now.time_since_epoch();
tp -= duration_cast<seconds>(tp);
time_t tt = system_clock::to_time_t(now);
print_time(*gmtime(&tt), tp);
print_time(*localtime(&tt), tp);
}
Следует иметь в виду, что тот факт, что таймер возвращает значения с точностью до миллисекунды, не обязательно указывает на то, что таймер имеет разрешение менее миллисекунды. Я думаю, что реализация Windows в VS2015, наконец, может быть исправлена, но таймер, который они использовали для поддержки своей хронологической реализации, до сих пор чувствителен к ОС timeBeginPeriod()
настройка, отображение с разным разрешением и настройка по умолчанию, я думаю, 16 миллисекунд.
Также приведенный выше код предполагает, что ни UTC, ни ваш местный часовой пояс не смещены относительно эпохи std::chrono::system_clock
дробным вторым значением.
Пример использования функций даты Говарда, чтобы избежать ctime: /questions/47670781/obyazatelno-li-gettimeofday-imeet-mikrosekundnoe-razreshenie/47670875#47670875
В этом ответе все еще используется немного API C, но он используется только в функции, поэтому вы можете забыть об этом:
template<typename T>
void print_time(std::chrono::time_point<T> time) {
using namespace std;
using namespace std::chrono;
time_t curr_time = T::to_time_t(time);
char sRep[100];
strftime(sRep,sizeof(sRep),"%Y-%m-%d %H:%M:%S",localtime(&curr_time));
typename T::duration since_epoch = time.time_since_epoch();
seconds s = duration_cast<seconds>(since_epoch);
since_epoch -= s;
milliseconds milli = duration_cast<milliseconds>(since_epoch);
cout << '[' << sRep << ":" << milli.count() << "]\n";
}
Это просто переписать код bames53, но использовать strftime, чтобы немного сократить код.
std::chrono
дать вам утилиты для представления момента времени или истекшей продолжительности между двумя моментами времени. Это позволяет получить информацию об этих временных интервалах.
Он не предоставляет никакой информации календаря. К сожалению, в настоящее время в стандарте C++ для них нет инструментов. boost::date_time
может быть полезно здесь.
Кто-нибудь заметил, что to_time_t округляет секунды вместо усечения
auto now = system_clock::now();
time_t secs = system_clock::to_time_t(now);
now {_MyDur={_MyRep=15107091978759765 } }
secs = 1510709198
поэтому, когда вы придерживаетесь миллисекунд
auto tse = now.time_since_epoch();
auto now_ms = duration_cast<milliseconds>(tse);
auto now_s = duration_cast<seconds>(tse);
auto jst_ms = now_ms - now_s;
DWORD msecs = jst_ms.count();
msecs = 875
секунд должно быть 1510709197, но посмотрите на now_s, это правильно
now_s {_MyRep=1510709197 }