关于c ++:序列化和反序列化time_t变量后的结果不正确

Incorrect result after serializing and deserializing time_t variable

这个小程序在我的项目中复制了这个错误。时间变量转换为struct_tm,然后转换为string,并序列化为文件。稍后,该字符串将从文件中加载,并应转换回时间。结果时间与原始时间相差一小时(可能是因为夏令时)。我只能更改反序列化部分,因为文件格式应该保持不变。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
#include"stdafx.h"
#include <iostream>
#include <string>
#include <time.h>

using namespace std;

string FormatDateTime(struct tm* time);
void Test();


int _tmain(int argc, _TCHAR* argv[])
{
    Test();
    return 0;
}


string FormatDateTime(struct tm* time)
{
    static const char* months[] =
    {
       "Jan","Feb", "Mar","Apr","May","Jun", "Jul","Aug", "Sep","Oct", "Nov","Dec"
    };

    char s[30];
    const char* month;

    if ( time->tm_mon >= 0  &&  time->tm_mon < 12 )
    {
        month = months[time->tm_mon];
    }
    else
    {
        month ="??";
    }

    sprintf(s,"%d-%s-%02d %02d:%02d:%02d",
        time->tm_year + 1900,
        month,
        time->tm_mday,
        time->tm_hour,
        time->tm_min,
        time->tm_sec);

    return s;
}

void Test()
{
    // time_t variable is initialized with current time
    time_t t = time(NULL);

    // time_t variable is converted to struct tm and then to string
    struct tm* ptm = localtime(&t);

    char buffer[100];

    sprintf(buffer,"%d %d %d %d %d %d",
        ptm->tm_mday, ptm->tm_mon + 1, ptm->tm_year + 1900, ptm->tm_hour, ptm->tm_min, ptm->tm_sec);

    cout << buffer << endl;         // string is OK


    // string is saved to the file

    // *********************************************************************************************

    // later this string is restored from the file

    // **** I can change something only after this line **** //

    struct tm stm;
    memset(&stm, 0, sizeof(stm));

    sscanf(buffer,"%d %d %d %d %d %d",
        &stm.tm_mday, &stm.tm_mon, &stm.tm_year, &stm.tm_hour, &stm.tm_min, &stm.tm_sec);

    stm.tm_mon -= 1;
    stm.tm_year -= 1900;

    string s = FormatDateTime(ptm);

    cout << s << endl;              // OK

    // *********************************************************************************************
    // Now I need to convert struct tm to time_t and keep it in the variable

    time_t t1 = mktime(&stm);       // not the same time - 1 hour difference

    if ( t1 == t )
    {
        cout <<"t1 == t" << endl;
    }
    else
    {
        cout <<"t1 != t   !!!!!" << endl;
    }

    // time_t is printed - result is incorrect

    // Utilities::FormatDateTime
    struct tm* ptm1 = localtime(&t1);

    s = FormatDateTime(ptm1);

    cout << s << endl;
}

当地时间是11点33分。结果:

1
2
3
4
19 7 2012 11 33 17
2012-Jul-19 11:33:17
t1 != t   !!!!!
2012-Jul-19 12:33:17

如何更改此程序的最后一部分以获得正确的结果?


我的猜测是tm_isdst在两个tm结构中是不同的。一种情况是0,另一种情况是1。


这不会解决问题,但对于以后可能出现的兼容性问题,0应该表示1970年1月1日,而不是1900年1月1日。