| 1 |  | 
|---|
| 2 | #ifndef _DATE_TIME_FACET__HPP__ | 
|---|
| 3 | #define _DATE_TIME_FACET__HPP__ | 
|---|
| 4 |  | 
|---|
| 5 | /* Copyright (c) 2004-2005 CrystalClear Software, Inc. | 
|---|
| 6 |  * Use, modification and distribution is subject to the  | 
|---|
| 7 |  * Boost Software License, Version 1.0. (See accompanying | 
|---|
| 8 |  * file LICENSE-1.0 or http://www.boost.org/LICENSE-1.0) | 
|---|
| 9 |  * Author:  Martin Andrian, Jeff Garland, Bart Garst | 
|---|
| 10 |  * $Date: 2006/02/18 20:58:01 $ | 
|---|
| 11 |  */ | 
|---|
| 12 |  | 
|---|
| 13 | #include "boost/date_time/date_facet.hpp" | 
|---|
| 14 | #include "boost/date_time/string_convert.hpp" | 
|---|
| 15 | #include "boost/algorithm/string/erase.hpp" | 
|---|
| 16 | #include <sstream> | 
|---|
| 17 | #include <iomanip> | 
|---|
| 18 | #include <exception> | 
|---|
| 19 |  | 
|---|
| 20 | namespace boost { | 
|---|
| 21 | namespace date_time { | 
|---|
| 22 |  | 
|---|
| 23 |   template <class CharT> | 
|---|
| 24 |   struct time_formats { | 
|---|
| 25 |     public: | 
|---|
| 26 |       typedef CharT char_type; | 
|---|
| 27 |       static const char_type fractional_seconds_format[3];               // f | 
|---|
| 28 |       static const char_type fractional_seconds_or_none_format[3];       // F | 
|---|
| 29 |       static const char_type seconds_with_fractional_seconds_format[3];  // s | 
|---|
| 30 |       static const char_type seconds_format[3];                          // S | 
|---|
| 31 |       static const char_type standard_format[9];                         // x X | 
|---|
| 32 |       static const char_type zone_abbrev_format[3];                      // z | 
|---|
| 33 |       static const char_type zone_name_format[3];                        // Z | 
|---|
| 34 |       static const char_type zone_iso_format[3];                         // q | 
|---|
| 35 |       static const char_type zone_iso_extended_format[3];                // Q | 
|---|
| 36 |       static const char_type posix_zone_string_format[4];                // ZP | 
|---|
| 37 |       static const char_type duration_sign_negative_only[3];             // - | 
|---|
| 38 |       static const char_type duration_sign_always[3];                    // + | 
|---|
| 39 |       static const char_type duration_seperator[2]; | 
|---|
| 40 |       static const char_type negative_sign[2];                           //- | 
|---|
| 41 |       static const char_type positive_sign[2];                           //+ | 
|---|
| 42 |       static const char_type iso_time_format_specifier[18]; | 
|---|
| 43 |       static const char_type iso_time_format_extended_specifier[22]; | 
|---|
| 44 |       //default ptime format is YYYY-Mon-DD HH:MM:SS[.fff...][ zzz] | 
|---|
| 45 |       static const char_type default_time_format[23];  | 
|---|
| 46 |       // default_time_input_format uses a posix_time_zone_string instead of a time zone abbrev | 
|---|
| 47 |       static const char_type default_time_input_format[24];  | 
|---|
| 48 |       //default time_duration format is HH:MM:SS[.fff...] | 
|---|
| 49 |       static const char_type default_time_duration_format[11]; | 
|---|
| 50 |   }; | 
|---|
| 51 |  | 
|---|
| 52 |   template <class CharT>   | 
|---|
| 53 |   const typename time_formats<CharT>::char_type  | 
|---|
| 54 |   time_formats<CharT>::fractional_seconds_format[3] = {'%','f'}; | 
|---|
| 55 |  | 
|---|
| 56 |   template <class CharT>   | 
|---|
| 57 |   const typename time_formats<CharT>::char_type  | 
|---|
| 58 |   time_formats<CharT>::fractional_seconds_or_none_format[3] = {'%','F'}; | 
|---|
| 59 |  | 
|---|
| 60 |   template <class CharT>   | 
|---|
| 61 |   const typename time_formats<CharT>::char_type  | 
|---|
| 62 |   time_formats<CharT>::seconds_with_fractional_seconds_format[3] =  | 
|---|
| 63 |     {'%','s'}; | 
|---|
| 64 |  | 
|---|
| 65 |   template <class CharT>   | 
|---|
| 66 |   const typename time_formats<CharT>::char_type  | 
|---|
| 67 |   time_formats<CharT>::seconds_format[3] =  {'%','S'}; | 
|---|
| 68 |  | 
|---|
| 69 |   template <class CharT>   | 
|---|
| 70 |   const typename time_formats<CharT>::char_type  | 
|---|
| 71 |   //time_formats<CharT>::standard_format[5] =  {'%','c',' ','%','z'}; | 
|---|
| 72 |   time_formats<CharT>::standard_format[9] =  {'%','x',' ','%','X',' ','%','z'}; | 
|---|
| 73 |  | 
|---|
| 74 |   template <class CharT>   | 
|---|
| 75 |   const typename time_formats<CharT>::char_type  | 
|---|
| 76 |   time_formats<CharT>::zone_abbrev_format[3] =  {'%','z'}; | 
|---|
| 77 |  | 
|---|
| 78 |   template <class CharT>   | 
|---|
| 79 |   const typename time_formats<CharT>::char_type  | 
|---|
| 80 |   time_formats<CharT>::zone_name_format[3] =  {'%','Z'}; | 
|---|
| 81 |  | 
|---|
| 82 |   template <class CharT>   | 
|---|
| 83 |   const typename time_formats<CharT>::char_type  | 
|---|
| 84 |   time_formats<CharT>::zone_iso_format[3] =  {'%','q'}; | 
|---|
| 85 |  | 
|---|
| 86 |   template <class CharT>   | 
|---|
| 87 |   const typename time_formats<CharT>::char_type  | 
|---|
| 88 |   time_formats<CharT>::zone_iso_extended_format[3] ={'%','Q'}; | 
|---|
| 89 |  | 
|---|
| 90 |   template <class CharT>   | 
|---|
| 91 |   const typename time_formats<CharT>::char_type  | 
|---|
| 92 |   time_formats<CharT>::posix_zone_string_format[4] ={'%','Z','P'}; | 
|---|
| 93 |  | 
|---|
| 94 |   template <class CharT>   | 
|---|
| 95 |   const typename time_formats<CharT>::char_type  | 
|---|
| 96 |   time_formats<CharT>::duration_seperator[2] =  {':'}; | 
|---|
| 97 |  | 
|---|
| 98 |   template <class CharT>   | 
|---|
| 99 |   const typename time_formats<CharT>::char_type  | 
|---|
| 100 |   time_formats<CharT>::negative_sign[2] =  {'-'}; | 
|---|
| 101 |  | 
|---|
| 102 |   template <class CharT>   | 
|---|
| 103 |   const typename time_formats<CharT>::char_type  | 
|---|
| 104 |   time_formats<CharT>::positive_sign[2] =  {'+'}; | 
|---|
| 105 |  | 
|---|
| 106 |   template <class CharT>   | 
|---|
| 107 |   const typename time_formats<CharT>::char_type  | 
|---|
| 108 |   time_formats<CharT>::duration_sign_negative_only[3] ={'%','-'}; | 
|---|
| 109 |  | 
|---|
| 110 |   template <class CharT>   | 
|---|
| 111 |   const typename time_formats<CharT>::char_type  | 
|---|
| 112 |   time_formats<CharT>::duration_sign_always[3] ={'%','+'}; | 
|---|
| 113 |  | 
|---|
| 114 |   template <class CharT>   | 
|---|
| 115 |   const typename time_formats<CharT>::char_type  | 
|---|
| 116 |   time_formats<CharT>::iso_time_format_specifier[18] =   | 
|---|
| 117 |     {'%', 'Y', '%', 'm', '%', 'd', 'T',  | 
|---|
| 118 |      '%', 'H', '%', 'M', '%', 'S', '%', 'F', '%','q' }; | 
|---|
| 119 |  | 
|---|
| 120 |   template <class CharT>   | 
|---|
| 121 |   const typename time_formats<CharT>::char_type  | 
|---|
| 122 |   time_formats<CharT>::iso_time_format_extended_specifier[22] =   | 
|---|
| 123 |     {'%', 'Y', '-', '%', 'm', '-', '%', 'd', ' ',  | 
|---|
| 124 |      '%', 'H', ':', '%', 'M', ':', '%', 'S', '%', 'F','%','Q'}; | 
|---|
| 125 |  | 
|---|
| 126 |   template <class CharT>   | 
|---|
| 127 |   const typename time_formats<CharT>::char_type  | 
|---|
| 128 |   time_formats<CharT>::default_time_format[23] =  | 
|---|
| 129 |     {'%','Y','-','%','b','-','%','d',' ', | 
|---|
| 130 |       '%','H',':','%','M',':','%','S','%','F',' ','%','z'}; | 
|---|
| 131 |  | 
|---|
| 132 |   template <class CharT>   | 
|---|
| 133 |   const typename time_formats<CharT>::char_type  | 
|---|
| 134 |   time_formats<CharT>::default_time_input_format[24] =  | 
|---|
| 135 |     {'%','Y','-','%','b','-','%','d',' ', | 
|---|
| 136 |       '%','H',':','%','M',':','%','S','%','F',' ','%','Z','P'}; | 
|---|
| 137 |  | 
|---|
| 138 |   template <class CharT>   | 
|---|
| 139 |   const typename time_formats<CharT>::char_type  | 
|---|
| 140 |   time_formats<CharT>::default_time_duration_format[11] =  | 
|---|
| 141 |     {'%','H',':','%','M',':','%','S','%','F'}; | 
|---|
| 142 |  | 
|---|
| 143 |  | 
|---|
| 144 |  | 
|---|
| 145 |   /*! Facet used for format-based output of time types  | 
|---|
| 146 |    * This class provides for the use of format strings to output times.  In addition | 
|---|
| 147 |    * to the flags for formatting date elements, the following are the allowed format flags: | 
|---|
| 148 |    *  - %x %X => default format - enables addition of more flags to default (ie. "%x %X %z") | 
|---|
| 149 |    *  - %f => fractional seconds ".123456" | 
|---|
| 150 |    *  - %F => fractional seconds or none: like frac sec but empty if frac sec == 0 | 
|---|
| 151 |    *  - %s => seconds w/ fractional sec "02.123" (this is the same as "%S%f)  | 
|---|
| 152 |    *  - %S => seconds "02" | 
|---|
| 153 |    *  - %z => abbreviated time zone "EDT" | 
|---|
| 154 |    *  - %Z => full time zone name "Eastern Daylight Time" | 
|---|
| 155 |    */ | 
|---|
| 156 |   template <class time_type, | 
|---|
| 157 |             class CharT,  | 
|---|
| 158 |             class OutItrT = std::ostreambuf_iterator<CharT, std::char_traits<CharT> > > | 
|---|
| 159 |   class time_facet :  | 
|---|
| 160 |     public boost::date_time::date_facet<typename time_type::date_type , CharT, OutItrT> { | 
|---|
| 161 |    public: | 
|---|
| 162 |     typedef typename time_type::date_type date_type; | 
|---|
| 163 |     typedef typename time_type::time_duration_type time_duration_type; | 
|---|
| 164 |     typedef boost::date_time::period<time_type,time_duration_type> period_type; | 
|---|
| 165 |     typedef boost::date_time::date_facet<typename time_type::date_type, CharT, OutItrT> base_type; | 
|---|
| 166 |     typedef typename base_type::string_type string_type; | 
|---|
| 167 |     typedef typename base_type::char_type   char_type; | 
|---|
| 168 |     typedef typename base_type::period_formatter_type period_formatter_type; | 
|---|
| 169 |     typedef typename base_type::special_values_formatter_type special_values_formatter_type; | 
|---|
| 170 |     typedef typename base_type::date_gen_formatter_type date_gen_formatter_type; | 
|---|
| 171 |     static const char_type* fractional_seconds_format;                // %f | 
|---|
| 172 |     static const char_type* fractional_seconds_or_none_format;        // %F | 
|---|
| 173 |     static const char_type* seconds_with_fractional_seconds_format;   // %s | 
|---|
| 174 |     static const char_type* seconds_format;                           // %S | 
|---|
| 175 |     static const char_type* standard_format;                          // %x X | 
|---|
| 176 |     static const char_type* zone_abbrev_format;                       // %z | 
|---|
| 177 |     static const char_type* zone_name_format;                         // %Z | 
|---|
| 178 |     static const char_type* zone_iso_format;                          // %q | 
|---|
| 179 |     static const char_type* zone_iso_extended_format;                 // %Q | 
|---|
| 180 |     static const char_type* posix_zone_string_format;                 // %ZP | 
|---|
| 181 |     static const char_type* duration_seperator; | 
|---|
| 182 |     static const char_type* duration_sign_always;                     // %+ | 
|---|
| 183 |     static const char_type* duration_sign_negative_only;              // %- | 
|---|
| 184 |     static const char_type* negative_sign;                            //- | 
|---|
| 185 |     static const char_type* positive_sign;                            //+ | 
|---|
| 186 |     static const char_type* iso_time_format_specifier; | 
|---|
| 187 |     static const char_type* iso_time_format_extended_specifier; | 
|---|
| 188 |  | 
|---|
| 189 |     //default ptime format is YYYY-Mon-DD HH:MM:SS[.fff...][ zzz] | 
|---|
| 190 |     static const char_type* default_time_format;  | 
|---|
| 191 |     //default time_duration format is HH:MM:SS[.fff...] | 
|---|
| 192 |     static const char_type* default_time_duration_format; | 
|---|
| 193 |     static std::locale::id id; | 
|---|
| 194 |  | 
|---|
| 195 | #if defined (__SUNPRO_CC) && defined (_RWSTD_VER) | 
|---|
| 196 |       std::locale::id& __get_id (void) const { return id; } | 
|---|
| 197 | #endif | 
|---|
| 198 |  | 
|---|
| 199 |     //! sets default formats for ptime, local_date_time, and time_duration | 
|---|
| 200 |     explicit time_facet(::size_t a_ref = 0)  | 
|---|
| 201 |       //: base_type(standard_format), | 
|---|
| 202 |       : base_type(default_time_format),  | 
|---|
| 203 |         m_time_duration_format(string_type(duration_sign_negative_only) + default_time_duration_format) | 
|---|
| 204 |     {} | 
|---|
| 205 |  | 
|---|
| 206 |     //! Construct the facet with an explicitly specified format | 
|---|
| 207 |     explicit time_facet(const char_type* a_format, | 
|---|
| 208 |                         period_formatter_type period_formatter = period_formatter_type(),  | 
|---|
| 209 |                         const special_values_formatter_type& special_value_formatter = special_values_formatter_type(),  | 
|---|
| 210 |                         date_gen_formatter_type dg_formatter = date_gen_formatter_type(), | 
|---|
| 211 |                          ::size_t a_ref = 0)  | 
|---|
| 212 |       : base_type(a_format,  | 
|---|
| 213 |                   period_formatter, | 
|---|
| 214 |                   special_value_formatter,  | 
|---|
| 215 |                   dg_formatter,  | 
|---|
| 216 |                   a_ref), | 
|---|
| 217 |         m_time_duration_format(string_type(duration_sign_negative_only) + default_time_duration_format) | 
|---|
| 218 |     {} | 
|---|
| 219 |  | 
|---|
| 220 |     //! Changes format for time_duration | 
|---|
| 221 |     void time_duration_format(const char_type* const format)  | 
|---|
| 222 |     { | 
|---|
| 223 |       m_time_duration_format = format; | 
|---|
| 224 |     } | 
|---|
| 225 |  | 
|---|
| 226 |     virtual void set_iso_format() | 
|---|
| 227 |     { | 
|---|
| 228 |       this->m_format = iso_time_format_specifier; | 
|---|
| 229 |     } | 
|---|
| 230 |     virtual void set_iso_extended_format() | 
|---|
| 231 |     { | 
|---|
| 232 |       this->m_format = iso_time_format_extended_specifier; | 
|---|
| 233 |     } | 
|---|
| 234 |  | 
|---|
| 235 |     OutItrT put(OutItrT a_next,  | 
|---|
| 236 |                 std::ios_base& a_ios,  | 
|---|
| 237 |                 char_type a_fill,  | 
|---|
| 238 |                 const time_type& a_time) const  | 
|---|
| 239 |     { | 
|---|
| 240 |       if (a_time.is_special()) {  | 
|---|
| 241 |         return this->do_put_special(a_next, a_ios, a_fill,  | 
|---|
| 242 |                               a_time.date().as_special()); | 
|---|
| 243 |       } | 
|---|
| 244 |       string_type format(this->m_format); | 
|---|
| 245 |       string_type frac_str; | 
|---|
| 246 |       if (format.find(seconds_with_fractional_seconds_format) != string_type::npos) { | 
|---|
| 247 |         // replace %s with %S.nnn  | 
|---|
| 248 |         frac_str =  | 
|---|
| 249 |           fractional_seconds_as_string(a_time.time_of_day(), false); | 
|---|
| 250 |         char_type sep = std::use_facet<std::numpunct<char_type> >(a_ios.getloc()).decimal_point(); | 
|---|
| 251 |          | 
|---|
| 252 |         string_type replace_string(seconds_format); | 
|---|
| 253 |         replace_string += sep; | 
|---|
| 254 |         replace_string += frac_str; | 
|---|
| 255 |         boost::algorithm::replace_all(format,  | 
|---|
| 256 |                                       seconds_with_fractional_seconds_format,  | 
|---|
| 257 |                                       replace_string); | 
|---|
| 258 |       } | 
|---|
| 259 |       /* NOTE: replacing posix_zone_string_format must be done BEFORE | 
|---|
| 260 |        * zone_name_format: "%ZP" & "%Z", if Z is checked first it will  | 
|---|
| 261 |        * incorrectly replace a zone_name where a posix_string should go */ | 
|---|
| 262 |       if (format.find(posix_zone_string_format) != string_type::npos) { | 
|---|
| 263 |         if(a_time.zone_abbrev().empty()) { | 
|---|
| 264 |           // if zone_abbrev() returns an empty string, we want to | 
|---|
| 265 |           // erase posix_zone_string_format from format | 
|---|
| 266 |           boost::algorithm::replace_all(format, | 
|---|
| 267 |                                         posix_zone_string_format, | 
|---|
| 268 |                                         ""); | 
|---|
| 269 |         } | 
|---|
| 270 |         else{ | 
|---|
| 271 |           boost::algorithm::replace_all(format, | 
|---|
| 272 |                                         posix_zone_string_format, | 
|---|
| 273 |                                         a_time.zone_as_posix_string()); | 
|---|
| 274 |         } | 
|---|
| 275 |       } | 
|---|
| 276 |       if (format.find(zone_name_format) != string_type::npos) { | 
|---|
| 277 |         if(a_time.zone_name().empty()) { | 
|---|
| 278 |           /* TODO: this'll probably create problems if a user places  | 
|---|
| 279 |            * the zone_*_format flag in the format with a ptime. This  | 
|---|
| 280 |            * code removes the flag from the default formats */ | 
|---|
| 281 |  | 
|---|
| 282 |           // if zone_name() returns an empty string, we want to | 
|---|
| 283 |           // erase zone_name_format & one preceeding space | 
|---|
| 284 |           std::basic_ostringstream<char_type> ss; | 
|---|
| 285 |           ss << ' ' << zone_name_format; | 
|---|
| 286 |           boost::algorithm::replace_all(format, | 
|---|
| 287 |                                         ss.str(), | 
|---|
| 288 |                                         ""); | 
|---|
| 289 |         } | 
|---|
| 290 |         else{ | 
|---|
| 291 |           boost::algorithm::replace_all(format, | 
|---|
| 292 |                                         zone_name_format, | 
|---|
| 293 |                                         a_time.zone_name()); | 
|---|
| 294 |         } | 
|---|
| 295 |       } | 
|---|
| 296 |       if (format.find(zone_abbrev_format) != string_type::npos) { | 
|---|
| 297 |         if(a_time.zone_abbrev(false).empty()) { | 
|---|
| 298 |           /* TODO: this'll probably create problems if a user places  | 
|---|
| 299 |            * the zone_*_format flag in the format with a ptime. This  | 
|---|
| 300 |            * code removes the flag from the default formats */ | 
|---|
| 301 |  | 
|---|
| 302 |           // if zone_abbrev() returns an empty string, we want to | 
|---|
| 303 |           // erase zone_abbrev_format & one preceeding space | 
|---|
| 304 |           std::basic_ostringstream<char_type> ss; | 
|---|
| 305 |           ss << ' ' << zone_abbrev_format; | 
|---|
| 306 |           boost::algorithm::replace_all(format, | 
|---|
| 307 |                                         ss.str(), | 
|---|
| 308 |                                         ""); | 
|---|
| 309 |         } | 
|---|
| 310 |         else{ | 
|---|
| 311 |           boost::algorithm::replace_all(format, | 
|---|
| 312 |                                         zone_abbrev_format, | 
|---|
| 313 |                                         a_time.zone_abbrev(false)); | 
|---|
| 314 |         } | 
|---|
| 315 |       } | 
|---|
| 316 |       if (format.find(zone_iso_extended_format) != string_type::npos) { | 
|---|
| 317 |         if(a_time.zone_name(true).empty()) { | 
|---|
| 318 |           /* TODO: this'll probably create problems if a user places  | 
|---|
| 319 |            * the zone_*_format flag in the format with a ptime. This  | 
|---|
| 320 |            * code removes the flag from the default formats */ | 
|---|
| 321 |  | 
|---|
| 322 |           // if zone_name() returns an empty string, we want to | 
|---|
| 323 |           // erase zone_iso_extended_format from format | 
|---|
| 324 |           boost::algorithm::replace_all(format, | 
|---|
| 325 |                                         zone_iso_extended_format, | 
|---|
| 326 |                                         ""); | 
|---|
| 327 |         } | 
|---|
| 328 |         else{ | 
|---|
| 329 |           boost::algorithm::replace_all(format, | 
|---|
| 330 |                                         zone_iso_extended_format, | 
|---|
| 331 |                                         a_time.zone_name(true)); | 
|---|
| 332 |         } | 
|---|
| 333 |       } | 
|---|
| 334 |  | 
|---|
| 335 |       if (format.find(zone_iso_format) != string_type::npos) { | 
|---|
| 336 |         if(a_time.zone_abbrev(true).empty()) { | 
|---|
| 337 |           /* TODO: this'll probably create problems if a user places  | 
|---|
| 338 |            * the zone_*_format flag in the format with a ptime. This  | 
|---|
| 339 |            * code removes the flag from the default formats */ | 
|---|
| 340 |  | 
|---|
| 341 |           // if zone_abbrev() returns an empty string, we want to | 
|---|
| 342 |           // erase zone_iso_format from format | 
|---|
| 343 |           boost::algorithm::replace_all(format, | 
|---|
| 344 |                                         zone_iso_format, | 
|---|
| 345 |                                         ""); | 
|---|
| 346 |         } | 
|---|
| 347 |         else{ | 
|---|
| 348 |           boost::algorithm::replace_all(format, | 
|---|
| 349 |                                         zone_iso_format, | 
|---|
| 350 |                                         a_time.zone_abbrev(true)); | 
|---|
| 351 |         } | 
|---|
| 352 |       } | 
|---|
| 353 |       if (format.find(fractional_seconds_format) != string_type::npos) { | 
|---|
| 354 |         // replace %f with nnnnnnn | 
|---|
| 355 |         if (!frac_str.size()) { | 
|---|
| 356 |           frac_str = fractional_seconds_as_string(a_time.time_of_day(), false); | 
|---|
| 357 |         } | 
|---|
| 358 |         boost::algorithm::replace_all(format, | 
|---|
| 359 |                                       fractional_seconds_format,  | 
|---|
| 360 |                                       frac_str); | 
|---|
| 361 |       } | 
|---|
| 362 |  | 
|---|
| 363 |       if (format.find(fractional_seconds_or_none_format) != string_type::npos) { | 
|---|
| 364 |         // replace %F with nnnnnnn or nothing if fs == 0 | 
|---|
| 365 |         frac_str =  | 
|---|
| 366 |           fractional_seconds_as_string(a_time.time_of_day(), true); | 
|---|
| 367 |         if (frac_str.size()) { | 
|---|
| 368 |           char_type sep = std::use_facet<std::numpunct<char_type> >(a_ios.getloc()).decimal_point(); | 
|---|
| 369 |           string_type replace_string; | 
|---|
| 370 |           replace_string += sep; | 
|---|
| 371 |           replace_string += frac_str; | 
|---|
| 372 |           boost::algorithm::replace_all(format, | 
|---|
| 373 |                                         fractional_seconds_or_none_format,  | 
|---|
| 374 |                                         replace_string); | 
|---|
| 375 |         } | 
|---|
| 376 |         else { | 
|---|
| 377 |           boost::algorithm::erase_all(format, | 
|---|
| 378 |                                       fractional_seconds_or_none_format); | 
|---|
| 379 |         } | 
|---|
| 380 |       } | 
|---|
| 381 |  | 
|---|
| 382 |       return this->do_put_tm(a_next, a_ios, a_fill,  | 
|---|
| 383 |                        to_tm(a_time), format); | 
|---|
| 384 |     } | 
|---|
| 385 |  | 
|---|
| 386 |     //! put function for time_duration | 
|---|
| 387 |     OutItrT put(OutItrT a_next,  | 
|---|
| 388 |                 std::ios_base& a_ios,  | 
|---|
| 389 |                 char_type a_fill,  | 
|---|
| 390 |                 const time_duration_type& a_time_dur) const  | 
|---|
| 391 |     { | 
|---|
| 392 |       if (a_time_dur.is_special()) {  | 
|---|
| 393 |         return this->do_put_special(a_next, a_ios, a_fill,  | 
|---|
| 394 |                               a_time_dur.get_rep().as_special()); | 
|---|
| 395 |       } | 
|---|
| 396 |  | 
|---|
| 397 |       string_type format(m_time_duration_format); | 
|---|
| 398 |       if (a_time_dur.is_negative()) { | 
|---|
| 399 |           // replace %- with minus sign.  Should we use the numpunct facet? | 
|---|
| 400 |           boost::algorithm::replace_all(format,  | 
|---|
| 401 |                                         duration_sign_negative_only,  | 
|---|
| 402 |                                         negative_sign); | 
|---|
| 403 |           // remove all the %+ in the string with '-' | 
|---|
| 404 |           boost::algorithm::replace_all(format,  | 
|---|
| 405 |                                         duration_sign_always,  | 
|---|
| 406 |                                         negative_sign); | 
|---|
| 407 |       } | 
|---|
| 408 |       else { //duration is positive | 
|---|
| 409 |           // remove all the %- combos from the string | 
|---|
| 410 |           boost::algorithm::replace_all(format,  | 
|---|
| 411 |                                         duration_sign_negative_only,  | 
|---|
| 412 |                                         ""); | 
|---|
| 413 |           // remove all the %+ in the string with '+' | 
|---|
| 414 |           boost::algorithm::replace_all(format,  | 
|---|
| 415 |                                         duration_sign_always,  | 
|---|
| 416 |                                         positive_sign); | 
|---|
| 417 |       } | 
|---|
| 418 |  | 
|---|
| 419 |       string_type frac_str; | 
|---|
| 420 |       if (format.find(seconds_with_fractional_seconds_format) != string_type::npos) { | 
|---|
| 421 |         // replace %s with %S.nnn  | 
|---|
| 422 |         frac_str =  | 
|---|
| 423 |           fractional_seconds_as_string(a_time_dur, false); | 
|---|
| 424 |         char_type sep = std::use_facet<std::numpunct<char_type> >(a_ios.getloc()).decimal_point(); | 
|---|
| 425 |          | 
|---|
| 426 |         string_type replace_string(seconds_format); | 
|---|
| 427 |         replace_string += sep; | 
|---|
| 428 |         replace_string += frac_str; | 
|---|
| 429 |         boost::algorithm::replace_all(format,  | 
|---|
| 430 |                                       seconds_with_fractional_seconds_format,  | 
|---|
| 431 |                                       replace_string); | 
|---|
| 432 |       } | 
|---|
| 433 |       if (format.find(fractional_seconds_format) != string_type::npos) { | 
|---|
| 434 |         // replace %f with nnnnnnn | 
|---|
| 435 |         if (!frac_str.size()) { | 
|---|
| 436 |           frac_str = fractional_seconds_as_string(a_time_dur, false); | 
|---|
| 437 |         } | 
|---|
| 438 |         boost::algorithm::replace_all(format, | 
|---|
| 439 |                                       fractional_seconds_format,  | 
|---|
| 440 |                                       frac_str); | 
|---|
| 441 |       } | 
|---|
| 442 |  | 
|---|
| 443 |       if (format.find(fractional_seconds_or_none_format) != string_type::npos) { | 
|---|
| 444 |         // replace %F with nnnnnnn or nothing if fs == 0 | 
|---|
| 445 |         frac_str =  | 
|---|
| 446 |           fractional_seconds_as_string(a_time_dur, true); | 
|---|
| 447 |         if (frac_str.size()) { | 
|---|
| 448 |           char_type sep = std::use_facet<std::numpunct<char_type> >(a_ios.getloc()).decimal_point(); | 
|---|
| 449 |           string_type replace_string; | 
|---|
| 450 |           replace_string += sep; | 
|---|
| 451 |           replace_string += frac_str; | 
|---|
| 452 |           boost::algorithm::replace_all(format, | 
|---|
| 453 |                                         fractional_seconds_or_none_format,  | 
|---|
| 454 |                                         replace_string); | 
|---|
| 455 |         } | 
|---|
| 456 |         else { | 
|---|
| 457 |           boost::algorithm::erase_all(format, | 
|---|
| 458 |                                       fractional_seconds_or_none_format); | 
|---|
| 459 |         } | 
|---|
| 460 |       } | 
|---|
| 461 |  | 
|---|
| 462 |       return this->do_put_tm(a_next, a_ios, a_fill,  | 
|---|
| 463 |                        to_tm(a_time_dur), format); | 
|---|
| 464 |     } | 
|---|
| 465 |      | 
|---|
| 466 |     OutItrT put(OutItrT next, std::ios_base& a_ios,  | 
|---|
| 467 |                 char_type fill, const period_type& p) const  | 
|---|
| 468 |     { | 
|---|
| 469 |       return this->m_period_formatter.put_period(next, a_ios, fill,p,*this); | 
|---|
| 470 |     } | 
|---|
| 471 |  | 
|---|
| 472 |  | 
|---|
| 473 |   protected: | 
|---|
| 474 |  | 
|---|
| 475 |     static  | 
|---|
| 476 |     string_type  | 
|---|
| 477 |     fractional_seconds_as_string(const time_duration_type& a_time, | 
|---|
| 478 |                                  bool null_when_zero)  | 
|---|
| 479 |     { | 
|---|
| 480 |       typename time_duration_type::fractional_seconds_type frac_sec =  | 
|---|
| 481 |         a_time.fractional_seconds(); | 
|---|
| 482 |  | 
|---|
| 483 |       if (null_when_zero && (frac_sec == 0)) { | 
|---|
| 484 |         return string_type(); | 
|---|
| 485 |       } | 
|---|
| 486 |  | 
|---|
| 487 |       //make sure there is no sign | 
|---|
| 488 |       frac_sec = date_time::absolute_value(frac_sec); | 
|---|
| 489 |       std::basic_ostringstream<char_type> ss; | 
|---|
| 490 |       ss.imbue(std::locale::classic()); // don't want any formatting | 
|---|
| 491 |       ss << std::setw(time_duration_type::num_fractional_digits()) | 
|---|
| 492 |          << std::setfill(static_cast<char_type>('0')); | 
|---|
| 493 | #if (defined(BOOST_MSVC) && (_MSC_VER < 1300)) | 
|---|
| 494 |       // JDG [7/6/02 VC++ compatibility] | 
|---|
| 495 |       char_type buff[34]; | 
|---|
| 496 |       ss << _i64toa(static_cast<boost::int64_t>(frac_sec), buff, 10); | 
|---|
| 497 | #else | 
|---|
| 498 |       ss << frac_sec; | 
|---|
| 499 | #endif | 
|---|
| 500 |       return ss.str(); | 
|---|
| 501 |     } | 
|---|
| 502 |  | 
|---|
| 503 |   private: | 
|---|
| 504 |     string_type m_time_duration_format; | 
|---|
| 505 |  | 
|---|
| 506 |   }; | 
|---|
| 507 |    | 
|---|
| 508 |   template <class time_type, class CharT, class OutItrT>   | 
|---|
| 509 |   std::locale::id time_facet<time_type, CharT, OutItrT>::id; | 
|---|
| 510 |  | 
|---|
| 511 |   template <class time_type, class CharT, class OutItrT>   | 
|---|
| 512 |   const typename time_facet<time_type, CharT, OutItrT>::char_type*  | 
|---|
| 513 |   time_facet<time_type, CharT, OutItrT>::fractional_seconds_format = time_formats<CharT>::fractional_seconds_format; | 
|---|
| 514 |  | 
|---|
| 515 |   template <class time_type, class CharT, class OutItrT>   | 
|---|
| 516 |   const typename time_facet<time_type, CharT, OutItrT>::char_type*  | 
|---|
| 517 |   time_facet<time_type, CharT, OutItrT>::fractional_seconds_or_none_format = time_formats<CharT>::fractional_seconds_or_none_format; | 
|---|
| 518 |  | 
|---|
| 519 |   template <class time_type, class CharT, class OutItrT>   | 
|---|
| 520 |   const typename time_facet<time_type, CharT, OutItrT>::char_type*  | 
|---|
| 521 |   time_facet<time_type, CharT, OutItrT>::seconds_with_fractional_seconds_format =  | 
|---|
| 522 |     time_formats<CharT>::seconds_with_fractional_seconds_format; | 
|---|
| 523 |  | 
|---|
| 524 |  | 
|---|
| 525 |   template <class time_type, class CharT, class OutItrT>   | 
|---|
| 526 |   const typename time_facet<time_type, CharT, OutItrT>::char_type* | 
|---|
| 527 |   time_facet<time_type, CharT, OutItrT>::zone_name_format =  time_formats<CharT>::zone_name_format; | 
|---|
| 528 |  | 
|---|
| 529 |   template <class time_type, class CharT, class OutItrT>   | 
|---|
| 530 |   const typename time_facet<time_type, CharT, OutItrT>::char_type* | 
|---|
| 531 |   time_facet<time_type, CharT, OutItrT>::zone_abbrev_format =  time_formats<CharT>::zone_abbrev_format; | 
|---|
| 532 |  | 
|---|
| 533 |   template <class time_type, class CharT, class OutItrT>   | 
|---|
| 534 |   const typename time_facet<time_type, CharT, OutItrT>::char_type* | 
|---|
| 535 |   time_facet<time_type, CharT, OutItrT>::zone_iso_extended_format =time_formats<CharT>::zone_iso_extended_format; | 
|---|
| 536 |  | 
|---|
| 537 |   template <class time_type, class CharT, class OutItrT>   | 
|---|
| 538 |   const typename time_facet<time_type, CharT, OutItrT>::char_type* | 
|---|
| 539 |   time_facet<time_type, CharT, OutItrT>::posix_zone_string_format =time_formats<CharT>::posix_zone_string_format; | 
|---|
| 540 |  | 
|---|
| 541 |   template <class time_type, class CharT, class OutItrT>   | 
|---|
| 542 |   const typename time_facet<time_type, CharT, OutItrT>::char_type* | 
|---|
| 543 |   time_facet<time_type, CharT, OutItrT>::zone_iso_format =  time_formats<CharT>::zone_iso_format; | 
|---|
| 544 |  | 
|---|
| 545 |   template <class time_type, class CharT, class OutItrT>   | 
|---|
| 546 |   const typename time_facet<time_type, CharT, OutItrT>::char_type* | 
|---|
| 547 |   time_facet<time_type, CharT, OutItrT>::seconds_format =  time_formats<CharT>::seconds_format; | 
|---|
| 548 |  | 
|---|
| 549 |   template <class time_type, class CharT, class OutItrT>   | 
|---|
| 550 |   const typename time_facet<time_type, CharT, OutItrT>::char_type* | 
|---|
| 551 |   time_facet<time_type, CharT, OutItrT>::standard_format =  time_formats<CharT>::standard_format; | 
|---|
| 552 |  | 
|---|
| 553 |   template <class time_type, class CharT, class OutItrT>   | 
|---|
| 554 |   const typename time_facet<time_type, CharT, OutItrT>::char_type* | 
|---|
| 555 |   time_facet<time_type, CharT, OutItrT>::duration_seperator =  time_formats<CharT>::duration_seperator; | 
|---|
| 556 |  | 
|---|
| 557 |   template <class time_type, class CharT, class OutItrT>   | 
|---|
| 558 |   const typename time_facet<time_type, CharT, OutItrT>::char_type* | 
|---|
| 559 |   time_facet<time_type, CharT, OutItrT>::negative_sign =  time_formats<CharT>::negative_sign; | 
|---|
| 560 |  | 
|---|
| 561 |   template <class time_type, class CharT, class OutItrT>   | 
|---|
| 562 |   const typename time_facet<time_type, CharT, OutItrT>::char_type* | 
|---|
| 563 |   time_facet<time_type, CharT, OutItrT>::positive_sign =  time_formats<CharT>::positive_sign; | 
|---|
| 564 |  | 
|---|
| 565 |   template <class time_type, class CharT, class OutItrT>   | 
|---|
| 566 |   const typename time_facet<time_type, CharT, OutItrT>::char_type* | 
|---|
| 567 |   time_facet<time_type, CharT, OutItrT>::duration_sign_negative_only =  time_formats<CharT>::duration_sign_negative_only; | 
|---|
| 568 |  | 
|---|
| 569 |   template <class time_type, class CharT, class OutItrT>   | 
|---|
| 570 |   const typename time_facet<time_type, CharT, OutItrT>::char_type* | 
|---|
| 571 |   time_facet<time_type, CharT, OutItrT>::duration_sign_always =  time_formats<CharT>::duration_sign_always; | 
|---|
| 572 |  | 
|---|
| 573 |   template <class time_type, class CharT, class OutItrT>   | 
|---|
| 574 |   const typename time_facet<time_type,CharT, OutItrT>::char_type* | 
|---|
| 575 |   time_facet<time_type,CharT, OutItrT>::iso_time_format_specifier = time_formats<CharT>::iso_time_format_specifier; | 
|---|
| 576 |  | 
|---|
| 577 |   template <class time_type, class CharT, class OutItrT>   | 
|---|
| 578 |   const typename time_facet<time_type, CharT, OutItrT>::char_type* | 
|---|
| 579 |   time_facet<time_type, CharT, OutItrT>::iso_time_format_extended_specifier = time_formats<CharT>::iso_time_format_extended_specifier; | 
|---|
| 580 |  | 
|---|
| 581 |   template <class time_type, class CharT, class OutItrT>   | 
|---|
| 582 |   const typename time_facet<time_type, CharT, OutItrT>::char_type* | 
|---|
| 583 |   time_facet<time_type, CharT, OutItrT>::default_time_format =  | 
|---|
| 584 |     time_formats<CharT>::default_time_format; | 
|---|
| 585 |  | 
|---|
| 586 |   template <class time_type, class CharT, class OutItrT>   | 
|---|
| 587 |   const typename time_facet<time_type, CharT, OutItrT>::char_type*  | 
|---|
| 588 |   time_facet<time_type, CharT, OutItrT>::default_time_duration_format =  | 
|---|
| 589 |     time_formats<CharT>::default_time_duration_format; | 
|---|
| 590 |  | 
|---|
| 591 |  | 
|---|
| 592 |   //! Facet for format-based input.   | 
|---|
| 593 |   /*! | 
|---|
| 594 |    */ | 
|---|
| 595 |   template <class time_type, | 
|---|
| 596 |             class CharT,  | 
|---|
| 597 |             class InItrT = std::istreambuf_iterator<CharT, std::char_traits<CharT> > > | 
|---|
| 598 |   class time_input_facet :  | 
|---|
| 599 |     public boost::date_time::date_input_facet<typename time_type::date_type , CharT, InItrT> { | 
|---|
| 600 |     public: | 
|---|
| 601 |       typedef typename time_type::date_type date_type; | 
|---|
| 602 |       typedef typename time_type::time_duration_type time_duration_type; | 
|---|
| 603 |       typedef typename time_duration_type::fractional_seconds_type fracional_seconds_type; | 
|---|
| 604 |       typedef boost::date_time::period<time_type,time_duration_type> period_type; | 
|---|
| 605 |       typedef boost::date_time::date_input_facet<typename time_type::date_type, CharT, InItrT> base_type; | 
|---|
| 606 |       typedef typename base_type::duration_type date_duration_type; | 
|---|
| 607 |       typedef typename base_type::year_type year_type; | 
|---|
| 608 |       typedef typename base_type::month_type month_type; | 
|---|
| 609 |       typedef typename base_type::day_type day_type; | 
|---|
| 610 |       typedef typename base_type::string_type string_type; | 
|---|
| 611 |       typedef typename string_type::const_iterator const_itr; | 
|---|
| 612 |       typedef typename base_type::char_type   char_type; | 
|---|
| 613 |       typedef typename base_type::format_date_parser_type format_date_parser_type; | 
|---|
| 614 |       typedef typename base_type::period_parser_type period_parser_type; | 
|---|
| 615 |       typedef typename base_type::special_values_parser_type special_values_parser_type; | 
|---|
| 616 |       typedef typename base_type::date_gen_parser_type date_gen_parser_type; | 
|---|
| 617 |       typedef typename base_type::special_values_parser_type::match_results match_results; | 
|---|
| 618 |  | 
|---|
| 619 |       static const char_type* fractional_seconds_format;                // f | 
|---|
| 620 |       static const char_type* fractional_seconds_or_none_format;        // F | 
|---|
| 621 |       static const char_type* seconds_with_fractional_seconds_format;   // s | 
|---|
| 622 |       static const char_type* seconds_format;                           // S | 
|---|
| 623 |       static const char_type* standard_format;                          // x X | 
|---|
| 624 |       static const char_type* zone_abbrev_format;                       // z | 
|---|
| 625 |       static const char_type* zone_name_format;                         // Z | 
|---|
| 626 |       static const char_type* zone_iso_format;                          // q | 
|---|
| 627 |       static const char_type* zone_iso_extended_format;                 // Q | 
|---|
| 628 |       static const char_type* duration_seperator; | 
|---|
| 629 |       static const char_type* iso_time_format_specifier; | 
|---|
| 630 |       static const char_type* iso_time_format_extended_specifier; | 
|---|
| 631 |       static const char_type* default_time_input_format;  | 
|---|
| 632 |       static const char_type* default_time_duration_format; | 
|---|
| 633 |       static std::locale::id id; | 
|---|
| 634 |  | 
|---|
| 635 |       //! Constructor that takes a format string for a ptime | 
|---|
| 636 |       explicit time_input_facet(const string_type& format, ::size_t a_ref = 0)  | 
|---|
| 637 |         : base_type(format, a_ref),  | 
|---|
| 638 |           m_time_duration_format(default_time_duration_format) | 
|---|
| 639 |       { } | 
|---|
| 640 |  | 
|---|
| 641 |       explicit time_input_facet(const string_type& format, | 
|---|
| 642 |                                 const format_date_parser_type& date_parser, | 
|---|
| 643 |                                 const special_values_parser_type& sv_parser, | 
|---|
| 644 |                                 const period_parser_type& per_parser, | 
|---|
| 645 |                                 const date_gen_parser_type& date_gen_parser, | 
|---|
| 646 |                                 ::size_t a_ref = 0) | 
|---|
| 647 |         : base_type(format, | 
|---|
| 648 |                     date_parser, | 
|---|
| 649 |                     sv_parser, | 
|---|
| 650 |                     per_parser, | 
|---|
| 651 |                     date_gen_parser, | 
|---|
| 652 |                     a_ref),  | 
|---|
| 653 |           m_time_duration_format(default_time_duration_format) | 
|---|
| 654 |       {} | 
|---|
| 655 |  | 
|---|
| 656 |       //! sets default formats for ptime, local_date_time, and time_duration | 
|---|
| 657 |       explicit time_input_facet(::size_t a_ref = 0)  | 
|---|
| 658 |         : base_type(default_time_input_format, a_ref),  | 
|---|
| 659 |           m_time_duration_format(default_time_duration_format) | 
|---|
| 660 |       { } | 
|---|
| 661 |        | 
|---|
| 662 |       //! Set the format for time_duration | 
|---|
| 663 |       void time_duration_format(const char_type* const format) { | 
|---|
| 664 |         m_time_duration_format = format; | 
|---|
| 665 |       } | 
|---|
| 666 |       virtual void set_iso_format() | 
|---|
| 667 |       { | 
|---|
| 668 |         this->m_format = iso_time_format_specifier; | 
|---|
| 669 |       } | 
|---|
| 670 |       virtual void set_iso_extended_format() | 
|---|
| 671 |       { | 
|---|
| 672 |         this->m_format = iso_time_format_extended_specifier; | 
|---|
| 673 |       } | 
|---|
| 674 |        | 
|---|
| 675 |       InItrT get(InItrT& sitr, | 
|---|
| 676 |                  InItrT& stream_end, | 
|---|
| 677 |                  std::ios_base& a_ios, | 
|---|
| 678 |                  period_type& p) const | 
|---|
| 679 |       { | 
|---|
| 680 |         p = this->m_period_parser.get_period(sitr,  | 
|---|
| 681 |                                              stream_end,  | 
|---|
| 682 |                                              a_ios,  | 
|---|
| 683 |                                              p,  | 
|---|
| 684 |                                              time_duration_type::unit(),  | 
|---|
| 685 |                                              *this); | 
|---|
| 686 |         return sitr; | 
|---|
| 687 |       } | 
|---|
| 688 |        | 
|---|
| 689 |       //default ptime format is YYYY-Mon-DD HH:MM:SS[.fff...][ zzz] | 
|---|
| 690 |       //default time_duration format is %H:%M:%S%F HH:MM:SS[.fff...] | 
|---|
| 691 |  | 
|---|
| 692 |       InItrT get(InItrT& sitr,  | 
|---|
| 693 |                  InItrT& stream_end,  | 
|---|
| 694 |                  std::ios_base& a_ios,  | 
|---|
| 695 |                  time_duration_type& td) const | 
|---|
| 696 |       { | 
|---|
| 697 |         // skip leading whitespace | 
|---|
| 698 |         while((sitr != stream_end) && std::isspace(*sitr)) { ++sitr; } | 
|---|
| 699 |          | 
|---|
| 700 |         bool use_current_char = false; | 
|---|
| 701 |          | 
|---|
| 702 |         // num_get will consume the +/-, we may need a copy if special_value | 
|---|
| 703 |         char_type c = '\0'; | 
|---|
| 704 |         if((sitr != stream_end) && (*sitr == '-' || *sitr == '+')) { | 
|---|
| 705 |           c = *sitr; | 
|---|
| 706 |         } | 
|---|
| 707 |          | 
|---|
| 708 |         long hour = 0;  | 
|---|
| 709 |         long min = 0;  | 
|---|
| 710 |         long sec = 0;  | 
|---|
| 711 |         typename time_duration_type::fractional_seconds_type frac(0); | 
|---|
| 712 |          | 
|---|
| 713 |         typedef std::num_get<CharT, InItrT> num_get; | 
|---|
| 714 |         if(!std::has_facet<num_get>(a_ios.getloc())) { | 
|---|
| 715 |           num_get* ng = new num_get(); | 
|---|
| 716 |           std::locale loc = std::locale(a_ios.getloc(), ng); | 
|---|
| 717 |           a_ios.imbue(loc); | 
|---|
| 718 |         } | 
|---|
| 719 |         | 
|---|
| 720 |         const_itr itr(m_time_duration_format.begin()); | 
|---|
| 721 |         while (itr != m_time_duration_format.end() && (sitr != stream_end)) { | 
|---|
| 722 |           if (*itr == '%') { | 
|---|
| 723 |             itr++; | 
|---|
| 724 |             if (*itr != '%') { | 
|---|
| 725 |               switch(*itr) { | 
|---|
| 726 |               case 'H':  | 
|---|
| 727 |                 { | 
|---|
| 728 |                   match_results mr; | 
|---|
| 729 |                   hour = fixed_string_to_int<short, CharT>(sitr, stream_end, mr, 2); | 
|---|
| 730 |                   if(hour == -1){ | 
|---|
| 731 |                      return check_special_value(sitr, stream_end, td, c); | 
|---|
| 732 |                   } | 
|---|
| 733 |                   break; | 
|---|
| 734 |                 } | 
|---|
| 735 |               case 'M':  | 
|---|
| 736 |                 { | 
|---|
| 737 |                   match_results mr; | 
|---|
| 738 |                   min = fixed_string_to_int<short, CharT>(sitr, stream_end, mr, 2); | 
|---|
| 739 |                   if(min == -1){ | 
|---|
| 740 |                      return check_special_value(sitr, stream_end, td, c); | 
|---|
| 741 |                   } | 
|---|
| 742 |                   break; | 
|---|
| 743 |                 } | 
|---|
| 744 |               case 'S':  | 
|---|
| 745 |                 { | 
|---|
| 746 |                   match_results mr; | 
|---|
| 747 |                   sec = fixed_string_to_int<short, CharT>(sitr, stream_end, mr, 2); | 
|---|
| 748 |                   if(sec == -1){ | 
|---|
| 749 |                      return check_special_value(sitr, stream_end, td, c); | 
|---|
| 750 |                   } | 
|---|
| 751 |                   break; | 
|---|
| 752 |                 } | 
|---|
| 753 |               case 's': | 
|---|
| 754 |                 { | 
|---|
| 755 |                   match_results mr; | 
|---|
| 756 |                   sec = fixed_string_to_int<short, CharT>(sitr, stream_end, mr, 2); | 
|---|
| 757 |                   if(sec == -1){ | 
|---|
| 758 |                      return check_special_value(sitr, stream_end, td, c); | 
|---|
| 759 |                   } | 
|---|
| 760 |                   // %s is the same as %S%f so we drop through into %f | 
|---|
| 761 |                   //break; | 
|---|
| 762 |                 } | 
|---|
| 763 |               case 'f': | 
|---|
| 764 |                 { | 
|---|
| 765 |                   // check for decimal, check special_values if missing | 
|---|
| 766 |                   if(*sitr == '.') { | 
|---|
| 767 |                     ++sitr; | 
|---|
| 768 |                     parse_frac_type(sitr, stream_end, frac); | 
|---|
| 769 |                     // sitr will point to next expected char after this parsing  | 
|---|
| 770 |                     // is complete so no need to advance it | 
|---|
| 771 |                     use_current_char = true; | 
|---|
| 772 |                   } | 
|---|
| 773 |                   else { | 
|---|
| 774 |                     return check_special_value(sitr, stream_end, td, c); | 
|---|
| 775 |                   } | 
|---|
| 776 |                   break; | 
|---|
| 777 |                 } | 
|---|
| 778 |               case 'F':  | 
|---|
| 779 |                 { | 
|---|
| 780 |                   // check for decimal, skip if missing | 
|---|
| 781 |                   if(*sitr == '.') { | 
|---|
| 782 |                     ++sitr; | 
|---|
| 783 |                     parse_frac_type(sitr, stream_end, frac); | 
|---|
| 784 |                     // sitr will point to next expected char after this parsing  | 
|---|
| 785 |                     // is complete so no need to advance it | 
|---|
| 786 |                     use_current_char = true; | 
|---|
| 787 |                   } | 
|---|
| 788 |                   else { | 
|---|
| 789 |                     // nothing was parsed so we don't want to advance sitr | 
|---|
| 790 |                     use_current_char = true; | 
|---|
| 791 |                   } | 
|---|
| 792 |                   break; | 
|---|
| 793 |                 } | 
|---|
| 794 |               default: | 
|---|
| 795 |                 {} // ignore what we don't understand? | 
|---|
| 796 |               }// switch | 
|---|
| 797 |             } | 
|---|
| 798 |             else { // itr == '%', second consecutive | 
|---|
| 799 |               sitr++; | 
|---|
| 800 |             } | 
|---|
| 801 |          | 
|---|
| 802 |             itr++; //advance past format specifier | 
|---|
| 803 |           } | 
|---|
| 804 |           else {  //skip past chars in format and in buffer | 
|---|
| 805 |             itr++; | 
|---|
| 806 |             // set use_current_char when sitr is already  | 
|---|
| 807 |             // pointing at the next character to process | 
|---|
| 808 |             if (use_current_char) { | 
|---|
| 809 |               use_current_char = false; | 
|---|
| 810 |             } | 
|---|
| 811 |             else { | 
|---|
| 812 |               sitr++; | 
|---|
| 813 |             } | 
|---|
| 814 |           } | 
|---|
| 815 |         } | 
|---|
| 816 |  | 
|---|
| 817 |         td = time_duration_type(hour, min, sec, frac); | 
|---|
| 818 |         return sitr; | 
|---|
| 819 |       } | 
|---|
| 820 |      | 
|---|
| 821 |  | 
|---|
| 822 |       //! Parses a time object from the input stream | 
|---|
| 823 |       InItrT get(InItrT& sitr,  | 
|---|
| 824 |                  InItrT& stream_end,  | 
|---|
| 825 |                  std::ios_base& a_ios,  | 
|---|
| 826 |                  time_type& t) const | 
|---|
| 827 |       { | 
|---|
| 828 |         string_type tz_str; | 
|---|
| 829 |         return get(sitr, stream_end, a_ios, t, tz_str, false); | 
|---|
| 830 |       } | 
|---|
| 831 |       //! Expects a time_zone in the input stream | 
|---|
| 832 |       InItrT get_local_time(InItrT& sitr,  | 
|---|
| 833 |                             InItrT& stream_end,  | 
|---|
| 834 |                             std::ios_base& a_ios,  | 
|---|
| 835 |                             time_type& t, | 
|---|
| 836 |                             string_type& tz_str) const | 
|---|
| 837 |       { | 
|---|
| 838 |         return get(sitr, stream_end, a_ios, t, tz_str, true); | 
|---|
| 839 |       } | 
|---|
| 840 |  | 
|---|
| 841 |     protected: | 
|---|
| 842 |  | 
|---|
| 843 |       InItrT get(InItrT& sitr,  | 
|---|
| 844 |                  InItrT& stream_end,  | 
|---|
| 845 |                  std::ios_base& a_ios,  | 
|---|
| 846 |                  time_type& t, | 
|---|
| 847 |                  string_type& tz_str, | 
|---|
| 848 |                  bool time_is_local) const | 
|---|
| 849 |       { | 
|---|
| 850 |         // skip leading whitespace | 
|---|
| 851 |         while((sitr != stream_end) && std::isspace(*sitr)) { ++sitr; } | 
|---|
| 852 |          | 
|---|
| 853 |         bool use_current_char = false; | 
|---|
| 854 |         bool use_current_format_char = false; // used whith two character flags | 
|---|
| 855 |          | 
|---|
| 856 |         // num_get will consume the +/-, we may need a copy if special_value | 
|---|
| 857 |         char_type c = '\0'; | 
|---|
| 858 |         if((sitr != stream_end) && (*sitr == '-' || *sitr == '+')) { | 
|---|
| 859 |           c = *sitr; | 
|---|
| 860 |         } | 
|---|
| 861 |         | 
|---|
| 862 |         // time elements | 
|---|
| 863 |         long hour = 0;  | 
|---|
| 864 |         long min = 0;  | 
|---|
| 865 |         long sec = 0;  | 
|---|
| 866 |         typename time_duration_type::fractional_seconds_type frac(0); | 
|---|
| 867 |         // date elements | 
|---|
| 868 |         short day_of_year(0); | 
|---|
| 869 |         /* Initialized the following to their minimum values. These intermediate  | 
|---|
| 870 |          * objects are used so we get specific exceptions when part of the input  | 
|---|
| 871 |          * is unparsable.  | 
|---|
| 872 |          * Ex: "205-Jan-15" will throw a bad_year, "2005-Jsn-15"- bad_month, etc.*/ | 
|---|
| 873 |         year_type t_year(1400); | 
|---|
| 874 |         month_type t_month(1); | 
|---|
| 875 |         day_type t_day(1); | 
|---|
| 876 |          | 
|---|
| 877 |         typedef std::num_get<CharT, InItrT> num_get; | 
|---|
| 878 |         if(!std::has_facet<num_get>(a_ios.getloc())) { | 
|---|
| 879 |           num_get* ng = new num_get(); | 
|---|
| 880 |           std::locale loc = std::locale(a_ios.getloc(), ng); | 
|---|
| 881 |           a_ios.imbue(loc); | 
|---|
| 882 |         } | 
|---|
| 883 |         | 
|---|
| 884 |         const_itr itr(this->m_format.begin()); | 
|---|
| 885 |         while (itr != this->m_format.end() && (sitr != stream_end)) { | 
|---|
| 886 |           if (*itr == '%') { | 
|---|
| 887 |             itr++; | 
|---|
| 888 |             if (*itr != '%') { | 
|---|
| 889 |               // the cases are grouped by date & time flags - not alphabetical order | 
|---|
| 890 |               switch(*itr) { | 
|---|
| 891 |                 // date flags | 
|---|
| 892 |                 case 'Y': | 
|---|
| 893 |                 case 'y': | 
|---|
| 894 |                   { | 
|---|
| 895 |                     char_type cs[3] = { '%', *itr }; | 
|---|
| 896 |                     string_type s(cs); | 
|---|
| 897 |                     match_results mr; | 
|---|
| 898 |                     try { | 
|---|
| 899 |                       t_year = this->m_parser.parse_year(sitr, stream_end, s, mr); | 
|---|
| 900 |                     } | 
|---|
| 901 |                     catch(std::out_of_range bad_year) { // base class for bad_year exception | 
|---|
| 902 |                       if(this->m_sv_parser.match(sitr, stream_end, mr)) { | 
|---|
| 903 |                         t = time_type(static_cast<special_values>(mr.current_match)); | 
|---|
| 904 |                         return sitr; | 
|---|
| 905 |                       } | 
|---|
| 906 |                       else { | 
|---|
| 907 |                         throw; // rethrow bad_year | 
|---|
| 908 |                       } | 
|---|
| 909 |                     } | 
|---|
| 910 |                     break; | 
|---|
| 911 |                   } | 
|---|
| 912 |                 case 'B': | 
|---|
| 913 |                 case 'b': | 
|---|
| 914 |                 case 'm': | 
|---|
| 915 |                   { | 
|---|
| 916 |                     char_type cs[3] = { '%', *itr }; | 
|---|
| 917 |                     string_type s(cs); | 
|---|
| 918 |                     match_results mr; | 
|---|
| 919 |                     try { | 
|---|
| 920 |                       t_month = this->m_parser.parse_month(sitr, stream_end, s, mr); | 
|---|
| 921 |                     } | 
|---|
| 922 |                     catch(std::out_of_range bad_month) { // base class for bad_month exception | 
|---|
| 923 |                       if(this->m_sv_parser.match(sitr, stream_end, mr)) { | 
|---|
| 924 |                         t = time_type(static_cast<special_values>(mr.current_match)); | 
|---|
| 925 |                         return sitr; | 
|---|
| 926 |                       } | 
|---|
| 927 |                       else { | 
|---|
| 928 |                         throw; // rethrow bad_year | 
|---|
| 929 |                       } | 
|---|
| 930 |                     } | 
|---|
| 931 |                     // did m_parser already advance sitr to next char? | 
|---|
| 932 |                     if(mr.has_remaining()) { | 
|---|
| 933 |                       use_current_char = true; | 
|---|
| 934 |                     } | 
|---|
| 935 |                     break; | 
|---|
| 936 |                   } | 
|---|
| 937 |                 case 'a': | 
|---|
| 938 |                 case 'A': | 
|---|
| 939 |                 case 'w': | 
|---|
| 940 |                   { | 
|---|
| 941 |                     // weekday is not used in construction but we need to get it out of the stream | 
|---|
| 942 |                     char_type cs[3] = { '%', *itr }; | 
|---|
| 943 |                     string_type s(cs); | 
|---|
| 944 |                     match_results mr; | 
|---|
| 945 |                     typename date_type::day_of_week_type wd(0); | 
|---|
| 946 |                     try { | 
|---|
| 947 |                       wd = this->m_parser.parse_weekday(sitr, stream_end, s, mr); | 
|---|
| 948 |                     } | 
|---|
| 949 |                     catch(std::out_of_range bad_weekday) { // base class for bad_weekday exception | 
|---|
| 950 |                       if(this->m_sv_parser.match(sitr, stream_end, mr)) { | 
|---|
| 951 |                         t = time_type(static_cast<special_values>(mr.current_match)); | 
|---|
| 952 |                         return sitr; | 
|---|
| 953 |                       } | 
|---|
| 954 |                       else { | 
|---|
| 955 |                         throw; // rethrow bad_weekday | 
|---|
| 956 |                       } | 
|---|
| 957 |                     } | 
|---|
| 958 |                     // did m_parser already advance sitr to next char? | 
|---|
| 959 |                     if(mr.has_remaining()) { | 
|---|
| 960 |                       use_current_char = true; | 
|---|
| 961 |                     } | 
|---|
| 962 |                     break; | 
|---|
| 963 |                   } | 
|---|
| 964 |                 case 'j': | 
|---|
| 965 |                   { | 
|---|
| 966 |                     // code that gets julian day (from format_date_parser) | 
|---|
| 967 |                     match_results mr; | 
|---|
| 968 |                     day_of_year = fixed_string_to_int<unsigned short, CharT>(sitr, stream_end, mr, 3); | 
|---|
| 969 |                     if(day_of_year == -1) { | 
|---|
| 970 |                       if(this->m_sv_parser.match(sitr, stream_end, mr)) { | 
|---|
| 971 |                         t = time_type(static_cast<special_values>(mr.current_match)); | 
|---|
| 972 |                         return sitr; | 
|---|
| 973 |                       } | 
|---|
| 974 |                     } | 
|---|
| 975 |                     // these next two lines are so we get an exception with bad input | 
|---|
| 976 |                     typedef typename time_type::date_type::day_of_year_type day_of_year_type; | 
|---|
| 977 |                     day_of_year_type t_day_of_year(day_of_year); | 
|---|
| 978 |                     break; | 
|---|
| 979 |                   } | 
|---|
| 980 |                 case 'd': | 
|---|
| 981 |                   { | 
|---|
| 982 |                     try { | 
|---|
| 983 |                       t_day = this->m_parser.parse_day_of_month(sitr, stream_end); | 
|---|
| 984 |                     } | 
|---|
| 985 |                     catch(std::out_of_range bad_day_of_month) { // base class for exception | 
|---|
| 986 |                       match_results mr; | 
|---|
| 987 |                       if(this->m_sv_parser.match(sitr, stream_end, mr)) { | 
|---|
| 988 |                         t = time_type(static_cast<special_values>(mr.current_match)); | 
|---|
| 989 |                         return sitr; | 
|---|
| 990 |                       } | 
|---|
| 991 |                       else { | 
|---|
| 992 |                         throw; // rethrow bad_year | 
|---|
| 993 |                       } | 
|---|
| 994 |                     } | 
|---|
| 995 |                     break; | 
|---|
| 996 |                   } | 
|---|
| 997 |                 // time flags | 
|---|
| 998 |                 case 'H':  | 
|---|
| 999 |                   { | 
|---|
| 1000 |                     match_results mr; | 
|---|
| 1001 |                     hour = fixed_string_to_int<short, CharT>(sitr, stream_end, mr, 2); | 
|---|
| 1002 |                     if(hour == -1){ | 
|---|
| 1003 |                        return check_special_value(sitr, stream_end, t, c); | 
|---|
| 1004 |                     } | 
|---|
| 1005 |                     break; | 
|---|
| 1006 |                   } | 
|---|
| 1007 |                 case 'M':  | 
|---|
| 1008 |                   { | 
|---|
| 1009 |                     match_results mr; | 
|---|
| 1010 |                     min = fixed_string_to_int<short, CharT>(sitr, stream_end, mr, 2); | 
|---|
| 1011 |                     if(min == -1){ | 
|---|
| 1012 |                        return check_special_value(sitr, stream_end, t, c); | 
|---|
| 1013 |                     } | 
|---|
| 1014 |                     break; | 
|---|
| 1015 |                   } | 
|---|
| 1016 |                 case 'S':  | 
|---|
| 1017 |                   { | 
|---|
| 1018 |                     match_results mr; | 
|---|
| 1019 |                     sec = fixed_string_to_int<short, CharT>(sitr, stream_end, mr, 2); | 
|---|
| 1020 |                     if(sec == -1){ | 
|---|
| 1021 |                        return check_special_value(sitr, stream_end, t, c); | 
|---|
| 1022 |                     } | 
|---|
| 1023 |                     break; | 
|---|
| 1024 |                   } | 
|---|
| 1025 |                 case 's': | 
|---|
| 1026 |                   { | 
|---|
| 1027 |                     match_results mr; | 
|---|
| 1028 |                     sec = fixed_string_to_int<short, CharT>(sitr, stream_end, mr, 2); | 
|---|
| 1029 |                     if(sec == -1){ | 
|---|
| 1030 |                        return check_special_value(sitr, stream_end, t, c); | 
|---|
| 1031 |                     } | 
|---|
| 1032 |                     // %s is the same as %S%f so we drop through into %f | 
|---|
| 1033 |                     //break; | 
|---|
| 1034 |                   } | 
|---|
| 1035 |                 case 'f': | 
|---|
| 1036 |                   { | 
|---|
| 1037 |                     // check for decimal, check SV if missing | 
|---|
| 1038 |                     if(*sitr == '.') { | 
|---|
| 1039 |                       ++sitr; | 
|---|
| 1040 |                       parse_frac_type(sitr, stream_end, frac); | 
|---|
| 1041 |                       // sitr will point to next expected char after this parsing  | 
|---|
| 1042 |                       // is complete so no need to advance it | 
|---|
| 1043 |                       use_current_char = true; | 
|---|
| 1044 |                     } | 
|---|
| 1045 |                     else { | 
|---|
| 1046 |                       return check_special_value(sitr, stream_end, t, c); | 
|---|
| 1047 |                     } | 
|---|
| 1048 |                     break; | 
|---|
| 1049 |                   } | 
|---|
| 1050 |                 case 'F':  | 
|---|
| 1051 |                   { | 
|---|
| 1052 |                     // check for decimal, skip if missing | 
|---|
| 1053 |                     if(*sitr == '.') { | 
|---|
| 1054 |                       ++sitr; | 
|---|
| 1055 |                       parse_frac_type(sitr, stream_end, frac); | 
|---|
| 1056 |                       // sitr will point to next expected char after this parsing  | 
|---|
| 1057 |                       // is complete so no need to advance it | 
|---|
| 1058 |                       use_current_char = true; | 
|---|
| 1059 |                     } | 
|---|
| 1060 |                     else { | 
|---|
| 1061 |                       // nothing was parsed so we don't want to advance sitr | 
|---|
| 1062 |                       use_current_char = true; | 
|---|
| 1063 |                     } | 
|---|
| 1064 |                     break; | 
|---|
| 1065 |                   } | 
|---|
| 1066 |                   // time_zone flags | 
|---|
| 1067 |                 //case 'q': | 
|---|
| 1068 |                 //case 'Q': | 
|---|
| 1069 |                 //case 'z': | 
|---|
| 1070 |                 case 'Z': | 
|---|
| 1071 |                   { | 
|---|
| 1072 |                     if(time_is_local) { // skip if 't' is a ptime | 
|---|
| 1073 |                       ++itr; | 
|---|
| 1074 |                       if(*itr == 'P') { | 
|---|
| 1075 |                         // skip leading whitespace | 
|---|
| 1076 |                         while((sitr != stream_end) && std::isspace(*sitr)) { ++sitr; } | 
|---|
| 1077 |                         // parse zone | 
|---|
| 1078 |                         while((sitr != stream_end) && (!std::isspace(*sitr))) { | 
|---|
| 1079 |                           tz_str += *sitr; | 
|---|
| 1080 |                           ++sitr; | 
|---|
| 1081 |                         } | 
|---|
| 1082 |                       } | 
|---|
| 1083 |                       else { | 
|---|
| 1084 |                         use_current_format_char = true; | 
|---|
| 1085 |                       } | 
|---|
| 1086 |                      | 
|---|
| 1087 |                     } | 
|---|
| 1088 |                     else { | 
|---|
| 1089 |                       // nothing was parsed so we don't want to advance sitr | 
|---|
| 1090 |                       use_current_char = true; | 
|---|
| 1091 |                     } | 
|---|
| 1092 |                     | 
|---|
| 1093 |                     break; | 
|---|
| 1094 |                   } | 
|---|
| 1095 |                 default: | 
|---|
| 1096 |                 {} // ignore what we don't understand? | 
|---|
| 1097 |               }// switch | 
|---|
| 1098 |             }  | 
|---|
| 1099 |             else { // itr == '%', second consecutive | 
|---|
| 1100 |               sitr++; | 
|---|
| 1101 |             } | 
|---|
| 1102 |         | 
|---|
| 1103 |             if(use_current_format_char) { | 
|---|
| 1104 |               use_current_format_char = false; | 
|---|
| 1105 |             } | 
|---|
| 1106 |             else { | 
|---|
| 1107 |               itr++; //advance past format specifier | 
|---|
| 1108 |             } | 
|---|
| 1109 |               | 
|---|
| 1110 |           } | 
|---|
| 1111 |           else {  //skip past chars in format and in buffer | 
|---|
| 1112 |             itr++; | 
|---|
| 1113 |             // set use_current_char when sitr is already  | 
|---|
| 1114 |             // pointing at the next character to process | 
|---|
| 1115 |             if (use_current_char) { | 
|---|
| 1116 |               use_current_char = false; | 
|---|
| 1117 |             } | 
|---|
| 1118 |             else { | 
|---|
| 1119 |               sitr++; | 
|---|
| 1120 |             } | 
|---|
| 1121 |           } | 
|---|
| 1122 |         } | 
|---|
| 1123 |          | 
|---|
| 1124 |         date_type d(not_a_date_time); | 
|---|
| 1125 |         if (day_of_year > 0) { | 
|---|
| 1126 |           d = date_type(static_cast<unsigned short>(t_year-1),12,31) + date_duration_type(day_of_year); | 
|---|
| 1127 |         } | 
|---|
| 1128 |         else { | 
|---|
| 1129 |           d = date_type(t_year, t_month, t_day); | 
|---|
| 1130 |         } | 
|---|
| 1131 |  | 
|---|
| 1132 |         time_duration_type td(hour, min, sec, frac); | 
|---|
| 1133 |         t = time_type(d, td); | 
|---|
| 1134 |         return sitr; | 
|---|
| 1135 |       } | 
|---|
| 1136 |  | 
|---|
| 1137 |       //! Helper function to check for special_value | 
|---|
| 1138 |       /*! First character may have been consumed during original parse  | 
|---|
| 1139 |        * attempt. Parameter 'c' should be a copy of that character.  | 
|---|
| 1140 |        * Throws ios_base::failure if parse fails. */ | 
|---|
| 1141 |       template<class temporal_type> | 
|---|
| 1142 |       inline | 
|---|
| 1143 |       InItrT check_special_value(InItrT& sitr,InItrT& stream_end, temporal_type& tt, char_type c='\0') const | 
|---|
| 1144 |       { | 
|---|
| 1145 |         match_results mr; | 
|---|
| 1146 |         if((c == '-' || c == '+') && (*sitr != c)) { // was the first character consumed? | 
|---|
| 1147 |           mr.cache += c; | 
|---|
| 1148 |         } | 
|---|
| 1149 |         this->m_sv_parser.match(sitr, stream_end, mr); | 
|---|
| 1150 |         if(mr.current_match == match_results::PARSE_ERROR) { | 
|---|
| 1151 |           std::string tmp = convert_string_type<char_type, char>(mr.cache); | 
|---|
| 1152 |           throw std::ios_base::failure("Parse failed. No match found for '" + tmp + "'"); | 
|---|
| 1153 |         } | 
|---|
| 1154 |         tt = temporal_type(static_cast<special_values>(mr.current_match));  | 
|---|
| 1155 |         return sitr; | 
|---|
| 1156 |       } | 
|---|
| 1157 |  | 
|---|
| 1158 |       //! Helper function for parsing a fractional second type from the stream | 
|---|
| 1159 |       void parse_frac_type(InItrT& sitr,  | 
|---|
| 1160 |                            InItrT& stream_end,  | 
|---|
| 1161 |                            fracional_seconds_type& frac) const | 
|---|
| 1162 |       { | 
|---|
| 1163 |         string_type cache; | 
|---|
| 1164 |         while((sitr != stream_end) && std::isdigit(*sitr)) { | 
|---|
| 1165 |           cache += *sitr; | 
|---|
| 1166 |           ++sitr; | 
|---|
| 1167 |         } | 
|---|
| 1168 |         if(cache.size() > 0) { | 
|---|
| 1169 |           unsigned short precision = time_duration_type::num_fractional_digits(); | 
|---|
| 1170 |           // input may be only the first few decimal places | 
|---|
| 1171 |           if(cache.size() < precision) { | 
|---|
| 1172 |             frac = lexical_cast<fracional_seconds_type>(cache); | 
|---|
| 1173 |             frac = decimal_adjust(frac, static_cast<unsigned short>(precision - cache.size())); | 
|---|
| 1174 |           } | 
|---|
| 1175 |           else { | 
|---|
| 1176 |             // if input has too many decimal places, drop excess digits | 
|---|
| 1177 |             frac = lexical_cast<fracional_seconds_type>(cache.substr(0, precision)); | 
|---|
| 1178 |           } | 
|---|
| 1179 |         } | 
|---|
| 1180 |       } | 
|---|
| 1181 |        | 
|---|
| 1182 |     private: | 
|---|
| 1183 |       string_type m_time_duration_format; | 
|---|
| 1184 |  | 
|---|
| 1185 |       //! Helper function to adjust trailing zeros when parsing fractional digits | 
|---|
| 1186 |       template<class int_type> | 
|---|
| 1187 |       inline | 
|---|
| 1188 |       int_type decimal_adjust(int_type val, const unsigned short places) const | 
|---|
| 1189 |       { | 
|---|
| 1190 |         unsigned long factor = 1; | 
|---|
| 1191 |         for(int i = 0; i < places; ++i){ | 
|---|
| 1192 |           factor *= 10; // shift decimal to the right | 
|---|
| 1193 |         } | 
|---|
| 1194 |         return val * factor; | 
|---|
| 1195 |       } | 
|---|
| 1196 |  | 
|---|
| 1197 |   }; | 
|---|
| 1198 |  | 
|---|
| 1199 | template <class time_type, class CharT, class InItrT> | 
|---|
| 1200 |   std::locale::id time_input_facet<time_type, CharT, InItrT>::id; | 
|---|
| 1201 |  | 
|---|
| 1202 | template <class time_type, class CharT, class InItrT>   | 
|---|
| 1203 |   const typename time_input_facet<time_type, CharT, InItrT>::char_type*  | 
|---|
| 1204 |   time_input_facet<time_type, CharT, InItrT>::fractional_seconds_format = time_formats<CharT>::fractional_seconds_format; | 
|---|
| 1205 |  | 
|---|
| 1206 |   template <class time_type, class CharT, class InItrT>   | 
|---|
| 1207 |   const typename time_input_facet<time_type, CharT, InItrT>::char_type*  | 
|---|
| 1208 |   time_input_facet<time_type, CharT, InItrT>::fractional_seconds_or_none_format = time_formats<CharT>::fractional_seconds_or_none_format; | 
|---|
| 1209 |  | 
|---|
| 1210 |   template <class time_type, class CharT, class InItrT>   | 
|---|
| 1211 |   const typename time_input_facet<time_type, CharT, InItrT>::char_type*  | 
|---|
| 1212 |   time_input_facet<time_type, CharT, InItrT>::seconds_with_fractional_seconds_format = time_formats<CharT>::seconds_with_fractional_seconds_format; | 
|---|
| 1213 |  | 
|---|
| 1214 |   template <class time_type, class CharT, class InItrT>   | 
|---|
| 1215 |   const typename time_input_facet<time_type, CharT, InItrT>::char_type*  | 
|---|
| 1216 |   time_input_facet<time_type, CharT, InItrT>::seconds_format = time_formats<CharT>::seconds_format; | 
|---|
| 1217 |  | 
|---|
| 1218 |   template <class time_type, class CharT, class InItrT>   | 
|---|
| 1219 |   const typename time_input_facet<time_type, CharT, InItrT>::char_type*  | 
|---|
| 1220 |   time_input_facet<time_type, CharT, InItrT>::standard_format = time_formats<CharT>::standard_format; | 
|---|
| 1221 |  | 
|---|
| 1222 |   template <class time_type, class CharT, class InItrT>   | 
|---|
| 1223 |   const typename time_input_facet<time_type, CharT, InItrT>::char_type*  | 
|---|
| 1224 |   time_input_facet<time_type, CharT, InItrT>::zone_abbrev_format = time_formats<CharT>::zone_abbrev_format; | 
|---|
| 1225 |  | 
|---|
| 1226 |   template <class time_type, class CharT, class InItrT>   | 
|---|
| 1227 |   const typename time_input_facet<time_type, CharT, InItrT>::char_type*  | 
|---|
| 1228 |   time_input_facet<time_type, CharT, InItrT>::zone_name_format = time_formats<CharT>::zone_name_format; | 
|---|
| 1229 |  | 
|---|
| 1230 |   template <class time_type, class CharT, class InItrT>   | 
|---|
| 1231 |   const typename time_input_facet<time_type, CharT, InItrT>::char_type*  | 
|---|
| 1232 |   time_input_facet<time_type, CharT, InItrT>::zone_iso_format = time_formats<CharT>::zone_iso_format; | 
|---|
| 1233 |  | 
|---|
| 1234 |   template <class time_type, class CharT, class InItrT>   | 
|---|
| 1235 |   const typename time_input_facet<time_type, CharT, InItrT>::char_type*  | 
|---|
| 1236 |   time_input_facet<time_type, CharT, InItrT>::zone_iso_extended_format = time_formats<CharT>::zone_iso_extended_format; | 
|---|
| 1237 |  | 
|---|
| 1238 |   template <class time_type, class CharT, class InItrT>   | 
|---|
| 1239 |   const typename time_input_facet<time_type, CharT, InItrT>::char_type*  | 
|---|
| 1240 |   time_input_facet<time_type, CharT, InItrT>::duration_seperator = time_formats<CharT>::duration_seperator; | 
|---|
| 1241 |  | 
|---|
| 1242 |   template <class time_type, class CharT, class InItrT>   | 
|---|
| 1243 |   const typename time_input_facet<time_type, CharT, InItrT>::char_type*  | 
|---|
| 1244 |   time_input_facet<time_type, CharT, InItrT>::iso_time_format_specifier = time_formats<CharT>::iso_time_format_specifier; | 
|---|
| 1245 |  | 
|---|
| 1246 |   template <class time_type, class CharT, class InItrT>   | 
|---|
| 1247 |   const typename time_input_facet<time_type, CharT, InItrT>::char_type*  | 
|---|
| 1248 |   time_input_facet<time_type, CharT, InItrT>::iso_time_format_extended_specifier = time_formats<CharT>::iso_time_format_extended_specifier; | 
|---|
| 1249 |  | 
|---|
| 1250 |   template <class time_type, class CharT, class InItrT>   | 
|---|
| 1251 |   const typename time_input_facet<time_type, CharT, InItrT>::char_type*  | 
|---|
| 1252 |   time_input_facet<time_type, CharT, InItrT>::default_time_input_format = time_formats<CharT>::default_time_input_format; | 
|---|
| 1253 |  | 
|---|
| 1254 |   template <class time_type, class CharT, class InItrT>   | 
|---|
| 1255 |   const typename time_input_facet<time_type, CharT, InItrT>::char_type*  | 
|---|
| 1256 |   time_input_facet<time_type, CharT, InItrT>::default_time_duration_format = time_formats<CharT>::default_time_duration_format; | 
|---|
| 1257 |  | 
|---|
| 1258 |  | 
|---|
| 1259 | } } // namespaces | 
|---|
| 1260 |  | 
|---|
| 1261 |  | 
|---|
| 1262 | #endif | 
|---|
| 1263 |  | 
|---|