posix_time_zone.hpp
来自「Boost provides free peer-reviewed portab」· HPP 代码 · 共 444 行 · 第 1/2 页
HPP
444 行
#ifndef _DATE_TIME_POSIX_TIME_ZONE__#define _DATE_TIME_POSIX_TIME_ZONE__ /* Copyright (c) 2003-2005 CrystalClear Software, Inc. * Subject to the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) * Author: Jeff Garland, Bart Garst * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ */#include <string>#include <sstream>#include "boost/date_time/gregorian/gregorian.hpp"#include "boost/date_time/time_zone_names.hpp"#include "boost/date_time/time_zone_base.hpp"#include "boost/date_time/local_time/dst_transition_day_rules.hpp"#include "boost/date_time/posix_time/posix_time.hpp"#include "boost/date_time/string_convert.hpp"#include "boost/date_time/time_parsing.hpp"#include "boost/tokenizer.hpp"#include <stdexcept>namespace boost{namespace local_time{ //! simple exception for UTC and Daylight savings start/end offsets struct bad_offset : public std::out_of_range { bad_offset(std::string _msg="") : std::out_of_range(std::string("Offset out of range: " + _msg)) {} }; //! simple exception for UTC daylight savings adjustment struct bad_adjustment : public std::out_of_range { bad_adjustment(std::string _msg="") : std::out_of_range(std::string("Adjustment out of range: " + _msg)) {} }; typedef boost::date_time::dst_adjustment_offsets<boost::posix_time::time_duration> dst_adjustment_offsets; //! A time zone class constructed from a POSIX time zone string /*! A POSIX time zone string takes the form of:<br> * "std offset dst [offset],start[/time],end[/time]" (w/no spaces) * 'std' specifies the abbrev of the time zone.<br> * 'offset' is the offset from UTC.<br> * 'dst' specifies the abbrev of the time zone during daylight savings time.<br> * The second offset is how many hours changed during DST. Default=1<br> * 'start' and'end' are the dates when DST goes into (and out of) effect.<br> * 'offset' takes the form of: [+|-]hh[:mm[:ss]] {h=0-23, m/s=0-59}<br> * 'time' and 'offset' take the same form. Time defaults=02:00:00<br> * 'start' and 'end' can be one of three forms:<br> * Mm.w.d {month=1-12, week=1-5 (5 is always last), day=0-6}<br> * Jn {n=1-365 Feb29 is never counted}<br> * n {n=0-365 Feb29 is counted in leap years}<br> * Example "PST-5PDT01:00:00,M4.1.0/02:00:00,M10.1.0/02:00:00" * <br> * Exceptions will be thrown under these conditions:<br> * An invalid date spec (see date class)<br> * A boost::local_time::bad_offset exception will be thrown for:<br> * A DST start or end offset that is negative or more than 24 hours<br> * A UTC zone that is greater than +12 or less than -12 hours<br> * A boost::local_time::bad_adjustment exception will be thrown for:<br> * A DST adjustment that is 24 hours or more (positive or negative)<br> */ template<class CharT> class posix_time_zone_base : public date_time::time_zone_base<posix_time::ptime,CharT> { public: typedef boost::posix_time::time_duration time_duration_type; typedef date_time::time_zone_names_base<CharT> time_zone_names; typedef date_time::time_zone_base<posix_time::ptime,CharT> base_type; typedef typename base_type::string_type string_type; typedef CharT char_type; typedef typename base_type::stringstream_type stringstream_type; typedef boost::char_separator<char_type, std::char_traits<char_type> > char_separator_type; typedef boost::tokenizer<char_separator_type, typename string_type::const_iterator, string_type> tokenizer_type; typedef typename boost::tokenizer<char_separator_type, typename string_type::const_iterator, string_type>::iterator tokenizer_iterator_type; //! Construct from a POSIX time zone string posix_time_zone_base(const string_type& s) : //zone_names_("std_name","std_abbrev","no-dst","no-dst"), zone_names_(), has_dst_(false), base_utc_offset_(posix_time::hours(0)), dst_offsets_(posix_time::hours(0),posix_time::hours(0),posix_time::hours(0)), dst_calc_rules_() { const char_type sep_chars[2] = {','}; char_separator_type sep(sep_chars); tokenizer_type tokens(s, sep); tokenizer_iterator_type it = tokens.begin(); calc_zone(*it++); if(has_dst_){ string_type tmp_str = *it++; calc_rules(tmp_str, *it); } } virtual ~posix_time_zone_base() {}; //!String for the zone when not in daylight savings (eg: EST) virtual string_type std_zone_abbrev()const { return zone_names_.std_zone_abbrev(); } //!String for the timezone when in daylight savings (eg: EDT) /*! For those time zones that have no DST, an empty string is used */ virtual string_type dst_zone_abbrev() const { return zone_names_.dst_zone_abbrev(); } //!String for the zone when not in daylight savings (eg: Eastern Standard Time) /*! The full STD name is not extracted from the posix time zone string. * Therefore, the STD abbreviation is used in it's place */ virtual string_type std_zone_name()const { return zone_names_.std_zone_name(); } //!String for the timezone when in daylight savings (eg: Eastern Daylight Time) /*! The full DST name is not extracted from the posix time zone string. * Therefore, the STD abbreviation is used in it's place. For time zones * that have no DST, an empty string is used */ virtual string_type dst_zone_name()const { return zone_names_.dst_zone_name(); } //! True if zone uses daylight savings adjustments otherwise false virtual bool has_dst()const { return has_dst_; } //! Local time that DST starts -- NADT if has_dst is false virtual posix_time::ptime dst_local_start_time(gregorian::greg_year y)const { gregorian::date d(gregorian::not_a_date_time); if(has_dst_) { d = dst_calc_rules_->start_day(y); } return posix_time::ptime(d, dst_offsets_.dst_start_offset_); } //! Local time that DST ends -- NADT if has_dst is false virtual posix_time::ptime dst_local_end_time(gregorian::greg_year y)const { gregorian::date d(gregorian::not_a_date_time); if(has_dst_) { d = dst_calc_rules_->end_day(y); } return posix_time::ptime(d, dst_offsets_.dst_end_offset_); } //! Base offset from UTC for zone (eg: -07:30:00) virtual time_duration_type base_utc_offset()const { return base_utc_offset_; } //! Adjustment forward or back made while DST is in effect virtual time_duration_type dst_offset()const { return dst_offsets_.dst_adjust_; } //! Returns a POSIX time_zone string for this object virtual string_type to_posix_string() const { // std offset dst [offset],start[/time],end[/time] - w/o spaces stringstream_type ss; ss.fill('0'); boost::shared_ptr<dst_calc_rule> no_rules; // std ss << std_zone_abbrev(); // offset if(base_utc_offset().is_negative()) { // inverting the sign guarantees we get two digits ss << '-' << std::setw(2) << base_utc_offset().invert_sign().hours(); } else { ss << '+' << std::setw(2) << base_utc_offset().hours(); } if(base_utc_offset().minutes() != 0 || base_utc_offset().seconds() != 0) { ss << ':' << std::setw(2) << base_utc_offset().minutes(); if(base_utc_offset().seconds() != 0) { ss << ':' << std::setw(2) << base_utc_offset().seconds(); } } if(dst_calc_rules_ != no_rules) { // dst ss << dst_zone_abbrev(); // dst offset if(dst_offset().is_negative()) { // inverting the sign guarantees we get two digits ss << '-' << std::setw(2) << dst_offset().invert_sign().hours(); } else { ss << '+' << std::setw(2) << dst_offset().hours(); } if(dst_offset().minutes() != 0 || dst_offset().seconds() != 0) { ss << ':' << std::setw(2) << dst_offset().minutes(); if(dst_offset().seconds() != 0) { ss << ':' << std::setw(2) << dst_offset().seconds(); } } // start/time ss << ',' << date_time::convert_string_type<char, char_type>(dst_calc_rules_->start_rule_as_string()) << '/' << std::setw(2) << dst_offsets_.dst_start_offset_.hours() << ':' << std::setw(2) << dst_offsets_.dst_start_offset_.minutes(); if(dst_offsets_.dst_start_offset_.seconds() != 0) { ss << ':' << std::setw(2) << dst_offsets_.dst_start_offset_.seconds(); } // end/time ss << ',' << date_time::convert_string_type<char, char_type>(dst_calc_rules_->end_rule_as_string()) << '/' << std::setw(2) << dst_offsets_.dst_end_offset_.hours() << ':' << std::setw(2) << dst_offsets_.dst_end_offset_.minutes(); if(dst_offsets_.dst_end_offset_.seconds() != 0) { ss << ':' << std::setw(2) << dst_offsets_.dst_end_offset_.seconds(); } } return ss.str(); } private: time_zone_names zone_names_; bool has_dst_;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?