Is there any way to store tm values using Boost?

Basically I'm trying to store a value, map<string, Date*> m_dates, into a data file. This map uses a string and Date, with a Date class being composed of:

1
2
3
4
tm m_due;
vector<tm> m_warning;
string event;
tm m_alert;


Because this is a class with tm values and not a single tm value, I don't think converting it to time_t is going to work here.

Is there a way I can simply store the tm values?

As an example:

1
2
3
4
5
6
tm m_time;
std::string filename(boost::archive::tmpdir());
filename4 += "/settingsStoreTime.txt";
std::ofstream ofs(filename);
boost::archive::text_oarchive oa(ofs);
oa << m_time;


The result is "'serialize': is not a member of 'tm'". I get a similar result with m_dates, since it has tm values. Changing a single tm value to a time_t value and back upon restoration isn't too hard, but doing it for this map of classes with multiple tm values doesn't seem feasible.

In this case, with m_dates...

1
2
3
4
5
std::string filename(boost::archive::tmpdir());
filename += "/scheduleDate.txt";
std::ofstream ofs(filename);
boost::archive::text_oarchive oa(ofs);
oa << m_dates;


I get the error:

'serialize': is not a member of 'std::map<std::string,Schedule::Date *,std::less<_Kty>,std::allocator<std::pair<const _Kty,_Ty>>>'
Last edited on
This doesn’t answer your question, but can be a (awkward) workaround:
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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
#include <ctime>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>


const char* glo_output { "%d/%m/%Y %H:%M %S (format: dd/mm/yyyy hh::mm ss)" };


class Date {
public:
    void readFromFile(std::ifstream& fin);

//private:
    std::tm m_due {};
    std::vector<std::tm> m_warnings;
    std::string event;
    std::tm m_alert {};
    bool readable { true };

//friend:
    friend std::ostream& operator << (std::ostream& os, const Date& rhs);
};


void Date::readFromFile(std::ifstream& fin)
{
    // Assume NOT human friendly format.
    // TODO: add checks and clean-up in case of errors.

    int stage {};
    for(std::string line; std::getline(fin, line); /**/) {
        std::istringstream iss { line };
        std::time_t tmp_val {};     // declared here to avoid warnings
        switch(stage) {
        case 0:                                         // m_due:
            iss >> tmp_val;
            m_due = *std::localtime(&tmp_val);
            break;

        case 1:                                         // m_warnings:
        {
            int size;
            iss >> line >> size;        // "warnings: x"
            for(int i {}; i < size; ++i) {
                std::getline(fin, line);
                iss.str(line);
                iss.clear();
                iss >> tmp_val;
                m_warnings.push_back(*std::localtime(&tmp_val));
            }
        }
            break;

        case 2:                                         // event
            event = line;
            break;

        case 3:                                         // m_alert
            iss >> tmp_val;
            m_alert = *std::localtime(&tmp_val);
            break;

        default:
            // throw std::invalid_argument("Input file format failure");
            std::cerr << "Error while reading data.\n";
            break;
        }
        stage = stage == 3 ? 0 : stage + 1;
    }
}


std::ostream& operator << (std::ostream& os, const Date& rhs)
{
    if(rhs.readable) {
        os << std::setw(12) << std::left << "due:"
           << std::put_time(&rhs.m_due, glo_output)
           << '\n';

        os << std::setw(12) << std::left << "warnings:";
        switch(rhs.m_warnings.size()) {
        case 0:
            os << "none.\n";
            break;
        case 1:
            os << std::put_time(&rhs.m_warnings.at(0), glo_output) << '\n';
            break;
        default:
            os << '\n';
            for(const auto& e : rhs.m_warnings) {
                os << '\t' << std::put_time(&e, glo_output) << '\n';
            }
            break;
        };

        os << std::setw(12) << std::left << "event:" << rhs.event << '\n';

        os << std::setw(12) << std:: left << "alert:"
           << std::put_time(&rhs.m_alert, glo_output);
    }

    // Not human friendly format:
    else {
        std::tm tmp { rhs.m_due };
        os << std::mktime(&tmp) << '\n';

        os << "warnings: " << rhs.m_warnings.size() << '\n';
        if(!rhs.m_warnings.empty()) {
            for(auto e : rhs.m_warnings) {
                os << std::mktime(&e) << '\n';
            }
        };

        os << rhs.event << '\n';

        tmp = rhs.m_alert;
        os << std::mktime(&tmp);
    }
    return os;
}


int main()
{
    // std::tm m_due {};
    // std::vector<std::tm> m_warnings;
    // std::string event;
    // std::tm m_alert {};
    Date dt;
    auto now { std::time(nullptr) };
    std::cout << "Clock now: "
              << std::put_time( std::localtime(&now), glo_output)
              << "\n\n";
    dt.m_due = *std::localtime( &now ) ;

    for(int i {}; i < 3; ++i) {
        now = std::time(nullptr);
        dt.m_warnings.push_back( *std::localtime( &now ) );
    }

    dt.event = "irrelevant event";

    now = std::time(nullptr);
    dt.m_alert = *std::localtime( &now );

    std::cout << "'dt' so far:\n" << dt << '\n';

    const std::string fname { "Monzaku.dat" };
    std::ofstream fout(fname);
    if(!fout) {
        std::cerr << "Cannot open " << fname << " for writing.\nExiting now.\n";
        return 0;
    }

    dt.readable = false;
    fout << dt << '\n';
    fout.close();

    std::ifstream fin(fname);
    if(!fin) {
        std::cerr << "Cannot open " << fname << ".\nExiting now.\n";
        return 0;
    }

    Date dt2;
    dt2.readFromFile(fin);
    std::cout << "\n'dt2':\n" << dt2 << '\n';
}


Output:
Clock now: 02/04/2019 09:52 25 (format: dd/mm/yyyy hh::mm ss)

'dt' so far:
due:        02/04/2019 09:52 25 (format: dd/mm/yyyy hh::mm ss)
warnings:
        02/04/2019 09:52 25 (format: dd/mm/yyyy hh::mm ss)
        02/04/2019 09:52 25 (format: dd/mm/yyyy hh::mm ss)
        02/04/2019 09:52 25 (format: dd/mm/yyyy hh::mm ss)
event:      irrelevant event
alert:      02/04/2019 09:52 25 (format: dd/mm/yyyy hh::mm ss)

'dt2':
due:        02/04/2019 09:52 25 (format: dd/mm/yyyy hh::mm ss)
warnings:
        02/04/2019 09:52 25 (format: dd/mm/yyyy hh::mm ss)
        02/04/2019 09:52 25 (format: dd/mm/yyyy hh::mm ss)
        02/04/2019 09:52 25 (format: dd/mm/yyyy hh::mm ss)
event:      irrelevant event
alert:      02/04/2019 09:52 25 (format: dd/mm/yyyy hh::mm ss)


Monzaku.dat:
1554191545
warnings: 3
1554191545
1554191545
1554191545
irrelevant event
1554191545

Topic archived. No new replies allowed.