os/ossrv/ossrv_pub/boost_apis/boost/date_time/time_facet.hpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     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