time_facet.hpp

来自「support vector clustering for vc++」· HPP 代码 · 共 1,264 行 · 第 1/4 页

HPP
1,264
字号

#ifndef _DATE_TIME_FACET__HPP__
#define _DATE_TIME_FACET__HPP__

/* Copyright (c) 2004-2005 CrystalClear Software, Inc.
 * Use, modification and distribution is subject to the 
 * Boost Software License, Version 1.0. (See accompanying
 * file LICENSE-1.0 or http://www.boost.org/LICENSE-1.0)
 * Author:  Martin Andrian, Jeff Garland, Bart Garst
 * $Date: 2006/02/18 20:58:01 $
 */

#include "boost/date_time/date_facet.hpp"
#include "boost/date_time/string_convert.hpp"
#include "boost/algorithm/string/erase.hpp"
#include <sstream>
#include <iomanip>
#include <exception>

namespace boost {
namespace date_time {

  template <class CharT>
  struct time_formats {
    public:
      typedef CharT char_type;
      static const char_type fractional_seconds_format[3];               // f
      static const char_type fractional_seconds_or_none_format[3];       // F
      static const char_type seconds_with_fractional_seconds_format[3];  // s
      static const char_type seconds_format[3];                          // S
      static const char_type standard_format[9];                         // x X
      static const char_type zone_abbrev_format[3];                      // z
      static const char_type zone_name_format[3];                        // Z
      static const char_type zone_iso_format[3];                         // q
      static const char_type zone_iso_extended_format[3];                // Q
      static const char_type posix_zone_string_format[4];                // ZP
      static const char_type duration_sign_negative_only[3];             // -
      static const char_type duration_sign_always[3];                    // +
      static const char_type duration_seperator[2];
      static const char_type negative_sign[2];                           //-
      static const char_type positive_sign[2];                           //+
      static const char_type iso_time_format_specifier[18];
      static const char_type iso_time_format_extended_specifier[22];
      //default ptime format is YYYY-Mon-DD HH:MM:SS[.fff...][ zzz]
      static const char_type default_time_format[23]; 
      // default_time_input_format uses a posix_time_zone_string instead of a time zone abbrev
      static const char_type default_time_input_format[24]; 
      //default time_duration format is HH:MM:SS[.fff...]
      static const char_type default_time_duration_format[11];
  };

  template <class CharT>  
  const typename time_formats<CharT>::char_type 
  time_formats<CharT>::fractional_seconds_format[3] = {'%','f'};

  template <class CharT>  
  const typename time_formats<CharT>::char_type 
  time_formats<CharT>::fractional_seconds_or_none_format[3] = {'%','F'};

  template <class CharT>  
  const typename time_formats<CharT>::char_type 
  time_formats<CharT>::seconds_with_fractional_seconds_format[3] = 
    {'%','s'};

  template <class CharT>  
  const typename time_formats<CharT>::char_type 
  time_formats<CharT>::seconds_format[3] =  {'%','S'};

  template <class CharT>  
  const typename time_formats<CharT>::char_type 
  //time_formats<CharT>::standard_format[5] =  {'%','c',' ','%','z'};
  time_formats<CharT>::standard_format[9] =  {'%','x',' ','%','X',' ','%','z'};

  template <class CharT>  
  const typename time_formats<CharT>::char_type 
  time_formats<CharT>::zone_abbrev_format[3] =  {'%','z'};

  template <class CharT>  
  const typename time_formats<CharT>::char_type 
  time_formats<CharT>::zone_name_format[3] =  {'%','Z'};

  template <class CharT>  
  const typename time_formats<CharT>::char_type 
  time_formats<CharT>::zone_iso_format[3] =  {'%','q'};

  template <class CharT>  
  const typename time_formats<CharT>::char_type 
  time_formats<CharT>::zone_iso_extended_format[3] ={'%','Q'};

  template <class CharT>  
  const typename time_formats<CharT>::char_type 
  time_formats<CharT>::posix_zone_string_format[4] ={'%','Z','P'};

  template <class CharT>  
  const typename time_formats<CharT>::char_type 
  time_formats<CharT>::duration_seperator[2] =  {':'};

  template <class CharT>  
  const typename time_formats<CharT>::char_type 
  time_formats<CharT>::negative_sign[2] =  {'-'};

  template <class CharT>  
  const typename time_formats<CharT>::char_type 
  time_formats<CharT>::positive_sign[2] =  {'+'};

