⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 posix_time_zone.hpp

📁 C++的一个好库。。。现在很流行
💻 HPP
📖 第 1 页 / 共 2 页
字号:
    /*! Extract time zone abbreviations for STD & DST as well
     * as the offsets for the time the shift occurs and how
     * much of a shift. At this time full time zone names are
     * NOT extracted so the abbreviations are used in their place */
    void calc_zone(const std::string& obj){
      std::stringstream ss("");
      std::string::const_iterator sit = obj.begin();
      std::string std_zone_abbrev("std_abbrev"), dst_zone_abbrev("");

      // get 'std' name/abbrev
      while(std::isalpha(*sit)){
        ss << *sit++;
      }
      std_zone_abbrev = ss.str(); 
      ss.str("");

      // get UTC offset
      if(sit != obj.end()){
        // get duration
        while(sit != obj.end() && !std::isalpha(*sit)){
        ss << *sit++;
        }
        base_utc_offset_ = posix_time::duration_from_string(ss.str()); 
        ss.str("");

        // base offset must be within range of -12 hours to +12 hours
        if(base_utc_offset_ < time_duration_type(-12,0,0) ||
            base_utc_offset_ > time_duration_type(12,0,0))
        {
            throw bad_offset(posix_time::to_simple_string(base_utc_offset_));
        }
      }

      // get DST data if given
      if(sit != obj.end()){
        has_dst_ = true;
    
        // get 'dst' name/abbrev
        while(sit != obj.end() && std::isalpha(*sit)){
          ss << *sit++;
        }
        dst_zone_abbrev = ss.str(); 
        ss.str("");

        // get DST offset if given
        if(sit != obj.end()){
          // get duration
          while(sit != obj.end() && !std::isalpha(*sit)){
            ss << *sit++;
          }
          dst_offsets_.dst_adjust_ = 
                posix_time::duration_from_string(ss.str());
        ss.str("");
        }
        else{ // default DST offset
          dst_offsets_.dst_adjust_ = posix_time::hours(1);
        }

        // adjustment must be within +|- 1 day
        if(dst_offsets_.dst_adjust_ <= time_duration_type(-24,0,0) ||
            dst_offsets_.dst_adjust_ >= time_duration_type(24,0,0))
        {
          throw bad_adjustment(posix_time::to_simple_string(dst_offsets_.dst_adjust_));
        }
      }
      // full names not extracted so abbrevs used in their place
      zone_names_ = time_zone_names(std_zone_abbrev, std_zone_abbrev, dst_zone_abbrev, dst_zone_abbrev);
    }

    void calc_rules(const std::string& start, const std::string& end){
      boost::char_separator<char> sep("/");
      tokenizer st_tok(start, sep);
      tokenizer et_tok(end, sep);
      tokenizer::iterator sit = st_tok.begin();
      tokenizer::iterator eit = et_tok.begin();

      // generate date spec
      char x = std::string(*sit).at(0);
      if(x == 'M'){
        M_func(*sit, *eit);
      }
      else if(x == 'J'){
        julian_no_leap(*sit, *eit);
      }
      else{
        julian_day(*sit, *eit);
      }

      ++sit;
      ++eit;
      // generate durations
      // starting offset
      if(sit != st_tok.end()){
        dst_offsets_.dst_start_offset_ = posix_time::duration_from_string(*sit);
      }
      else{
        // default
        dst_offsets_.dst_start_offset_ = posix_time::hours(2);
      }
      // start/end offsets must fall on given date
      if(dst_offsets_.dst_start_offset_ < time_duration_type(0,0,0) ||
          dst_offsets_.dst_start_offset_ >= time_duration_type(24,0,0))
      {
        throw bad_offset(posix_time::to_simple_string(dst_offsets_.dst_start_offset_));
      }

      // ending offset
      if(eit != et_tok.end()){
        dst_offsets_.dst_end_offset_ = posix_time::duration_from_string(*eit);
      }
      else{
        // default
        dst_offsets_.dst_end_offset_ = posix_time::hours(2);
      }
      // start/end offsets must fall on given date
      if(dst_offsets_.dst_end_offset_ < time_duration_type(0,0,0) ||
        dst_offsets_.dst_end_offset_ >= time_duration_type(24,0,0))
      {
        throw bad_offset(posix_time::to_simple_string(dst_offsets_.dst_end_offset_));
      }
    }

    /* Parses out a start/end date spec from a posix time zone string.
     * Date specs come in three possible formats, this function handles
     * the 'M' spec. Ex "M2.2.4" => 2nd month, 2nd week, 4th day .
     */
    void M_func(const std::string& s, const std::string& e){
      typedef gregorian::nth_kday_of_month nkday;
      unsigned short sm=0,sw=0,sd=0,em=0,ew=0,ed=0; // start/end month,week,day
      char_separator<char> sep("M.");
      tokenizer stok(s, sep), etok(e, sep);
      
      tokenizer::iterator it = stok.begin();
      sm = lexical_cast<unsigned short>(*it++);
      sw = lexical_cast<unsigned short>(*it++);
      sd = lexical_cast<unsigned short>(*it);
     
      it = etok.begin();
      em = lexical_cast<unsigned short>(*it++);
      ew = lexical_cast<unsigned short>(*it++);
      ed = lexical_cast<unsigned short>(*it);

      dst_calc_rules_ = shared_ptr<dst_calc_rule>(
        new nth_kday_dst_rule(
          nth_last_dst_rule::start_rule(
            static_cast<nkday::week_num>(sw),sd,sm), 
          nth_last_dst_rule::start_rule(
            static_cast<nkday::week_num>(ew),ed,em) 
          )
      );
    }
    
    //! Julian day. Feb29 is never counted, even in leap years
    // expects range of 1-365
    void julian_no_leap(const std::string& s, const std::string& e){
      typedef gregorian::gregorian_calendar calendar;
      const unsigned short year = 2001; // Non-leap year
      unsigned short sm=1;
      int sd=0;
      sd = lexical_cast<int>(s.substr(1)); // skip 'J'
      while(sd >= calendar::end_of_month_day(year,sm)){
        sd -= calendar::end_of_month_day(year,sm++);
      }
      unsigned short em=1;
      int ed=0;
      ed = lexical_cast<int>(e.substr(1)); // skip 'J'
      while(ed > calendar::end_of_month_day(year,em)){
        ed -= calendar::end_of_month_day(year,em++);
      }

      dst_calc_rules_ = shared_ptr<dst_calc_rule>(
        new partial_date_dst_rule(
          partial_date_dst_rule::start_rule(
            sd, static_cast<date_time::months_of_year>(sm)), 
          partial_date_dst_rule::end_rule(
            ed, static_cast<date_time::months_of_year>(em)) 
          )
      );
    }

    //! Julian day. Feb29 is always counted, but exception thrown in non-leap years
    // expects range of 0-365
    void julian_day(const std::string& s, const std::string& e){
      int sd=0, ed=0;
      sd = lexical_cast<int>(s);
      ed = lexical_cast<int>(e);
      dst_calc_rules_ = shared_ptr<dst_calc_rule>(
        new partial_date_dst_rule(
          partial_date_dst_rule::start_rule(++sd),// args are 0-365
          partial_date_dst_rule::end_rule(++ed) // pd expects 1-366
          )
      );
    }

    //! helper function used when throwing exceptions
    static std::string td_as_string(const time_duration_type& td)
    {
      std::string s;
#if defined(USE_DATE_TIME_PRE_1_33_FACET_IO)
      s = posix_time::to_simple_string(td);
#else
      std::stringstream ss;
      ss << td;
      s = ss.str();
#endif
      return s;
    }
  };

} } // namespace boost::local_time


#endif // _DATE_TIME_POSIX_TIME_ZONE__ 

⌨️ 快捷键说明

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