Преобразование time_t в строку и строку в time_t дает неправильный год и час

Я пытаюсь и пытаюсь написать функции, которые помогут мне легко преобразовать string в time_t и time_t в string. Однако он всегда дает мне неправильный год и неправильный час. Что случилось?

Мне нужно, чтобы он был независимым от ОС!

Например, для даты 30/11/2012:09:49:55 он дает 30/11/3912:08:49:55 вместо 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;
}

person mazix    schedule 24.09.2015    source источник
comment
Определите неправильно. Каков является результатом? Вы читали документацию по функциям, которые вы используете?   -  person Lightness Races in Orbit    schedule 24.09.2015
comment
@LightnessRacesinOrbit: отредактировал мой вопрос с примером   -  person mazix    schedule 24.09.2015
comment
попробуйте when.tm_year = yy-1900; (ссылка).   -  person wendelbsilva    schedule 24.09.2015
comment
К вашему сведению, это не будет компилироваться в MSVS 2015.   -  person NathanOliver    schedule 24.09.2015
comment
Он компилируется без ошибок на Kubuntu 14.04 с новейшим g++/gcc. А в Windows с новейшим Code::Blocks, так что...   -  person mazix    schedule 24.09.2015
comment
Итак, ответ на мой второй вопрос - нет.   -  person Lightness Races in Orbit    schedule 24.09.2015
comment
попробуйте это: time_t SetTime (год, месяц, день, час, мин, сек) { time_t rawtime; структура тм * информация о времени; время (&rawtime); timeinfo = gmtime ( &rawtime ); timeinfo-›tm_year = год - 1900; timeinfo-›tm_mon = месяц - 1; timeinfo-›tm_mday = день; timeinfo-›tm_hour = час; timeinfo-›tm_min = мин; timeinfo-›tm_sec = сек; вернуть mktime (информация о времени); }   -  person Victor    schedule 24.09.2015
comment
@wendelbsilva исправила проблему с годом, но вам также нужно разобраться с тем, как обрабатывается полночь. Вы можете взглянуть на stackoverflow.com/questions/321849/   -  person sfjac    schedule 24.09.2015


Ответы (1)


tm_year в структуре std::tm хранит годы с 1900.

Таким образом, вместо when.tm_year = yy; из года нужно вычесть 1900: when.tm_year = yy-1900;

Вы можете проверить работающий код здесь.

Изменить: как указал sfjac, мой ответ не касался проблемы летнего времени.

Проблема с часами - это флаг DST. Поскольку я не могу воспроизвести проблему на ideone, только локально. Система может устанавливать tm_isdst на основе локальные настройки.

Вам нужно будет установить when.tm_isdst равным 0 или отрицательным, в зависимости от того, что вы хотите. Установите 0, если вы знаете, что дата и время не имеют летнего времени, -1 (отрицательное), если оно неизвестно.

person wendelbsilva    schedule 24.09.2015