1 #ifndef LOCAL_TIME_CUSTOM_TIME_ZONE_HPP__ 2 #define LOCAL_TIME_CUSTOM_TIME_ZONE_HPP__ 3 4 /* Copyright (c) 2003-2005 CrystalClear Software, Inc. 5 * Subject to the Boost Software License, Version 1.0. 6 * (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) 7 * Author: Jeff Garland, Bart Garst 8 * $Date$ 9 */ 10 11 #include "boost/date_time/time_zone_base.hpp" 12 #include "boost/date_time/time_zone_names.hpp" 13 #include "boost/date_time/posix_time/posix_time.hpp" 14 #include "boost/date_time/local_time/dst_transition_day_rules.hpp" 15 #include "boost/date_time/string_convert.hpp" 16 //#include "boost/date_time/special_defs.hpp" 17 #include "boost/shared_ptr.hpp" 18 19 namespace boost { 20 namespace local_time { 21 22 //typedef boost::date_time::time_zone_names time_zone_names; 23 typedef boost::date_time::dst_adjustment_offsets<boost::posix_time::time_duration> dst_adjustment_offsets; 24 //typedef boost::date_time::time_zone_base<boost::posix_time::ptime> time_zone; 25 typedef boost::shared_ptr<dst_calc_rule> dst_calc_rule_ptr; 26 27 //! A real time zone 28 template<class CharT> 29 class custom_time_zone_base : public date_time::time_zone_base<posix_time::ptime,CharT> { 30 public: 31 typedef boost::posix_time::time_duration time_duration_type; 32 typedef date_time::time_zone_base<posix_time::ptime,CharT> base_type; 33 typedef typename base_type::string_type string_type; 34 typedef typename base_type::stringstream_type stringstream_type; 35 typedef date_time::time_zone_names_base<CharT> time_zone_names; 36 typedef CharT char_type; 37 custom_time_zone_base(const time_zone_names & zone_names,const time_duration_type & utc_offset,const dst_adjustment_offsets & dst_shift,boost::shared_ptr<dst_calc_rule> calc_rule)38 custom_time_zone_base(const time_zone_names& zone_names, 39 const time_duration_type& utc_offset, 40 const dst_adjustment_offsets& dst_shift, 41 boost::shared_ptr<dst_calc_rule> calc_rule) : 42 zone_names_(zone_names), 43 base_utc_offset_(utc_offset), 44 dst_offsets_(dst_shift), 45 dst_calc_rules_(calc_rule) 46 {} ~custom_time_zone_base()47 virtual ~custom_time_zone_base() {} dst_zone_abbrev() const48 virtual string_type dst_zone_abbrev() const 49 { 50 return zone_names_.dst_zone_abbrev(); 51 } std_zone_abbrev() const52 virtual string_type std_zone_abbrev() const 53 { 54 return zone_names_.std_zone_abbrev(); 55 } dst_zone_name() const56 virtual string_type dst_zone_name() const 57 { 58 return zone_names_.dst_zone_name(); 59 } std_zone_name() const60 virtual string_type std_zone_name() const 61 { 62 return zone_names_.std_zone_name(); 63 } 64 //! True if zone uses daylight savings adjustments has_dst() const65 virtual bool has_dst() const 66 { 67 return (bool) dst_calc_rules_; //if calc_rule is set the tz has dst 68 } 69 //! Local time that DST starts -- NADT if has_dst is false dst_local_start_time(gregorian::greg_year y) const70 virtual posix_time::ptime dst_local_start_time(gregorian::greg_year y) const 71 { 72 gregorian::date d(gregorian::not_a_date_time); 73 if (dst_calc_rules_) { 74 d = dst_calc_rules_->start_day(y); 75 } 76 return posix_time::ptime(d, dst_offsets_.dst_start_offset_); 77 } 78 //! Local time that DST ends -- NADT if has_dst is false dst_local_end_time(gregorian::greg_year y) const79 virtual posix_time::ptime dst_local_end_time(gregorian::greg_year y) const 80 { 81 gregorian::date d(gregorian::not_a_date_time); 82 if (dst_calc_rules_) { 83 d = dst_calc_rules_->end_day(y); 84 } 85 return posix_time::ptime(d, dst_offsets_.dst_end_offset_); 86 } 87 //! Base offset from UTC for zone (eg: -07:30:00) base_utc_offset() const88 virtual time_duration_type base_utc_offset() const 89 { 90 return base_utc_offset_; 91 } 92 //! Adjustment forward or back made while DST is in effect dst_offset() const93 virtual time_duration_type dst_offset() const 94 { 95 return dst_offsets_.dst_adjust_; 96 } 97 //! Returns a POSIX time_zone string for this object to_posix_string() const98 virtual string_type to_posix_string() const 99 { 100 // std offset dst [offset],start[/time],end[/time] - w/o spaces 101 stringstream_type ss; 102 ss.fill('0'); 103 boost::shared_ptr<dst_calc_rule> no_rules; 104 // std 105 ss << std_zone_abbrev(); 106 // offset 107 if(base_utc_offset().is_negative()) { 108 // inverting the sign guarantees we get two digits 109 ss << '-' << std::setw(2) << base_utc_offset().invert_sign().hours(); 110 } 111 else { 112 ss << '+' << std::setw(2) << base_utc_offset().hours(); 113 } 114 if(base_utc_offset().minutes() != 0 || base_utc_offset().seconds() != 0) { 115 ss << ':' << std::setw(2) << base_utc_offset().minutes(); 116 if(base_utc_offset().seconds() != 0) { 117 ss << ':' << std::setw(2) << base_utc_offset().seconds(); 118 } 119 } 120 if(dst_calc_rules_ != no_rules) { 121 // dst 122 ss << dst_zone_abbrev(); 123 // dst offset 124 if(dst_offset().is_negative()) { 125 // inverting the sign guarantees we get two digits 126 ss << '-' << std::setw(2) << dst_offset().invert_sign().hours(); 127 } 128 else { 129 ss << '+' << std::setw(2) << dst_offset().hours(); 130 } 131 if(dst_offset().minutes() != 0 || dst_offset().seconds() != 0) { 132 ss << ':' << std::setw(2) << dst_offset().minutes(); 133 if(dst_offset().seconds() != 0) { 134 ss << ':' << std::setw(2) << dst_offset().seconds(); 135 } 136 } 137 // start/time 138 ss << ',' << date_time::convert_string_type<char, char_type>(dst_calc_rules_->start_rule_as_string()) << '/' 139 << std::setw(2) << dst_offsets_.dst_start_offset_.hours() << ':' 140 << std::setw(2) << dst_offsets_.dst_start_offset_.minutes(); 141 if(dst_offsets_.dst_start_offset_.seconds() != 0) { 142 ss << ':' << std::setw(2) << dst_offsets_.dst_start_offset_.seconds(); 143 } 144 // end/time 145 ss << ',' << date_time::convert_string_type<char, char_type>(dst_calc_rules_->end_rule_as_string()) << '/' 146 << std::setw(2) << dst_offsets_.dst_end_offset_.hours() << ':' 147 << std::setw(2) << dst_offsets_.dst_end_offset_.minutes(); 148 if(dst_offsets_.dst_end_offset_.seconds() != 0) { 149 ss << ':' << std::setw(2) << dst_offsets_.dst_end_offset_.seconds(); 150 } 151 } 152 153 return ss.str(); 154 } 155 private: 156 time_zone_names zone_names_; 157 time_duration_type base_utc_offset_; 158 dst_adjustment_offsets dst_offsets_; 159 boost::shared_ptr<dst_calc_rule> dst_calc_rules_; 160 }; 161 162 typedef custom_time_zone_base<char> custom_time_zone; 163 164 } }//namespace 165 166 167 168 #endif 169