[boost] [datetime] IANA Time Zone Database

828 views
Skip to first unread message

Maxim Yegorushkin

unread,
Nov 8, 2012, 9:53:08 AM11/8/12
to bo...@lists.boost.org
Hi Boost,

I have files with timestamps in various timezones. I would like to be
able to convert these timestamps, no matter what timezone they are in (I
know the names of the timezones) to UTC timestamps.

I looked through datatime library documentation and found
date_time_zonespec.csv database which doesn't seem to support the notion
of different rules for the same timezone depending on the date. For
example, Russia used to have summer time but not any more. Another
method seems to be passing a timezone specification string manually,
which requires the user to figure what it should be for a particular date.

In other words, given a timestamp and its timezone, I would like to be
able to convert that timestamp into a UTC timestamp using conversion
rules in force at that particular date in the past. Ideally, this would
use IANA Time Zone Database or something similar. Is there a facility in
boost to do just that?

-- Maxim


_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Jeff Garland

unread,
Nov 8, 2012, 10:07:35 AM11/8/12
to bo...@lists.boost.org
On Thu, Nov 8, 2012 at 7:53 AM, Maxim Yegorushkin <
maxim.ye...@gmail.com> wrote:

> Hi Boost,
>
> I have files with timestamps in various timezones. I would like to be able
> to convert these timestamps, no matter what timezone they are in (I know
> the names of the timezones) to UTC timestamps.
>
> I looked through datatime library documentation and found
> date_time_zonespec.csv database which doesn't seem to support the notion of
> different rules for the same timezone depending on the date. For example,
> Russia used to have summer time but not any more. Another method seems to
> be passing a timezone specification string manually, which requires the
> user to figure what it should be for a particular date.
>
> In other words, given a timestamp and its timezone, I would like to be
> able to convert that timestamp into a UTC timestamp using conversion rules
> in force at that particular date in the past. Ideally, this would use IANA
> Time Zone Database or something similar. Is there a facility in boost to do
> just that?
>
>
Hi Maxim -

That would require an extension to date-time to handle -- all the
interfaces are there, but the machinery to lookup in a database that has
historical entries would need to be developed. Unfortunately it's not a
function that's been requested much and there isn't really a plan to
develop it...sorry.

Jeff

Artyom Beilis

unread,
Nov 8, 2012, 10:15:59 AM11/8/12
to bo...@lists.boost.org
You can use Boost.Locale that is compiled with ICU backend.

ICU supports Time Zone database and you can specify the timezone by its name, parse time or create

date_time object and get POSIX (UTC) time form it.

 
Artyom Beilis
--------------
CppCMS - C++ Web Framework:   http://cppcms.com/
CppDB - C++ SQL Connectivity: http://cppcms.com/sql/cppdb/



>________________________________
> From: Maxim Yegorushkin <maxim.ye...@gmail.com>
>To: bo...@lists.boost.org
>Sent: Thursday, November 8, 2012 4:53 PM
>Subject: [boost] [datetime] IANA Time Zone Database

Maxim Yegorushkin

unread,
Nov 8, 2012, 12:36:07 PM11/8/12
to bo...@lists.boost.org
On 08/11/12 15:15, Artyom Beilis wrote:
> You can use Boost.Locale that is compiled with ICU backend.
>
> ICU supports Time Zone database and you can specify the timezone by its name, parse time or create
>
> date_time object and get POSIX (UTC) time form it.
>
>
> Artyom Beilis
> --------------
> CppCMS - C++ Web Framework: http://cppcms.com/
> CppDB - C++ SQL Connectivity: http://cppcms.com/sql/cppdb/
>> ________________________________
>> From: Maxim Yegorushkin <maxim.ye...@gmail.com>
>> To: bo...@lists.boost.org
>> Sent: Thursday, November 8, 2012 4:53 PM
>> Subject: [boost] [datetime] IANA Time Zone Database
>>
>> Hi Boost,
>>
>> I have files with timestamps in various timezones. I would like to be able to convert these timestamps, no matter what timezone they are in (I know the names of the timezones) to UTC timestamps.
>>
>> I looked through datatime library documentation and found date_time_zonespec.csv database which doesn't seem to support the notion of different rules for the same timezone depending on the date. For example, Russia used to have summer time but not any more. Another method seems to be passing a timezone specification string manually, which requires the user to figure what it should be for a particular date.
>>
>> In other words, given a timestamp and its timezone, I would like to be able to convert that timestamp into a UTC timestamp using conversion rules in force at that particular date in the past. Ideally, this would use IANA Time Zone Database or something similar. Is there a facility in boost to do just that?

Oh, thanks Artyom.

That is quite a surprising place to find this functionality. Not sure
why it is not in datetime library.

Anyway, I managed to get a small test working:

