Boost logo

Boost Users :

Subject: Re: [Boost-users] [date_time] howto determine date format?
From: Amadeus W.M. (amadeus84_at_[hidden])
Date: 2010-04-15 23:47:42


> BOOST_FOREACH(std: :string const
%20format,%20possible_formats)%0A>%20%20%20%20%20%7B%0A>%20%20%20%20%20%20%20%20%20if%20(inform_user)%0A>%20%20%20%20%20%20%20%20%20%7B%0A>%20%20%20%20%20%20%20%20%20%20%20%20%20std:
        :cout%20<<%20%22Trying%20format%20'%22%20<<%20format%20<<%20%22'%20...%22%20<<%20std::endl;%20%0A>%20%20%20%20%20%20%20%20%20%7D%20%0A>%20%0A>%20%20%20%20%20%20%20%20%20try%0A>%20%20%20%20%20%20%20%20%20%7B%0A>%20%20%20%20%20%20%20%20%20%20%20%20%20date_input_facet%20*%20input_facet%20:
> std: :istringstream iss(s);
> iss.imbue(std: :locale(iss.getloc(), input_facet));
Content-type: text/plain; charset=UTF-8
Date: Thu, 15 Apr 2010 23:47:31 -0400
Message-id: <1271389651.25933.26.camel_at_localhost>
MIME-version: 1.0
X-Mailer: Evolution 2.28.3 (2.28.3-1.fc12)
Content-transfer-encoding: 7bit

On 2010-02-24 14:08, Markus Werle wrote:
> Hi!
>
> With the code below I try to automagically determine the date
> format found in input files. I'd expect the code below to find the
> date format "%d.%m.%Y" for "05.02.2008", but I got surprised by
> obtaining "%m/%d/%Y". A major pain it is with those dates.
> Whether my shallow knowledge of locales and imbue
> or boost::date_time (from boost-1.37.0) is to be blamed is
> beyond my horizon.
>
> I feel like date accepts '.' where I said "expect '/'", so I think
> this should be changed. I may be wrong.
>
> Could you please shed some light on the issue?
>
> Thanks, Markus
>
>
> #include <boost/assign/list_of.hpp>
>
> #include <boost/date_time/posix_time/posix_time.hpp>
> #include <boost/date_time/gregorian/gregorian.hpp>
> #include <boost/date_time/local_time/local_time.hpp>
> #include <boost/foreach.hpp>
> #include <boost/algorithm/string.hpp>
>
> #include <string>
> #include <list>
>
> inline std::string determine_date_format(std::string const

I'm having the similar problems, with similar code. It's aggravating.
Oh, yeah, I have boost-1.39.0-9.fc12.x86_64.

This is what happens when I run the executable:

echo "1230735660" | ./dateIO
5660-Dec-07 00:00:00 %m/%d/%Y %H:%M:%S

It thinks 1230735660 is in the format %m/%d/%Y %H:%M:%S, as if 3 were
the separator, which then produces m=12, d=07 and Y=5660. How come? If I
want / to be the separator, then / should be the separator, not 3.

And this is the code:

// g++ -g -Wall -o dateIO dateIO.C -lboost_date_time

#include <iostream>
#include <sstream>
#include <cstdlib>
#include <string>
#include <boost/date_time/posix_time/posix_time.hpp>

using namespace boost::posix_time;
using namespace std;

// Known date formats.
const char * knownFormats[]={
    "%Y-%m-%d %H:%M:%S",
    "%Y-%m-%d, %H:%M:%S",
    "%Y/%m/%d %H:%M:%S",
    "%Y/%m/%d, %H:%M:%S",
    "%m/%d/%Y %H:%M:%S",
    "%m/%d/%Y, %H:%M:%S",
    "%m-%d-%Y %H:%M:%S",
    "%m-%d-%Y, %H:%M:%S",
    "%b %d, %Y %H:%M:%S",
    "%Y-%b-%d %H:%M:%S",
    "%Y-%b-%d, %H:%M:%S",
    0
};

ptime readDateGivenFormat(istream & IN, const char * fmt)
{
    ptime pt(not_a_date_time);

    // Always allocate facet with new! Only locale can destroy it
because
    // facet's destructor is not public (and locale is a friend).
    //
    // Thank you Angelika Langer! Long live Angelika Langer!
    //http://www.angelikalanger.com/Conferences/Slides/CppLocales-ACCU-2001.pdf
    
    time_input_facet * tifacet = new time_input_facet(fmt);
    locale loc(IN.getloc(),tifacet);

    IN.imbue(loc);
    IN >> pt;

    return pt;
}

int datestr2ptime(const char * datestr, ptime & pt)
{
    istringstream * INSTR=0;
    int i=0;

    pt=ptime(not_a_date_time);

    // Can't read it in a loop from stdin, because once read,
    // it won't be read again!
    // Keep creating a new istringstream bound to datestr for each
    // known format.
    while(knownFormats[i]!=0){

        // Put it into INSTR - each time with new!
        INSTR = new istringstream(datestr);

        pt=readDateGivenFormat(*INSTR, knownFormats[i]);
        delete INSTR;
        
        if(pt!=not_a_date_time)
            return i;

        i++;
    }

    return i;
}

int main(int argc, char * argv[])
{
    ptime pt(not_a_date_time);
    string datestr;
    int i=-1;

    getline(cin,datestr);

    i=datestr2ptime(datestr.c_str(), pt);
    cout << pt;
    if(knownFormats[i])
        cout << "\t" << knownFormats[i];
    cout << endl;

    return 0;
}


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