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

📄 posix_time_zone.hpp

📁 C++的一个好库。。。现在很流行
💻 HPP
📖 第 1 页 / 共 2 页
字号:
#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 or http://www.boost.org/LICENSE-1.0)
 * Author: Jeff Garland, Bart Garst
 * $Date: 2005/05/25 14:15:41 $
 */

#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/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::time_zone_names time_zone_names;
  typedef boost::date_time::dst_adjustment_offsets<boost::posix_time::time_duration> dst_adjustment_offsets;
  typedef boost::date_time::time_zone_base<boost::posix_time::ptime> time_zone;

  //! 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>
   */
  class posix_time_zone : public time_zone  {
  public:
    typedef boost::posix_time::time_duration time_duration_type;
    typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
    typedef time_zone base_type;
    typedef base_type::string_type string_type;
    typedef base_type::stringstream_type stringstream_type;

    //! Construct from a POSIX time zone string
    posix_time_zone(const std::string& s) : 
      zone_names_("std_name","std_abbrev","no-dst","no-dst"),
      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_()
    {
      boost::char_separator<char> sep(",");
      tokenizer tokens(s, sep);
      tokenizer::iterator it = tokens.begin();
      calc_zone(*it++);
      if(has_dst_){
        std::string tmp_str = *it++;
        calc_rules(tmp_str, *it);
      }
    } 
    virtual ~posix_time_zone() {};
    //!String for the zone when not in daylight savings (eg: EST)
    virtual std::string 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 std::string 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 std::string 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 std::string 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 << ',' << 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 << ',' << 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_;
    time_duration_type base_utc_offset_;
    dst_adjustment_offsets dst_offsets_;
    boost::shared_ptr<dst_calc_rule> dst_calc_rules_;

⌨️ 快捷键说明

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