1 #ifndef DATE_TIME_POSIX_TIME_IO_HPP__
2 #define DATE_TIME_POSIX_TIME_IO_HPP__
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
14 #include <iterator> // i/ostreambuf_iterator
15 #include <boost/io/ios_state.hpp>
16 #include <boost/date_time/time_facet.hpp>
17 #include <boost/date_time/period_formatter.hpp>
18 #include <boost/date_time/posix_time/ptime.hpp>
19 #include <boost/date_time/posix_time/time_period.hpp>
20 #include <boost/date_time/posix_time/posix_time_duration.hpp>
21 #include <boost/date_time/posix_time/conversion.hpp> // to_tm will be needed in the facets
24 namespace posix_time
{
27 //! wptime_facet is depricated and will be phased out. use wtime_facet instead
28 //typedef boost::date_time::time_facet<ptime, wchar_t> wptime_facet;
29 //! ptime_facet is depricated and will be phased out. use time_facet instead
30 //typedef boost::date_time::time_facet<ptime, char> ptime_facet;
32 //! wptime_input_facet is depricated and will be phased out. use wtime_input_facet instead
33 //typedef boost::date_time::time_input_facet<ptime,wchar_t> wptime_input_facet;
34 //! ptime_input_facet is depricated and will be phased out. use time_input_facet instead
35 //typedef boost::date_time::time_input_facet<ptime,char> ptime_input_facet;
37 typedef boost::date_time::time_facet
<ptime
, wchar_t> wtime_facet
;
38 typedef boost::date_time::time_facet
<ptime
, char> time_facet
;
40 typedef boost::date_time::time_input_facet
<ptime
, wchar_t> wtime_input_facet
;
41 typedef boost::date_time::time_input_facet
<ptime
, char> time_input_facet
;
43 template <class CharT
, class TraitsT
>
45 std::basic_ostream
<CharT
, TraitsT
>&
46 operator<<(std::basic_ostream
<CharT
, TraitsT
>& os
,
48 boost::io::ios_flags_saver
iflags(os
);
49 typedef boost::date_time::time_facet
<ptime
, CharT
> custom_ptime_facet
;
50 typedef std::time_put
<CharT
> std_ptime_facet
;
51 std::ostreambuf_iterator
<CharT
> oitr(os
);
52 if (std::has_facet
<custom_ptime_facet
>(os
.getloc()))
53 std::use_facet
<custom_ptime_facet
>(os
.getloc()).put(oitr
, os
, os
.fill(), p
);
55 //instantiate a custom facet for dealing with times since the user
56 //has not put one in the stream so far. This is for efficiency
57 //since we would always need to reconstruct for every time period
58 //if the locale did not already exist. Of course this will be overridden
59 //if the user imbues as some later point.
60 custom_ptime_facet
* f
= new custom_ptime_facet();
61 std::locale l
= std::locale(os
.getloc(), f
);
63 f
->put(oitr
, os
, os
.fill(), p
);
68 //! input operator for ptime
69 template <class CharT
, class Traits
>
71 std::basic_istream
<CharT
, Traits
>&
72 operator>>(std::basic_istream
<CharT
, Traits
>& is
, ptime
& pt
)
74 boost::io::ios_flags_saver
iflags(is
);
75 typename
std::basic_istream
<CharT
, Traits
>::sentry
strm_sentry(is
, false);
78 typedef typename
date_time::time_input_facet
<ptime
, CharT
> time_input_facet
;
79 std::istreambuf_iterator
<CharT
,Traits
> sit(is
), str_end
;
80 if(std::has_facet
<time_input_facet
>(is
.getloc())) {
81 std::use_facet
<time_input_facet
>(is
.getloc()).get(sit
, str_end
, is
, pt
);
84 time_input_facet
* f
= new time_input_facet();
85 std::locale l
= std::locale(is
.getloc(), f
);
87 f
->get(sit
, str_end
, is
, pt
);
91 // mask tells us what exceptions are turned on
92 std::ios_base::iostate exception_mask
= is
.exceptions();
93 // if the user wants exceptions on failbit, we'll rethrow our
94 // date_time exception & set the failbit
95 if(std::ios_base::failbit
& exception_mask
) {
96 try { is
.setstate(std::ios_base::failbit
); }
97 catch(std::ios_base::failure
&) {} // ignore this one
98 throw; // rethrow original exception
101 // if the user want's to fail quietly, we simply set the failbit
102 is
.setstate(std::ios_base::failbit
);
110 template <class CharT
, class TraitsT
>
112 std::basic_ostream
<CharT
, TraitsT
>&
113 operator<<(std::basic_ostream
<CharT
, TraitsT
>& os
,
114 const boost::posix_time::time_period
& p
) {
115 boost::io::ios_flags_saver
iflags(os
);
116 typedef boost::date_time::time_facet
<ptime
, CharT
> custom_ptime_facet
;
117 typedef std::time_put
<CharT
> std_time_facet
;
118 std::ostreambuf_iterator
<CharT
> oitr(os
);
119 if (std::has_facet
<custom_ptime_facet
>(os
.getloc())) {
120 std::use_facet
<custom_ptime_facet
>(os
.getloc()).put(oitr
, os
, os
.fill(), p
);
123 //instantiate a custom facet for dealing with periods since the user
124 //has not put one in the stream so far. This is for efficiency
125 //since we would always need to reconstruct for every time period
126 //if the local did not already exist. Of course this will be overridden
127 //if the user imbues as some later point.
128 custom_ptime_facet
* f
= new custom_ptime_facet();
129 std::locale l
= std::locale(os
.getloc(), f
);
131 f
->put(oitr
, os
, os
.fill(), p
);
136 //! input operator for time_period
137 template <class CharT
, class Traits
>
139 std::basic_istream
<CharT
, Traits
>&
140 operator>>(std::basic_istream
<CharT
, Traits
>& is
, time_period
& tp
)
142 boost::io::ios_flags_saver
iflags(is
);
143 typename
std::basic_istream
<CharT
, Traits
>::sentry
strm_sentry(is
, false);
146 typedef typename
date_time::time_input_facet
<ptime
, CharT
> time_input_facet
;
147 std::istreambuf_iterator
<CharT
,Traits
> sit(is
), str_end
;
148 if(std::has_facet
<time_input_facet
>(is
.getloc())) {
149 std::use_facet
<time_input_facet
>(is
.getloc()).get(sit
, str_end
, is
, tp
);
152 time_input_facet
* f
= new time_input_facet();
153 std::locale l
= std::locale(is
.getloc(), f
);
155 f
->get(sit
, str_end
, is
, tp
);
159 std::ios_base::iostate exception_mask
= is
.exceptions();
160 if(std::ios_base::failbit
& exception_mask
) {
161 try { is
.setstate(std::ios_base::failbit
); }
162 catch(std::ios_base::failure
&) {}
163 throw; // rethrow original exception
166 is
.setstate(std::ios_base::failbit
);
174 //! ostream operator for posix_time::time_duration
175 // todo fix to use facet -- place holder for now...
176 template <class CharT
, class Traits
>
178 std::basic_ostream
<CharT
, Traits
>&
179 operator<<(std::basic_ostream
<CharT
, Traits
>& os
, const time_duration
& td
)
181 boost::io::ios_flags_saver
iflags(os
);
182 typedef boost::date_time::time_facet
<ptime
, CharT
> custom_ptime_facet
;
183 typedef std::time_put
<CharT
> std_ptime_facet
;
184 std::ostreambuf_iterator
<CharT
> oitr(os
);
185 if (std::has_facet
<custom_ptime_facet
>(os
.getloc()))
186 std::use_facet
<custom_ptime_facet
>(os
.getloc()).put(oitr
, os
, os
.fill(), td
);
188 //instantiate a custom facet for dealing with times since the user
189 //has not put one in the stream so far. This is for efficiency
190 //since we would always need to reconstruct for every time period
191 //if the locale did not already exist. Of course this will be overridden
192 //if the user imbues as some later point.
193 custom_ptime_facet
* f
= new custom_ptime_facet();
194 std::locale l
= std::locale(os
.getloc(), f
);
196 f
->put(oitr
, os
, os
.fill(), td
);
201 //! input operator for time_duration
202 template <class CharT
, class Traits
>
204 std::basic_istream
<CharT
, Traits
>&
205 operator>>(std::basic_istream
<CharT
, Traits
>& is
, time_duration
& td
)
207 boost::io::ios_flags_saver
iflags(is
);
208 typename
std::basic_istream
<CharT
, Traits
>::sentry
strm_sentry(is
, false);
211 typedef typename
date_time::time_input_facet
<ptime
, CharT
> time_input_facet
;
212 std::istreambuf_iterator
<CharT
,Traits
> sit(is
), str_end
;
213 if(std::has_facet
<time_input_facet
>(is
.getloc())) {
214 std::use_facet
<time_input_facet
>(is
.getloc()).get(sit
, str_end
, is
, td
);
217 time_input_facet
* f
= new time_input_facet();
218 std::locale l
= std::locale(is
.getloc(), f
);
220 f
->get(sit
, str_end
, is
, td
);
224 std::ios_base::iostate exception_mask
= is
.exceptions();
225 if(std::ios_base::failbit
& exception_mask
) {
226 try { is
.setstate(std::ios_base::failbit
); }
227 catch(std::ios_base::failure
&) {}
228 throw; // rethrow original exception
231 is
.setstate(std::ios_base::failbit
);
239 #endif // DATE_TIME_POSIX_TIME_IO_HPP__