String to Date in C++ [Using Anjuta IDE]

2.5k views Asked by At

I'm writing a program and I need to read date from file. In date is year, month and day. How I need to read all date information?? Can you give some examples??

5

There are 5 answers

1
Baltasarq On BEST ANSWER

Firstly you'd probably need a struct to hold the values. There is a standard struct, tm, but this one has a lot of members, some of them depending on the others, and it would be confusing when the yday would not be conformant with wday and mday.

struct Date {
    int year;
    int month;
    int day;
};

Then you need a function able to read the data into the structure. You firstly need to open the file, read the first line, and process it. In order to accomplish this, you can use ifstream, which is the standard class in C++ for reading files.

std::ifstream f( fileName.c_str() );

Then you need to read a line in which the date is stored. Since it is an exercie, I assumed it was the first one. getline() reads a whole line from input and stored it in a previously created string.

std::string line;
std::getline( f, line );

Finally, you have to process that line. There are varios way to accomplish this, but probably the most comfortable one in C++ is to use streams related to strings, and read each field by its type.

 std::istringstream str( line );

 str >> date.year
     >> firstDot
     >> date.month
     >> lastDot
     >> date.day
;

About error checking, there are various verifications you could do (I'll leave that to you). At the very least, we should check that we have read dots as separators where we should.

if ( firstDot != '.'
  || lastDot != '.' )
{
    date.year = date.month = date.day = -1;
}

Here it is the whole function:

bool readDate(const std::string &fileName, Date &date)
{
    char firstDot;
    char lastDot;
    std::ifstream f( fileName.c_str() );
    bool toret = false;

    date .year = date.month = date.day = -1;

    if ( f.is_open() ) {
        std::string line;

        // Read line containing the date
        std::getline( f, line );

        //  Chk string
        std::istringstream str( line );

        str >> date.year
             >> firstDot
             >> date.month
             >> lastDot
             >> date.day
        ;

        if ( firstDot != '.'
           || lastDot != '.' )
        {
            date.year = date.month = date.day = -1;
        }
        else toret = true;
    }

    return toret;
}

As you can see, error condition is signaled by the return value of the function, as well as the contents of the struct Date.

Hope this helps.

2
robert On

I suggest using strptime. I don't know what internal format you're looking to have date in, but this should work for you. Note that it doesn't do any error checking.

struct tm tm;
time_t t;
strptime("%Y:%m:%d", &tm);
printf("year: %d; month: %d; day: %d;\n",
    tm.tm_year, tm.tm_mon, tm.tm_mday);
t = mktime(&tm);
0
Oralet On

You can also split string with "." character and put data into variables (may be an array for example).
Then you can create your own format and string by combining them.

1
Howard Hinnant On

If you have a C++0x std::lib (doesn't have to be too recent), here's a library solution that's free, easy and small (1 source, 1 header):

http://howardhinnant.github.io/date.html

Here is example use:

#include "date.h"
#include <iostream>
#include <sstream>

int main()
{
    using namespace gregorian;
    date d;
    std::istringstream in("2011.02.07");
    in >> date_fmt("%Y.%m.%d") >> d;
    if (in.fail())
        std::cout << "failed\n";
    else
        std::cout << date_fmt("%A %B %e, %Y") << d << '\n';
}

Output:

Monday February  7, 2011

The syntax follows from C's strftime function. And the date library requires the C++0x header <cstdint> and some additions to time_get made in 2006.

0
ntg On

Using Boost is an answer.

This question is similar and has a really good answer, though not exactly to your problem.

#include <fstream>
#include <iostream>
#include <string>
#include <boost/date_time.hpp>

using std::cout;
using std::cin;
using std::endl;
using std::string;
namespace bt = boost::posix_time;

int main()
{
    string dd=" 12 December 2011 15:00:42";
    //string dd="December 2011 15:00:42";
    cout<<dd<<endl;
    std::stringstream time1is(dd);
    std::locale dForm = std::locale(std::locale::classic(),new bt::time_input_facet("%d %B %Y %H:%M:%S"));//12 December 2011 15:00:42

    time1is.imbue(dForm);
    bt::ptime t1;
    if ((time1is>>t1).fail()) {
        std::cerr<<"error while parsing  "<<dd<<std::endl;
    }else{
        std::cerr<<"success!!  "<<dd<<std::endl;
    }
    cout<<t1<<endl;

    }

    //char c;  cin >> c;
    return 0;
}