Boost logo

Boost Users :

From: Jeff Garland (jeff_at_[hidden])
Date: 2005-01-11 21:59:35


On Tue, 11 Jan 2005 09:22:06 -0500, Caleb Epstein wrote

Not sure what happened to my reply 12 hours ago, but I'll try again...

> On Tue, 11 Jan 2005 07:26:20 -0600, Bill Lear <rael_at_[hidden]> wrote:
> > I'd like to determine the total number of seconds between a date and
> > the epoch ('00:00:00 1970-01-01 UTC'), The date can be in a timezone
> > that has daylight savings. The date should be converted to UTC, with
> > appropriate daylight savings adjustments made, and then the epoch
> > subtracted from it. This should mirror the unix GNU 'date' utility,
> > which can be run as:
> >
> > % TZ="America/New_York" date --date='2004-10-04 12:14:32' +%s
> > 1096906472
> >
> > I've looked at the doc, but it's not clear how to do this. Could
> > someone give me a few pointers, please?
>
> I would make use of the standard library facilities timelocal or
> timegm to convert a struct tm to time_t format. The former assumes
> the time is expressed in local time (as specified by the TZ
> environment variable or via tzset) and the latter assumes it is in
> GMT.
>
> The support for timezone conversions in Boost.DateTime is rudimentary
> at best and does not currently make use of operating system
> facilities like the zoneinfo database.
>

Caleb is right, the released functionality in date-time makes this difficult
to do. However, the current CVS actually has everything you need. I wrote
the following small program that does the calculation using new features which
will be released as part of 1.33:

//convert.cpp
#include "boost/date_time/local_time/local_time.hpp"
#include <iostream>

int main()
{
  using namespace boost::gregorian;
  using namespace boost::local_time;
  using namespace boost::posix_time;
  
  tz_database tz_db;
  tz_db.load_from_file("date_time_zonespec.csv");
  boost::shared_ptr<time_zone_base> nyc_tz =
                      tz_db.time_zone_from_region("America/New_York");
  date in_date(2004,10,04);
  time_duration td(12,14,32);
  // construct with local time value -- create not-a-date-time
  // if invalid (eg: in dst transition)
  local_date_time nyc_time(in_date, td, nyc_tz,
                           local_date_time::NOT_DATE_TIME_ON_ERROR);

  std::cout << nyc_time << std::endl;

  ptime time_t_epoch(date(1970,1,1));
  std::cout << time_t_epoch << std::endl;

  time_duration diff = nyc_time.utc_time() - time_t_epoch;
  std::cout << "Seconds diff: " << diff.total_seconds() << std::endl;
  return 0;
}

Output:
Mon Oct 4 12:14:32 2004 EDTEDT
1970-Jan-01 00:00:00
Seconds diff: 1096906472

I see there is a bug in the output code right now that prints the short time
zone abbreviation twice right now. We are in the process of a major I/O
overall. But anyway, if you are willing to work with 'alpha' code with no docs
you can use it now. I say alpha code, but there are already pretty complete
tests in the tests/local_time directory...

BTW, the tz_database class is reading a file you will find in cvs at
libs/date_time/data/date_time_zonespec.csv. This CSV file contains a dump of
time zone database data into a form that is handing for reading, porting, and
editing. This is what allows the regional time_zone specification that
contains all the dst rules, etc.

HTH,

Jeff


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net