1 #ifndef BOOST_DATE_TIME_LOCAL_TIME_IO_HPP__
2 #define BOOST_DATE_TIME_LOCAL_TIME_IO_HPP__
4 /* Copyright (c) 2003-2004 CrystalClear Software, Inc.
5 * Subject to the Boost Software License, Version 1.0.
6 * (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
7 * Author: Jeff Garland, Bart Garst
13 #include <iterator> // i/ostreambuf_iterator
14 #include <boost/io/ios_state.hpp>
15 #include <boost/date_time/time_facet.hpp>
16 #include <boost/date_time/string_convert.hpp>
17 #include <boost/date_time/local_time/local_date_time.hpp>
18 #include <boost/date_time/local_time/posix_time_zone.hpp>
19 #include <boost/date_time/local_time/conversion.hpp> // to_tm will be needed in the facets
22 namespace local_time
{
24 typedef boost::date_time::time_facet
<local_date_time
, wchar_t> wlocal_time_facet
;
25 typedef boost::date_time::time_facet
<local_date_time
, char> local_time_facet
;
27 typedef boost::date_time::time_input_facet
<local_date_time::utc_time_type
,wchar_t> wlocal_time_input_facet
;
28 typedef boost::date_time::time_input_facet
<local_date_time::utc_time_type
,char> local_time_input_facet
;
30 //! operator<< for local_date_time - see local_time docs for formatting details
31 template<class CharT
, class TraitsT
>
33 std::basic_ostream
<CharT
, TraitsT
>&
34 operator<<(std::basic_ostream
<CharT
, TraitsT
>& os
, const local_date_time
& ldt
)
36 boost::io::ios_flags_saver
iflags(os
);
37 typedef local_date_time time_type
;//::utc_time_type typename
38 typedef date_time::time_facet
<time_type
, CharT
> custom_time_facet
;
39 typedef std::time_put
<CharT
> std_time_facet
;
40 std::ostreambuf_iterator
<CharT
> oitr(os
);
42 if(std::has_facet
<custom_time_facet
>(os
.getloc())) {
43 std::use_facet
<custom_time_facet
>(os
.getloc()).put(oitr
,
49 custom_time_facet
* f
= new custom_time_facet();
50 std::locale l
= std::locale(os
.getloc(), f
);
52 f
->put(oitr
, os
, os
.fill(), ldt
);
59 //! input operator for local_date_time
60 template <class CharT
, class Traits
>
62 std::basic_istream
<CharT
, Traits
>&
63 operator>>(std::basic_istream
<CharT
, Traits
>& is
, local_date_time
& ldt
)
65 boost::io::ios_flags_saver
iflags(is
);
66 typename
std::basic_istream
<CharT
, Traits
>::sentry
strm_sentry(is
, false);
69 typedef typename
local_date_time::utc_time_type utc_time_type
;
70 typedef typename
date_time::time_input_facet
<utc_time_type
, CharT
> time_input_facet
;
72 // intermediate objects
73 std::basic_string
<CharT
> tz_str
;
74 utc_time_type
pt(not_a_date_time
);
76 std::istreambuf_iterator
<CharT
,Traits
> sit(is
), str_end
;
77 if(std::has_facet
<time_input_facet
>(is
.getloc())) {
78 std::use_facet
<time_input_facet
>(is
.getloc()).get_local_time(sit
, str_end
, is
, pt
, tz_str
);
81 time_input_facet
* f
= new time_input_facet();
82 std::locale l
= std::locale(is
.getloc(), f
);
84 f
->get_local_time(sit
, str_end
, is
, pt
, tz_str
);
87 time_zone_ptr null_ptr
;
88 // a null time_zone_ptr creates a local_date_time that is UTC
89 ldt
= local_date_time(pt
, null_ptr
);
92 time_zone_ptr
tz_ptr(new posix_time_zone(date_time::convert_string_type
<CharT
,char>(tz_str
)));
93 // the "date & time" constructor expects the time label to *not* be utc.
94 // a posix_tz_string also expects the time label to *not* be utc.
95 ldt
= local_date_time(pt
.date(), pt
.time_of_day(), tz_ptr
, local_date_time::EXCEPTION_ON_ERROR
);
99 // mask tells us what exceptions are turned on
100 std::ios_base::iostate exception_mask
= is
.exceptions();
101 // if the user wants exceptions on failbit, we'll rethrow our
102 // date_time exception & set the failbit
103 if(std::ios_base::failbit
& exception_mask
) {
104 try { is
.setstate(std::ios_base::failbit
); }
105 catch(std::ios_base::failure
&) {} // ignore this one
106 throw; // rethrow original exception
109 // if the user want's to fail quietly, we simply set the failbit
110 is
.setstate(std::ios_base::failbit
);
118 //! output operator for local_time_period
119 template <class CharT
, class TraitsT
>
121 std::basic_ostream
<CharT
, TraitsT
>&
122 operator<<(std::basic_ostream
<CharT
, TraitsT
>& os
,
123 const boost::local_time::local_time_period
& p
) {
124 boost::io::ios_flags_saver
iflags(os
);
125 typedef boost::date_time::time_facet
<local_date_time
, CharT
> custom_facet
;
126 typedef std::time_put
<CharT
> std_time_facet
;
127 std::ostreambuf_iterator
<CharT
> oitr(os
);
128 if (std::has_facet
<custom_facet
>(os
.getloc())) {
129 std::use_facet
<custom_facet
>(os
.getloc()).put(oitr
, os
, os
.fill(), p
);
132 //instantiate a custom facet for dealing with periods since the user
133 //has not put one in the stream so far. This is for efficiency
134 //since we would always need to reconstruct for every time period
135 //if the local did not already exist. Of course this will be overridden
136 //if the user imbues as some later point.
137 custom_facet
* f
= new custom_facet();
138 std::locale l
= std::locale(os
.getloc(), f
);
140 f
->put(oitr
, os
, os
.fill(), p
);
145 //! input operator for local_time_period
146 template <class CharT
, class Traits
>
148 std::basic_istream
<CharT
, Traits
>&
149 operator>>(std::basic_istream
<CharT
, Traits
>& is
, boost::local_time::local_time_period
& tp
)
151 boost::io::ios_flags_saver
iflags(is
);
152 typename
std::basic_istream
<CharT
, Traits
>::sentry
strm_sentry(is
, false);
155 typedef typename
date_time::time_input_facet
<local_date_time
, CharT
> time_input_facet
;
157 std::istreambuf_iterator
<CharT
,Traits
> sit(is
), str_end
;
158 if(std::has_facet
<time_input_facet
>(is
.getloc())) {
159 std::use_facet
<time_input_facet
>(is
.getloc()).get(sit
, str_end
, is
, tp
);
162 time_input_facet
* f
= new time_input_facet();
163 std::locale l
= std::locale(is
.getloc(), f
);
165 f
->get(sit
, str_end
, is
, tp
);
169 std::ios_base::iostate exception_mask
= is
.exceptions();
170 if(std::ios_base::failbit
& exception_mask
) {
171 try { is
.setstate(std::ios_base::failbit
); }
172 catch(std::ios_base::failure
&) {}
173 throw; // rethrow original exception
176 is
.setstate(std::ios_base::failbit
);
186 #endif // BOOST_DATE_TIME_LOCAL_TIME_IO_HPP__