#include <iostream>
#include <boost/date_time/gregorian/gregorian.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/date_time/local_time_adjustor.hpp>
using namespace std;
using namespace boost::gregorian;
using namespace boost::date_time;
using namespace boost::posix_time;
typedef local_adjustor<ptime, -5, us_dst> EasternTZ;
typedef local_adjustor<ptime, -7, no_dst> 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 содержит процедуры, выполняющие эти вычисления.
#include <iostream>
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;
}
