C++. Сборник рецептов - [78]

Шрифт
Интервал

Високосные годы предназначены для компенсации несинхронности вращения Земли вокруг Солнца и продолжительности дня. Другими словами, частное отделения продолжительности солнечного года на длительность дня — это не целое число. В результате если календарь не корректировать, то мы получим смещение сезонов, когда равноденствия и солнцестояния (которые определяют сезоны) будут все более и более рассинхронизированы с каждым новым годом.

Решение

Вызовите функцию >time из заголовочного файла >, передав в качестве параметра значение 0. Результатом будет значение типа >time_t. Для преобразования значения >time_t в структуру >tm, представляющую текущее время UTC (также известное как Greenwich Mean Time (время по Гринвичу), или GMT), используется функция >gmtime, а для преобразования значения >time_t в структуру >tm, представляющую локальное время, используется функция >localtime. Программа в примере 5.1 получает текущие дату/время, а затем преобразует их в локальное время и выводит на экран. Затем программа преобразует текущие дату/время во время/дату UTC и также выводит результат на экран.

Пример 5.1. Получение локального времени и времени UTC

>#include

>#include

>#include


>using namespace std;


>int main() {

> // Текущие дата/время используемой системы

> time_t now = time(0);

> // Преобразуем в структуру tm для локальной временной зоны

> tm* localtm = localtime(&now);

> cout << "Локальные дата и время. " << asctime(localtm) << endl;

> // Преобразуем в структуру tm для UTC

> tm* gmtm = gmtime(&now);

> if (gmtm ! = NULL) {

>  cout << "Дата и время UTC: " << asctime(gmtm) << endl;

> } else {

>  cerr << "Невозможно получить дату и время UTC" << endl;

>  return EXIT_FAILURE;

> }

>}

Обсуждение

Функция >time возвращает тип >time_t, который является зависящим от реализации арифметическим типом, представляющим временной период (интервал времени) с точностью до одной секунды. Наибольший интервал времени, который можно представить с помощью >time_t, сохранив совместимость и переносимость кода, — это 2 147 483 648 секунд, или примерно 68 лет.

Вызов >time(0) возвращает >time_t, представляющее временной интервал от зависящего от реализации начала отсчета (обычно 0:00:00 1 января 1970 года) до текущего момента.

Ошибка 2038 года

Так как >time_t может представлять интервалы времени длиной в 68 лет, а многие реализации для представления текущего времени в качестве начала отсчета используют 1970 год, в большинстве популярных реализаций C++ невозможно представлять даты и времена после 2038 года. Это означает, что если программисты не предпримут мер предосторожности, то в 2038 году большая часть программного обеспечения перестанет работать.

Наиболее удобное представление текущих даты и времени можно получить, преобразовав их с помощью функций >localtime или >gmtime в структуру >tm. Структура >tm содержит целочисленные поля, показанные в примере 5.2.

Пример 5.2. Содержимое структуры tm

>struct tm {

> int tm_sec;   // секунды в минуте от 0 до 61 (60 и 61 для секунд координации)

> int tm_min;   // минуты в часе от 0 до 59

> int tm_hour;  // часы в сутках от 0 до 23

> int tm_mday;  // день месяца от 0 до 31

> int tm_mon;   // месяц года от 0 до 11

> int tm_year;  // год после 1900

> int tm_wday;  // дней после воскресенья

> int tm_yday;  // дней после 1-го января

> int tm_isdst; // часы летнего времени

>};

При использовании функции >gmtime не забудьте проверить ее возвращаемое значение. Если компьютер, на котором выполняется код, не имеет определенной локальной временной зоны (часового пояса), функция >gmtime не сможет вычислить время UTC и вернет 0. Если передать 0 в функцию >asctime, то результатом будет неопределенное поведение.

Функции >localtime, >gmtime и >asctime возвращают указатели на статически размещенные в памяти объекты. Это более эффективно для библиотеки, не означает, что последующие вызовы будут изменять значение этих объектов. Код в примере 5.3 показывает, как это может привести к неожиданным эффектам.

Пример 5.3. Подводные камни использования asctime

>void f() {

> char* x = asctime(localtime(time(0)));

> wait_for_15_seconds(); // выполняет длительную задачу обработки

> asctime(localtime(time(0)));

> cout << x << endl; // печатает текущее время, а не то что 15 секунд назад.

>}

