BVB Source Codes

mars Show date_generators.hpp Source code

Return Download mars: download date_generators.hpp Source code - Download mars Source code - Type:.hpp
  1. #ifndef DATE_TIME_DATE_GENERATORS_HPP__
  2. #define DATE_TIME_DATE_GENERATORS_HPP__
  3.  
  4. /* Copyright (c) 2002,2003,2005 CrystalClear Software, Inc.
  5.  * Use, modification and distribution is subject to the
  6.  * Boost Software License, Version 1.0. (See accompanying
  7.  * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
  8.  * Author: Jeff Garland, Bart Garst
  9.  * $Date$
  10.  */
  11.  
  12. /*! @file date_generators.hpp
  13.   Definition and implementation of date algorithm templates
  14. */
  15.  
  16. #include <stdexcept>
  17. #include <sstream>
  18. #include <boost/throw_exception.hpp>
  19. #include <boost/date_time/date.hpp>
  20. #include <boost/date_time/compiler_config.hpp>
  21.  
  22. namespace mars_boost {} namespace boost = mars_boost; namespace mars_boost {
  23. namespace date_time {
  24.  
  25.   //! Base class for all generators that take a year and produce a date.
  26.   /*! This class is a base class for polymorphic function objects that take
  27.     a year and produce a concrete date.
  28.     @param date_type The type representing a date.  This type must
  29.     export a calender_type which defines a year_type.
  30.   */
  31.   template<class date_type>
  32.   class year_based_generator
  33.   {
  34.   public:
  35.     typedef typename date_type::calendar_type calendar_type;
  36.     typedef typename calendar_type::year_type        year_type;
  37.     year_based_generator() {}
  38.     virtual ~year_based_generator() {}
  39.     virtual date_type get_date(year_type y) const = 0;
  40.     //! Returns a string for use in a POSIX time_zone string
  41.     virtual std::string to_string() const =0;
  42.   };
  43.  
  44.   //! Generates a date by applying the year to the given month and day.
  45.   /*!
  46.     Example usage:
  47.     @code
  48.     partial_date pd(1, Jan);
  49.     partial_date pd2(70);
  50.     date d = pd.get_date(2002); //2002-Jan-01
  51.     date d2 = pd2.get_date(2002); //2002-Mar-10
  52.     @endcode
  53.     \ingroup date_alg
  54.   */
  55.   template<class date_type>
  56.  class partial_date : public year_based_generator<date_type>
  57.  {
  58.  public:
  59.    typedef typename date_type::calendar_type calendar_type;
  60.    typedef typename calendar_type::day_type         day_type;
  61.    typedef typename calendar_type::month_type       month_type;
  62.    typedef typename calendar_type::year_type        year_type;
  63.    typedef typename date_type::duration_type        duration_type;
  64.    typedef typename duration_type::duration_rep     duration_rep;
  65.    partial_date(day_type d, month_type m) :
  66.      day_(d),
  67.      month_(m)
  68.    {}
  69.    //! Partial date created from number of days into year. Range 1-366
  70.    /*! Allowable values range from 1 to 366. 1=Jan1, 366=Dec31. If argument
  71.     * exceeds range, partial_date will be created with closest in-range value.
  72.     * 60 will always be Feb29, if get_date() is called with a non-leap year
  73.     * an exception will be thrown */
  74.    partial_date(duration_rep days) :
  75.      day_(1), // default values
  76.      month_(1)
  77.    {
  78.      date_type d1(2000,1,1);
  79.      if(days > 1) {
  80.        if(days > 366) // prevents wrapping
  81.        {
  82.          days = 366;
  83.        }
  84.        days = days - 1;
  85.        duration_type dd(days);
  86.        d1 = d1 + dd;
  87.      }
  88.      day_ = d1.day();
  89.      month_ = d1.month();
  90.    }
  91.    //! Return a concrete date when provided with a year specific year.
  92.    /*! Will throw an 'invalid_argument' exception if a partial_date object,
  93.     * instantiated with Feb-29, has get_date called with a non-leap year.
  94.     * Example:
  95.     * @code
  96.     * partial_date pd(29, Feb);
  97.     * pd.get_date(2003); // throws invalid_argument exception
  98.     * pg.get_date(2000); // returns 2000-2-29
  99.     * @endcode
  100.          */
  101.    date_type get_date(year_type y) const
  102.    {
  103.      if((day_ == 29) && (month_ == 2) && !(calendar_type::is_leap_year(y))) {
  104.        std::ostringstream ss;
  105.        ss << "No Feb 29th in given year of " << y << ".";
  106.        mars_boost::throw_exception(std::invalid_argument(ss.str()));
  107.      }
  108.      return date_type(y, month_, day_);
  109.    }
  110.    date_type operator()(year_type y) const
  111.    {
  112.      return get_date(y);
  113.      //return date_type(y, month_, day_);
  114.    }
  115.    bool operator==(const partial_date& rhs) const
  116.    {
  117.      return (month_ == rhs.month_) && (day_ == rhs.day_);
  118.    }
  119.    bool operator<(const partial_date& rhs) const
  120.    {
  121.      if (month_ < rhs.month_) return true;
  122.      if (month_ > rhs.month_) return false;
  123.      //months are equal
  124.      return (day_ < rhs.day_);
  125.    }
  126.  
  127.    // added for streaming purposes
  128.    month_type month() const
  129.    {
  130.      return month_;
  131.    }
  132.    day_type day() const
  133.    {
  134.      return day_;
  135.    }
  136.  
  137.    //! Returns string suitable for use in POSIX time zone string
  138.    /*! Returns string formatted with up to 3 digits:
  139.     * Jan-01 == "0"
  140.     * Feb-29 == "58"
  141.     * Dec-31 == "365" */
  142.    virtual std::string to_string() const
  143.    {
  144.      std::ostringstream ss;
  145.      date_type d(2004, month_, day_);
  146.      unsigned short c = d.day_of_year();
  147.      c--; // numbered 0-365 while day_of_year is 1 based...
  148.      ss << c;
  149.      return ss.str();
  150.    }
  151.  private:
  152.    day_type day_;
  153.    month_type month_;
  154.  };
  155.  
  156.  
  157.   //! Returns nth arg as string. 1 -> "first", 2 -> "second", max is 5.
  158.   BOOST_DATE_TIME_DECL const char* nth_as_str(int n);
  159.  
  160.   //! Useful generator functor for finding holidays
  161.   /*! Based on the idea in Cal. Calc. for finding holidays that are
  162.    *  the 'first Monday of September'. When instantiated with
  163.    *  'fifth' kday of month, the result will be the last kday of month
  164.    *  which can be the fourth or fifth depending on the structure of
  165.    *  the month.
  166.    *
  167.    *  The algorithm here basically guesses for the first
  168.    *  day of the month.  Then finds the first day of the correct
  169.    *  type.  That is, if the first of the month is a Tuesday
  170.    *  and it needs Wenesday then we simply increment by a day
  171.    *  and then we can add the length of a week until we get
  172.    *  to the 'nth kday'.  There are probably more efficient
  173.    *  algorithms based on using a mod 7, but this one works
  174.    *  reasonably well for basic applications.
  175.    *  \ingroup date_alg
  176.    */
  177.   template<class date_type>
  178.   class nth_kday_of_month : public year_based_generator<date_type>
  179.   {
  180.   public:
  181.     typedef typename date_type::calendar_type calendar_type;
  182.     typedef typename calendar_type::day_of_week_type  day_of_week_type;
  183.     typedef typename calendar_type::month_type        month_type;
  184.     typedef typename calendar_type::year_type         year_type;
  185.     typedef typename date_type::duration_type        duration_type;
  186.     enum week_num {first=1, second, third, fourth, fifth};
  187.     nth_kday_of_month(week_num week_no,
  188.                       day_of_week_type dow,
  189.                       month_type m) :
  190.       month_(m),
  191.       wn_(week_no),
  192.       dow_(dow)
  193.     {}
  194.     //! Return a concrete date when provided with a year specific year.
  195.     date_type get_date(year_type y) const
  196.     {
  197.       date_type d(y, month_, 1); //first day of month
  198.       duration_type one_day(1);
  199.       duration_type one_week(7);
  200.       while (dow_ != d.day_of_week()) {
  201.         d = d + one_day;
  202.       }
  203.       int week = 1;
  204.       while (week < wn_) {
  205.         d = d + one_week;
  206.         week++;
  207.       }
  208.       // remove wrapping to next month behavior
  209.       if(d.month() != month_) {
  210.         d = d - one_week;
  211.       }
  212.       return d;
  213.     }
  214.     // added for streaming
  215.     month_type month() const
  216.     {
  217.       return month_;
  218.     }
  219.     week_num nth_week() const
  220.     {
  221.       return wn_;
  222.     }
  223.     day_of_week_type day_of_week() const
  224.     {
  225.       return dow_;
  226.     }
  227.     const char* nth_week_as_str() const
  228.     {
  229.       return nth_as_str(wn_);
  230.     }
  231.     //! Returns string suitable for use in POSIX time zone string
  232.     /*! Returns a string formatted as "M4.3.0" ==> 3rd Sunday in April. */
  233.     virtual std::string to_string() const
  234.     {
  235.      std::ostringstream ss;
  236.      ss << 'M'
  237.        << static_cast<int>(month_) << '.'
  238.        << static_cast<int>(wn_) << '.'
  239.        << static_cast<int>(dow_);
  240.      return ss.str();
  241.     }
  242.   private:
  243.     month_type month_;
  244.     week_num wn_;
  245.     day_of_week_type dow_;
  246.   };
  247.  
  248.   //! Useful generator functor for finding holidays and daylight savings
  249.   /*! Similar to nth_kday_of_month, but requires less paramters
  250.    *  \ingroup date_alg
  251.    */
  252.   template<class date_type>
  253.   class first_kday_of_month : public year_based_generator<date_type>
  254.   {
  255.   public:
  256.     typedef typename date_type::calendar_type calendar_type;
  257.     typedef typename calendar_type::day_of_week_type  day_of_week_type;
  258.     typedef typename calendar_type::month_type        month_type;
  259.     typedef typename calendar_type::year_type         year_type;
  260.     typedef typename date_type::duration_type        duration_type;
  261.     //!Specify the first 'Sunday' in 'April' spec
  262.     /*!@param dow The day of week, eg: Sunday, Monday, etc
  263.      * @param m The month of the year, eg: Jan, Feb, Mar, etc
  264.      */
  265.     first_kday_of_month(day_of_week_type dow, month_type m) :
  266.       month_(m),
  267.       dow_(dow)
  268.     {}
  269.     //! Return a concrete date when provided with a year specific year.
  270.     date_type get_date(year_type year) const
  271.     {
  272.       date_type d(year, month_,1);
  273.       duration_type one_day(1);
  274.       while (dow_ != d.day_of_week()) {
  275.         d = d + one_day;
  276.       }
  277.       return d;
  278.     }
  279.     // added for streaming
  280.     month_type month() const
  281.     {
  282.       return month_;
  283.     }
  284.     day_of_week_type day_of_week() const
  285.     {
  286.       return dow_;
  287.     }
  288.     //! Returns string suitable for use in POSIX time zone string
  289.     /*! Returns a string formatted as "M4.1.0" ==> 1st Sunday in April. */
  290.     virtual std::string to_string() const
  291.     {
  292.      std::ostringstream ss;
  293.      ss << 'M'
  294.        << static_cast<int>(month_) << '.'
  295.        << 1 << '.'
  296.        << static_cast<int>(dow_);
  297.      return ss.str();
  298.     }
  299.   private:
  300.     month_type month_;
  301.     day_of_week_type dow_;
  302.   };
  303.  
  304.  
  305.  
  306.   //! Calculate something like Last Sunday of January
  307.   /*! Useful generator functor for finding holidays and daylight savings
  308.    *  Get the last day of the month and then calculate the difference
  309.    *  to the last previous day.
  310.    *  @param date_type A date class that exports day_of_week, month_type, etc.
  311.    *  \ingroup date_alg
  312.    */
  313.   template<class date_type>
  314.   class last_kday_of_month : public year_based_generator<date_type>
  315.   {
  316.   public:
  317.     typedef typename date_type::calendar_type calendar_type;
  318.     typedef typename calendar_type::day_of_week_type  day_of_week_type;
  319.     typedef typename calendar_type::month_type        month_type;
  320.     typedef typename calendar_type::year_type         year_type;
  321.     typedef typename date_type::duration_type        duration_type;
  322.     //!Specify the date spec like last 'Sunday' in 'April' spec
  323.     /*!@param dow The day of week, eg: Sunday, Monday, etc
  324.      * @param m The month of the year, eg: Jan, Feb, Mar, etc
  325.      */
  326.     last_kday_of_month(day_of_week_type dow, month_type m) :
  327.       month_(m),
  328.       dow_(dow)
  329.     {}
  330.     //! Return a concrete date when provided with a year specific year.
  331.     date_type get_date(year_type year) const
  332.     {
  333.       date_type d(year, month_, calendar_type::end_of_month_day(year,month_));
  334.       duration_type one_day(1);
  335.       while (dow_ != d.day_of_week()) {
  336.         d = d - one_day;
  337.       }
  338.       return d;
  339.     }
  340.     // added for streaming
  341.     month_type month() const
  342.     {
  343.       return month_;
  344.     }
  345.     day_of_week_type day_of_week() const
  346.     {
  347.       return dow_;
  348.     }
  349.     //! Returns string suitable for use in POSIX time zone string
  350.     /*! Returns a string formatted as "M4.5.0" ==> last Sunday in April. */
  351.     virtual std::string to_string() const
  352.     {
  353.       std::ostringstream ss;
  354.       ss << 'M'
  355.          << static_cast<int>(month_) << '.'
  356.          << 5 << '.'
  357.          << static_cast<int>(dow_);
  358.       return ss.str();
  359.     }
  360.   private:
  361.     month_type month_;
  362.     day_of_week_type dow_;
  363.    };
  364.  
  365.  
  366.   //! Calculate something like "First Sunday after Jan 1,2002
  367.   /*! Date generator that takes a date and finds kday after
  368.    *@code
  369.      typedef mars_boost::date_time::first_kday_after<date> firstkdayafter;
  370.      firstkdayafter fkaf(Monday);
  371.      fkaf.get_date(date(2002,Feb,1));
  372.    @endcode
  373.    *  \ingroup date_alg
  374.    */
  375.   template<class date_type>
  376.   class first_kday_after
  377.   {
  378.   public:
  379.     typedef typename date_type::calendar_type calendar_type;
  380.     typedef typename calendar_type::day_of_week_type day_of_week_type;
  381.     typedef typename date_type::duration_type        duration_type;
  382.     first_kday_after(day_of_week_type dow) :
  383.       dow_(dow)
  384.     {}
  385.     //! Return next kday given.
  386.     date_type get_date(date_type start_day) const
  387.     {
  388.       duration_type one_day(1);
  389.       date_type d = start_day + one_day;
  390.       while (dow_ != d.day_of_week()) {
  391.         d = d + one_day;
  392.       }
  393.       return d;
  394.     }
  395.     // added for streaming
  396.     day_of_week_type day_of_week() const
  397.     {
  398.       return dow_;
  399.     }
  400.   private:
  401.     day_of_week_type dow_;
  402.   };
  403.  
  404.   //! Calculate something like "First Sunday before Jan 1,2002
  405.   /*! Date generator that takes a date and finds kday after
  406.    *@code
  407.      typedef mars_boost::date_time::first_kday_before<date> firstkdaybefore;
  408.      firstkdaybefore fkbf(Monday);
  409.      fkbf.get_date(date(2002,Feb,1));
  410.    @endcode
  411.    *  \ingroup date_alg
  412.    */
  413.   template<class date_type>
  414.   class first_kday_before
  415.   {
  416.   public:
  417.     typedef typename date_type::calendar_type calendar_type;
  418.     typedef typename calendar_type::day_of_week_type day_of_week_type;
  419.     typedef typename date_type::duration_type        duration_type;
  420.     first_kday_before(day_of_week_type dow) :
  421.       dow_(dow)
  422.     {}
  423.     //! Return next kday given.
  424.     date_type get_date(date_type start_day) const
  425.     {
  426.       duration_type one_day(1);
  427.       date_type d = start_day - one_day;
  428.       while (dow_ != d.day_of_week()) {
  429.         d = d - one_day;
  430.       }
  431.       return d;
  432.     }
  433.     // added for streaming
  434.     day_of_week_type day_of_week() const
  435.     {
  436.       return dow_;
  437.     }
  438.   private:
  439.     day_of_week_type dow_;
  440.   };
  441.  
  442.   //! Calculates the number of days until the next weekday
  443.   /*! Calculates the number of days until the next weekday.
  444.    * If the date given falls on a Sunday and the given weekday
  445.    * is Tuesday the result will be 2 days */
  446.   template<typename date_type, class weekday_type>
  447.   inline
  448.   typename date_type::duration_type days_until_weekday(const date_type& d, const weekday_type& wd)
  449.   {
  450.     typedef typename date_type::duration_type duration_type;
  451.     duration_type wks(0);
  452.     duration_type dd(wd.as_number() - d.day_of_week().as_number());
  453.     if(dd.is_negative()){
  454.       wks = duration_type(7);
  455.     }
  456.     return dd + wks;
  457.   }
  458.  
  459.   //! Calculates the number of days since the previous weekday
  460.   /*! Calculates the number of days since the previous weekday
  461.    * If the date given falls on a Sunday and the given weekday
  462.    * is Tuesday the result will be 5 days. The answer will be a positive
  463.    * number because Tuesday is 5 days before Sunday, not -5 days before. */
  464.   template<typename date_type, class weekday_type>
  465.   inline
  466.   typename date_type::duration_type days_before_weekday(const date_type& d, const weekday_type& wd)
  467.   {
  468.     typedef typename date_type::duration_type duration_type;
  469.     duration_type wks(0);
  470.     duration_type dd(wd.as_number() - d.day_of_week().as_number());
  471.     if(dd.days() > 0){
  472.       wks = duration_type(7);
  473.     }
  474.     // we want a number of days, not an offset. The value returned must
  475.     // be zero or larger.
  476.     return (-dd + wks);
  477.   }
  478.  
  479.   //! Generates a date object representing the date of the following weekday from the given date
  480.   /*! Generates a date object representing the date of the following
  481.    * weekday from the given date. If the date given is 2004-May-9
  482.    * (a Sunday) and the given weekday is Tuesday then the resulting date
  483.    * will be 2004-May-11. */
  484.   template<class date_type, class weekday_type>
  485.   inline
  486.   date_type next_weekday(const date_type& d, const weekday_type& wd)
  487.   {
  488.     return d + days_until_weekday(d, wd);
  489.   }
  490.  
  491.   //! Generates a date object representing the date of the previous weekday from the given date
  492.   /*! Generates a date object representing the date of the previous
  493.    * weekday from the given date. If the date given is 2004-May-9
  494.    * (a Sunday) and the given weekday is Tuesday then the resulting date
  495.    * will be 2004-May-4. */
  496.   template<class date_type, class weekday_type>
  497.   inline
  498.   date_type previous_weekday(const date_type& d, const weekday_type& wd)
  499.   {
  500.     return d - days_before_weekday(d, wd);
  501.   }
  502.  
  503. } } //namespace date_time
  504.  
  505.  
  506.  
  507.  
  508. #endif
  509.  
  510.  
