locale/doc/html/dates_times_timezones.html
2015-10-18 17:31:48 +03:00

187 lines
17 KiB
HTML

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.8.6"/>
<title>Boost.Locale: Working with dates, times, timezones and calendars.</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="navtree.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="resize.js"></script>
<script type="text/javascript" src="navtree.js"></script>
<script type="text/javascript">
$(document).ready(initResizable);
$(window).load(resizeHeight);
</script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr style="height: 56px;">
<td id="projectlogo"><img alt="Logo" src="boost-small.png"/></td>
<td style="padding-left: 0.5em;">
<div id="projectname">Boost.Locale
</div>
</td>
</tr>
</tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.8.6 -->
<div id="navrow1" class="tabs">
<ul class="tablist">
<li><a href="index.html"><span>Main&#160;Page</span></a></li>
<li class="current"><a href="pages.html"><span>Related&#160;Pages</span></a></li>
<li><a href="modules.html"><span>Modules</span></a></li>
<li><a href="namespaces.html"><span>Namespaces</span></a></li>
<li><a href="annotated.html"><span>Classes</span></a></li>
<li><a href="files.html"><span>Files</span></a></li>
<li><a href="examples.html"><span>Examples</span></a></li>
</ul>
</div>
</div><!-- top -->
<div id="side-nav" class="ui-resizable side-nav-resizable">
<div id="nav-tree">
<div id="nav-tree-contents">
<div id="nav-sync" class="sync"></div>
</div>
</div>
<div id="splitbar" style="-moz-user-select:none;"
class="ui-resizable-handle">
</div>
</div>
<script type="text/javascript">
$(document).ready(function(){initNavTree('dates_times_timezones.html','');});
</script>
<div id="doc-content">
<div class="header">
<div class="headertitle">
<div class="title">Working with dates, times, timezones and calendars. </div> </div>
</div><!--header-->
<div class="contents">
<div class="textblock"><h1><a class="anchor" id="dates_times_timezones_intro"></a>
Introduction</h1>
<p>There are several important flaws in the standard C, C++ and Boost libraries that handle dates and time:</p>
<ol type="1">
<li>The biggest flaw of most libraries that provide operations over dates is the fact that they only support the Gregorian calendar. <code>boost::date_time</code> , <code>std::tm</code> , and standard functions like <code>localtime</code> and <code>gmtime</code>, all assume the Gregorian calendar.</li>
<li>The information about local start of week is not provided. <br/>
For example the standard C and C++ library has <code>mktime</code> and <code>localtime</code>, but they do not give user the information about the first day of week. This information is locale dependent. It is Monday in France and it is Sunday in United States.</li>
</ol>
<p>Boost.Locale provides generic <a class="el" href="classboost_1_1locale_1_1date__time.html">date_time</a>, and <a class="el" href="classboost_1_1locale_1_1calendar.html">calendar</a> classes that allow you to perform operations on dates and times for non-Gregorian calendars such as Hebrew, Islamic, Japanese and others.</p>
<p><a class="el" href="using_localization_backends.html">Non-ICU based backends</a> support the Gregorian calendar only. Unlike <code>boost::date_time</code>, they are fully aware of the local first day of week. Thus, if the current day of week is Monday, then setting "current day of week" to Sunday would move the actual date 6 days forward in Russian or French locales and move one day backward in USA and Israeli locales.</p>
<h1><a class="anchor" id="dates_times_timezones_dt"></a>
Handling Dates and Time</h1>
<ul>
<li><a class="el" href="classboost_1_1locale_1_1calendar.html">boost::locale::calendar</a> &ndash; 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.</li>
<li><a class="el" href="classboost_1_1locale_1_1date__time.html">boost::locale::date_time</a> &ndash; represents a time point. It is constructed from a calendar and allows manipulation of various time periods.</li>
<li><a class="el" href="namespaceboost_1_1locale_1_1period.html">boost::locale::period</a> &ndash; holds a list of functions that represent various periods, such as month, year, day, and hour, allowing manipulation of dates and times. You can add periods, multiply them by integers, get or set them, or add them to <a class="el" href="classboost_1_1locale_1_1date__time.html">date_time</a> objects.</li>
</ul>
<p>For example:</p>
<div class="fragment"><div class="line"><span class="keyword">using namespace </span>boost::locale;</div>
<div class="line"><a class="code" href="classboost_1_1locale_1_1date__time.html">date_time</a> now; <span class="comment">// Create date_time class with default calendar initialized to current time</span></div>
<div class="line"><a class="code" href="classboost_1_1locale_1_1date__time.html">date_time</a> tomorrow = now + <a class="code" href="namespaceboost_1_1locale_1_1period.html#a72438d8d7da8493457e043aa442f0d9d">period::day</a>();</div>
<div class="line">cout &lt;&lt; <span class="stringliteral">&quot;Let&#39;s meet tomorrow at &quot;</span> &lt;&lt; <a class="code" href="group__manipulators.html#gae05b82e6658dc573521518fed5f5c77f">as::date</a> &lt;&lt; tomorrow &lt;&lt; endl;</div>
<div class="line"><a class="code" href="classboost_1_1locale_1_1date__time.html">date_time</a> some_point = <a class="code" href="namespaceboost_1_1locale_1_1period.html#a9ea8d1453bed512ee16bea3199fd92af">period::year</a>(1995) + <a class="code" href="namespaceboost_1_1locale_1_1period.html#a6073ebcf60bf690662c3a9d113b49e9b">period::january</a>() + <a class="code" href="namespaceboost_1_1locale_1_1period.html#a72438d8d7da8493457e043aa442f0d9d">period::day</a>(1);</div>
<div class="line"><span class="comment">// Set some_point&#39;s date to 1995-Jan-1.</span></div>
<div class="line">cout &lt;&lt; <span class="stringliteral">&quot;The &quot;</span>&lt;&lt; <a class="code" href="group__manipulators.html#gae05b82e6658dc573521518fed5f5c77f">as::date</a> &lt;&lt; some_point &lt;&lt; <span class="stringliteral">&quot; is the &quot;</span> </div>
<div class="line"> &lt;&lt; <a class="code" href="group__manipulators.html#ga50cc23779fd846809182e50345b4eb7c">as::ordinal</a> &lt;&lt; some_point / <a class="code" href="namespaceboost_1_1locale_1_1period.html#a57d6b8f97bd6604e13c6982ed0953678">period::day_of_week_local</a>() &lt;&lt; <span class="stringliteral">&quot; day of the week&quot;</span> &lt;&lt; endl;</div>
</div><!-- fragment --><p>You can calculate the difference between dates by dividing the difference by a period:</p>
<div class="fragment"><div class="line">date_time now;</div>
<div class="line">cout &lt;&lt; <span class="stringliteral">&quot; There are &quot;</span> &lt;&lt; (now + 2 * period::month() - now) / period::day() &lt;&lt; <span class="stringliteral">&quot; days &quot;</span></div>
<div class="line"> <span class="stringliteral">&quot;between &quot;</span> &lt;&lt; <a class="code" href="group__manipulators.html#gae05b82e6658dc573521518fed5f5c77f">as::date</a> &lt;&lt; now &lt;&lt; <span class="stringliteral">&quot; and &quot;</span> &lt;&lt; now + 2*period::month() &lt;&lt; endl;</div>
</div><!-- fragment --><p>You can also use different syntax (less operator overloading)</p>
<div class="fragment"><div class="line">date_time now;</div>
<div class="line">cout &lt;&lt; <span class="stringliteral">&quot; There are &quot;</span> &lt;&lt; period::day(now + period::month(2) - now) &lt;&lt; <span class="stringliteral">&quot; days &quot;</span></div>
<div class="line"> <span class="stringliteral">&quot;between &quot;</span> &lt;&lt; <a class="code" href="group__manipulators.html#gae05b82e6658dc573521518fed5f5c77f">as::date</a> &lt;&lt; now &lt;&lt; <span class="stringliteral">&quot; and &quot;</span> &lt;&lt; now + period::month(2) &lt;&lt; endl;</div>
</div><!-- fragment --><p><a class="el" href="classboost_1_1locale_1_1date__time.html">date_time</a> &ndash; provides the member functions <a class="el" href="classboost_1_1locale_1_1date__time.html#a3363a0c562300095432a17e472d2e52d">minimum</a> and <a class="el" href="classboost_1_1locale_1_1date__time.html#adb258ce11408b62bc0f14a60a05f0752">maximum</a> to get the information about smallest and largest possible values of a certain period for a specific time.</p>
<p>For example, for February the <code>maximum(period::day())</code> would be 28 (or 29 for a leap year), and for January it would be 31.</p>
<dl class="section note"><dt>Note</dt><dd>Be very careful with assumptions about calendars. For example, in the Hebrew calendar, the number of months is different for leap years and non-leap years.</dd></dl>
<p>We recommend you to look at the <code>calendar.cpp</code> example provided with this library to get an understanding of how to manipulate dates and times using these classes.</p>
<p>To convert between various calendar dates, you may get the current POSIX time via the <a class="el" href="classboost_1_1locale_1_1date__time.html#a17aa2b54462ebcf1860f8e4db9f7868e">time</a> member function.</p>
<p>For example:</p>
<div class="fragment"><div class="line"><span class="keyword">using namespace </span>boost::locale;</div>
<div class="line"><span class="keyword">using namespace </span>boost::locale::period;</div>
<div class="line"><a class="code" href="classboost_1_1locale_1_1generator.html">generator</a> gen;</div>
<div class="line"><span class="comment">// Create locales with Hebrew and Gregorian (default) calendars.</span></div>
<div class="line">std::locale l_hebrew=gen(<span class="stringliteral">&quot;en_US.UTF-8@calendar=hebrew&quot;</span>);</div>
<div class="line">std::locale l_gregorian=gen(<span class="stringliteral">&quot;en_US.UTF-8&quot;</span>);</div>
<div class="line"></div>
<div class="line"><span class="comment">// Create a Gregorian date from fields</span></div>
<div class="line"><a class="code" href="classboost_1_1locale_1_1date__time.html">date_time</a> greg(<a class="code" href="namespaceboost_1_1locale_1_1period.html#a9ea8d1453bed512ee16bea3199fd92af">year</a>(2010) + <a class="code" href="namespaceboost_1_1locale_1_1period.html#ab0610583a720120e8dcf90d0fe01cb01">february</a>() + <a class="code" href="namespaceboost_1_1locale_1_1period.html#a72438d8d7da8493457e043aa442f0d9d">day</a>(5),l_gregorian);</div>
<div class="line"><span class="comment">// Assign a time point taken from the Gregorian date to date_time with</span></div>
<div class="line"><span class="comment">// the Hebrew calendar</span></div>
<div class="line"><a class="code" href="classboost_1_1locale_1_1date__time.html">date_time</a> heb(greg.time(),l_hebrew);</div>
<div class="line"><span class="comment">// Now we can query the year.</span></div>
<div class="line">std::cout &lt;&lt; <span class="stringliteral">&quot;Hebrew year is &quot;</span> &lt;&lt; heb / <a class="code" href="namespaceboost_1_1locale_1_1period.html#a9ea8d1453bed512ee16bea3199fd92af">year</a> &lt;&lt; std::endl;</div>
</div><!-- fragment --><dl class="section note"><dt>Note</dt><dd></dd></dl>
<p>Non-ICU based backends support the same date-time range as <code>mktime</code> and <code>localtime</code> C library functions.</p>
<ul>
<li>Unix 32 bit: dates between 1901 and 2038</li>
<li>Unix 64 bit: dates from 1 BC</li>
<li>Windows: dates from 1970. If the <code>time_t</code> is 32 bits wide (mingw), then the upper limit is year 2038</li>
</ul>
<h1><a class="anchor" id="dates_times_timezones_tz"></a>
Time Zone</h1>
<p>The current operating system's time zone is used by default, however the time zone can be modified at several different levels:</p>
<ol type="1">
<li>Calendar level: you can specify a timezone when creating a new instance of <a class="el" href="classboost_1_1locale_1_1calendar.html">boost::locale::calendar</a> in its constructor.</li>
<li>iostream level: you can use <a class="el" href="group__manipulators.html#gad51fbdc634fe0c81e5183915e9eeb238">as::time_zone</a> manipulator to set a specific time zone to the iostream so all dates and times would be represented in this time zone</li>
<li>You can specify the default global time zone by calling: <a class="el" href="namespaceboost_1_1locale_1_1time__zone.html#aa5eb7b1d7d55c3069eebea3ab378ad99">boost::locale::time_zone::global(std::string const &amp;)</a>. This time zone would be the default one for newly created iostream object and calendar instances.</li>
</ol>
<dl class="section note"><dt>Note</dt><dd></dd></dl>
<p><a class="el" href="using_localization_backends.html">Non-ICU based backends</a> support only two kinds of time zones:</p>
<ol type="1">
<li>The current OS time zone, as it is handled by <code>localtime</code> and <code>mktime</code> the standard library functions - the default time zone</li>
<li>Simple time zone in format "GMT+HH:MM" - the time zone represented using fixed shift from the UTC without support of daylight saving time.</li>
</ol>
<h1><a class="anchor" id="dates_times_timezones_io"></a>
I/O Operations on date_time objects</h1>
<p>Writing a <a class="el" href="classboost_1_1locale_1_1date__time.html">date_time</a> is equivalent to:</p>
<ul>
<li>Applying <a class="el" href="group__manipulators.html#ga820edf843e20847a0c4ccb8da0c4acd8">as::datetime</a> manipulator on the stream</li>
<li>Writing POSIX time as number that is fetched by calling <a class="el" href="classboost_1_1locale_1_1date__time.html#a17aa2b54462ebcf1860f8e4db9f7868e">date_time::time()</a> function.</li>
<li>Reverting the manipulator effect back.</li>
</ul>
<p>For example this code:</p>
<div class="fragment"><div class="line"><span class="keyword">using namespace </span>boost::locale;</div>
<div class="line"><a class="code" href="classboost_1_1locale_1_1date__time.html">date_time</a> now;</div>
<div class="line">std::cout &lt;&lt; now &lt;&lt; std::endl;</div>
</div><!-- fragment --><p>Would print in the default format, something like:</p>
<pre class="fragment">2/3/2011 12:00 am
</pre><p>However if you need to change the default behavior (for example show only date), then you need to use specific iostream manipulator in order to display current date or time, it would override the default formatting.</p>
<p>For example</p>
<div class="fragment"><div class="line"><span class="keyword">using namespace </span>boost::locale;</div>
<div class="line"><a class="code" href="classboost_1_1locale_1_1date__time.html">date_time</a> now;</div>
<div class="line">std::cout &lt;&lt; <a class="code" href="group__manipulators.html#gae05b82e6658dc573521518fed5f5c77f">as::date</a> &lt;&lt; now &lt;&lt; std::endl;</div>
</div><!-- fragment --><p>Would print something like:</p>
<pre class="fragment">2/3/2011
</pre><p>This is important to remember that <code>date_time</code> object is always rendered and parsed in the context of the <code>iostream's</code> locale and time zone and not in the context of specific <code>date_time</code> object.</p>
<h1><a class="anchor" id="dates_times_timezones_qna"></a>
Questions and Answers</h1>
<p><b>Why should I use Boost.Locale over Boost.DateTime when I need Gregorian calendar only?</b></p>
<ul>
<li>Boost.DateTime is locale agnostic library and ignores the fact that the first day of week varies by the locale.</li>
<li>Boost.Locale provides a unified access to date and time in time zone aware way. It represents a time as universal scalar - the POSIX time and over that builds dates, local times and time-zones handling. <br/>
For example, <code>date_time(<a class="el" href="group__manipulators.html#gae669b101cbeaed6f6d246ebdcaa8f39c">some_time.time()</a> + 3600)</code> may be not equal to <code>some_time + hour()</code>, because of the daylight savings time.</li>
</ul>
<p><b>Why don't you use Boost.DateTime time zone support?</b></p>
<p>Boost.DateTime's time zone support is broken. Time zones can not be represented with a simple table of rules where daylight saving depend only on certain n'th day of week in month. The daylight savings time may vary by year, political issues and many other things.</p>
<p>Most of the modern operating systems (Linux, *BSD, Mac OS X, OpenVMS) and many important software packages (ICU, Java, Python) use so called Olson database in order to handle daylight saving time correctly.</p>
<p>If you need full time zone database support, then you should use ICU library. </p>
</div></div><!-- contents -->
</div><!-- doc-content -->
<li class="footer">
&copy; Copyright 2009-2012 Artyom Beilis, Distributed under the <a href="http://www.boost.org/LICENSE_1_0.txt">Boost Software License</a>, Version 1.0.
</li>
</ul>
</div>
</body>
</html>