#include <iostream>
#include <sstream>
#include <boost/locale.hpp>

int main() {
boost::locale::generator gen;
std::locale::global(gen("en_GB.UTF-8"));
std::cout.imbue(std::locale());

boost::locale::date_time d;
std::istringstream ss("8 Nov 2012 17:00:00");
ss >> boost::locale::as::time_zone("America/New_York") >> d;

std::cout << boost::locale::as::time_zone("UTC") << d << '\n';
// prints 8 Nov 2012 22:00:00
}

Thanks a lot!

Jeff Garland

unread,
Nov 8, 2012, 12:54:07 PM11/8/12
to bo...@lists.boost.org
On Thu, Nov 8, 2012 at 10:36 AM, Maxim Yegorushkin <
maxim.ye...@gmail.com> wrote:

>
> Oh, thanks Artyom.
>
> That is quite a surprising place to find this functionality. Not sure why
> it is not in datetime library.
>
> Anyway, I managed to get a small test working:
>
> #include <iostream>
> #include <sstream>
> #include <boost/locale.hpp>
>
> int main() {
> boost::locale::generator gen;
> std::locale::global(gen("en_**GB.UTF-8"));
> std::cout.imbue(std::locale())**;
>
> boost::locale::date_time d;
> std::istringstream ss("8 Nov 2012 17:00:00");
> ss >> boost::locale::as::time_zone("**America/New_York") >> d;
>
> std::cout << boost::locale::as::time_zone("**UTC") << d << '\n';
> // prints 8 Nov 2012 22:00:00
> }
>
> Thanks a lot!
>
>
> -- Maxim
>
>
Yes, surprising -- obviously I've been asleep b/c I was completely unaware
of this work...seems like we now have a lot of library duplication :-(

Joshua Boyce

unread,
Nov 8, 2012, 10:24:50 PM11/8/12
to bo...@lists.boost.org
The Boost.Locale docs explain why it it has its own date and time
functionality rather than using or building on for example Boost.DateTime:
http://www.boost.org/doc/libs/1_52_0/libs/locale/doc/html/dates_times_timezones.html

Markus Raab

unread,
Nov 9, 2012, 12:57:42 AM11/9/12
to bo...@lists.boost.org
Hi!

Artyom Beilis wrote:
> You can use Boost.Locale that is compiled with ICU backend.
>
> ICU supports Time Zone database and you can specify the timezone by its
> name, parse time or create
>
> date_time object and get POSIX (UTC) time form it.

On POSIX systems with tzdata installed Boost.Locale could also have this
feature without ICU. Any plans to do this?

best regards
Markus Raab

--
http://www.markus-raab.org | "Those who make peaceful revolution
-o) | impossible, will make violent revolution
Kernel 2.6.32-5-a /\ | inevitable." -- John F. Kennedy
on a x86_64 _\_v |

Maxim Yegorushkin

unread,
Nov 9, 2012, 5:22:23 AM11/9/12
to bo...@lists.boost.org
Thinking more about it, my local times are coming in as broken down time
representation (year, month, ...), so I won't be dealing with streams at
all.

Is there a way to do timezone conversions without using streams?
Something similar to pytz:

timezone paris("Europe/Paris"), utc("UTC");
date_time t(2012, 10, 9, 10, 19, 0); // no timezone associated
date_time utc_t(paris.localize(t).astimezone(utc));

?

Maxim Yegorushkin

unread,
Nov 9, 2012, 5:25:20 AM11/9/12
to bo...@lists.boost.org
On 09/11/12 05:57, Markus Raab wrote:

> Artyom Beilis wrote:
>> You can use Boost.Locale that is compiled with ICU backend.
>>
>> ICU supports Time Zone database and you can specify the timezone by its
>> name, parse time or create
>>
>> date_time object and get POSIX (UTC) time form it.
>
> On POSIX systems with tzdata installed Boost.Locale could also have this
> feature without ICU. Any plans to do this?

Not sure if it could, since there is no official API in C standard
library to do timezone conversions between arbitrary timezones and UTC.
Only between the local timezone and UTC.
http://sourceware.org/bugzilla/show_bug.cgi?id=11620

-- Maxim

Jeff Garland

unread,
Nov 9, 2012, 5:52:11 AM11/9/12
to bo...@lists.boost.org
On Thu, Nov 8, 2012 at 8:24 PM, Joshua Boyce
<raptor...@raptorfactor.com>wrote:

>
> The Boost.Locale docs explain why it it has its own date and time
> functionality rather than using or building on for example Boost.DateTime:
>
> http://www.boost.org/doc/libs/1_52_0/libs/locale/doc/html/dates_times_timezones.html
>
>
Thanks that's helpful. Unfortunately, I don't think some of the analysis
on this page is correct. Good that I see this now, though so that I can
work with Artyom and make sure this stuff is in date_time2 :-)

