2

I'm trying and trying to write functions to help myself easily convert string to time_t and time_t to string. However, it always gives me wrong a year and a wrong hour. What's wrong?

I need it to be OS independent!

For instance, for date 30/11/2012:09:49:55 it gives 30/11/3912:08:49:55 instead of 30/11/2012:09:49:55.

#include <iostream>
#include <string.h>
#include <cstdio>
using namespace std;

time_t string_to_time_t(string s)
{
    int yy, mm, dd, hour, min, sec;
    struct tm when;
    long tme;

    memset(&when, 0, sizeof(struct tm));
    sscanf(s.c_str(), "%d/%d/%d:%d:%d:%d", &dd, &mm, &yy, &hour, &min, &sec);

    time(&tme);
    when = *localtime(&tme);
    when.tm_year = yy;
    when.tm_mon = mm-1;
    when.tm_mday = dd;
    when.tm_hour = hour;
    when.tm_min = min;
    when.tm_sec = sec;

    return mktime(&when);
}

string time_t_to_string(time_t t)
{
    char buff[20];
    strftime(buff, 20, "%d/%m/%Y:%H:%M:%S", localtime(&t));
    string s(buff);
    return s;
}

int main()
{
    string s = "30/11/2012:13:49:55";

    time_t t = string_to_time_t(s);
    string ss = time_t_to_string(t);

    cout << ss << "\n";


    return 0;
}
mazix
  • 2,540
  • 8
  • 39
  • 56
  • 4
    Define "wrong". What _is_ the result? Did you read the documentation for the functions that you're using? – Lightness Races in Orbit Sep 24 '15 at 14:39
  • @LightnessRacesinOrbit: edited my question with an example – mazix Sep 24 '15 at 14:46
  • 2
    [try](https://ideone.com/Sv5MBr) `when.tm_year = yy-1900;` ([reference](http://www.cplusplus.com/reference/ctime/mktime/)). – wendelbsilva Sep 24 '15 at 14:49
  • FYI as is this will not compile on MSVS 2015. – NathanOliver Sep 24 '15 at 14:50
  • It compiles with no errors on Kubuntu 14.04 with newest g++/gcc. And on Windows with newest Code::Blocks, so ... – mazix Sep 24 '15 at 14:51
  • 1
    Okay, so the answer to my second question is "no". – Lightness Races in Orbit Sep 24 '15 at 14:57
  • try this: time_t SetTime(int year, int month, int day, int hour, int min, int sec) { time_t rawtime; struct tm * timeinfo; time ( &rawtime ); timeinfo = gmtime ( &rawtime ); timeinfo->tm_year = year - 1900; timeinfo->tm_mon = month - 1; timeinfo->tm_mday = day; timeinfo->tm_hour = hour; timeinfo->tm_min = min; timeinfo->tm_sec = sec; return mktime ( timeinfo ); } – Victor Sep 24 '15 at 15:01
  • 1
    @wendelbsilva fixed the year issue, but you also have to deal with how midnight is handled. You might take a look at http://stackoverflow.com/questions/321849/strptime-equivalent-on-windows – sfjac Sep 24 '15 at 15:08

1 Answers1

2

the tm_year in the structure std::tm keeps the years since 1900.

Thus, instead of when.tm_year = yy; its necessary to subtract 1900 from the year: when.tm_year = yy-1900;

You can check the code running here.

Edit: as sfjac pointed out, my answer wasnt addressing the DST problem.

The problem with the hour is the DST flag. Since I can't reproduce the problem on ideone, only locally.. the system may be setting the tm_isdst based on local settings.

You will need to set the when.tm_isdst to 0 or negative, depending on what you want. Set to 0 if you know the datetime doesnt have DST, -1 (negative) if it is unknown.

Community
  • 1
  • 1
wendelbsilva
  • 774
  • 6
  • 21