• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1//
2//  Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
3//
4//  Distributed under the Boost Software License, Version 1.0. (See
5//  accompanying file LICENSE_1_0.txt or copy at
6//  http://www.boost.org/LICENSE_1_0.txt)
7//
8
9// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4 filetype=cpp.doxygen
10/*!
11\page dates_times_timezones Working with dates, times, timezones and calendars.
12
13\section dates_times_timezones_intro Introduction
14
15There are several important flaws in the standard C, C++ and Boost libraries that handle dates and time:
16
17-#  The biggest flaw of most libraries that provide operations over dates is the fact that they only support
18    the Gregorian calendar. \c boost::date_time , \c std::tm , and standard functions like \c localtime and \c gmtime,
19    all assume the Gregorian calendar.
20-#  The information about local start of week is not provided.
21    \n
22    For example the standard C and C++ library has \c mktime and \c localtime, but they do not give
23    user the information about the first day of week. This information is locale dependent.
24    It is Monday in France and it is Sunday in United States.
25
26Boost.Locale provides generic \ref boost::locale::date_time "date_time", and \ref boost::locale::calendar "calendar" classes
27that allow you to perform operations on dates and times for non-Gregorian calendars such as Hebrew, Islamic, Japanese and others.
28
29\ref using_localization_backends "Non-ICU based backends" support the Gregorian calendar only.
30Unlike \c boost::date_time, they are fully aware of the local first day of week. Thus,
31if the current day of week is Monday, then setting "current day of week" to Sunday would move the actual date 6 days
32forward in Russian or French locales and move one day backward in USA and Israeli locales.
33
34\section dates_times_timezones_dt Handling Dates and Time
35
36- \ref boost::locale::calendar -- represents generic information about the calendar, independent from a specific time point. For example, you can get the maximum number of days in a month for a specific calendar.
37- \ref boost::locale::date_time  -- represents a time point. It is constructed from a calendar and allows manipulation of various time periods.
38- \ref boost::locale::period -- holds a list of functions that represent various periods, such as month, year, day, and hour, allowing
39manipulation of dates and times. You can add periods, multiply them by integers, get or set them, or add them to
40\ref boost::locale::date_time "date_time" objects.
41
42
43For example:
44
45\code
46    using namespace boost::locale;
47    date_time now; // Create date_time class with default calendar initialized to current time
48    date_time tomorrow = now + period::day();
49    cout << "Let's meet tomorrow at " << as::date << tomorrow << endl;
50    date_time some_point = period::year(1995) + period::january() + period::day(1);
51    // Set some_point's date to 1995-Jan-1.
52    cout << "The "<< as::date << some_point << " is the "
53        << as::ordinal << some_point / period::day_of_week_local() << " day of the week"  << endl;
54\endcode
55
56You can calculate the difference between dates by dividing the difference by a period:
57
58\code
59    date_time now;
60    cout << " There are " << (now + 2 * period::month() - now) / period::day() << " days "
61            "between " << as::date << now << " and " << now + 2*period::month() << endl;
62\endcode
63
64You can also use different syntax (less operator overloading)
65
66\code
67    date_time now;
68    cout << " There are " << period::day(now + period::month(2) - now) << " days "
69            "between " << as::date << now << " and " << now + period::month(2) << endl;
70\endcode
71
72
73
74\ref boost::locale::date_time "date_time"  -- provides the member functions \ref boost::locale::date_time::minimum() "minimum" and
75\ref boost::locale::date_time::maximum() "maximum" to get the information about smallest and largest
76possible values of a certain period for a specific time.
77
78For example, for February the <tt>maximum(period::day())</tt> would be 28 (or 29 for a leap year), and for January it would be 31.
79
80\note Be very careful with assumptions about calendars. For example, in the Hebrew calendar, the
81number of months is different for leap years and non-leap years.
82
83We recommend you to look at the \c calendar.cpp example provided with this library to get an understanding of how
84to manipulate dates and times using these classes.
85
86To convert between various calendar dates, you may get the current POSIX time via the
87\ref boost::locale::date_time::time "time" member function.
88
89For example:
90
91\code
92    using namespace boost::locale;
93    using namespace boost::locale::period;
94    generator gen;
95    // Create locales with Hebrew and Gregorian (default) calendars.
96    std::locale l_hebrew=gen("en_US.UTF-8@calendar=hebrew");
97    std::locale l_gregorian=gen("en_US.UTF-8");
98
99    // Create a Gregorian date from fields
100    date_time greg(year(2010) + february() + day(5),l_gregorian);
101    // Assign a time point taken from the Gregorian date to date_time with
102    // the Hebrew calendar
103    date_time heb(greg.time(),l_hebrew);
104    // Now we can query the year.
105    std::cout << "Hebrew year is " << heb / year << std::endl;
106\endcode
107
108\note
109
110Non-ICU based backends support the same date-time range as \c mktime and \c localtime C library functions.
111
112- Unix 32 bit: dates between 1901 and 2038
113- Unix 64 bit: dates from 1 BC
114- Windows: dates from 1970. If the \c time_t is 32 bits wide (mingw), then the upper limit is year 2038
115
116\section dates_times_timezones_tz Time Zone
117
118The current operating system's time zone is used by default, however the time zone can be modified at
119several different levels:
120
121-#  Calendar level: you can specify a timezone when creating a new instance of \ref boost::locale::calendar
122    in its constructor.
123-#  iostream level: you can use \ref boost::locale::as::time_zone "as::time_zone" manipulator to set a specific
124    time zone to the iostream so all dates and times would be represented in this time zone
125-#  You can specify the default global time zone by calling: \ref boost::locale::time_zone::global(std::string const &).
126    This time zone would be the default one for newly created iostream object and calendar instances.
127
128\note
129
130\ref using_localization_backends "Non-ICU based backends" support only two kinds of time zones:
131
132-#  The current OS time zone, as it is handled by \c localtime and \c mktime the standard
133    library functions - the default time zone
134-#  Simple time zone in format "GMT+HH:MM" - the time zone represented using fixed shift from
135    the UTC without support of daylight saving time.
136
137
138\section dates_times_timezones_io I/O Operations on date_time objects
139
140Writing a \ref boost::locale::date_time "date_time" is equivalent
141to:
142
143-   Applying \ref boost::locale::as::datetime "as::datetime" manipulator on the stream
144-   Writing POSIX time as number that is fetched by calling \ref boost::locale::date_time::time()
145    "date_time::time()" function.
146-   Reverting the manipulator effect back.
147
148For example this code:
149
150\code
151using namespace boost::locale;
152date_time now;
153std::cout << now << std::endl;
154\endcode
155
156Would print in the default format, something like:
157
158\verbatim
1592/3/2011 12:00 am
160\endverbatim
161
162However if you need to change the default behavior (for example show only date),
163then you need to use specific iostream manipulator in order to display current date or time,
164it would override the default formatting.
165
166For example
167
168\code
169using namespace boost::locale;
170date_time now;
171std::cout << as::date << now << std::endl;
172\endcode
173
174Would print something like:
175
176\verbatim
1772/3/2011
178\endverbatim
179
180This is important to remember that \c date_time object is always rendered and parsed in the context
181of the \c iostream's locale and time zone and not in the context of specific \c date_time object.
182
183\section dates_times_timezones_qna Questions and Answers
184
185
186<b>Why should I use Boost.Locale over Boost.DateTime when I need Gregorian calendar only?</b>
187
188-   Boost.DateTime is locale agnostic library and ignores the fact that the first day of week
189    varies by the locale.
190-   Boost.Locale provides a unified access to date and time in time zone aware way.
191    It represents a time as universal scalar - the POSIX time and over that builds dates,
192    local times and time-zones handling.
193    \n
194    For example, <tt>date_time(some_time.time() + 3600)</tt> may be not equal to
195    <tt>some_time + hour()</tt>, because of the daylight savings time.
196
197<b>Why don't you use Boost.DateTime time zone support?</b>
198
199Boost.DateTime's time zone support is broken. Time zones can not be represented with
200a simple table of rules where daylight saving depend only on certain n'th day of week in month.
201The daylight savings time may vary by year, political issues and many other things.
202
203Most of the modern operating systems (Linux, *BSD, Mac OS X, OpenVMS) and many important software packages
204(ICU, Java, Python) use so called Olson database in order to handle daylight saving time
205correctly.
206
207If you need full time zone database support, then you should use ICU library.
208
209*/
210
211
212