  template <class CharT>  
  const typename time_formats<CharT>::char_type 
  time_formats<CharT>::duration_sign_negative_only[3] ={'%','-'};

  template <class CharT>  
  const typename time_formats<CharT>::char_type 
  time_formats<CharT>::duration_sign_always[3] ={'%','+'};

  template <class CharT>  
  const typename time_formats<CharT>::char_type 
  time_formats<CharT>::iso_time_format_specifier[18] =  
    {'%', 'Y', '%', 'm', '%', 'd', 'T', 
     '%', 'H', '%', 'M', '%', 'S', '%', 'F', '%','q' };

  template <class CharT>  
  const typename time_formats<CharT>::char_type 
  time_formats<CharT>::iso_time_format_extended_specifier[22] =  
    {'%', 'Y', '-', '%', 'm', '-', '%', 'd', ' ', 
     '%', 'H', ':', '%', 'M', ':', '%', 'S', '%', 'F','%','Q'};

  template <class CharT>  
  const typename time_formats<CharT>::char_type 
  time_formats<CharT>::default_time_format[23] = 
    {'%','Y','-','%','b','-','%','d',' ',
      '%','H',':','%','M',':','%','S','%','F',' ','%','z'};

  template <class CharT>  
  const typename time_formats<CharT>::char_type 
  time_formats<CharT>::default_time_input_format[24] = 
    {'%','Y','-','%','b','-','%','d',' ',
      '%','H',':','%','M',':','%','S','%','F',' ','%','Z','P'};

  template <class CharT>  
  const typename time_formats<CharT>::char_type 
  time_formats<CharT>::default_time_duration_format[11] = 
    {'%','H',':','%','M',':','%','S','%','F'};



