time_facet.hpp

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

HPP
1,264
字号
      static std::locale::id id;

      //! Constructor that takes a format string for a ptime
      explicit time_input_facet(const string_type& format, ::size_t a_ref = 0) 
        : base_type(format, a_ref), 
          m_time_duration_format(default_time_duration_format)
      { }

      explicit time_input_facet(const string_type& format,
                                const format_date_parser_type& date_parser,
                                const special_values_parser_type& sv_parser,
                                const period_parser_type& per_parser,
                                const date_gen_parser_type& date_gen_parser,
                                ::size_t a_ref = 0)
        : base_type(format,
                    date_parser,
                    sv_parser,
                    per_parser,
                    date_gen_parser,
                    a_ref), 
          m_time_duration_format(default_time_duration_format)
      {}

      //! sets default formats for ptime, local_date_time, and time_duration
      explicit time_input_facet(::size_t a_ref = 0) 
        : base_type(default_time_input_format, a_ref), 
          m_time_duration_format(default_time_duration_format)
      { }
      
      //! Set the 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;
      }
      
      InItrT get(InItrT& sitr,
                 InItrT& stream_end,
                 std::ios_base& a_ios,
                 period_type& p) const
      {
        p = this->m_period_parser.get_period(sitr, 
                                             stream_end, 
                                             a_ios, 
                                             p, 
                                             time_duration_type::unit(), 
                                             *this);
        return sitr;
      }
      
      //default ptime format is YYYY-Mon-DD HH:MM:SS[.fff...][ zzz]
      //default time_duration format is %H:%M:%S%F HH:MM:SS[.fff...]

      InItrT get(InItrT& sitr, 
                 InItrT& stream_end, 
                 std::ios_base& a_ios, 
                 time_duration_type& td) const
      {
        // skip leading whitespace
        while((sitr != stream_end) && std::isspace(*sitr)) { ++sitr; }
        
        bool use_current_char = false;
        
        // num_get will consume the +/-, we may need a copy if special_value
        char_type c = '\0';
        if((sitr != stream_end) && (*sitr == '-' || *sitr == '+')) {
          c = *sitr;
        }
        
        long hour = 0; 
        long min = 0; 
        long sec = 0; 
        typename time_duration_type::fractional_seconds_type frac(0);
        
        typedef std::num_get<CharT, InItrT> num_get;
        if(!std::has_facet<num_get>(a_ios.getloc())) {
          num_get* ng = new num_get();
          std::locale loc = std::locale(a_ios.getloc(), ng);
          a_ios.imbue(loc);
        }
       
        const_itr itr(m_time_duration_format.begin());
        while (itr != m_time_duration_format.end() && (sitr != stream_end)) {
          if (*itr == '%') {
            itr++;
            if (*itr != '%') {
              switch(*itr) {
              case 'H': 
                {
                  match_results mr;
                  hour = fixed_string_to_int<short, CharT>(sitr, stream_end, mr, 2);
                  if(hour == -1){
                     return check_special_value(sitr, stream_end, td, c);
                  }
                  break;
                }
              case 'M': 
                {
                  match_results mr;
                  min = fixed_string_to_int<short, CharT>(sitr, stream_end, mr, 2);
                  if(min == -1){
                     return check_special_value(sitr, stream_end, td, c);
                  }
                  break;
                }
              case 'S': 
                {
                  match_results mr;
                  sec = fixed_string_to_int<short, CharT>(sitr, stream_end, mr, 2);
                  if(sec == -1){
                     return check_special_value(sitr, stream_end, td, c);
                  }
                  break;
                }
              case 's':
                {
                  match_results mr;
                  sec = fixed_string_to_int<short, CharT>(sitr, stream_end, mr, 2);
                  if(sec == -1){
                     return check_special_value(sitr, stream_end, td, c);
                  }
                  // %s is the same as %S%f so we drop through into %f
                  //break;
                }
              case 'f':
                {
                  // check for decimal, check special_values if missing
                  if(*sitr == '.') {
                    ++sitr;
                    parse_frac_type(sitr, stream_end, frac);
                    // sitr will point to next expected char after this parsing 
                    // is complete so no need to advance it
                    use_current_char = true;
                  }
                  else {
                    return check_special_value(sitr, stream_end, td, c);
                  }
                  break;
                }
              case 'F': 
                {
                  // check for decimal, skip if missing
                  if(*sitr == '.') {
                    ++sitr;
                    parse_frac_type(sitr, stream_end, frac);
                    // sitr will point to next expected char after this parsing 
                    // is complete so no need to advance it
                    use_current_char = true;
                  }
                  else {
                    // nothing was parsed so we don't want to advance sitr
                    use_current_char = true;
                  }
                  break;
                }
              default:
                {} // ignore what we don't understand?
              }// switch
            }
            else { // itr == '%', second consecutive
              sitr++;
            }
        
            itr++; //advance past format specifier
          }
          else {  //skip past chars in format and in buffer
            itr++;
            // set use_current_char when sitr is already 
            // pointing at the next character to process
            if (use_current_char) {
              use_current_char = false;
            }
            else {
              sitr++;
            }
          }
        }

        td = time_duration_type(hour, min, sec, frac);
        return sitr;
      }
    

      //! Parses a time object from the input stream
      InItrT get(InItrT& sitr, 
                 InItrT& stream_end, 
                 std::ios_base& a_ios, 
                 time_type& t) const
      {
        string_type tz_str;
        return get(sitr, stream_end, a_ios, t, tz_str, false);
      }
      //! Expects a time_zone in the input stream
      InItrT get_local_time(InItrT& sitr, 
                            InItrT& stream_end, 
                            std::ios_base& a_ios, 
                            time_type& t,
                            string_type& tz_str) const
      {
        return get(sitr, stream_end, a_ios, t, tz_str, true);
      }

    protected:

      InItrT get(InItrT& sitr, 
                 InItrT& stream_end, 
                 std::ios_base& a_ios, 
                 time_type& t,
                 string_type& tz_str,
                 bool time_is_local) const
      {
        // skip leading whitespace
        while((sitr != stream_end) && std::isspace(*sitr)) { ++sitr; }
        
        bool use_current_char = false;
        bool use_current_format_char = false; // used whith two character flags
        
        // num_get will consume the +/-, we may need a copy if special_value
        char_type c = '\0';
        if((sitr != stream_end) && (*sitr == '-' || *sitr == '+')) {
          c = *sitr;
        }
       
        // time elements
        long hour = 0; 
        long min = 0; 
        long sec = 0; 
        typename time_duration_type::fractional_seconds_type frac(0);
        // date elements
        short day_of_year(0);
        /* Initialized the following to their minimum values. These intermediate 
         * objects are used so we get specific exceptions when part of the input 
         * is unparsable. 
         * Ex: "205-Jan-15" will throw a bad_year, "2005-Jsn-15"- bad_month, etc.*/
        year_type t_year(1400);
        month_type t_month(1);
        day_type t_day(1);
        
        typedef std::num_get<CharT, InItrT> num_get;
        if(!std::has_facet<num_get>(a_ios.getloc())) {
          num_get* ng = new num_get();
          std::locale loc = std::locale(a_ios.getloc(), ng);
          a_ios.imbue(loc);
        }
       
        const_itr itr(this->m_format.begin());
        while (itr != this->m_format.end() && (sitr != stream_end)) {
          if (*itr == '%') {
            itr++;
            if (*itr != '%') {
              // the cases are grouped by date & time flags - not alphabetical order
              switch(*itr) {
                // date flags
                case 'Y':
                case 'y':
                  {
                    char_type cs[3] = { '%', *itr };
                    string_type s(cs);
                    match_results mr;
                    try {
                      t_year = this->m_parser.parse_year(sitr, stream_end, s, mr);
                    }
                    catch(std::out_of_range bad_year) { // base class for bad_year exception
                      if(this->m_sv_parser.match(sitr, stream_end, mr)) {
                        t = time_type(static_cast<special_values>(mr.current_match));
                        return sitr;
                      }
                      else {
                        throw; // rethrow bad_year
                      }
                    }
                    break;
                  }
                case 'B':
                case 'b':
                case 'm':
                  {
                    char_type cs[3] = { '%', *itr };
                    string_type s(cs);
                    match_results mr;
                    try {
                      t_month = this->m_parser.parse_month(sitr, stream_end, s, mr);
                    }
                    catch(std::out_of_range bad_month) { // base class for bad_month exception
                      if(this->m_sv_parser.match(sitr, stream_end, mr)) {
                        t = time_type(static_cast<special_values>(mr.current_match));
                        return sitr;
                      }
                      else {
                        throw; // rethrow bad_year
                      }
                    }
                    // did m_parser already advance sitr to next char?
                    if(mr.has_remaining()) {
                      use_current_char = true;
                    }
                    break;
                  }
                case 'a':
                case 'A':
                case 'w':
                  {
                    // weekday is not used in construction but we need to get it out of the stream
                    char_type cs[3] = { '%', *itr };
                    string_type s(cs);
                    match_results mr;
                    typename date_type::day_of_week_type wd(0);
                    try {
                      wd = this->m_parser.parse_weekday(sitr, stream_end, s, mr);
                    }

⌨️ 快捷键说明

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