downloaddate_generators.hpp Source code - Download mars Source code
Related Source Codes/Software:
Hero - Elegant transition library for iOS & tvOS 2017-06-09
deep-photo-styletransfer - Code and data for paper "Deep Photo Style Transfer... 2017-06-09
mastodon - A GNU Social-compatible microblogging server ... 2017-06-09
plyr - A simple HTML5, YouTube and Vimeo player ... 2017-06-08
prepack - Prepack is a partial evaluator for JavaScript. Pre... 2017-06-08
Public-APIs - 2017-06-09
lottie-ios - An iOS library to natively render After Effects ve... 2017-06-09
Awesome-Hacking - A collection of various awesome lists for hackers,... 2017-06-09
algorithms - Minimal examples of data structures and algorithms... 2017-06-10
lectures - Oxford Deep NLP 2017 course 2017-06-10
CRYENGINE - CRYENGINE is a powerful real-time game development... 2017-06-11
postal - 2017-06-11
reactide - Reactide is the first dedicated IDE for React web ... 2017-06-11
rkt - rkt is a pod-native container engine for Linux. It... 2017-06-11
uWebSockets - Tiny WebSockets https://for... 2017-06-11
realworld - TodoMVC for the RealWorld - Exemplary fullstack Me... 2017-06-11
goreplay - GoReplay is an open-source tool for capturing and ... 2017-06-10
pyenv - Simple Python version management 2017-06-10
redux-saga - An alternative side effect model for Redux apps ... 2017-06-10
angular-starter - 2017-06-10

 Back to top