  /*! Facet used for format-based output of time types 
   * This class provides for the use of format strings to output times.  In addition
   * to the flags for formatting date elements, the following are the allowed format flags:
   *  - %x %X => default format - enables addition of more flags to default (ie. "%x %X %z")
   *  - %f => fractional seconds ".123456"
   *  - %F => fractional seconds or none: like frac sec but empty if frac sec == 0
   *  - %s => seconds w/ fractional sec "02.123" (this is the same as "%S%f) 
   *  - %S => seconds "02"
   *  - %z => abbreviated time zone "EDT"
   *  - %Z => full time zone name "Eastern Daylight Time"
   */
  template <class time_type,
            class CharT, 
            class OutItrT = std::ostreambuf_iterator<CharT, std::char_traits<CharT> > >
  class time_facet : 
    public boost::date_time::date_facet<typename time_type::date_type , CharT, OutItrT> {
   public:
    typedef typename time_type::date_type date_type;
    typedef typename time_type::time_duration_type time_duration_type;
    typedef boost::date_time::period<time_type,time_duration_type> period_type;
    typedef boost::date_time::date_facet<typename time_type::date_type, CharT, OutItrT> base_type;
    typedef typename base_type::string_type string_type;
    typedef typename base_type::char_type   char_type;
    typedef typename base_type::period_formatter_type period_formatter_type;
    typedef typename base_type::special_values_formatter_type special_values_formatter_type;
    typedef typename base_type::date_gen_formatter_type date_gen_formatter_type;
    static const char_type* fractional_seconds_format;                // %f
    static const char_type* fractional_seconds_or_none_format;        // %F
    static const char_type* seconds_with_fractional_seconds_format;   // %s
    static const char_type* seconds_format;                           // %S
    static const char_type* standard_format;                          // %x X
    static const char_type* zone_abbrev_format;                       // %z
    static const char_type* zone_name_format;                         // %Z
    static const char_type* zone_iso_format;                          // %q
    static const char_type* zone_iso_extended_format;                 // %Q
    static const char_type* posix_zone_string_format;                 // %ZP
    static const char_type* duration_seperator;
    static const char_type* duration_sign_always;                     // %+
    static const char_type* duration_sign_negative_only;              // %-
    static const char_type* negative_sign;                            //-
    static const char_type* positive_sign;                            //+
    static const char_type* iso_time_format_specifier;
    static const char_type* iso_time_format_extended_specifier;

    //default ptime format is YYYY-Mon-DD HH:MM:SS[.fff...][ zzz]
    static const char_type* default_time_format; 
    //default time_duration format is HH:MM:SS[.fff...]
    static const char_type* default_time_duration_format;
    static std::locale::id id;

#if defined (__SUNPRO_CC) && defined (_RWSTD_VER)
      std::locale::id& __get_id (void) const { return id; }
#endif

    //! sets default formats for ptime, local_date_time, and time_duration
    explicit time_facet(::size_t a_ref = 0) 
      //: base_type(standard_format),
      : base_type(default_time_format), 
        m_time_duration_format(string_type(duration_sign_negative_only) + default_time_duration_format)
    {}

    //! Construct the facet with an explicitly specified format
    explicit time_facet(const char_type* a_format,
                        period_formatter_type period_formatter = period_formatter_type(), 
                        const special_values_formatter_type& special_value_formatter = special_values_formatter_type(), 
                        date_gen_formatter_type dg_formatter = date_gen_formatter_type(),
                         ::size_t a_ref = 0) 
      : base_type(a_format, 
                  period_formatter,
                  special_value_formatter, 
                  dg_formatter, 
                  a_ref),
        m_time_duration_format(string_type(duration_sign_negative_only) + default_time_duration_format)
    {}

    //! Changes format for time_duration
    void time_duration_format(const char_type* const format) 
    {
      m_time_duration_format = format;
    }

    virtual void set_iso_format()
    {
      this->m_format = iso_time_format_specifier;
    }
    virtual void set_iso_extended_format()
    {
      this->m_format = iso_time_format_extended_specifier;
    }

    OutItrT put(OutItrT a_next, 
                std::ios_base& a_ios, 
                char_type a_fill, 
                const time_type& a_time) const 
    {
      if (a_time.is_special()) { 
        return this->do_put_special(a_next, a_ios, a_fill, 
                              a_time.date().as_special());
      }
      string_type format(this->m_format);
      string_type frac_str;
      if (format.find(seconds_with_fractional_seconds_format) != string_type::npos) {
        // replace %s with %S.nnn 
        frac_str = 
          fractional_seconds_as_string(a_time.time_of_day(), false);
        char_type sep = std::use_facet<std::numpunct<char_type> >(a_ios.getloc()).decimal_point();
        
        string_type replace_string(seconds_format);
        replace_string += sep;
        replace_string += frac_str;
        boost::algorithm::replace_all(format, 
                                      seconds_with_fractional_seconds_format, 
                                      replace_string);
      }
      /* NOTE: replacing posix_zone_string_format must be done BEFORE
       * zone_name_format: "%ZP" & "%Z", if Z is checked first it will 
       * incorrectly replace a zone_name where a posix_string should go */
      if (format.find(posix_zone_string_format) != string_type::npos) {
        if(a_time.zone_abbrev().empty()) {
          // if zone_abbrev() returns an empty string, we want to
          // erase posix_zone_string_format from format
          boost::algorithm::replace_all(format,
                                        posix_zone_string_format,
                                        "");
        }
        else{
          boost::algorithm::replace_all(format,
                                        posix_zone_string_format,
                                        a_time.zone_as_posix_string());
        }
      }
      if (format.find(zone_name_format) != string_type::npos) {
        if(a_time.zone_name().empty()) {
          /* TODO: this'll probably create problems if a user places 
           * the zone_*_format flag in the format with a ptime. This 
           * code removes the flag from the default formats */

          // if zone_name() returns an empty string, we want to
          // erase zone_name_format & one preceeding space
          std::basic_ostringstream<char_type> ss;
          ss << ' ' << zone_name_format;
          boost::algorithm::replace_all(format,
                                        ss.str(),
                                        "");
        }
        else{
          boost::algorithm::replace_all(format,
                                        zone_name_format,
                                        a_time.zone_name());
        }
      }
      if (format.find(zone_abbrev_format) != string_type::npos) {
        if(a_time.zone_abbrev(false).empty()) {
          /* TODO: this'll probably create problems if a user places 
           * the zone_*_format flag in the format with a ptime. This 
           * code removes the flag from the default formats */

          // if zone_abbrev() returns an empty string, we want to
          // erase zone_abbrev_format & one preceeding space
          std::basic_ostringstream<char_type> ss;
          ss << ' ' << zone_abbrev_format;
          boost::algorithm::replace_all(format,
                                        ss.str(),
                                        "");
        }
        else{
          boost::algorithm::replace_all(format,
                                        zone_abbrev_format,
                                        a_time.zone_abbrev(false));
        }
      }
      if (format.find(zone_iso_extended_format) != string_type::npos) {

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?