4

I want to use the date_time library in boost to represent time in my application. This application will generate Atom feeds, which in turn mandates time-stamps in the format specified in RFC 3339, for example "1990-12-31T23:59:60Z" or "1990-12-31T15:59:60-08:00".

So, how do I format time according to this RFC?

I have been reading the Date Time Input/Output documentation all day, and I can't seem to find out how to put the Z at the end when I need it. Also, the RFC supports an optional fractional second, but only one digit of it (eg. "1990-12-31T23:59:60.5Z") (*). I can't seem to find out how to do this either.

I could always write my own formatting routine that reads out the different needed fields, but that seems to me to be working against the grain of the date_time library.

Any experience with writing formatters for this library? Or am I doing the wrong thing?

(*): It seems to me that the ABNF given in the RFC only allows one-digit fractional seconds, but the examples in the same RFC have two-digit fractional seconds. What is that supposed to mean?

Community
  • 1
  • 1
Magnus Hoff
  • 21,529
  • 9
  • 63
  • 82
  • have you tried it using facets? they seem to be pretty powerful and may be able to do what you want (i dunno). have a look here: http://stackoverflow.com/questions/327673/convert-wide-character-strings-to-boost-dates/327680#327680 – Johannes Schaub - litb Jan 29 '09 at 14:59
  • Yes, I am using facets. And I *want* to use facets. But to me they don't seem powerful enough. But, as you say, i dunno :) – Magnus Hoff Jan 29 '09 at 15:01

1 Answers1

5
  1. ABNF from RFC says that there must be at least one digit after dot, there is no defined maximum.

  2. There is no real need for the Z, you can use 00:00 instead, and this is possible with facets

  3. In some rare circumstances date_time will generate a "Z". See code snapshot from boost (local_date_time.hpp) that suggests this is below:


    std::string zone_name(bool as_offset=false) const
    {
      if(zone_ == boost::shared_ptr()) {
        if(as_offset) {
          return std::string("Z");
        }
        else {
          return std::string("Coordinated Universal Time");
        }
    ...

There is similar if in zone_abbrev function...

And example usage of this

slimak@daradei:~/store/kodowanie/moje/test$ cat boost_date_time.cpp
#include "boost/date_time.hpp"
#include "boost/date_time/local_time/local_time.hpp"

using namespace boost::posix_time;
using namespace boost::local_time;

int main()
{
        local_date_time t = local_sec_clock::local_time(time_zone_ptr());
        local_time_facet* lf(new local_time_facet("%Y-%m-%dT%H:%M:%S%F%Q"));
        std::cout.imbue(std::locale(std::cout.getloc(), lf));
        std::cout << t << std::endl;
        return 0;
}
slimak@daradei:~/store/kodowanie/moje/test$ g++ boost_date_time.cpp && ./a.out
2009-01-30T12:15:56Z
slimak@daradei:~/store/kodowanie/moje/test$

Slimak
  • 1,396
  • 1
  • 8
  • 17
  • Ah. Thanks. Nice. I never got the time zone stuff completely right. Maybe I should try to learn the library *first*? :) – Magnus Hoff Jan 30 '09 at 12:32
  • 1
    BTW, you might want to use the `time_zone_ptr`-typedef rather than `boost::shared_ptr`. – Magnus Hoff Jan 30 '09 at 12:32
  • Ptr corrected. BTW I do not use this library currently --- I was considering switch to it from wxWidgets date and time used in one project some time ago, and learned it a bit by the way. And refreshing memory was a nice break during some test plan preparation :). – Slimak Jan 30 '09 at 23:20
  • facets are extremely slow and should only be used once in a blue moon - if at all. –  Jan 19 '11 at 09:09