5.2. Форматирование даты/времени в виде строки

Проблема

Требуется преобразовать дату и/или время в строковый формат

Решение

Используйте шаблон класса >time_put из заголовочного файла >, как показано в примере 5.4.

Пример 5.4. Форматирование строки даты/времени

>#include

>#include

>#include

>#include

>#include

>#include

>#include

>#include


>using namespace std;


>ostream& formatDateTime(ostream& out, const tm& t, const char* fmt) {

> const time_put& dateWriter = use_facet >(out.getloc());

> int n = strlen(fmt);

> if (dateWriter.put(out, out, ' ', &t, fmt, fmt + n).failed()) {

>  throw runtime_error("невозможно отформатировать дату и время");

> }

> return out;

>}


>string dateTimeToString(const tm& t, const char* format) {

> stringstream s;

> formatDateTime(s, t.format);


Рекомендуем почитать
Изучаем Java EE 7

Java Enterprise Edition (Java EE) остается одной из ведущих технологий и платформ на основе Java. Данная книга представляет собой логичное пошаговое руководство, в котором подробно описаны многие спецификации и эталонные реализации Java EE 7. Работа с ними продемонстрирована на практических примерах. В этом фундаментальном издании также используется новейшая версия инструмента GlassFish, предназначенного для развертывания и администрирования примеров кода. Книга написана ведущим специалистом по обработке запросов на спецификацию Java EE, членом наблюдательного совета организации Java Community Process (JCP)


Pro Git

Разработчику часто требуется много сторонних инструментов, чтобы создавать и поддерживать проект. Система Git — один из таких инструментов и используется для контроля промежуточных версий вашего приложения, позволяя вам исправлять ошибки, откатывать к старой версии, разрабатывать проект в команде и сливать его потом. В книге вы узнаете об основах работы с Git: установка, ключевые команды, gitHub и многое другое.В книге рассматриваются следующие темы:основы Git;ветвление в Git;Git на сервере;распределённый Git;GitHub;инструменты Git;настройка Git;Git и другие системы контроля версий.


Java 7

Рассмотрено все необходимое для разработки, компиляции, отладки и запуска приложений Java. Изложены практические приемы использования как традиционных, так и новейших конструкций объектно-ориентированного языка Java, графической библиотеки классов Swing, расширенной библиотеки Java 2D, работа со звуком, печать, способы русификации программ. Приведено полное описание нововведений Java SE 7: двоичная запись чисел, строковые варианты разветвлений, "ромбовидный оператор", NIO2, новые средства многопоточности и др.


Фундаментальные алгоритмы и структуры данных в Delphi

Книга "Фундаментальные алгоритмы и структуры данных в Delphi" представляет собой уникальное учебное и справочное пособие по наиболее распространенным алгоритмам манипулирования данными, которые зарекомендовали себя как надежные и проверенные многими поколениями программистов. По данным журнала "Delphi Informant" за 2002 год, эта книга была признана сообществом разработчиков прикладных приложений на Delphi как «самая лучшая книга по практическому применению всех версий Delphi».В книге подробно рассматриваются базовые понятия алгоритмов и основополагающие структуры данных, алгоритмы сортировки, поиска, хеширования, синтаксического разбора, сжатия данных, а также многие другие темы, тесно связанные с прикладным программированием.


Питон — модули, пакеты, классы, экземпляры

Python - объектно-ориентированный язык сверхвысокого уровня. Python, в отличии от Java, не требует исключительно объектной ориентированности, но классы в Python так просто изучить и так удобно использовать, что даже новые и неискушенные пользователи быстро переходят на ОО-подход.


Как пасти котов. Наставление для программистов, руководящих другими программистами

«Как пасти котов» – это книга о лидерстве и руководстве, о том, как первое совмещать со вторым. Это, если хотите, словарь трудных случаев управления IT-проектами. Программист подобен кошке, которая гуляет сама по себе. Так уж исторически сложилось. Именно поэтому так непросто быть руководителем команды разработчиков. Даже если вы еще месяц назад были блестящим и дисциплинированным программистом и вдруг оказались в роли менеджера, вряд ли вы знаете, с чего надо начать, какой выбрать стиль руководства, как нанимать и увольнять сотрудников, проводить совещания, добиваться своевременного выполнения задач.