Jeff

Jeff Garland

unread,
Nov 9, 2012, 6:29:28 AM11/9/12
to bo...@lists.boost.org
On Fri, Nov 9, 2012 at 3:22 AM, Maxim Yegorushkin <
maxim.ye...@gmail.com> wrote:

>
> Thinking more about it, my local times are coming in as broken down time
> representation (year, month, ...), so I won't be dealing with streams at
> all.
>
> Is there a way to do timezone conversions without using streams? Something
> similar to pytz:
>
> timezone paris("Europe/Paris"), utc("UTC");
> date_time t(2012, 10, 9, 10, 19, 0); // no timezone associated
> date_time utc_t(paris.localize(t).**astimezone(utc));
>
>
> ?
>
>
You're probably asking about locale, but this you can do in date_time:

ptime pt(date(2004,Nov,5), hours(10));
time_zone_ptr zone(new posix_time_zone("MST-07"));
local_date_time az(pt, zone);
cout << az.utc_time() << endl; // 10am 2004-Nov-5
cout << az.local_time() << endl; // 3am 2004-Nov-5
time_zone_ptr nyc_zone = ... //get an nyc timezone
local_date_time nyc = az.local_time_in(nyc_zone);

In bdt the time_zone is abstract -- so you can build your own time
zone names and such in any fashion you like. What's needed to handle
all the historic cases correctly is a derivative of time_zone which has
the history and when asked to convert local to utc, adjusts
appropriately for the
relative time historically (effectively a list of offset rules).
There's an example and
code that creates custom timezone types. And lastly, you'd need to create some
code to parse the iana data and create the tz objects to lookup by
string...not a
huge amount of work. Certainly this should be out of the box
some day...

Rutger ter Borg

unread,
Nov 9, 2012, 6:56:15 AM11/9/12
to bo...@lists.boost.org

On 2012-11-09 12:29, Jeff Garland wrote:
>
> In bdt the time_zone is abstract -- so you can build your own time
> zone names and such in any fashion you like. What's needed to handle
> all the historic cases correctly is a derivative of time_zone which has
> the history and when asked to convert local to utc, adjusts
> appropriately for the
> relative time historically (effectively a list of offset rules).

Unfortunately, time_zone_base is not able to handle "any fashion you
like", e.g., the Olsen database. It assumes exactly 2 switches per year,
whereas there are cases that require 1 or 3 time zone changes in a
single year.

Cheers,

Rutger

Jeff Garland

unread,
Nov 9, 2012, 8:20:40 AM11/9/12
to bo...@lists.boost.org
On Fri, Nov 9, 2012 at 4:56 AM, Rutger ter Borg <rut...@terborg.net> wrote:

>
>
> Unfortunately, time_zone_base is not able to handle "any fashion you
> like", e.g., the Olsen database. It assumes exactly 2 switches per year,
> whereas there are cases that require 1 or 3 time zone changes in a single
> year.
>

Well maybe, although some of this might be treated a bit differently. I
guess I'll have to look those examples up, but a "1 time per year" sounds
more like a permanent shift in base time from UTC then dst change. And not
sure what you'd do with 3 either. If that's the case, v2 will have to
treat these events as a list.

Jeff

Artyom Beilis

unread,
Nov 9, 2012, 9:27:56 AM11/9/12
to bo...@lists.boost.org

>________________________________
> From: Markus Raab <use...@markus-raab.org>
>To: bo...@lists.boost.org
>Sent: Friday, November 9, 2012 7:57 AM
>Subject: Re: [boost] [datetime] IANA Time Zone Database
>
>Hi!
>
>Artyom Beilis wrote:
>> You can use Boost.Locale that is compiled with ICU backend.
>>
>> ICU supports Time Zone database and you can specify the timezone by its
>> name, parse time or create
>>
>> date_time object and get POSIX (UTC) time form it.
>
>On POSIX systems with tzdata installed Boost.Locale could also have this
>feature without ICU. Any plans to do this?
>
>

Currently there is no API that allows to to get TZ offset for specific
date for specific time zone.  The OS API that provides TZ handing
is limited and assumes global TZ.

The only way I can see, and it is probably simpler way is to use Olson
database directly and implement it withing Boost.Locale.

>best regards
>Markus Raab
>
>on a x86_64           _\_v | 
>



Regards,

Artyom Beilis
--------------
CppCMS - C++ Web Framework:   http://cppcms.com/
CppDB - C++ SQL Connectivity: http://cppcms.com/sql/cppdb/

Artyom Beilis

