Работа с датой и временем на С++

      Комментарии к записи Работа с датой и временем на С++ отключены

Помечено: , , , ,

В этой теме 1 ответ, 2 участника, последнее обновление  Васильев Владимир Сергеевич 10 мес., 3 нед. назад.

  • Автор
    Сообщения
  • #2989

    questioner
    Участник

    Моя программа должна обрабатывать дату и время, мне нужно:

    1. получать текущую дату/время от операционной системы;
    2. вычислять разницу в днях/часах/секундах между двумя моментами времени;
    3. создавать объект для произвольного момента времени (например в файле или базе данных находится дата регистрации пользователя, которую должна обработать моя программа).

    Как решить эти задачи на С++?

  • #2990

    В стандарте С++11 появился набор классов для работы со временем, он позволяет больше чем старый модуль time.h и расположен в пространстве имен std::chrono. В нем определены классы для задания моментов времени (std::chrono::timepoint), интервалов времени (std::chrono::duration) и несколько видов часов:

    1. std::chrono::system_clock предназначен для получения данных от системных часов реального времени, моменты времени system_clock::time_point могут быть преобразованы в тип time_t с округлением до секунд при помощи метода system_clock::to_time_t(). Получить текущее время можно с помощью метода system_clock::now(). Недостатком системных часов является их нестабильность — системные часы могут быть подведены пользователем или процессом автоматической синхронизации с внешним сервером;
    2. std::chrono::steady_clock предоставляет возможность работы со стабильными системными часами. Эти часы возвращают не системное время (на них не влияет напрямую изменение системного времени). Эти часы оптимально подходят для замера времени выполнения фрагмента кода. Текущее время можно получить при помощи steady_clock::now();
    3. Класс std::chrono::high_resolution_clock позволяет работать с системными часами максимально высокого разрешения (как и для обычные системные часы, он не является стабильным, т.е. допускает подведение времени). При помощи метода high_resolution_clock::now() можно получить самое высокое разрешение из всех видов часов, входящих в библиотеку.

    Чтобы получить текущее время от операционной системы нужно использовать один из трех видов часов — вызвать у них метод now(), в результате будет получен объект типа timepoint. Чтобы вывести время на экран вы можете преобразовать его функцией to_time_t в тип time_t, а затем в строку при помощи функции ctime:

    #include <iostream>
    #include <chrono>
    
    int main() {
      auto current_time = std::chrono::system_clock::now();
      
      std::time_t current_time_t = std::chrono::system_clock::to_time_t(current_time);
      std::cout << "current time is: " << ctime(&current_time_t);
    }

    Обычно этого достаточно, при преобразовании в тип time_t момент времени округляется до секунд. Если же такое преобразование не выполняется, а лишь вычисляется разница двух моментов времени — можно работать даже с наносекундами — см. Пример с замером времени работы функции.

    Вы можете создавать моменты времени (chrono::timepoint), преобразованием из time_t, который в свою очередь проще создавать преобразованием из типа std::tm:

    #include <iostream>
    #include <chrono>
    using namespace std;
    
    int main() {
      // Create 7-8-2016 11:41:10 UTC as a std::tm
      std::tm timepoint_tm = {0};
      timepoint_tm.tm_sec = 10;
      timepoint_tm.tm_min = 41;
      timepoint_tm.tm_hour = 11;
      timepoint_tm.tm_mday = 7;
      timepoint_tm.tm_mon = 7;
      timepoint_tm.tm_year = 116;
      timepoint_tm.tm_isdst = -1;
    
      std::time_t timepoint_time_t_1 = timegm(&timepoint_tm);
      
      chrono::system_clock::time_point timepoint;
      timepoint = chrono::system_clock::from_time_t(timepoint_time_t_1);
      
      std::time_t timepoint_time_t_2 = std::chrono::system_clock::to_time_t(timepoint);
      std::cout << "time is: " << ctime(&timepoint_time_t_2);
    }

    Обратите внимание, что несмотря на то, что в структуре tm:

    • нумерация месяцев начинается с нуля (мы пишем седьмой месяц, хотя создаем август);
    • год задается как целое число лет, прошедших с 1900 года (пишем 116 вместо 2016);
    • поле tm_isdst отвечает за перевод времени на летнее и зимнее (пишем -1 если ничего про это не известно).

    chrono_create_date_time

    Таким образом, вы можете использовать std::chrono для хранения интервалов времени в своей программе, определения наиболее точного времени и замера времени со стабильными часами (без возможности их подведения пользователем), однако при вводе произвольного момента времени в программу или выводе времени на экран/файл наиболее удобным способом является использование структур time_t и std::tm.

Для ответа в этой теме необходимо авторизоваться.