posix_time_zone.hpp
来自「Boost provides free peer-reviewed portab」· HPP 代码 · 共 444 行 · 第 1/2 页
HPP
444 行
time_duration_type base_utc_offset_; dst_adjustment_offsets dst_offsets_; boost::shared_ptr<dst_calc_rule> dst_calc_rules_; /*! Extract time zone abbreviations for STD & DST as well * as the offsets for the time shift that 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 string_type& obj){ const char_type empty_string[2] = {'\0'}; stringstream_type ss(empty_string); typename string_type::const_iterator sit = obj.begin(); string_type l_std_zone_abbrev, l_dst_zone_abbrev; // get 'std' name/abbrev while(std::isalpha(*sit)){ ss << *sit++; } l_std_zone_abbrev = ss.str(); ss.str(empty_string); // get UTC offset if(sit != obj.end()){ // get duration while(sit != obj.end() && !std::isalpha(*sit)){ ss << *sit++; } base_utc_offset_ = date_time::str_from_delimited_time_duration<time_duration_type,char_type>(ss.str()); ss.str(empty_string); // 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++; } l_dst_zone_abbrev = ss.str(); ss.str(empty_string); // get DST offset if given if(sit != obj.end()){ // get duration while(sit != obj.end() && !std::isalpha(*sit)){ ss << *sit++; } dst_offsets_.dst_adjust_ = date_time::str_from_delimited_time_duration<time_duration_type,char_type>(ss.str()); ss.str(empty_string); } 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(l_std_zone_abbrev, l_std_zone_abbrev, l_dst_zone_abbrev, l_dst_zone_abbrev); } void calc_rules(const string_type& start, const string_type& end){ const char_type sep_chars[2] = {'/'}; char_separator_type sep(sep_chars); tokenizer_type st_tok(start, sep); tokenizer_type et_tok(end, sep); tokenizer_iterator_type sit = st_tok.begin(); tokenizer_iterator_type eit = et_tok.begin(); // generate date spec char_type x = string_type(*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_ = date_time::str_from_delimited_time_duration<time_duration_type,char_type>(*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_ = date_time::str_from_delimited_time_duration<time_duration_type,char_type>(*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 string_type& s, const string_type& 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 const char_type sep_chars[3] = {'M','.'}; char_separator_type sep(sep_chars); tokenizer_type stok(s, sep), etok(e, sep); tokenizer_iterator_type 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 string_type& s, const string_type& 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 string_type& s, const string_type& 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; } }; typedef posix_time_zone_base<char> posix_time_zone; } } // namespace boost::local_time#endif // _DATE_TIME_POSIX_TIME_ZONE__
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?