unread,
Nov 9, 2012, 9:38:04 AM11/9/12
to bo...@lists.boost.org
>> [snip]
>>
>> Thanks a lot!
>
> Thinking more about it, my local times are coming in as broken down time
> representation (year, month, ...), so I won't be dealing with streams at
> all.
>
> Is there a way to do timezone conversions without using streams?
> Something similar to pytz:
>
>     timezone paris("Europe/Paris"), utc("UTC");
>     date_time t(2012, 10, 9, 10, 19, 0); // no timezone associated
>     date_time utc_t(paris.localize(t).astimezone(utc));
>
> ?
>
> -- Maxim
>



First you can create boost::locale::calendar using TZ name

http://www.boost.org/doc/libs/1_52_0/libs/locale/doc/html/classboost_1_1locale_1_1calendar.html#af9538c3aab4b8eaf7229ed2d9af18328



Than you create a date_time object using calendar and than setup all parameters you need.

http://www.boost.org/doc/libs/1_52_0/libs/locale/doc/html/classboost_1_1locale_1_1date__time.html#a871745debde77a28f5fbc6e2b2a5f869


It should be something like
using namespace boost::locale::period;
boost::locale::date_time dt(
year(2012) + month(10) + day(9) + hour(10) + minute(19) + second(0),
boost::locale::calendar("Europe/Paris"));

Than you can get a POSIX time from it dt.time(), print it to stream with UTC time zone or
create other date_time object like

boost::locale::date_time dt_utc(dt.time(),boost::locale::calendar("UTC"));

And fetch its parameters.

I hadn't tested the chunk of code above but this is a general direction.
 
Artyom Beilis
--------------
CppCMS - C++ Web Framework:   http://cppcms.com/
CppDB - C++ SQL Connectivity: http://cppcms.com/sql/cppdb/

Artyom Beilis

unread,
Nov 9, 2012, 9:48:44 AM11/9/12
to bo...@lists.boost.org


----- Original Message -----
> From: Jeff Garland <azsw...@gmail.com>
> To: bo...@lists.boost.org
> Cc:
> Sent: Friday, November 9, 2012 12:52 PM
> Subject: Re: [boost] [datetime] IANA Time Zone Database
>
> On Thu, Nov 8, 2012 at 8:24 PM, Joshua Boyce
> <raptor...@raptorfactor.com>wrote:
>
>>
>> The Boost.Locale docs explain why it it has its own date and time
>> functionality rather than using or building on for example Boost.DateTime:
>>
>>
> http://www.boost.org/doc/libs/1_52_0/libs/locale/doc/html/dates_times_timezones.html
>>
>>
> Thanks that's helpful.  Unfortunately, I don't think some of the
> analysis
> on this page is correct.  Good that I see this now, though so that I can
> work with Artyom and make sure this stuff is in date_time2 :-)


I mostly had 3 major problems with boost.DateTime:

1. Broken TZ API (you see the discussion, it is not capable
   of handling all TZ in Olson DB)

2. There is a mixup of POSIX time (ptime) and local time for example
   stuff like 

     ptime second_clock::local_time()

Makes no sense (for me) as POSIX time is by _definition_ UTC time.

3. There was a need of locale aware date handling, which is ok.

I think boost date_time can be significantly improved, and I assume
boost::locale::date_time as well.

I'd be glad to cooperate.

> Jeff



 
Artyom Beilis
--------------
CppCMS - C++ Web Framework:   http://cppcms.com/
CppDB - C++ SQL Connectivity: http://cppcms.com/sql/cppdb/

Maxim Yegorushkin

unread,
Nov 9, 2012, 10:59:16 AM11/9/12
to bo...@lists.boost.org
On 09/11/12 14:38, Artyom Beilis wrote:

[]

> First you can create boost::locale::calendar using TZ name
>
> http://www.boost.org/doc/libs/1_52_0/libs/locale/doc/html/classboost_1_1locale_1_1calendar.html#af9538c3aab4b8eaf7229ed2d9af18328
>
>
>
> Than you create a date_time object using calendar and than setup all parameters you need.
>
> http://www.boost.org/doc/libs/1_52_0/libs/locale/doc/html/classboost_1_1locale_1_1date__time.html#a871745debde77a28f5fbc6e2b2a5f869
>
>
> It should be something like
> using namespace boost::locale::period;
> boost::locale::date_time dt(
> year(2012) + month(10) + day(9) + hour(10) + minute(19) + second(0),
> boost::locale::calendar("Europe/Paris"));
>
> Than you can get a POSIX time from it dt.time(), print it to stream with UTC time zone or
> create other date_time object like
>
> boost::locale::date_time dt_utc(dt.time(),boost::locale::calendar("UTC"));
>
> And fetch its parameters.
>
> I hadn't tested the chunk of code above but this is a general direction.

Thanks again Artyom, this is exactly what I was looking for.

-- Maxim
Reply all
Reply to author
Forward
0 new messages