1 #ifndef POSIX_TIME_SERIALIZE_HPP___
2 #define POSIX_TIME_SERIALIZE_HPP___
3 
4 /* Copyright (c) 2004-2005 CrystalClear Software, Inc.
5  * Use, modification and distribution is subject to the
6  * Boost Software License, Version 1.0. (See accompanying
7  * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
8  * Author: Jeff Garland, Bart Garst
9  * $Date$
10  */
11 
12 #include "boost/date_time/posix_time/posix_time.hpp"
13 #include "boost/date_time/gregorian/greg_serialize.hpp"
14 #include "boost/serialization/split_free.hpp"
15 #include "boost/serialization/nvp.hpp"
16 
17 
18 // macros to split serialize functions into save & load functions
19 // NOTE: these macros define template functions in the boost::serialization namespace.
20 // They must be expanded *outside* of any namespace
21 BOOST_SERIALIZATION_SPLIT_FREE(boost::posix_time::ptime)
22 BOOST_SERIALIZATION_SPLIT_FREE(boost::posix_time::time_duration)
23 BOOST_SERIALIZATION_SPLIT_FREE(boost::posix_time::time_period)
24 
25 namespace boost {
26 namespace serialization {
27 
28 
29 /*** time_duration ***/
30 
31 //! Function to save posix_time::time_duration objects using serialization lib
32 /*! time_duration objects are broken down into 4 parts for serialization:
33  * types are hour_type, min_type, sec_type, and fractional_seconds_type
34  * as defined in the time_duration class
35  */
36 template<class Archive>
save(Archive & ar,const posix_time::time_duration & td,unsigned int)37 void save(Archive & ar,
38           const posix_time::time_duration& td,
39           unsigned int /*version*/)
40 {
41   // serialize a bool so we know how to read this back in later
42   bool is_special = td.is_special();
43   ar & make_nvp("is_special", is_special);
44   if(is_special) {
45     std::string s = to_simple_string(td);
46     ar & make_nvp("sv_time_duration", s);
47   }
48   else {
49     posix_time::time_duration::hour_type h = td.hours();
50     posix_time::time_duration::min_type m = td.minutes();
51     posix_time::time_duration::sec_type s = td.seconds();
52     posix_time::time_duration::fractional_seconds_type fs = td.fractional_seconds();
53     ar & make_nvp("time_duration_hours", h);
54     ar & make_nvp("time_duration_minutes", m);
55     ar & make_nvp("time_duration_seconds", s);
56     ar & make_nvp("time_duration_fractional_seconds", fs);
57   }
58 }
59 
60 //! Function to load posix_time::time_duration objects using serialization lib
61 /*! time_duration objects are broken down into 4 parts for serialization:
62  * types are hour_type, min_type, sec_type, and fractional_seconds_type
63  * as defined in the time_duration class
64  */
65 template<class Archive>
load(Archive & ar,posix_time::time_duration & td,unsigned int)66 void load(Archive & ar,
67           posix_time::time_duration & td,
68           unsigned int /*version*/)
69 {
70   bool is_special = false;
71   ar & make_nvp("is_special", is_special);
72   if(is_special) {
73     std::string s;
74     ar & make_nvp("sv_time_duration", s);
75     posix_time::special_values sv = gregorian::special_value_from_string(s);
76     td = posix_time::time_duration(sv);
77   }
78   else {
79     posix_time::time_duration::hour_type h(0);
80     posix_time::time_duration::min_type m(0);
81     posix_time::time_duration::sec_type s(0);
82     posix_time::time_duration::fractional_seconds_type fs(0);
83     ar & make_nvp("time_duration_hours", h);
84     ar & make_nvp("time_duration_minutes", m);
85     ar & make_nvp("time_duration_seconds", s);
86     ar & make_nvp("time_duration_fractional_seconds", fs);
87     td = posix_time::time_duration(h,m,s,fs);
88   }
89 }
90 
91 // no load_construct_data function provided as time_duration provides a
92 // default constructor
93 
94 /*** ptime ***/
95 
96 //! Function to save posix_time::ptime objects using serialization lib
97 /*! ptime objects are broken down into 2 parts for serialization:
98  * a date object and a time_duration onject
99  */
100 template<class Archive>
save(Archive & ar,const posix_time::ptime & pt,unsigned int)101 void save(Archive & ar,
102           const posix_time::ptime& pt,
103           unsigned int /*version*/)
104 {
105   // from_iso_string does not include fractional seconds
106   // therefore date and time_duration are used
107   posix_time::ptime::date_type d = pt.date();
108   ar & make_nvp("ptime_date", d);
109   if(!pt.is_special()) {
110     posix_time::ptime::time_duration_type td = pt.time_of_day();
111     ar & make_nvp("ptime_time_duration", td);
112   }
113 }
114 
115 //! Function to load posix_time::ptime objects using serialization lib
116 /*! ptime objects are broken down into 2 parts for serialization:
117  * a date object and a time_duration onject
118  */
119 template<class Archive>
load(Archive & ar,posix_time::ptime & pt,unsigned int)120 void load(Archive & ar,
121           posix_time::ptime & pt,
122           unsigned int /*version*/)
123 {
124   // from_iso_string does not include fractional seconds
125   // therefore date and time_duration are used
126   posix_time::ptime::date_type d(posix_time::not_a_date_time);
127   posix_time::ptime::time_duration_type td;
128   ar & make_nvp("ptime_date", d);
129   if(!d.is_special()) {
130     ar & make_nvp("ptime_time_duration", td);
131     pt = boost::posix_time::ptime(d,td);
132   }
133   else {
134     pt = boost::posix_time::ptime(d.as_special());
135   }
136 
137 }
138 
139 //!override needed b/c no default constructor
140 template<class Archive>
load_construct_data(Archive &,posix_time::ptime * pt,const unsigned int)141 inline void load_construct_data(Archive & /*ar*/,
142                                 posix_time::ptime* pt,
143                                 const unsigned int /*file_version*/)
144 {
145   // retrieve data from archive required to construct new
146   // invoke inplace constructor to initialize instance of date
147   new(pt) boost::posix_time::ptime(boost::posix_time::not_a_date_time);
148 }
149 
150 /*** time_period ***/
151 
152 //! Function to save posix_time::time_period objects using serialization lib
153 /*! time_period objects are broken down into 2 parts for serialization:
154  * a begining ptime object and an ending ptime object
155  */
156 template<class Archive>
save(Archive & ar,const posix_time::time_period & tp,unsigned int)157 void save(Archive & ar,
158           const posix_time::time_period& tp,
159           unsigned int /*version*/)
160 {
161   posix_time::ptime beg(tp.begin().date(), tp.begin().time_of_day());
162   posix_time::ptime end(tp.end().date(), tp.end().time_of_day());
163   ar & make_nvp("time_period_begin", beg);
164   ar & make_nvp("time_period_end", end);
165 }
166 
167 //! Function to load posix_time::time_period objects using serialization lib
168 /*! time_period objects are broken down into 2 parts for serialization:
169  * a begining ptime object and an ending ptime object
170  */
171 template<class Archive>
load(Archive & ar,boost::posix_time::time_period & tp,unsigned int)172 void load(Archive & ar,
173           boost::posix_time::time_period & tp,
174           unsigned int /*version*/)
175 {
176   posix_time::time_duration td(1,0,0);
177   gregorian::date d(gregorian::not_a_date_time);
178   posix_time::ptime beg(d,td);
179   posix_time::ptime end(d,td);
180   ar & make_nvp("time_period_begin", beg);
181   ar & make_nvp("time_period_end", end);
182   tp = boost::posix_time::time_period(beg, end);
183 }
184 
185 //!override needed b/c no default constructor
186 template<class Archive>
load_construct_data(Archive &,boost::posix_time::time_period * tp,const unsigned int)187 inline void load_construct_data(Archive & /*ar*/,
188                                 boost::posix_time::time_period* tp,
189                                 const unsigned int /*file_version*/)
190 {
191   posix_time::time_duration td(1,0,0);
192   gregorian::date d(gregorian::not_a_date_time);
193   posix_time::ptime beg(d,td);
194   posix_time::ptime end(d,td);
195   new(tp) boost::posix_time::time_period(beg,end);
196 }
197 
198 } // namespace serialization
199 } // namespace boost
200 
201 #endif
202