Update to allow traits-based local time adjustment

[SVN r17304]
This commit is contained in:
Jeff Garland
2003-02-10 13:23:54 +00:00
parent facde48090
commit 6d3227d5a9
11 changed files with 436 additions and 43 deletions

View File

@@ -14,6 +14,9 @@ namespace date_time {
//! An enumeration of weekday names
enum weekdays {Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday};
//! Simple enum to allow for nice programming with Jan, Feb, etc
enum months_of_year {Jan=1,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec,NotAMonth,NumMonths};
} } //namespace date_time
/* Copyright (c) 2000,2002

View File

@@ -16,12 +16,12 @@ namespace date_time {
//! Generates a date by applying the year to the given month and day.
/*!
*Example usage:
*@code
* partial_date pd(Jan,1);
* date d = pd.get_date(2002);//2002-Jan-01
*@endcode
* \ingroup date_alg
Example usage:
@code
partial_date pd(1, Jan);
date d = pd.get_date(2002); //2002-Jan-01
@endcode
\ingroup date_alg
*/
template<class date_type>
class partial_date {
@@ -31,9 +31,9 @@ namespace date_time {
typedef typename calendar_type::month_type month_type;
typedef typename calendar_type::year_type year_type;
typedef typename date_type::duration_type duration_type;
partial_date(month_type m, day_type d) :
month_(m),
day_(d)
partial_date(day_type d, month_type m) :
day_(d),
month_(m)
{}
//! Return a concrete date when provided with a year specific year.
date_type get_date(year_type y) const
@@ -44,11 +44,22 @@ namespace date_time {
{
return date_type(y, month_, day_);
}
bool operator==(const partial_date& rhs) const
{
return (month_ == rhs.month_) && (day_ == rhs.day_);
}
bool operator<(const partial_date& rhs) const
{
if (month_ < rhs.month_) return true;
if (month_ > rhs.month_) return false;
//months are equal
return (day_ < rhs.day_);
}
private:
month_type month_;
day_type day_;
month_type month_;
};
@@ -144,6 +155,7 @@ namespace date_time {
/*! Useful generator functor for finding holidays and daylight savings
* Get the last day of the month and then calculate the difference
* to the last previous day.
* @param date_type A date class that exports day_of_week, month_type, etc.
* \ingroup date_alg
*/
template<class date_type>
@@ -154,7 +166,7 @@ namespace date_time {
typedef typename calendar_type::month_type month_type;
typedef typename calendar_type::year_type year_type;
typedef typename date_type::duration_type duration_type;
//!Specify the date spec like 'Sunday' in 'April' spec
//!Specify the date spec like last 'Sunday' in 'April' spec
/*!@param dow The day of week, eg: Sunday, Monday, etc
* @param month The month of the year, eg: Jan, Feb, Mar, etc
*/

View File

@@ -21,7 +21,7 @@ namespace boost {
ambiguous, invalid_time_label};
//! Generic functions to calculate dst transition information
//! Dynamic class used to caluclate dst transition information
template<class date_type_,
class time_duration_type_>
class dst_calculator
@@ -90,7 +90,7 @@ namespace boost {
* @param dst_start_offset_minutes Offset within day for dst
* boundary (eg 120 for US which is 02:00:00)
* @param dst_end_day Ending day of dst for the given locality
* @param dst_end_offset_minutes Offset within day for dst
* @param dst_end_offset_minutes Offset within day given in dst for dst
* boundary (eg 120 for US which is 02:00:00)
* @param dst_length_minutes Length of dst adjusment (eg: 60 for US)
* @retval The time is either ambiguous, invalid, in dst, or not in dst
@@ -140,14 +140,104 @@ namespace boost {
};
//! Class to calculate dst boundaries for US time zones
/*
//! Compile-time configurable daylight savings time calculation engine
/* This template provides the ability to configure a daylight savings
* calculation at compile time covering all the cases. Unfortunately
* because of the number of dimensions related to daylight savings
* calculation the number of parameters is high. In addition, the
* start and end transition rules are complex types that specify
* an algorithm for calculation of the starting day and ending
* day of daylight savings time including the month and day
* specifications (eg: last sunday in October).
*
* @param date_type A type that represents dates, typically gregorian::date
* @param time_duration_type Used for the offset in the day calculations
* @param dst_traits A set of traits that define the rules of dst
* calculation. The dst_trait must include the following:
* start_rule_functor - Rule to calculate the starting date of a
* dst transition (eg: last_kday_of_month).
* start_day - static function that returns month of dst start for
* start_rule_functor
* start_month -static function that returns day or day of week for
* dst start of dst
* end_rule_functor - Rule to calculate the end of dst day.
* end_day - static fucntion that returns end day for end_rule_functor
* end_month - static function that returns end month for end_rule_functor
* dst_start_offset_minutes - number of minutes from start of day to transition to dst -- 120 (or 2:00 am) is typical for the U.S. and E.U.
* dst_start_offset_minutes - number of minutes from start of day to transition off of dst -- 180 (or 3:00 am) is typical for E.U.
* dst_length_minutes - number of minutes that dst shifts clock
*/
template<class date_type,
class time_duration_type,
class dst_traits>
class dst_calc_engine
{
public:
typedef typename date_type::year_type year_type;
typedef typename date_type::calendar_type calendar_type;
typedef dst_calculator<date_type, time_duration_type> dstcalc;
//! Calculates if the given local time is dst or not
/*! Determines if the time is really in DST or not. Also checks for
* invalid and ambiguous.
* @retval The time is either ambiguous, invalid, in dst, or not in dst
*/
static time_is_dst_result local_is_dst(const date_type& d,
const time_duration_type& td)
{
year_type y = d.year();
date_type dst_start = local_dst_start_day(y);
date_type dst_end = local_dst_end_day(y);
return dstcalc::local_is_dst(d,td,
dst_start,
dst_traits::dst_start_offset_minutes(),
dst_end,
dst_traits::dst_end_offset_minutes(),
dst_traits::dst_shift_length_minutes());
}
static bool is_dst_boundary_day(date_type d)
{
year_type y = d.year();
return ((d == local_dst_start_day(y)) ||
(d == local_dst_end_day(y)));
}
//! The time of day for the dst transition (eg: typically 01:00:00 or 02:00:00)
static time_duration_type dst_offset()
{
return time_duration_type(0,dst_traits::dst_shift_length_minutes(),0);
}
static date_type local_dst_start_day(year_type year)
{
typedef typename dst_traits::start_rule_functor start_rule;
start_rule start(dst_traits::start_day(),
dst_traits::start_month());
return start.get_date(year);
}
static date_type local_dst_end_day(year_type year)
{
typedef typename dst_traits::end_rule_functor end_rule;
end_rule end(dst_traits::end_day(),
dst_traits::end_month());
return end.get_date(year);
}
};
//! Depricated: Class to calculate dst boundaries for US time zones
/* Use dst_calc_engine instead.
*/
template<class date_type_,
class time_duration_type_,
unsigned int dst_start_offset_minutes=120, //from start of day
short dst_length_minutes=60> //1 hour == 60 min in US
class us_dst_rules
class us_dst_rules
{
public:
typedef time_duration_type_ time_duration_type;
@@ -199,15 +289,14 @@ namespace boost {
return lsio.get_date(year);
}
static time_duration_type dst_offset()
static time_duration_type dst_offset()
{
return time_duration_type(0,dst_length_minutes,0);
}
};
//! Used for local time adjustments in places that don't use dst
template<class date_type_, class time_duration_type_>
class null_dst_rules

View File

@@ -6,6 +6,7 @@
*/
#include "boost/date_time/constrained_value.hpp"
#include "boost/date_time/date_defs.hpp"
#include <stdexcept>
#include <string>
@@ -13,9 +14,23 @@
namespace boost {
namespace gregorian {
typedef date_time::months_of_year months_of_year;
//! Simple enum to allow for nice programming with Jan, Feb, etc
enum months_of_year {Jan=1,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec,NotAMonth,NumMonths};
//bring enum values into the namespace
using date_time::Jan;
using date_time::Feb;
using date_time::Mar;
using date_time::Apr;
using date_time::May;
using date_time::Jun;
using date_time::Jul;
using date_time::Aug;
using date_time::Sep;
using date_time::Oct;
using date_time::Nov;
using date_time::Dec;
using date_time::NotAMonth;
using date_time::NumMonths;
//! Exception thrown if a greg_month is constructed with a value out of range
struct bad_month : public std::out_of_range
@@ -31,9 +46,9 @@ namespace gregorian {
//! Wrapper class to represent months in gregorian based calendar
class greg_month : public greg_month_rep {
public:
typedef months_of_year month_enum;
typedef date_time::months_of_year month_enum;
//! Construct a month from the months_of_year enumeration
greg_month(months_of_year theMonth) : greg_month_rep(theMonth) {}
greg_month(month_enum theMonth) : greg_month_rep(theMonth) {}
//! Construct from a short value
greg_month(unsigned short theMonth) : greg_month_rep(theMonth) {}
//! Convert the value back to a short

View File

@@ -168,11 +168,11 @@ namespace boost {
* For example:
* @code
* //eastern timezone is utc-5
typedef date_time::us_local_adjustor<ptime, -5, us_dst> us_eastern;
typedef date_time::us_local_adjustor<ptime, -6, us_dst> us_central;
typedef date_time::us_local_adjustor<ptime, -7, us_dst> us_mountain;
typedef date_time::us_local_adjustor<ptime, -8, us_dst> us_pacific;
typedef date_time::us_local_adjustor<ptime, -7, no_dst> us_arizona;
typedef date_time::local_adjustor<ptime, -5, us_dst> us_eastern;
typedef date_time::local_adjustor<ptime, -6, us_dst> us_central;
typedef date_time::local_adjustor<ptime, -7, us_dst> us_mountain;
typedef date_time::local_adjustor<ptime, -8, us_dst> us_pacific;
typedef date_time::local_adjustor<ptime, -7, no_dst> us_arizona;
@endcode
*/