custom_time_zone.hpp 6.1 KB

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