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

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

>#include

>#include


>using namespace std;

>using namespace boost::gregorian;


>int main() {

> date_duration dd = date(2000, 1, 1) - date(1900, 1, 1);

> cout << "Двадцатый век содержал " << dd.days() << " дней" << endl;

> dd = date(2100, 1, 1) - date(2000, 1, 1);

> cout << "Двадцать первый век будет содержать " <<

>  dd.days() << " дней" << endl;

>}

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

>Двадцатый век содержал 36 524 дней

>Двадцать первый век будет содержать 36 525 дней

5.4. Преобразование между часовыми поясами

Проблема

Требуется преобразовать текущее время из одного часового пояса в другой.

Решение

Чтобы выполнить преобразование между часовыми поясами, используйте процедуры преобразования часовых поясов из библиотеки Boost date_time. Пример 5.8 показывает, как, зная время в Нью-Йорке, определить время в Туксоне, Аризона.

Пример 5.8. Преобразование между часовыми поясами

>#include

>#include

>#include

>#include


>using namespace std;

>using namespace boost::gregorian;

>using namespace boost::date_time;

>using namespace boost::posix_time;


>typedef local_adjustor EasternTZ;

>typedef local_adjustor ArizonaTZ;


>ptime NYtoAZ(prime nytime) {

> ptime utctime = EasternTZ::local_to_utc(nytime);

> return ArizonaTZ::utc_to_local(utctime);

>}


>int main() {

> // May 1st 2004.

> boost::gregorian::date thedate(2004, 6, 1);

> ptime nytime(thedate, hours(19)); // 7 pm

> ptime aztime = NYtoAZ(nytime);

> cout << "1 мая 2004 г. когда было " << nytime.time_of_day().hours();

> cout << ":00 часов в Нью-Йорке, было " << aztime.time_of_day().hours();

> cout << ":00 часов в Аризоне" << endl;

>}

Программа из примера 5.8 выводит следующее.

>1 мая 2004 г., когда было 19:00 часов в Нью-Йорке, было 16:00 часов в Аризоне

Обсуждение

Преобразование часовых поясов в примере 5.8 выполняется в два шага. Вначале время преобразуется в UTC, а затем время в UTC преобразуется во второй часовой пояс. Заметьте, что часовые пояса в библиотеке Boost >date_time представлены как типы, использующие шаблон класса >local_adjustor. Каждый тип содержит функции преобразования, которые преобразуют из данного часового пояса в UTC (функция >local_tc_utс) и из UTC в данный часовой пояс (функция >utc_to_local).

5.5. Определение номера дня в году

Проблема

Требуется определить номер дня в году. Например, 1 января — это первый день в году, 5 февраля это 36-й день в году, и так далее. Но так как некоторые годы — високосные, то после 28 февраля указанный день может иметь не такой же номер, как и в другие годы.

Решение

Решение этой проблемы требует одновременного решения сразу нескольких проблем. Во-первых, требуется знать, сколько дней в каждом месяце, что в свою очередь требует определить, является ли год високосным. Пример 5.9 содержит процедуры, выполняющие эти вычисления.

Пример 5.9. Процедуры, определяющие номер дня в году

>#include


>using namespace std;


>enum MonthEnum {

> jan = 0, feb = 1, mar = 2, apr = 3, may = 4, jun = 5,

> jul = 6, aug = 7, sep = 8, oct = 9, nov = 10, dec = 11

>};


>bool isLeapYear(int y) {

> return (y % 4 == 0) && ((y % 100 != 0) || (y % 400 == 0));

>}


>const int arrayDaysInMonth[] = {

> 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31

>};


>int n;

>int arrayFirstOfMonth[] = {

> n = 0,

> n += arrayDaysInMonth[jan],

> n += arrayDaysInMonth[feb],

> n += arrayDaysInMonth[mar],

> n += arrayDaysInMonth[apr],

> n += arrayDaysInMonth[may],

> n += arrayDaysInMonth[jun],

> n += arrayDaysInMonth[jul],

> n += arrayDaysInMonth[aug],

> n += arrayDaysInMonth[sep],

> n += arrayDaysInMonth[::oct],

> n += arrayDaysInMonth[nov]

>};


>int daysInMonth(MonthEnum month, int year) {

> if (month == feb) {

>  return isLeapYear(year) ? 29 : 28;

> } else {

>  return arrayDaysInMonth[month];

> }

>}


>int firstOfMonth(MonthEnum month, int year) {

> return arrayFirstOfMonth[month] + isLeapYear(year);

>}


>int dayOfYear(MonthEnum month, int monthDay, int year) {

> return firstOfMonth(month, year) + monthDay - 1;

>}


>int main() {

> cout << "1 июля 1971 г. был " << dayOfYear(jul, 1, 1971);

> cout << днем года" << endl;

>}

Программа из примера 5.9 выводит следующее.

>1 июля 1971 г. был 181 днем года

Обсуждение

Код примера 5.9 довольно прост, но содержит набор полезных функций для работы с датами в високосных годах. Обратите внимание, что я отбросил подход, который я называю «задокументируй и молись», использованный в предыдущих рецептах. Под этим я подразумеваю, что месяцы больше не представляются индексами, вместо которых используются перечисления. Это значительно снижает вероятность программистской ошибки при передаче месяца в функцию в качестве ее аргумента.

Вычисление високосного года, показанное в примере 5.9, выполняется в соответствии с современным григорианским календарем. Каждый четвертый год — високосный, за исключением каждого сотого, если он не делится на 400 (т.е. 1896 год был високосным, 1900 не был, 2000 был, 2004 был, 2100 год не будет).

5.6. Определение ограниченных типов значений

Проблема

Требуются самопроверяющиеся типы числовых данных, представляющие числа в ограниченном диапазоне допустимых значений, гаком как часы в сутках или минуты в часе.


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