0

Thanks to people who contributed to this question.

I did a bit of hack to it to convert a string to epoch time with a flexible custom format.

I do not understand why my format "%m/%d/%Y %H:%M:%S" fails but the other one %Y/%m/%d %H:%M:%S works. How should I fix it?

#include <iostream>
#include <boost/date_time.hpp>
namespace bt = boost::posix_time;

std::time_t pt_to_time_t(const bt::ptime& pt)
{
    bt::ptime timet_start(boost::gregorian::date(1970,1,1));
    bt::time_duration diff = pt - timet_start;
    return diff.ticks()/bt::time_duration::rep_type::ticks_per_second;
}
void seconds_from_epoch(const std::string& s,const std::string format_string)
{
    const std::locale format = std::locale(std::locale::classic(),new bt::time_input_facet(format_string));
    bt::ptime pt;
    std::istringstream is(s);
    is.imbue(format);
    is >> pt;
    // if(pt != bt::ptime())
    //     break;
    std::cout << " ptime is " << pt << '\n';
    std::cout << " seconds from epoch are " << pt_to_time_t(pt) << '\n';
}
int main()
{
    seconds_from_epoch("7/23/2012 4:10:43","%m/%d/%Y %H:%M:%S");
    seconds_from_epoch("2004/03/21 12:45:33","%Y/%m/%d %H:%M:%S");
}

Results:

g++ main.cpp -Wall -Wconversion -Wfatal-errors -Wextra -std=c++11 -o main
./main
 ptime is not-a-date-time
 seconds from epoch are 9223372036854
 ptime is 2004-Mar-21 12:45:33
 seconds from epoch are 1079873133
Community
  • 1
  • 1
ar2015
  • 5,558
  • 8
  • 53
  • 110

2 Answers2

0

Quote from doc:

%H The hour as a decimal number using a 24-hour clock (range 00 to 23).

So change the line

seconds_from_epoch("7/23/2012 4:10:43","%m/%d/%Y %H:%M:%S");

to

seconds_from_epoch("7/23/2012 04:10:43","%m/%d/%Y %H:%M:%S"); // 4:10 => 04:10

Then it works.

[Update:] The issue here is not related to the order of format specifiers, but the %H specifier's valid value should be in range 00 to 23.

Mine
  • 4,123
  • 1
  • 25
  • 46
  • thanks, but what if I dont want to change the first string?? how to fix it by changing the rest of code? – ar2015 Jun 02 '16 at 10:18
  • What do you mean by "changing the rest of code"? The issue is not related to the order your format specifiers, but the specifier `%H`'s value should be in range `00` to `23`. – Mine Jun 02 '16 at 11:21
  • But the user likes to give the hour with one digit too. e.g. `4`. I cannot force them to enter `04` – ar2015 Jun 02 '16 at 11:28
  • Actually, I dont use scanf. I read from a file. The date is read into a string. Is there any way without hacking the input to the function? – ar2015 Jun 02 '16 at 11:38
0

If you are flexible on your date library, you could use this one. This would make your example look like:

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

void
seconds_from_epoch(const std::string& s,const std::string format_string)
{
    std::istringstream is(s);
    is.exceptions(std::ios::failbit);
    date::sys_seconds pt;
    date::parse(is, format_string, pt);
    using namespace date;
    std::cout << " ptime is " << pt << '\n';
    std::cout << " seconds from epoch are " << pt.time_since_epoch().count() << '\n';
}

int
main()
{
    seconds_from_epoch("7/23/2012 4:10:43","%m/%d/%Y %H:%M:%S");
    seconds_from_epoch("2004/03/21 12:45:33","%Y/%m/%d %H:%M:%S");
}

 ptime is 2012-07-23 04:10:43
 seconds from epoch are 1343016643
 ptime is 2004-03-21 12:45:33
 seconds from epoch are 1079873133

This would allow you to work in the C++ <chrono> time system.

Howard Hinnant
  • 206,506
  • 52
  • 449
  • 577