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

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

> return s.str();

>}


>tm now() {

> time_t now = time(0);

> return *localtime(&now);

>}


>int main() {

> try {

>  string s = dateTimeToString(now(), "%A %B, %d %Y %I:%M%p");

>  cout << s << endl;

>  s = dateTimeToString(now(), "%Y-%m-%d %H:%M:%S);

>  cout << s << endl;

> } catch(...) {

>  cerr << "невозможно отформатировать дату и время" << endl;

>  return EXIT FAILURE.

> }

> return EXIT_SUCCESS;

>}

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

>Sunday July, 24 2005 05:48PM 2005-07-24 17:48:11

Обсуждение

Метод >put из >time_put использует спецификатор форматирования строки, аналогичный строке формата функции С >printf. Символы строки формата выводятся в выходной буфер по мере их появления при условии, что им не предшествует символ >%. Символ, перед которым стоит >%, — это спецификатор формата, который имеет специальное значение, приведенное в табл. 5.1. Спецификаторы формата также поддерживают модификаторы, такие как целое число, указывающее длину поля, как в >%4B.


Tабл. 5.1. Спецификаторы формата даты/времени

СпецификаторОписание
>aСокращенное название дня недели (например, Mon (пн))
>AПолное название дня недели (например, Monday (понедельник))
>bСокращенное название месяца (например, Dec (дек))
>BПолное название месяца (например, May (май))
>cПолные дата и время
>dДень месяца (01-31)
>HЧас (00-23)
>IЧас (01-12)
>jДень года (001-366)
>mМесяц (01-12)
>MМинуты (00-59)
>pПризнак AM/PM
>SСекунды, включая до двух секунд координации
>UНомер недели (00-53), причем неделя 1 начинается в первое воскресенье
>wДень недели (0-6), где 0 — это воскресенье
>WНомер недели (00-53), причем неделя 1 начинается в первый понедельник
>xДата в формате MM/DD/YY
>XВремя в формате HH/MM/SS и 24-часовыми часами
>yГод текущего столетия (00-99)
>YГод
>ZСокращение временной зоны (часового пояса), или пустая строка, если зона неизвестна

Библиотека Boost date_time, обсуждаемая в дальнейших рецептах, не содержит возможностей форматирования, предлагаемых >time_put. Для удобства пример 5.5 содержит несколько процедур, преобразующих классы даты/времени Boost в формат структуры >tm, так что вы можете использовать процедуры >time_put.

Пример 5.5. Преобразование из классов даты/времени Boost в структуру tm

>using boost::gregorian;

>using boost::posix_time;


>void dateToTmAux(const date& src, tm& dest) {

> dest.tm_mday = src.day();

> dest tm_year = src.year() - 1900;

> dest.tm_mon = src.month() - 1;

>}


>void ptimeToTmAux(const ptime& src, tm& dest) {

> dest.tm_sec = src.seconds();

> dest.tm_min = st.minutes();

> dest.tm_hour = src.hours();

> dateToTmAux(src.date(), dest);

>}


>tm ptimeToTm(const ptime& t) {

> tm ret = tm();

> ptimeToTmAux(t.ret);

> return ret;

>}

Смотри также

Рецепт 13.3.

5.3. Выполнение вычислений с датами и временем

Проблема

Требуется узнать количество времени, прошедшего между двумя точками даты/времени.

Решение

Если обе временные точки находятся между 1970 и 2038 годами, то используйте тип >time_t и функцию >difftime, определенную в заголовочном файле >. Пример 5.6 показывает, как вычислить число дней, прошедших между двумя датами.

Пример 5.6. Вычисление даты и времени в формате time_t

>#include

>#include

>#include


>using namespace std;


>time_t dateToTimeT(int month, int day, int year) {

> // 5 января 2000 года передается как (1, 5, 2000)

> tm tmp = tm();

> tmp.tm_mday = day;

> tmp.tm_mon = month - 1;

> tmp.tm_year = year - 1900;

> return mktime(&tmp);

>}


>time_t badTime() {

> return time_t(-1);

>}


>time_t now() {

> return time(0);

>}


>int main() {

> time_t date1 = dateToTimeT(1,1,2000);

> time_t date2 = dateToTimeT(1,1,2001);

> if ((date1 == badTime()) || (date2 == badTime())) {

>  cerr << "невозможно создать структуру time_t" << endl;

>  return EXIT_FAILURE;

> }

> double sec = difftime(date2, date1);

> long days = static_cast(sec / (60 * 60 — 24));

> cout << число дней между 1 января 2000 г. и 1 января 2001 г. составляет ";

> cout << days << endl;

> return EXIT_SUCCESS;

>}

Программа из примера 5.6 должна вывести:

>число дней между 1 января 2000 г. и 1 января 2001 г. составляет 366

Обратите внимание, что 2000 год високосный, так как, несмотря на то что он делится на 100, он также делится и на 400 и, следовательно, состоит из 366 дней.

Обсуждение

Тип >time_t — это зависящий от реализации арифметический тип. Это означает, что это либо целый тип, либо тип с плавающей точкой, и, таким образом, он поддерживает основные арифметические операции. Его можно складывать, вычитать, делить, умножать и т.д. Чтобы вычислить интервал между двумя значениями >time_t в секундах, используйте функцию >difftime. Не думайте, что сам >time_t содержит секунды, даже если это и так. Многие реализации C++ могут в ближайшем будущем молча изменить его так, чтобы он содержал доли секунд (это одна из причин, по которым >difftime возвращает >double).

Если ограничения >time_t слишком жестки, то вместо него для вычисления временных интервалов потребуется использовать различные классы из библиотеки Boost >date_time. Пример 5.7 показывает, как использовать классы Boost для вычисления числа дней в 20-м и 21-м столетиях.

Пример 5.7. Вычисление даты и времени с помощью date_duration


Рекомендуем почитать
Изучаем 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-проектами. Программист подобен кошке, которая гуляет сама по себе. Так уж исторически сложилось. Именно поэтому так непросто быть руководителем команды разработчиков. Даже если вы еще месяц назад были блестящим и дисциплинированным программистом и вдруг оказались в роли менеджера, вряд ли вы знаете, с чего надо начать, какой выбрать стиль руководства, как нанимать и увольнять сотрудников, проводить совещания, добиваться своевременного выполнения задач.