New upstream version 8.1.0

This commit is contained in:
geos_one
2025-08-10 01:34:16 +02:00
commit c891bb7105
4398 changed files with 838833 additions and 0 deletions

View File

@@ -0,0 +1,178 @@
#ifndef _DATE_TIME_ADJUST_FUNCTORS_HPP___
#define _DATE_TIME_ADJUST_FUNCTORS_HPP___
/* Copyright (c) 2002,2003 CrystalClear Software, Inc.
* Use, modification and distribution is subject to the
* Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
* Author: Jeff Garland, Bart Garst
* $Date$
*/
#include "boost/date_time/date.hpp"
#include "boost/date_time/wrapping_int.hpp"
namespace boost {
namespace date_time {
//! Functor to iterate a fixed number of days
template<class date_type>
class day_functor
{
public:
typedef typename date_type::duration_type duration_type;
day_functor(int f) : f_(f) {}
duration_type get_offset(const date_type& d) const
{
// why is 'd' a parameter???
// fix compiler warnings
d.year();
return duration_type(f_);
}
duration_type get_neg_offset(const date_type& d) const
{
// fix compiler warnings
d.year();
return duration_type(-f_);
}
private:
int f_;
};
//! Provides calculation to find next nth month given a date
/*! This adjustment function provides the logic for 'month-based'
* advancement on a ymd based calendar. The policy it uses
* to handle the non existant end of month days is to back
* up to the last day of the month. Also, if the starting
* date is the last day of a month, this functor will attempt
* to adjust to the end of the month.
*/
template<class date_type>
class month_functor
{
public:
typedef typename date_type::duration_type duration_type;
typedef typename date_type::calendar_type cal_type;
typedef typename cal_type::ymd_type ymd_type;
typedef typename cal_type::day_type day_type;
month_functor(int f) : f_(f), origDayOfMonth_(0) {}
duration_type get_offset(const date_type& d) const
{
ymd_type ymd(d.year_month_day());
if (origDayOfMonth_ == 0) {
origDayOfMonth_ = ymd.day;
day_type endOfMonthDay(cal_type::end_of_month_day(ymd.year,ymd.month));
if (endOfMonthDay == ymd.day) {
origDayOfMonth_ = -1; //force the value to the end of month
}
}
typedef date_time::wrapping_int2<short,1,12> wrap_int2;
typedef typename wrap_int2::int_type int_type;
wrap_int2 wi(ymd.month);
//calc the year wrap around, add() returns 0 or 1 if wrapped
int_type year = wi.add(static_cast<int_type>(f_));
year = static_cast<int_type>(year + ymd.year); //calculate resulting year
// std::cout << "trace wi: " << wi.as_int() << std::endl;
// std::cout << "trace year: " << year << std::endl;
//find the last day for the new month
day_type resultingEndOfMonthDay(cal_type::end_of_month_day(year, wi.as_int()));
//original was the end of month -- force to last day of month
if (origDayOfMonth_ == -1) {
return date_type(year, wi.as_int(), resultingEndOfMonthDay) - d;
}
day_type dayOfMonth = origDayOfMonth_;
if (dayOfMonth > resultingEndOfMonthDay) {
dayOfMonth = resultingEndOfMonthDay;
}
return date_type(year, wi.as_int(), dayOfMonth) - d;
}
//! Returns a negative duration_type
duration_type get_neg_offset(const date_type& d) const
{
ymd_type ymd(d.year_month_day());
if (origDayOfMonth_ == 0) {
origDayOfMonth_ = ymd.day;
day_type endOfMonthDay(cal_type::end_of_month_day(ymd.year,ymd.month));
if (endOfMonthDay == ymd.day) {
origDayOfMonth_ = -1; //force the value to the end of month
}
}
typedef date_time::wrapping_int2<short,1,12> wrap_int2;
typedef typename wrap_int2::int_type int_type;
wrap_int2 wi(ymd.month);
//calc the year wrap around, add() returns 0 or 1 if wrapped
int_type year = wi.subtract(static_cast<int_type>(f_));
year = static_cast<int_type>(year + ymd.year); //calculate resulting year
//find the last day for the new month
day_type resultingEndOfMonthDay(cal_type::end_of_month_day(year, wi.as_int()));
//original was the end of month -- force to last day of month
if (origDayOfMonth_ == -1) {
return date_type(year, wi.as_int(), resultingEndOfMonthDay) - d;
}
day_type dayOfMonth = origDayOfMonth_;
if (dayOfMonth > resultingEndOfMonthDay) {
dayOfMonth = resultingEndOfMonthDay;
}
return date_type(year, wi.as_int(), dayOfMonth) - d;
}
private:
int f_;
mutable short origDayOfMonth_;
};
//! Functor to iterate a over weeks
template<class date_type>
class week_functor
{
public:
typedef typename date_type::duration_type duration_type;
typedef typename date_type::calendar_type calendar_type;
week_functor(int f) : f_(f) {}
duration_type get_offset(const date_type& d) const
{
// why is 'd' a parameter???
// fix compiler warnings
d.year();
return duration_type(f_*calendar_type::days_in_week());
}
duration_type get_neg_offset(const date_type& d) const
{
// fix compiler warnings
d.year();
return duration_type(-f_*calendar_type::days_in_week());
}
private:
int f_;
};
//! Functor to iterate by a year adjusting for leap years
template<class date_type>
class year_functor
{
public:
//typedef typename date_type::year_type year_type;
typedef typename date_type::duration_type duration_type;
year_functor(int f) : _mf(f * 12) {}
duration_type get_offset(const date_type& d) const
{
return _mf.get_offset(d);
}
duration_type get_neg_offset(const date_type& d) const
{
return _mf.get_neg_offset(d);
}
private:
month_functor<date_type> _mf;
};
} }//namespace date_time
#endif

View File

@@ -0,0 +1,123 @@
#ifndef DATE_TIME_C_TIME_HPP___
#define DATE_TIME_C_TIME_HPP___
/* Copyright (c) 2002,2003,2005 CrystalClear Software, Inc.
* Use, modification and distribution is subject to the
* Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
* Author: Jeff Garland, Bart Garst
* $Date$
*/
/*! @file c_time.hpp
Provide workarounds related to the ctime header
*/
#include <ctime>
#include <string> // to be able to convert from string literals to exceptions
#include <stdexcept>
#include <boost/throw_exception.hpp>
#include <boost/date_time/compiler_config.hpp>
//Work around libraries that don't put time_t and time in namespace std
#ifdef BOOST_NO_STDC_NAMESPACE
namespace std { using ::time_t; using ::time; using ::localtime;
using ::tm; using ::gmtime; }
#endif // BOOST_NO_STDC_NAMESPACE
//The following is used to support high precision time clocks
#ifdef BOOST_HAS_GETTIMEOFDAY
#include <sys/time.h>
#endif
#ifdef BOOST_HAS_FTIME
#include <time.h>
#endif
namespace boost {
namespace date_time {
//! Provides a uniform interface to some 'ctime' functions
/*! Provides a uniform interface to some ctime functions and
* their '_r' counterparts. The '_r' functions require a pointer to a
* user created std::tm struct whereas the regular functions use a
* staticly created struct and return a pointer to that. These wrapper
* functions require the user to create a std::tm struct and send in a
* pointer to it. This struct may be used to store the resulting time.
* The returned pointer may or may not point to this struct, however,
* it will point to the result of the corresponding function.
* All functions do proper checking of the C function results and throw
* exceptions on error. Therefore the functions will never return NULL.
*/
struct c_time {
public:
#if defined(BOOST_DATE_TIME_HAS_REENTRANT_STD_FUNCTIONS)
//! requires a pointer to a user created std::tm struct
inline
static std::tm* localtime(const std::time_t* t, std::tm* result)
{
// localtime_r() not in namespace std???
#if defined(__VMS) && __INITIAL_POINTER_SIZE == 64
std::tm tmp;
if(!localtime_r(t,&tmp))
result = 0;
else
*result = tmp;
#else
result = localtime_r(t, result);
#endif
if (!result)
boost::throw_exception(std::runtime_error("could not convert calendar time to local time"));
return result;
}
//! requires a pointer to a user created std::tm struct
inline
static std::tm* gmtime(const std::time_t* t, std::tm* result)
{
// gmtime_r() not in namespace std???
#if defined(__VMS) && __INITIAL_POINTER_SIZE == 64
std::tm tmp;
if(!gmtime_r(t,&tmp))
result = 0;
else
*result = tmp;
#else
result = gmtime_r(t, result);
#endif
if (!result)
boost::throw_exception(std::runtime_error("could not convert calendar time to UTC time"));
return result;
}
#else // BOOST_DATE_TIME_HAS_REENTRANT_STD_FUNCTIONS
#if (defined(_MSC_VER) && (_MSC_VER >= 1400))
#pragma warning(push) // preserve warning settings
#pragma warning(disable : 4996) // disable depricated localtime/gmtime warning on vc8
#endif // _MSC_VER >= 1400
//! requires a pointer to a user created std::tm struct
inline
static std::tm* localtime(const std::time_t* t, std::tm* result)
{
result = std::localtime(t);
if (!result)
boost::throw_exception(std::runtime_error("could not convert calendar time to local time"));
return result;
}
//! requires a pointer to a user created std::tm struct
inline
static std::tm* gmtime(const std::time_t* t, std::tm* result)
{
result = std::gmtime(t);
if (!result)
boost::throw_exception(std::runtime_error("could not convert calendar time to UTC time"));
return result;
}
#if (defined(_MSC_VER) && (_MSC_VER >= 1400))
#pragma warning(pop) // restore warnings to previous state
#endif // _MSC_VER >= 1400
#endif // BOOST_DATE_TIME_HAS_REENTRANT_STD_FUNCTIONS
};
}} // namespaces
#endif // DATE_TIME_C_TIME_HPP___

View File

@@ -0,0 +1,169 @@
#ifndef DATE_TIME_COMPILER_CONFIG_HPP___
#define DATE_TIME_COMPILER_CONFIG_HPP___
/* Copyright (c) 2002-2004 CrystalClear Software, Inc.
* Subject to the Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
* Author: Jeff Garland, Bart Garst
* $Date$
*/
#include <cstdlib>
#include <boost/config.hpp>
#include <boost/detail/workaround.hpp>
// With boost release 1.33, date_time will be using a different,
// more flexible, IO system. This new system is not compatible with
// old compilers. The original date_time IO system remains for those
// compilers. They must define this macro to use the legacy IO.
// (defined(__BORLANDC__) && (__BORLANDC__ <= 0x0581) ) ) &&
#if( BOOST_WORKAROUND( __BORLANDC__, BOOST_TESTED_AT(0x581) ) \
|| BOOST_WORKAROUND( __GNUC__, < 3) \
|| (BOOST_WORKAROUND( _MSC_VER, <= 1300) ) \
) \
&& !defined(USE_DATE_TIME_PRE_1_33_FACET_IO)
# define USE_DATE_TIME_PRE_1_33_FACET_IO
#endif
// This file performs some local compiler configurations
#include <boost/date_time/locale_config.hpp> //set up locale configurations
//Set up a configuration parameter for platforms that have
//GetTimeOfDay
#if defined(BOOST_HAS_GETTIMEOFDAY) || defined(BOOST_HAS_FTIME)
#define BOOST_DATE_TIME_HAS_HIGH_PRECISION_CLOCK
#endif
// To Force no default constructors for date & ptime, un-comment following
//#define DATE_TIME_NO_DEFAULT_CONSTRUCTOR
// Include extensions to date_duration - comment out to remove this feature
#define BOOST_DATE_TIME_OPTIONAL_GREGORIAN_TYPES
// these extensions are known to cause problems with gcc295
#if defined(__GNUC__) && (__GNUC__ < 3)
#undef BOOST_DATE_TIME_OPTIONAL_GREGORIAN_TYPES
#endif
#if (defined(BOOST_NO_INCLASS_MEMBER_INITIALIZATION) || BOOST_WORKAROUND( __BORLANDC__, BOOST_TESTED_AT(0x581) ) )
#define BOOST_DATE_TIME_NO_MEMBER_INIT
#endif
// include these types before we try to re-define them
#include <boost/cstdint.hpp>
//Define INT64_C for compilers that don't have it
#if (!defined(INT64_C))
#define INT64_C(value) int64_t(value)
#endif
/* Workaround for Borland iterator error. Error was "Cannot convert 'istream *' to 'wistream *' in function istream_iterator<>::istream_iterator() */
#if defined(__BORLANDC__) && defined(BOOST_BCB_WITH_RW_LIB)
#define BOOST_DATE_TIME_NO_WISTREAM_ITERATOR
#endif
// Borland v5.64 does not have the following in std namespace; v5.5.1 does
#if defined(__BORLANDC__) && defined(BOOST_BCB_WITH_STLPORT)
#include <locale>
namespace std {
using stlport::tolower;
using stlport::ctype;
using stlport::use_facet;
}
#endif
// workaround for errors associated with output for date classes
// modifications and input streaming for time classes.
// Compilers affected are:
// gcc295, msvc (neither with STLPort), any borland
//
#if (((defined(__GNUC__) && (__GNUC__ < 3)) || \
(defined(_MSC_VER) && (_MSC_VER < 1300)) ) && \
!defined(_STLP_OWN_IOSTREAMS) ) || \
BOOST_WORKAROUND( __BORLANDC__, BOOST_TESTED_AT(0x581) )
#define BOOST_DATE_TIME_INCLUDE_LIMITED_HEADERS
#endif
// The macro marks up places where compiler complains for missing return statement or
// uninitialized variables after calling to boost::throw_exception.
// BOOST_UNREACHABLE_RETURN doesn't work since even compilers that support
// unreachable statements detection emit such warnings.
#if defined(_MSC_VER)
// Use special MSVC extension to markup unreachable code
# define BOOST_DATE_TIME_UNREACHABLE_EXPRESSION(x) __assume(false)
#elif !defined(BOOST_NO_UNREACHABLE_RETURN_DETECTION)
// Call to a non-returning function should suppress the warning
# if defined(BOOST_NO_STDC_NAMESPACE)
namespace std {
using ::abort;
}
# endif // defined(BOOST_NO_STDC_NAMESPACE)
# define BOOST_DATE_TIME_UNREACHABLE_EXPRESSION(x) std::abort()
#else
// For other poor compilers the specified expression is compiled. Usually, this would be a return statement.
# define BOOST_DATE_TIME_UNREACHABLE_EXPRESSION(x) x
#endif
/* The following handles the definition of the necessary macros
* for dll building on Win32 platforms.
*
* For code that will be placed in the date_time .dll,
* it must be properly prefixed with BOOST_DATE_TIME_DECL.
* The corresponding .cpp file must have BOOST_DATE_TIME_SOURCE
* defined before including its header. For examples see:
* greg_month.hpp & greg_month.cpp
*
*/
// we need to import/export our code only if the user has specifically
// asked for it by defining either BOOST_ALL_DYN_LINK if they want all boost
// libraries to be dynamically linked, or BOOST_DATE_TIME_DYN_LINK
// if they want just this one to be dynamically liked:
#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_DATE_TIME_DYN_LINK)
// export if this is our own source, otherwise import:
# ifdef BOOST_DATE_TIME_SOURCE
# define BOOST_DATE_TIME_DECL BOOST_SYMBOL_EXPORT
# else
# define BOOST_DATE_TIME_DECL BOOST_SYMBOL_IMPORT
# endif // BOOST_DATE_TIME_SOURCE
#endif // DYN_LINK
//
// if BOOST_WHATEVER_DECL isn't defined yet define it now:
#ifndef BOOST_DATE_TIME_DECL
# define BOOST_DATE_TIME_DECL
#endif
//
// Automatically link to the correct build variant where possible.
//
#if !defined(BOOST_ALL_NO_LIB) && !defined(BOOST_DATE_TIME_NO_LIB) && !defined(BOOST_DATE_TIME_SOURCE)
//
// Set the name of our library, this will get undef'ed by auto_link.hpp
// once it's done with it:
//
#define BOOST_LIB_NAME boost_date_time
//
// If we're importing code from a dll, then tell auto_link.hpp about it:
//
#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_DATE_TIME_DYN_LINK)
# define BOOST_DYN_LINK
#endif
//
// And include the header that does the work:
//
#include <boost/config/auto_link.hpp>
#endif // auto-linking disabled
#if defined(BOOST_HAS_THREADS)
# if defined(_MSC_VER) || defined(__MWERKS__) || defined(__MINGW32__) || defined(__BORLANDC__)
//no reentrant posix functions (eg: localtime_r)
# elif (!defined(__hpux) || (defined(__hpux) && defined(_REENTRANT)))
# define BOOST_DATE_TIME_HAS_REENTRANT_STD_FUNCTIONS
# endif
#endif
#endif

View File

@@ -0,0 +1,121 @@
#ifndef CONSTRAINED_VALUE_HPP___
#define CONSTRAINED_VALUE_HPP___
/* Copyright (c) 2002,2003 CrystalClear Software, Inc.
* Use, modification and distribution is subject to the
* Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
* Author: Jeff Garland
* $Date$
*/
#include <exception>
#include <stdexcept>
#include <boost/config.hpp>
#include <boost/throw_exception.hpp>
#include <boost/mpl/if.hpp>
#include <boost/type_traits/is_base_of.hpp>
namespace boost {
//! Namespace containing constrained_value template and types
namespace CV {
//! Represent a min or max violation type
enum violation_enum {min_violation, max_violation};
//! A template to specify a constrained basic value type
/*! This template provides a quick way to generate
* an integer type with a constrained range. The type
* provides for the ability to specify the min, max, and
* and error handling policy.
*
* <b>value policies</b>
* A class that provides the range limits via the min and
* max functions as well as a function on_error that
* determines how errors are handled. A common strategy
* would be to assert or throw and exception. The on_error
* is passed both the current value and the new value that
* is in error.
*
*/
template<class value_policies>
class constrained_value {
public:
typedef typename value_policies::value_type value_type;
// typedef except_type exception_type;
constrained_value(value_type value) : value_((min)())
{
assign(value);
}
constrained_value& operator=(value_type v)
{
assign(v);
return *this;
}
//! Return the max allowed value (traits method)
static value_type max BOOST_PREVENT_MACRO_SUBSTITUTION () {return (value_policies::max)();}
//! Return the min allowed value (traits method)
static value_type min BOOST_PREVENT_MACRO_SUBSTITUTION () {return (value_policies::min)();}
//! Coerce into the representation type
operator value_type() const {return value_;}
protected:
value_type value_;
private:
void assign(value_type value)
{
//adding 1 below gets rid of a compiler warning which occurs when the
//min_value is 0 and the type is unsigned....
if (value+1 < (min)()+1) {
value_policies::on_error(value_, value, min_violation);
return;
}
if (value > (max)()) {
value_policies::on_error(value_, value, max_violation);
return;
}
value_ = value;
}
};
//! Template to shortcut the constrained_value policy creation process
template<typename rep_type, rep_type min_value,
rep_type max_value, class exception_type>
class simple_exception_policy
{
struct exception_wrapper : public exception_type
{
// In order to support throw_exception mechanism in the BOOST_NO_EXCEPTIONS mode,
// we'll have to provide a way to acquire std::exception from the exception being thrown.
// However, we cannot derive from it, since it would make it interceptable by this class,
// which might not be what the user wanted.
operator std::out_of_range () const
{
// TODO: Make the message more descriptive by using arguments to on_error
return std::out_of_range("constrained value boundary has been violated");
}
};
typedef typename mpl::if_<
is_base_of< std::exception, exception_type >,
exception_type,
exception_wrapper
>::type actual_exception_type;
public:
typedef rep_type value_type;
static rep_type min BOOST_PREVENT_MACRO_SUBSTITUTION () { return min_value; }
static rep_type max BOOST_PREVENT_MACRO_SUBSTITUTION () { return max_value; }
static void on_error(rep_type, rep_type, violation_enum)
{
boost::throw_exception(actual_exception_type());
}
};
} } //namespace CV
#endif

View File

@@ -0,0 +1,208 @@
#ifndef DATE_TIME_DATE_HPP___
#define DATE_TIME_DATE_HPP___
/* Copyright (c) 2002,2003 CrystalClear Software, Inc.
* Use, modification and distribution is subject to the
* Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
* Author: Jeff Garland, Bart Garst
* $Date$
*/
#include <boost/operators.hpp>
#include <boost/date_time/year_month_day.hpp>
#include <boost/date_time/special_defs.hpp>
namespace boost {
namespace date_time {
//!Representation of timepoint at the one day level resolution.
/*!
The date template represents an interface shell for a date class
that is based on a year-month-day system such as the gregorian
or iso systems. It provides basic operations to enable calculation
and comparisons.
<b>Theory</b>
This date representation fundamentally departs from the C tm struct
approach. The goal for this type is to provide efficient date
operations (add, subtract) and storage (minimize space to represent)
in a concrete class. Thus, the date uses a count internally to
represent a particular date. The calendar parameter defines
the policies for converting the the year-month-day and internal
counted form here. Applications that need to perform heavy
formatting of the same date repeatedly will perform better
by using the year-month-day representation.
Internally the date uses a day number to represent the date.
This is a monotonic time representation. This representation
allows for fast comparison as well as simplifying
the creation of writing numeric operations. Essentially, the
internal day number is like adjusted julian day. The adjustment
is determined by the Epoch date which is represented as day 1 of
the calendar. Day 0 is reserved for negative infinity so that
any actual date is automatically greater than negative infinity.
When a date is constructed from a date or formatted for output,
the appropriate conversions are applied to create the year, month,
day representations.
*/
template<class T, class calendar, class duration_type_>
class date : private
boost::less_than_comparable<T
, boost::equality_comparable<T
> >
{
public:
typedef T date_type;
typedef calendar calendar_type;
typedef typename calendar::date_traits_type traits_type;
typedef duration_type_ duration_type;
typedef typename calendar::year_type year_type;
typedef typename calendar::month_type month_type;
typedef typename calendar::day_type day_type;
typedef typename calendar::ymd_type ymd_type;
typedef typename calendar::date_rep_type date_rep_type;
typedef typename calendar::date_int_type date_int_type;
typedef typename calendar::day_of_week_type day_of_week_type;
date(year_type y, month_type m, day_type d)
: days_(calendar::day_number(ymd_type(y, m, d)))
{}
date(const ymd_type& ymd)
: days_(calendar::day_number(ymd))
{}
//let the compiler write copy, assignment, and destructor
year_type year() const
{
ymd_type ymd = calendar::from_day_number(days_);
return ymd.year;
}
month_type month() const
{
ymd_type ymd = calendar::from_day_number(days_);
return ymd.month;
}
day_type day() const
{
ymd_type ymd = calendar::from_day_number(days_);
return ymd.day;
}
day_of_week_type day_of_week() const
{
ymd_type ymd = calendar::from_day_number(days_);
return calendar::day_of_week(ymd);
}
ymd_type year_month_day() const
{
return calendar::from_day_number(days_);
}
bool operator<(const date_type& rhs) const
{
return days_ < rhs.days_;
}
bool operator==(const date_type& rhs) const
{
return days_ == rhs.days_;
}
//! check to see if date is a special value
bool is_special()const
{
return(is_not_a_date() || is_infinity());
}
//! check to see if date is not a value
bool is_not_a_date() const
{
return traits_type::is_not_a_number(days_);
}
//! check to see if date is one of the infinity values
bool is_infinity() const
{
return traits_type::is_inf(days_);
}
//! check to see if date is greater than all possible dates
bool is_pos_infinity() const
{
return traits_type::is_pos_inf(days_);
}
//! check to see if date is greater than all possible dates
bool is_neg_infinity() const
{
return traits_type::is_neg_inf(days_);
}
//! return as a special value or a not_special if a normal date
special_values as_special() const
{
return traits_type::to_special(days_);
}
duration_type operator-(const date_type& d) const
{
if (!this->is_special() && !d.is_special())
{
// The duration underlying type may be wider than the date underlying type.
// Thus we calculate the difference in terms of two durations from some common fixed base date.
typedef typename duration_type::duration_rep_type duration_rep_type;
return duration_type(static_cast< duration_rep_type >(days_) - static_cast< duration_rep_type >(d.days_));
}
else
{
// In this case the difference will be a special value, too
date_rep_type val = date_rep_type(days_) - date_rep_type(d.days_);
return duration_type(val.as_special());
}
}
date_type operator-(const duration_type& dd) const
{
if(dd.is_special())
{
return date_type(date_rep_type(days_) - dd.get_rep());
}
return date_type(date_rep_type(days_) - static_cast<date_int_type>(dd.days()));
}
date_type operator-=(const duration_type& dd)
{
*this = *this - dd;
return date_type(days_);
}
date_rep_type day_count() const
{
return days_;
}
//allow internal access from operators
date_type operator+(const duration_type& dd) const
{
if(dd.is_special())
{
return date_type(date_rep_type(days_) + dd.get_rep());
}
return date_type(date_rep_type(days_) + static_cast<date_int_type>(dd.days()));
}
date_type operator+=(const duration_type& dd)
{
*this = *this + dd;
return date_type(days_);
}
//see reference
protected:
/*! This is a private constructor which allows for the creation of new
dates. It is not exposed to users since that would require class
users to understand the inner workings of the date class.
*/
explicit date(date_int_type days) : days_(days) {}
explicit date(date_rep_type days) : days_(days.as_number()) {}
date_int_type days_;
};
} } // namespace date_time
#endif

View File

@@ -0,0 +1,77 @@
#ifndef DATE_CLOCK_DEVICE_HPP___
#define DATE_CLOCK_DEVICE_HPP___
/* Copyright (c) 2002,2003,2005 CrystalClear Software, Inc.
* Use, modification and distribution is subject to the
* Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
* Author: Jeff Garland, Bart Garst
* $Date$
*/
#include "boost/date_time/c_time.hpp"
namespace boost {
namespace date_time {
//! A clock providing day level services based on C time_t capabilities
/*! This clock uses Posix interfaces as its implementation and hence
* uses the timezone settings of the operating system. Incorrect
* user settings will result in incorrect results for the calls
* to local_day.
*/
template<class date_type>
class day_clock
{
public:
typedef typename date_type::ymd_type ymd_type;
//! Get the local day as a date type
static date_type local_day()
{
return date_type(local_day_ymd());
}
//! Get the local day as a ymd_type
static typename date_type::ymd_type local_day_ymd()
{
::std::tm result;
::std::tm* curr = get_local_time(result);
return ymd_type(static_cast<unsigned short>(curr->tm_year + 1900),
static_cast<unsigned short>(curr->tm_mon + 1),
static_cast<unsigned short>(curr->tm_mday));
}
//! Get the current day in universal date as a ymd_type
static typename date_type::ymd_type universal_day_ymd()
{
::std::tm result;
::std::tm* curr = get_universal_time(result);
return ymd_type(static_cast<unsigned short>(curr->tm_year + 1900),
static_cast<unsigned short>(curr->tm_mon + 1),
static_cast<unsigned short>(curr->tm_mday));
}
//! Get the UTC day as a date type
static date_type universal_day()
{
return date_type(universal_day_ymd());
}
private:
static ::std::tm* get_local_time(std::tm& result)
{
::std::time_t t;
::std::time(&t);
return c_time::localtime(&t, &result);
}
static ::std::tm* get_universal_time(std::tm& result)
{
::std::time_t t;
::std::time(&t);
return c_time::gmtime(&t, &result);
}
};
} } //namespace date_time
#endif

View File

@@ -0,0 +1,26 @@
#ifndef DATE_TIME_DATE_DEFS_HPP
#define DATE_TIME_DATE_DEFS_HPP
/* Copyright (c) 2002,2003 CrystalClear Software, Inc.
* Use, modification and distribution is subject to the
* Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
* Author: Jeff Garland
* $Date$
*/
namespace boost {
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
#endif

View File

@@ -0,0 +1,146 @@
#ifndef DATE_TIME_DATE_DURATION__
#define DATE_TIME_DATE_DURATION__
/* Copyright (c) 2002,2003 CrystalClear Software, Inc.
* Use, modification and distribution is subject to the
* Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
* Author: Jeff Garland, Bart Garst
* $Date$
*/
#include <boost/operators.hpp>
#include <boost/date_time/special_defs.hpp>
namespace boost {
namespace date_time {
//! Duration type with date level resolution
template<class duration_rep_traits>
class date_duration : private
boost::less_than_comparable1< date_duration< duration_rep_traits >
, boost::equality_comparable1< date_duration< duration_rep_traits >
, boost::addable1< date_duration< duration_rep_traits >
, boost::subtractable1< date_duration< duration_rep_traits >
, boost::dividable2< date_duration< duration_rep_traits >, int
> > > > >
{
public:
typedef typename duration_rep_traits::int_type duration_rep_type;
typedef typename duration_rep_traits::impl_type duration_rep;
//! Construct from a day count
explicit date_duration(duration_rep day_count) : days_(day_count) {}
/*! construct from special_values - only works when
* instantiated with duration_traits_adapted */
date_duration(special_values sv) :
days_(duration_rep::from_special(sv))
{}
// copy constructor required for addable<> & subtractable<>
//! Construct from another date_duration (Copy Constructor)
date_duration(const date_duration<duration_rep_traits>& other) :
days_(other.days_)
{}
//! returns days_ as it's instantiated type - used for streaming
duration_rep get_rep()const
{
return days_;
}
bool is_special()const
{
return days_.is_special();
}
//! returns days as value, not object.
duration_rep_type days() const
{
return duration_rep_traits::as_number(days_);
}
//! Returns the smallest duration -- used by to calculate 'end'
static date_duration unit()
{
return date_duration<duration_rep_traits>(1);
}
//! Equality
bool operator==(const date_duration& rhs) const
{
return days_ == rhs.days_;
}
//! Less
bool operator<(const date_duration& rhs) const
{
return days_ < rhs.days_;
}
/* For shortcut operators (+=, -=, etc) simply using
* "days_ += days_" may not work. If instantiated with
* an int_adapter, shortcut operators are not present,
* so this will not compile */
//! Subtract another duration -- result is signed
date_duration& operator-=(const date_duration& rhs)
{
//days_ -= rhs.days_;
days_ = days_ - rhs.days_;
return *this;
}
//! Add a duration -- result is signed
date_duration& operator+=(const date_duration& rhs)
{
days_ = days_ + rhs.days_;
return *this;
}
//! unary- Allows for dd = -date_duration(2); -> dd == -2
date_duration operator-() const
{
return date_duration<duration_rep_traits>(get_rep() * (-1));
}
//! Division operations on a duration with an integer.
date_duration& operator/=(int divisor)
{
days_ = days_ / divisor;
return *this;
}
//! return sign information
bool is_negative() const
{
return days_ < 0;
}
private:
duration_rep days_;
};
/*! Struct for instantiating date_duration with <b>NO</b> special values
* functionality. Allows for transparent implementation of either
* date_duration<long> or date_duration<int_adapter<long> > */
struct duration_traits_long
{
typedef long int_type;
typedef long impl_type;
static int_type as_number(impl_type i) { return i; }
};
/*! Struct for instantiating date_duration <b>WITH</b> special values
* functionality. Allows for transparent implementation of either
* date_duration<long> or date_duration<int_adapter<long> > */
struct duration_traits_adapted
{
typedef long int_type;
typedef boost::date_time::int_adapter<long> impl_type;
static int_type as_number(impl_type i) { return i.as_number(); }
};
} } //namspace date_time
#endif

View File

@@ -0,0 +1,269 @@
#ifndef DATE_DURATION_TYPES_HPP___
#define DATE_DURATION_TYPES_HPP___
/* Copyright (c) 2004 CrystalClear Software, Inc.
* Subject to the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or
* http://www.boost.org/LICENSE_1_0.txt)
* Author: Jeff Garland, Bart Garst
* $Date$
*/
#include <boost/date_time/int_adapter.hpp>
#include <boost/date_time/special_defs.hpp>
#include <boost/date_time/date_duration.hpp>
namespace boost {
namespace date_time {
//! Additional duration type that represents a number of n*7 days
template <class duration_config>
class weeks_duration : public date_duration<duration_config> {
public:
weeks_duration(typename duration_config::impl_type w)
: date_duration<duration_config>(w * 7) {}
weeks_duration(special_values sv)
: date_duration<duration_config>(sv) {}
};
// predeclare
template<class t>
class years_duration;
//! additional duration type that represents a logical month
/*! A logical month enables things like: "date(2002,Mar,2) + months(2) ->
* 2002-May2". If the date is a last day-of-the-month, the result will
* also be a last-day-of-the-month.
*/
template<class base_config>
class months_duration
{
private:
typedef typename base_config::int_rep int_rep;
typedef typename int_rep::int_type int_type;
typedef typename base_config::date_type date_type;
typedef typename date_type::duration_type duration_type;
typedef typename base_config::month_adjustor_type month_adjustor_type;
typedef months_duration<base_config> months_type;
typedef years_duration<base_config> years_type;
public:
months_duration(int_rep num) : _m(num) {}
months_duration(special_values sv) : _m(sv)
{
_m = int_rep::from_special(sv);
}
int_rep number_of_months() const { return _m; }
//! returns a negative duration
duration_type get_neg_offset(const date_type& d) const
{
month_adjustor_type m_adj(_m.as_number());
return duration_type(m_adj.get_neg_offset(d));
}
duration_type get_offset(const date_type& d) const
{
month_adjustor_type m_adj(_m.as_number());
return duration_type(m_adj.get_offset(d));
}
bool operator==(const months_type& rhs) const
{
return(_m == rhs._m);
}
bool operator!=(const months_type& rhs) const
{
return(_m != rhs._m);
}
months_type operator+(const months_type& rhs)const
{
return months_type(_m + rhs._m);
}
months_type& operator+=(const months_type& rhs)
{
_m = _m + rhs._m;
return *this;
}
months_type operator-(const months_type& rhs)const
{
return months_type(_m - rhs._m);
}
months_type& operator-=(const months_type& rhs)
{
_m = _m - rhs._m;
return *this;
}
months_type operator*(const int_type rhs)const
{
return months_type(_m * rhs);
}
months_type& operator*=(const int_type rhs)
{
_m = _m * rhs;
return *this;
}
months_type operator/(const int_type rhs)const
{
return months_type(_m / rhs);
}
months_type& operator/=(const int_type rhs)
{
_m = _m / rhs;
return *this;
}
months_type operator+(const years_type& y)const
{
return months_type(y.number_of_years() * 12 + _m);
}
months_type& operator+=(const years_type& y)
{
_m = y.number_of_years() * 12 + _m;
return *this;
}
months_type operator-(const years_type& y) const
{
return months_type(_m - y.number_of_years() * 12);
}
months_type& operator-=(const years_type& y)
{
_m = _m - y.number_of_years() * 12;
return *this;
}
//
friend date_type operator+(const date_type& d, const months_type& m)
{
return d + m.get_offset(d);
}
friend date_type operator+=(date_type& d, const months_type& m)
{
return d += m.get_offset(d);
}
friend date_type operator-(const date_type& d, const months_type& m)
{
// get_neg_offset returns a negative duration, so we add
return d + m.get_neg_offset(d);
}
friend date_type operator-=(date_type& d, const months_type& m)
{
// get_neg_offset returns a negative duration, so we add
return d += m.get_neg_offset(d);
}
private:
int_rep _m;
};
//! additional duration type that represents a logical year
/*! A logical year enables things like: "date(2002,Mar,2) + years(2) ->
* 2004-Mar-2". If the date is a last day-of-the-month, the result will
* also be a last-day-of-the-month (ie date(2001-Feb-28) + years(3) ->
* 2004-Feb-29).
*/
template<class base_config>
class years_duration
{
private:
typedef typename base_config::int_rep int_rep;
typedef typename int_rep::int_type int_type;
typedef typename base_config::date_type date_type;
typedef typename date_type::duration_type duration_type;
typedef typename base_config::month_adjustor_type month_adjustor_type;
typedef years_duration<base_config> years_type;
typedef months_duration<base_config> months_type;
public:
years_duration(int_rep num) : _y(num) {}
years_duration(special_values sv) : _y(sv)
{
_y = int_rep::from_special(sv);
}
int_rep number_of_years() const { return _y; }
//! returns a negative duration
duration_type get_neg_offset(const date_type& d) const
{
month_adjustor_type m_adj(_y.as_number() * 12);
return duration_type(m_adj.get_neg_offset(d));
}
duration_type get_offset(const date_type& d) const
{
month_adjustor_type m_adj(_y.as_number() * 12);
return duration_type(m_adj.get_offset(d));
}
bool operator==(const years_type& rhs) const
{
return(_y == rhs._y);
}
bool operator!=(const years_type& rhs) const
{
return(_y != rhs._y);
}
years_type operator+(const years_type& rhs)const
{
return years_type(_y + rhs._y);
}
years_type& operator+=(const years_type& rhs)
{
_y = _y + rhs._y;
return *this;
}
years_type operator-(const years_type& rhs)const
{
return years_type(_y - rhs._y);
}
years_type& operator-=(const years_type& rhs)
{
_y = _y - rhs._y;
return *this;
}
years_type operator*(const int_type rhs)const
{
return years_type(_y * rhs);
}
years_type& operator*=(const int_type rhs)
{
_y = _y * rhs;
return *this;
}
years_type operator/(const int_type rhs)const
{
return years_type(_y / rhs);
}
years_type& operator/=(const int_type rhs)
{
_y = _y / rhs;
return *this;
}
months_type operator+(const months_type& m) const
{
return(months_type(_y * 12 + m.number_of_months()));
}
months_type operator-(const months_type& m) const
{
return(months_type(_y * 12 - m.number_of_months()));
}
//
friend date_type operator+(const date_type& d, const years_type& y)
{
return d + y.get_offset(d);
}
friend date_type operator+=(date_type& d, const years_type& y)
{
return d += y.get_offset(d);
}
friend date_type operator-(const date_type& d, const years_type& y)
{
// get_neg_offset returns a negative duration, so we add
return d + y.get_neg_offset(d);
}
friend date_type operator-=(date_type& d, const years_type& y)
{
// get_neg_offset returns a negative duration, so we add
return d += y.get_neg_offset(d);
}
private:
int_rep _y;
};
}} // namespace boost::date_time
#endif // DATE_DURATION_TYPES_HPP___

View File

@@ -0,0 +1,159 @@
#ifndef DATE_TIME_SIMPLE_FORMAT_HPP___
#define DATE_TIME_SIMPLE_FORMAT_HPP___
/* Copyright (c) 2002,2003 CrystalClear Software, Inc.
* Use, modification and distribution is subject to the
* Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
* Author: Jeff Garland, Bart Garst
* $Date$
*/
#include "boost/date_time/parse_format_base.hpp"
namespace boost {
namespace date_time {
//! Class to provide simple basic formatting rules
template<class charT>
class simple_format {
public:
//! String used printed is date is invalid
static const charT* not_a_date()
{
return "not-a-date-time";
}
//! String used to for positive infinity value
static const charT* pos_infinity()
{
return "+infinity";
}
//! String used to for positive infinity value
static const charT* neg_infinity()
{
return "-infinity";
}
//! Describe month format
static month_format_spec month_format()
{
return month_as_short_string;
}
static ymd_order_spec date_order()
{
return ymd_order_iso; //YYYY-MM-DD
}
//! This format uses '-' to separate date elements
static bool has_date_sep_chars()
{
return true;
}
//! Char to sep?
static charT year_sep_char()
{
return '-';
}
//! char between year-month
static charT month_sep_char()
{
return '-';
}
//! Char to separate month-day
static charT day_sep_char()
{
return '-';
}
//! char between date-hours
static charT hour_sep_char()
{
return ' ';
}
//! char between hour and minute
static charT minute_sep_char()
{
return ':';
}
//! char for second
static charT second_sep_char()
{
return ':';
}
};
#ifndef BOOST_NO_STD_WSTRING
//! Specialization of formmating rules for wchar_t
template<>
class simple_format<wchar_t> {
public:
//! String used printed is date is invalid
static const wchar_t* not_a_date()
{
return L"not-a-date-time";
}
//! String used to for positive infinity value
static const wchar_t* pos_infinity()
{
return L"+infinity";
}
//! String used to for positive infinity value
static const wchar_t* neg_infinity()
{
return L"-infinity";
}
//! Describe month format
static month_format_spec month_format()
{
return month_as_short_string;
}
static ymd_order_spec date_order()
{
return ymd_order_iso; //YYYY-MM-DD
}
//! This format uses '-' to separate date elements
static bool has_date_sep_chars()
{
return true;
}
//! Char to sep?
static wchar_t year_sep_char()
{
return '-';
}
//! char between year-month
static wchar_t month_sep_char()
{
return '-';
}
//! Char to separate month-day
static wchar_t day_sep_char()
{
return '-';
}
//! char between date-hours
static wchar_t hour_sep_char()
{
return ' ';
}
//! char between hour and minute
static wchar_t minute_sep_char()
{
return ':';
}
//! char for second
static wchar_t second_sep_char()
{
return ':';
}
};
#endif // BOOST_NO_STD_WSTRING
} } //namespace date_time
#endif

View File

@@ -0,0 +1,135 @@
#ifndef DATE_TIME_DATE_FORMATTING_HPP___
#define DATE_TIME_DATE_FORMATTING_HPP___
/* Copyright (c) 2002-2004 CrystalClear Software, Inc.
* Use, modification and distribution is subject to the
* Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
* Author: Jeff Garland, Bart Garst
* $Date$
*/
#include "boost/date_time/iso_format.hpp"
#include "boost/date_time/compiler_config.hpp"
#include <string>
#include <sstream>
#include <iomanip>
/* NOTE: "formatter" code for older compilers, ones that define
* BOOST_DATE_TIME_INCLUDE_LIMITED_HEADERS, is located in
* date_formatting_limited.hpp
*/
namespace boost {
namespace date_time {
//! Formats a month as as string into an ostream
template<class month_type, class format_type, class charT=char>
class month_formatter
{
typedef std::basic_ostream<charT> ostream_type;
public:
//! Formats a month as as string into an ostream
/*! This function demands that month_type provide
* functions for converting to short and long strings
* if that capability is used.
*/
static ostream_type& format_month(const month_type& month,
ostream_type &os)
{
switch (format_type::month_format())
{
case month_as_short_string:
{
os << month.as_short_string();
break;
}
case month_as_long_string:
{
os << month.as_long_string();
break;
}
case month_as_integer:
{
os << std::setw(2) << std::setfill(os.widen('0')) << month.as_number();
break;
}
default:
break;
}
return os;
} // format_month
};
//! Convert ymd to a standard string formatting policies
template<class ymd_type, class format_type, class charT=char>
class ymd_formatter
{
public:
//! Convert ymd to a standard string formatting policies
/*! This is standard code for handling date formatting with
* year-month-day based date information. This function
* uses the format_type to control whether the string will
* contain separator characters, and if so what the character
* will be. In addtion, it can format the month as either
* an integer or a string as controled by the formatting
* policy
*/
static std::basic_string<charT> ymd_to_string(ymd_type ymd)
{
typedef typename ymd_type::month_type month_type;
std::basic_ostringstream<charT> ss;
// Temporarily switch to classic locale to prevent possible formatting
// of year with comma or other character (for example 2,008).
ss.imbue(std::locale::classic());
ss << ymd.year;
ss.imbue(std::locale());
if (format_type::has_date_sep_chars()) {
ss << format_type::month_sep_char();
}
//this name is a bit ugly, oh well....
month_formatter<month_type,format_type,charT>::format_month(ymd.month, ss);
if (format_type::has_date_sep_chars()) {
ss << format_type::day_sep_char();
}
ss << std::setw(2) << std::setfill(ss.widen('0'))
<< ymd.day;
return ss.str();
}
};
//! Convert a date to string using format policies
template<class date_type, class format_type, class charT=char>
class date_formatter
{
public:
typedef std::basic_string<charT> string_type;
//! Convert to a date to standard string using format policies
static string_type date_to_string(date_type d)
{
typedef typename date_type::ymd_type ymd_type;
if (d.is_not_a_date()) {
return string_type(format_type::not_a_date());
}
if (d.is_neg_infinity()) {
return string_type(format_type::neg_infinity());
}
if (d.is_pos_infinity()) {
return string_type(format_type::pos_infinity());
}
ymd_type ymd = d.year_month_day();
return ymd_formatter<ymd_type, format_type, charT>::ymd_to_string(ymd);
}
};
} } //namespace date_time
#endif

View File

@@ -0,0 +1,121 @@
#ifndef DATE_TIME_DATE_FORMATTING_LIMITED_HPP___
#define DATE_TIME_DATE_FORMATTING_LIMITED_HPP___
/* Copyright (c) 2002-2004 CrystalClear Software, Inc.
* Use, modification and distribution is subject to the
* Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
* Author: Jeff Garland, Bart Garst
* $Date$
*/
#include "boost/date_time/iso_format.hpp"
#include "boost/date_time/compiler_config.hpp"
#include <string>
#include <sstream>
#include <iomanip>
namespace boost {
namespace date_time {
//! Formats a month as as string into an ostream
template<class month_type, class format_type>
class month_formatter
{
public:
//! Formats a month as as string into an ostream
/*! This function demands that month_type provide
* functions for converting to short and long strings
* if that capability is used.
*/
static std::ostream& format_month(const month_type& month,
std::ostream& os)
{
switch (format_type::month_format())
{
case month_as_short_string:
{
os << month.as_short_string();
break;
}
case month_as_long_string:
{
os << month.as_long_string();
break;
}
case month_as_integer:
{
os << std::setw(2) << std::setfill('0') << month.as_number();
break;
}
}
return os;
} // format_month
};
//! Convert ymd to a standard string formatting policies
template<class ymd_type, class format_type>
class ymd_formatter
{
public:
//! Convert ymd to a standard string formatting policies
/*! This is standard code for handling date formatting with
* year-month-day based date information. This function
* uses the format_type to control whether the string will
* contain separator characters, and if so what the character
* will be. In addtion, it can format the month as either
* an integer or a string as controled by the formatting
* policy
*/
static std::string ymd_to_string(ymd_type ymd)
{
typedef typename ymd_type::month_type month_type;
std::ostringstream ss;
ss << ymd.year;
if (format_type::has_date_sep_chars()) {
ss << format_type::month_sep_char();
}
//this name is a bit ugly, oh well....
month_formatter<month_type,format_type>::format_month(ymd.month, ss);
if (format_type::has_date_sep_chars()) {
ss << format_type::day_sep_char();
}
ss << std::setw(2) << std::setfill('0')
<< ymd.day;
return ss.str();
}
};
//! Convert a date to string using format policies
template<class date_type, class format_type>
class date_formatter
{
public:
//! Convert to a date to standard string using format policies
static std::string date_to_string(date_type d)
{
typedef typename date_type::ymd_type ymd_type;
if (d.is_not_a_date()) {
return format_type::not_a_date();
}
if (d.is_neg_infinity()) {
return format_type::neg_infinity();
}
if (d.is_pos_infinity()) {
return format_type::pos_infinity();
}
ymd_type ymd = d.year_month_day();
return ymd_formatter<ymd_type, format_type>::ymd_to_string(ymd);
}
};
} } //namespace date_time
#endif

View File

@@ -0,0 +1,233 @@
#ifndef DATE_TIME_DATE_FORMATTING_LOCALES_HPP___
#define DATE_TIME_DATE_FORMATTING_LOCALES_HPP___
/* Copyright (c) 2002,2003 CrystalClear Software, Inc.
* Use, modification and distribution is subject to the
* Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
* Author: Jeff Garland, Bart Garst
* $Date$
*/
#include "boost/date_time/locale_config.hpp" // set BOOST_DATE_TIME_NO_LOCALE
#ifndef BOOST_DATE_TIME_NO_LOCALE
#include "boost/date_time/iso_format.hpp"
#include "boost/date_time/date_names_put.hpp"
#include "boost/date_time/parse_format_base.hpp"
//#include <string>
#include <sstream>
#include <iomanip>
namespace boost {
namespace date_time {
//! Formats a month as as string into an ostream
template<class facet_type,
class charT = char>
class ostream_month_formatter
{
public:
typedef typename facet_type::month_type month_type;
typedef std::basic_ostream<charT> ostream_type;
//! Formats a month as as string into an output iterator
static void format_month(const month_type& month,
ostream_type& os,
const facet_type& f)
{
switch (f.month_format())
{
case month_as_short_string:
{
std::ostreambuf_iterator<charT> oitr(os);
f.put_month_short(oitr, month.as_enum());
break;
}
case month_as_long_string:
{
std::ostreambuf_iterator<charT> oitr(os);
f.put_month_long(oitr, month.as_enum());
break;
}
case month_as_integer:
{
charT fill_char = '0';
os << std::setw(2) << std::setfill(fill_char) << month.as_number();
break;
}
}
} // format_month
};
//! Formats a weekday
template<class weekday_type,
class facet_type,
class charT = char>
class ostream_weekday_formatter
{
public:
typedef typename facet_type::month_type month_type;
typedef std::basic_ostream<charT> ostream_type;
//! Formats a month as as string into an output iterator
static void format_weekday(const weekday_type& wd,
ostream_type& os,
const facet_type& f,
bool as_long_string)
{
std::ostreambuf_iterator<charT> oitr(os);
if (as_long_string) {
f.put_weekday_long(oitr, wd.as_enum());
}
else {
f.put_weekday_short(oitr, wd.as_enum());
}
} // format_weekday
};
//! Convert ymd to a standard string formatting policies
template<class ymd_type,
class facet_type,
class charT = char>
class ostream_ymd_formatter
{
public:
typedef typename ymd_type::month_type month_type;
typedef ostream_month_formatter<facet_type, charT> month_formatter_type;
typedef std::basic_ostream<charT> ostream_type;
typedef std::basic_string<charT> foo_type;
//! Convert ymd to a standard string formatting policies
/*! This is standard code for handling date formatting with
* year-month-day based date information. This function
* uses the format_type to control whether the string will
* contain separator characters, and if so what the character
* will be. In addtion, it can format the month as either
* an integer or a string as controled by the formatting
* policy
*/
// static string_type ymd_to_string(ymd_type ymd)
// {
// std::ostringstream ss;
// facet_type dnp;
// ymd_put(ymd, ss, dnp);
// return ss.str();
// }
// Put ymd to ostream -- part of ostream refactor
static void ymd_put(ymd_type ymd,
ostream_type& os,
const facet_type& f)
{
std::ostreambuf_iterator<charT> oitr(os);
charT fill_char = '0';
switch (f.date_order()) {
case ymd_order_iso: {
os << ymd.year;
if (f.has_date_sep_chars()) {
f.month_sep_char(oitr);
}
month_formatter_type::format_month(ymd.month, os, f);
if (f.has_date_sep_chars()) {
f.day_sep_char(oitr);
}
os << std::setw(2) << std::setfill(fill_char)
<< ymd.day;
break;
}
case ymd_order_us: {
month_formatter_type::format_month(ymd.month, os, f);
if (f.has_date_sep_chars()) {
f.day_sep_char(oitr);
}
os << std::setw(2) << std::setfill(fill_char)
<< ymd.day;
if (f.has_date_sep_chars()) {
f.month_sep_char(oitr);
}
os << ymd.year;
break;
}
case ymd_order_dmy: {
os << std::setw(2) << std::setfill(fill_char)
<< ymd.day;
if (f.has_date_sep_chars()) {
f.day_sep_char(oitr);
}
month_formatter_type::format_month(ymd.month, os, f);
if (f.has_date_sep_chars()) {
f.month_sep_char(oitr);
}
os << ymd.year;
break;
}
}
}
};
//! Convert a date to string using format policies
template<class date_type,
class facet_type,
class charT = char>
class ostream_date_formatter
{
public:
typedef std::basic_ostream<charT> ostream_type;
typedef typename date_type::ymd_type ymd_type;
//! Put date into an ostream
static void date_put(const date_type& d,
ostream_type& os,
const facet_type& f)
{
special_values sv = d.as_special();
if (sv == not_special) {
ymd_type ymd = d.year_month_day();
ostream_ymd_formatter<ymd_type, facet_type, charT>::ymd_put(ymd, os, f);
}
else { // output a special value
std::ostreambuf_iterator<charT> coi(os);
f.put_special_value(coi, sv);
}
}
//! Put date into an ostream
static void date_put(const date_type& d,
ostream_type& os)
{
//retrieve the local from the ostream
std::locale locale = os.getloc();
if (std::has_facet<facet_type>(locale)) {
const facet_type& f = std::use_facet<facet_type>(locale);
date_put(d, os, f);
}
else {
//default to something sensible if no facet installed
facet_type default_facet;
date_put(d, os, default_facet);
}
} // date_to_ostream
}; //class date_formatter
} } //namespace date_time
#endif
#endif

View File

@@ -0,0 +1,509 @@
#ifndef DATE_TIME_DATE_GENERATORS_HPP__
#define DATE_TIME_DATE_GENERATORS_HPP__
/* Copyright (c) 2002,2003,2005 CrystalClear Software, Inc.
* Use, modification and distribution is subject to the
* Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
* Author: Jeff Garland, Bart Garst
* $Date$
*/
/*! @file date_generators.hpp
Definition and implementation of date algorithm templates
*/
#include <stdexcept>
#include <sstream>
#include <boost/throw_exception.hpp>
#include <boost/date_time/date.hpp>
#include <boost/date_time/compiler_config.hpp>
namespace boost {
namespace date_time {
//! Base class for all generators that take a year and produce a date.
/*! This class is a base class for polymorphic function objects that take
a year and produce a concrete date.
@param date_type The type representing a date. This type must
export a calender_type which defines a year_type.
*/
template<class date_type>
class year_based_generator
{
public:
typedef typename date_type::calendar_type calendar_type;
typedef typename calendar_type::year_type year_type;
year_based_generator() {}
virtual ~year_based_generator() {}
virtual date_type get_date(year_type y) const = 0;
//! Returns a string for use in a POSIX time_zone string
virtual std::string to_string() const =0;
};
//! Generates a date by applying the year to the given month and day.
/*!
Example usage:
@code
partial_date pd(1, Jan);
partial_date pd2(70);
date d = pd.get_date(2002); //2002-Jan-01
date d2 = pd2.get_date(2002); //2002-Mar-10
@endcode
\ingroup date_alg
*/
template<class date_type>
class partial_date : public year_based_generator<date_type>
{
public:
typedef typename date_type::calendar_type calendar_type;
typedef typename calendar_type::day_type day_type;
typedef typename calendar_type::month_type month_type;
typedef typename calendar_type::year_type year_type;
typedef typename date_type::duration_type duration_type;
typedef typename duration_type::duration_rep duration_rep;
partial_date(day_type d, month_type m) :
day_(d),
month_(m)
{}
//! Partial date created from number of days into year. Range 1-366
/*! Allowable values range from 1 to 366. 1=Jan1, 366=Dec31. If argument
* exceeds range, partial_date will be created with closest in-range value.
* 60 will always be Feb29, if get_date() is called with a non-leap year
* an exception will be thrown */
partial_date(duration_rep days) :
day_(1), // default values
month_(1)
{
date_type d1(2000,1,1);
if(days > 1) {
if(days > 366) // prevents wrapping
{
days = 366;
}
days = days - 1;
duration_type dd(days);
d1 = d1 + dd;
}
day_ = d1.day();
month_ = d1.month();
}
//! Return a concrete date when provided with a year specific year.
/*! Will throw an 'invalid_argument' exception if a partial_date object,
* instantiated with Feb-29, has get_date called with a non-leap year.
* Example:
* @code
* partial_date pd(29, Feb);
* pd.get_date(2003); // throws invalid_argument exception
* pg.get_date(2000); // returns 2000-2-29
* @endcode
*/
date_type get_date(year_type y) const
{
if((day_ == 29) && (month_ == 2) && !(calendar_type::is_leap_year(y))) {
std::ostringstream ss;
ss << "No Feb 29th in given year of " << y << ".";
boost::throw_exception(std::invalid_argument(ss.str()));
}
return date_type(y, month_, day_);
}
date_type operator()(year_type y) const
{
return get_date(y);
//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_);
}
// added for streaming purposes
month_type month() const
{
return month_;
}
day_type day() const
{
return day_;
}
//! Returns string suitable for use in POSIX time zone string
/*! Returns string formatted with up to 3 digits:
* Jan-01 == "0"
* Feb-29 == "58"
* Dec-31 == "365" */
virtual std::string to_string() const
{
std::ostringstream ss;
date_type d(2004, month_, day_);
unsigned short c = d.day_of_year();
c--; // numbered 0-365 while day_of_year is 1 based...
ss << c;
return ss.str();
}
private:
day_type day_;
month_type month_;
};
//! Returns nth arg as string. 1 -> "first", 2 -> "second", max is 5.
BOOST_DATE_TIME_DECL const char* nth_as_str(int n);
//! Useful generator functor for finding holidays
/*! Based on the idea in Cal. Calc. for finding holidays that are
* the 'first Monday of September'. When instantiated with
* 'fifth' kday of month, the result will be the last kday of month
* which can be the fourth or fifth depending on the structure of
* the month.
*
* The algorithm here basically guesses for the first
* day of the month. Then finds the first day of the correct
* type. That is, if the first of the month is a Tuesday
* and it needs Wenesday then we simply increment by a day
* and then we can add the length of a week until we get
* to the 'nth kday'. There are probably more efficient
* algorithms based on using a mod 7, but this one works
* reasonably well for basic applications.
* \ingroup date_alg
*/
template<class date_type>
class nth_kday_of_month : public year_based_generator<date_type>
{
public:
typedef typename date_type::calendar_type calendar_type;
typedef typename calendar_type::day_of_week_type day_of_week_type;
typedef typename calendar_type::month_type month_type;
typedef typename calendar_type::year_type year_type;
typedef typename date_type::duration_type duration_type;
enum week_num {first=1, second, third, fourth, fifth};
nth_kday_of_month(week_num week_no,
day_of_week_type dow,
month_type m) :
month_(m),
wn_(week_no),
dow_(dow)
{}
//! Return a concrete date when provided with a year specific year.
date_type get_date(year_type y) const
{
date_type d(y, month_, 1); //first day of month
duration_type one_day(1);
duration_type one_week(7);
while (dow_ != d.day_of_week()) {
d = d + one_day;
}
int week = 1;
while (week < wn_) {
d = d + one_week;
week++;
}
// remove wrapping to next month behavior
if(d.month() != month_) {
d = d - one_week;
}
return d;
}
// added for streaming
month_type month() const
{
return month_;
}
week_num nth_week() const
{
return wn_;
}
day_of_week_type day_of_week() const
{
return dow_;
}
const char* nth_week_as_str() const
{
return nth_as_str(wn_);
}
//! Returns string suitable for use in POSIX time zone string
/*! Returns a string formatted as "M4.3.0" ==> 3rd Sunday in April. */
virtual std::string to_string() const
{
std::ostringstream ss;
ss << 'M'
<< static_cast<int>(month_) << '.'
<< static_cast<int>(wn_) << '.'
<< static_cast<int>(dow_);
return ss.str();
}
private:
month_type month_;
week_num wn_;
day_of_week_type dow_;
};
//! Useful generator functor for finding holidays and daylight savings
/*! Similar to nth_kday_of_month, but requires less paramters
* \ingroup date_alg
*/
template<class date_type>
class first_kday_of_month : public year_based_generator<date_type>
{
public:
typedef typename date_type::calendar_type calendar_type;
typedef typename calendar_type::day_of_week_type day_of_week_type;
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 first 'Sunday' in 'April' spec
/*!@param dow The day of week, eg: Sunday, Monday, etc
* @param m The month of the year, eg: Jan, Feb, Mar, etc
*/
first_kday_of_month(day_of_week_type dow, month_type m) :
month_(m),
dow_(dow)
{}
//! Return a concrete date when provided with a year specific year.
date_type get_date(year_type year) const
{
date_type d(year, month_,1);
duration_type one_day(1);
while (dow_ != d.day_of_week()) {
d = d + one_day;
}
return d;
}
// added for streaming
month_type month() const
{
return month_;
}
day_of_week_type day_of_week() const
{
return dow_;
}
//! Returns string suitable for use in POSIX time zone string
/*! Returns a string formatted as "M4.1.0" ==> 1st Sunday in April. */
virtual std::string to_string() const
{
std::ostringstream ss;
ss << 'M'
<< static_cast<int>(month_) << '.'
<< 1 << '.'
<< static_cast<int>(dow_);
return ss.str();
}
private:
month_type month_;
day_of_week_type dow_;
};
//! Calculate something like Last Sunday of January
/*! 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>
class last_kday_of_month : public year_based_generator<date_type>
{
public:
typedef typename date_type::calendar_type calendar_type;
typedef typename calendar_type::day_of_week_type day_of_week_type;
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 last 'Sunday' in 'April' spec
/*!@param dow The day of week, eg: Sunday, Monday, etc
* @param m The month of the year, eg: Jan, Feb, Mar, etc
*/
last_kday_of_month(day_of_week_type dow, month_type m) :
month_(m),
dow_(dow)
{}
//! Return a concrete date when provided with a year specific year.
date_type get_date(year_type year) const
{
date_type d(year, month_, calendar_type::end_of_month_day(year,month_));
duration_type one_day(1);
while (dow_ != d.day_of_week()) {
d = d - one_day;
}
return d;
}
// added for streaming
month_type month() const
{
return month_;
}
day_of_week_type day_of_week() const
{
return dow_;
}
//! Returns string suitable for use in POSIX time zone string
/*! Returns a string formatted as "M4.5.0" ==> last Sunday in April. */
virtual std::string to_string() const
{
std::ostringstream ss;
ss << 'M'
<< static_cast<int>(month_) << '.'
<< 5 << '.'
<< static_cast<int>(dow_);
return ss.str();
}
private:
month_type month_;
day_of_week_type dow_;
};
//! Calculate something like "First Sunday after Jan 1,2002
/*! Date generator that takes a date and finds kday after
*@code
typedef boost::date_time::first_kday_after<date> firstkdayafter;
firstkdayafter fkaf(Monday);
fkaf.get_date(date(2002,Feb,1));
@endcode
* \ingroup date_alg
*/
template<class date_type>
class first_kday_after
{
public:
typedef typename date_type::calendar_type calendar_type;
typedef typename calendar_type::day_of_week_type day_of_week_type;
typedef typename date_type::duration_type duration_type;
first_kday_after(day_of_week_type dow) :
dow_(dow)
{}
//! Return next kday given.
date_type get_date(date_type start_day) const
{
duration_type one_day(1);
date_type d = start_day + one_day;
while (dow_ != d.day_of_week()) {
d = d + one_day;
}
return d;
}
// added for streaming
day_of_week_type day_of_week() const
{
return dow_;
}
private:
day_of_week_type dow_;
};
//! Calculate something like "First Sunday before Jan 1,2002
/*! Date generator that takes a date and finds kday after
*@code
typedef boost::date_time::first_kday_before<date> firstkdaybefore;
firstkdaybefore fkbf(Monday);
fkbf.get_date(date(2002,Feb,1));
@endcode
* \ingroup date_alg
*/
template<class date_type>
class first_kday_before
{
public:
typedef typename date_type::calendar_type calendar_type;
typedef typename calendar_type::day_of_week_type day_of_week_type;
typedef typename date_type::duration_type duration_type;
first_kday_before(day_of_week_type dow) :
dow_(dow)
{}
//! Return next kday given.
date_type get_date(date_type start_day) const
{
duration_type one_day(1);
date_type d = start_day - one_day;
while (dow_ != d.day_of_week()) {
d = d - one_day;
}
return d;
}
// added for streaming
day_of_week_type day_of_week() const
{
return dow_;
}
private:
day_of_week_type dow_;
};
//! Calculates the number of days until the next weekday
/*! Calculates the number of days until the next weekday.
* If the date given falls on a Sunday and the given weekday
* is Tuesday the result will be 2 days */
template<typename date_type, class weekday_type>
inline
typename date_type::duration_type days_until_weekday(const date_type& d, const weekday_type& wd)
{
typedef typename date_type::duration_type duration_type;
duration_type wks(0);
duration_type dd(wd.as_number() - d.day_of_week().as_number());
if(dd.is_negative()){
wks = duration_type(7);
}
return dd + wks;
}
//! Calculates the number of days since the previous weekday
/*! Calculates the number of days since the previous weekday
* If the date given falls on a Sunday and the given weekday
* is Tuesday the result will be 5 days. The answer will be a positive
* number because Tuesday is 5 days before Sunday, not -5 days before. */
template<typename date_type, class weekday_type>
inline
typename date_type::duration_type days_before_weekday(const date_type& d, const weekday_type& wd)
{
typedef typename date_type::duration_type duration_type;
duration_type wks(0);
duration_type dd(wd.as_number() - d.day_of_week().as_number());
if(dd.days() > 0){
wks = duration_type(7);
}
// we want a number of days, not an offset. The value returned must
// be zero or larger.
return (-dd + wks);
}
//! Generates a date object representing the date of the following weekday from the given date
/*! Generates a date object representing the date of the following
* weekday from the given date. If the date given is 2004-May-9
* (a Sunday) and the given weekday is Tuesday then the resulting date
* will be 2004-May-11. */
template<class date_type, class weekday_type>
inline
date_type next_weekday(const date_type& d, const weekday_type& wd)
{
return d + days_until_weekday(d, wd);
}
//! Generates a date object representing the date of the previous weekday from the given date
/*! Generates a date object representing the date of the previous
* weekday from the given date. If the date given is 2004-May-9
* (a Sunday) and the given weekday is Tuesday then the resulting date
* will be 2004-May-4. */
template<class date_type, class weekday_type>
inline
date_type previous_weekday(const date_type& d, const weekday_type& wd)
{
return d - days_before_weekday(d, wd);
}
} } //namespace date_time
#endif

View File

@@ -0,0 +1,101 @@
#ifndef DATE_ITERATOR_HPP___
#define DATE_ITERATOR_HPP___
/* Copyright (c) 2002,2003 CrystalClear Software, Inc.
* Use, modification and distribution is subject to the
* Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
* Author: Jeff Garland, Bart Garst
* $Date$
*/
#include <iterator>
namespace boost {
namespace date_time {
//! An iterator over dates with varying resolution (day, week, month, year, etc)
enum date_resolutions {day, week, months, year, decade, century, NumDateResolutions};
//! Base date iterator type
/*! This class provides the skeleton for the creation of iterators.
* New and interesting interators can be created by plugging in a new
* function that derives the next value from the current state.
* generation of various types of -based information.
*
* <b>Template Parameters</b>
*
* <b>date_type</b>
*
* The date_type is a concrete date_type. The date_type must
* define a duration_type and a calendar_type.
*/
template<class date_type>
class date_itr_base {
// works, but benefit unclear at the moment
// class date_itr_base : public std::iterator<std::input_iterator_tag,
// date_type, void, void, void>{
public:
typedef typename date_type::duration_type duration_type;
typedef date_type value_type;
typedef std::input_iterator_tag iterator_category;
date_itr_base(date_type d) : current_(d) {}
virtual ~date_itr_base() {}
date_itr_base& operator++()
{
current_ = current_ + get_offset(current_);
return *this;
}
date_itr_base& operator--()
{
current_ = current_ + get_neg_offset(current_);
return *this;
}
virtual duration_type get_offset(const date_type& current) const=0;
virtual duration_type get_neg_offset(const date_type& current) const=0;
date_type operator*() {return current_;}
date_type* operator->() {return &current_;}
bool operator< (const date_type& d) {return current_ < d;}
bool operator<= (const date_type& d) {return current_ <= d;}
bool operator> (const date_type& d) {return current_ > d;}
bool operator>= (const date_type& d) {return current_ >= d;}
bool operator== (const date_type& d) {return current_ == d;}
bool operator!= (const date_type& d) {return current_ != d;}
private:
date_type current_;
};
//! Overrides the base date iterator providing hook for functors
/*
* <b>offset_functor</b>
*
* The offset functor must define a get_offset function that takes the
* current point in time and calculates and offset.
*
*/
template<class offset_functor, class date_type>
class date_itr : public date_itr_base<date_type> {
public:
typedef typename date_type::duration_type duration_type;
date_itr(date_type d, int factor=1) :
date_itr_base<date_type>(d),
of_(factor)
{}
private:
virtual duration_type get_offset(const date_type& current) const
{
return of_.get_offset(current);
}
virtual duration_type get_neg_offset(const date_type& current) const
{
return of_.get_neg_offset(current);
}
offset_functor of_;
};
} } //namespace date_time
#endif

View File

@@ -0,0 +1,320 @@
#ifndef DATE_TIME_DATE_NAMES_PUT_HPP___
#define DATE_TIME_DATE_NAMES_PUT_HPP___
/* Copyright (c) 2002-2005 CrystalClear Software, Inc.
* Use, modification and distribution is subject to the
* Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
* Author: Jeff Garland, Bart Garst
* $Date$
*/
#include "boost/date_time/locale_config.hpp" // set BOOST_DATE_TIME_NO_LOCALE
#ifndef BOOST_DATE_TIME_NO_LOCALE
#include "boost/date_time/special_defs.hpp"
#include "boost/date_time/date_defs.hpp"
#include "boost/date_time/parse_format_base.hpp"
#include "boost/lexical_cast.hpp"
#include <locale>
namespace boost {
namespace date_time {
//! Output facet base class for gregorian dates.
/*! This class is a base class for date facets used to localize the
* names of months and the names of days in the week.
*
* Requirements of Config
* - define an enumeration month_enum that enumerates the months.
* The enumeration should be '1' based eg: Jan==1
* - define as_short_string and as_long_string
*
* (see langer & kreft p334).
*
*/
template<class Config,
class charT = char,
class OutputIterator = std::ostreambuf_iterator<charT> >
class date_names_put : public std::locale::facet
{
public:
date_names_put() {}
typedef OutputIterator iter_type;
typedef typename Config::month_type month_type;
typedef typename Config::month_enum month_enum;
typedef typename Config::weekday_enum weekday_enum;
typedef typename Config::special_value_enum special_value_enum;
//typedef typename Config::format_type format_type;
typedef std::basic_string<charT> string_type;
typedef charT char_type;
static const char_type default_special_value_names[3][17];
static const char_type separator[2];
static std::locale::id id;
#if defined (__SUNPRO_CC) && defined (_RWSTD_VER)
std::locale::id& __get_id (void) const { return id; }
#endif
void put_special_value(iter_type& oitr, special_value_enum sv) const
{
do_put_special_value(oitr, sv);
}
void put_month_short(iter_type& oitr, month_enum moy) const
{
do_put_month_short(oitr, moy);
}
void put_month_long(iter_type& oitr, month_enum moy) const
{
do_put_month_long(oitr, moy);
}
void put_weekday_short(iter_type& oitr, weekday_enum wd) const
{
do_put_weekday_short(oitr, wd);
}
void put_weekday_long(iter_type& oitr, weekday_enum wd) const
{
do_put_weekday_long(oitr, wd);
}
bool has_date_sep_chars() const
{
return do_has_date_sep_chars();
}
void year_sep_char(iter_type& oitr) const
{
do_year_sep_char(oitr);
}
//! char between year-month
void month_sep_char(iter_type& oitr) const
{
do_month_sep_char(oitr);
}
//! Char to separate month-day
void day_sep_char(iter_type& oitr) const
{
do_day_sep_char(oitr);
}
//! Determines the order to put the date elements
ymd_order_spec date_order() const
{
return do_date_order();
}
//! Determines if month is displayed as integer, short or long string
month_format_spec month_format() const
{
return do_month_format();
}
protected:
//! Default facet implementation uses month_type defaults
virtual void do_put_month_short(iter_type& oitr, month_enum moy) const
{
month_type gm(moy);
charT c = '\0';
put_string(oitr, gm.as_short_string(c));
}
//! Default facet implementation uses month_type defaults
virtual void do_put_month_long(iter_type& oitr,
month_enum moy) const
{
month_type gm(moy);
charT c = '\0';
put_string(oitr, gm.as_long_string(c));
}
//! Default facet implementation for special value types
virtual void do_put_special_value(iter_type& oitr, special_value_enum sv) const
{
if(sv <= 2) { // only output not_a_date_time, neg_infin, or pos_infin
string_type s(default_special_value_names[sv]);
put_string(oitr, s);
}
}
virtual void do_put_weekday_short(iter_type&, weekday_enum) const
{
}
virtual void do_put_weekday_long(iter_type&, weekday_enum) const
{
}
virtual bool do_has_date_sep_chars() const
{
return true;
}
virtual void do_year_sep_char(iter_type& oitr) const
{
string_type s(separator);
put_string(oitr, s);
}
//! char between year-month
virtual void do_month_sep_char(iter_type& oitr) const
{
string_type s(separator);
put_string(oitr, s);
}
//! Char to separate month-day
virtual void do_day_sep_char(iter_type& oitr) const
{
string_type s(separator); //put in '-'
put_string(oitr, s);
}
//! Default for date order
virtual ymd_order_spec do_date_order() const
{
return ymd_order_iso;
}
//! Default month format
virtual month_format_spec do_month_format() const
{
return month_as_short_string;
}
void put_string(iter_type& oi, const charT* const s) const
{
string_type s1(boost::lexical_cast<string_type>(s));
typename string_type::iterator si,end;
for (si=s1.begin(), end=s1.end(); si!=end; si++, oi++) {
*oi = *si;
}
}
void put_string(iter_type& oi, const string_type& s1) const
{
typename string_type::const_iterator si,end;
for (si=s1.begin(), end=s1.end(); si!=end; si++, oi++) {
*oi = *si;
}
}
};
template<class Config, class charT, class OutputIterator>
const typename date_names_put<Config, charT, OutputIterator>::char_type
date_names_put<Config, charT, OutputIterator>::default_special_value_names[3][17] = {
{'n','o','t','-','a','-','d','a','t','e','-','t','i','m','e'},
{'-','i','n','f','i','n','i','t','y'},
{'+','i','n','f','i','n','i','t','y'} };
template<class Config, class charT, class OutputIterator>
const typename date_names_put<Config, charT, OutputIterator>::char_type
date_names_put<Config, charT, OutputIterator>::separator[2] =
{'-', '\0'} ;
//! Generate storage location for a std::locale::id
template<class Config, class charT, class OutputIterator>
std::locale::id date_names_put<Config, charT, OutputIterator>::id;
//! A date name output facet that takes an array of char* to define strings
template<class Config,
class charT = char,
class OutputIterator = std::ostreambuf_iterator<charT> >
class all_date_names_put : public date_names_put<Config, charT, OutputIterator>
{
public:
all_date_names_put(const charT* const month_short_names[],
const charT* const month_long_names[],
const charT* const special_value_names[],
const charT* const weekday_short_names[],
const charT* const weekday_long_names[],
charT separator_char = '-',
ymd_order_spec order_spec = ymd_order_iso,
month_format_spec month_format = month_as_short_string) :
month_short_names_(month_short_names),
month_long_names_(month_long_names),
special_value_names_(special_value_names),
weekday_short_names_(weekday_short_names),
weekday_long_names_(weekday_long_names),
order_spec_(order_spec),
month_format_spec_(month_format)
{
separator_char_[0] = separator_char;
separator_char_[1] = '\0';
}
typedef OutputIterator iter_type;
typedef typename Config::month_enum month_enum;
typedef typename Config::weekday_enum weekday_enum;
typedef typename Config::special_value_enum special_value_enum;
const charT* const* get_short_month_names() const
{
return month_short_names_;
}
const charT* const* get_long_month_names() const
{
return month_long_names_;
}
const charT* const* get_special_value_names() const
{
return special_value_names_;
}
const charT* const* get_short_weekday_names()const
{
return weekday_short_names_;
}
const charT* const* get_long_weekday_names()const
{
return weekday_long_names_;
}
protected:
//! Generic facet that takes array of chars
virtual void do_put_month_short(iter_type& oitr, month_enum moy) const
{
this->put_string(oitr, month_short_names_[moy-1]);
}
//! Long month names
virtual void do_put_month_long(iter_type& oitr, month_enum moy) const
{
this->put_string(oitr, month_long_names_[moy-1]);
}
//! Special values names
virtual void do_put_special_value(iter_type& oitr, special_value_enum sv) const
{
this->put_string(oitr, special_value_names_[sv]);
}
virtual void do_put_weekday_short(iter_type& oitr, weekday_enum wd) const
{
this->put_string(oitr, weekday_short_names_[wd]);
}
virtual void do_put_weekday_long(iter_type& oitr, weekday_enum wd) const
{
this->put_string(oitr, weekday_long_names_[wd]);
}
//! char between year-month
virtual void do_month_sep_char(iter_type& oitr) const
{
this->put_string(oitr, separator_char_);
}
//! Char to separate month-day
virtual void do_day_sep_char(iter_type& oitr) const
{
this->put_string(oitr, separator_char_);
}
//! Set the date ordering
virtual ymd_order_spec do_date_order() const
{
return order_spec_;
}
//! Set the date ordering
virtual month_format_spec do_month_format() const
{
return month_format_spec_;
}
private:
const charT* const* month_short_names_;
const charT* const* month_long_names_;
const charT* const* special_value_names_;
const charT* const* weekday_short_names_;
const charT* const* weekday_long_names_;
charT separator_char_[2];
ymd_order_spec order_spec_;
month_format_spec month_format_spec_;
};
} } //namespace boost::date_time
#endif //BOOST_NO_STD_LOCALE
#endif

View File

@@ -0,0 +1,316 @@
#ifndef _DATE_TIME_DATE_PARSING_HPP___
#define _DATE_TIME_DATE_PARSING_HPP___
/* Copyright (c) 2002,2003,2005 CrystalClear Software, Inc.
* Use, modification and distribution is subject to the
* Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
* Author: Jeff Garland, Bart Garst
* $Date$
*/
#include <string>
#include <iterator>
#include <algorithm>
#include <boost/tokenizer.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/date_time/compiler_config.hpp>
#include <boost/date_time/parse_format_base.hpp>
#if defined(BOOST_DATE_TIME_NO_LOCALE)
#include <cctype> // ::tolower(int)
#else
#include <locale> // std::tolower(char, locale)
#endif
namespace boost {
namespace date_time {
//! A function to replace the std::transform( , , ,tolower) construct
/*! This function simply takes a string, and changes all the characters
* in that string to lowercase (according to the default system locale).
* In the event that a compiler does not support locales, the old
* C style tolower() is used.
*/
inline
std::string
convert_to_lower(std::string inp)
{
#if !defined(BOOST_DATE_TIME_NO_LOCALE)
const std::locale loc(std::locale::classic());
#endif
std::string::size_type i = 0, n = inp.length();
for (; i < n; ++i) {
inp[i] =
#if defined(BOOST_DATE_TIME_NO_LOCALE)
static_cast<char>(std::tolower(inp[i]));
#else
// tolower and others were brought in to std for borland >= v564
// in compiler_config.hpp
std::tolower(inp[i], loc);
#endif
}
return inp;
}
//! Helper function for parse_date.
/* Used by-value parameter because we change the string and may
* want to preserve the original argument */
template<class month_type>
inline unsigned short
month_str_to_ushort(std::string const& s) {
if((s.at(0) >= '0') && (s.at(0) <= '9')) {
return boost::lexical_cast<unsigned short>(s);
}
else {
std::string str = convert_to_lower(s);
typename month_type::month_map_ptr_type ptr = month_type::get_month_map_ptr();
typename month_type::month_map_type::iterator iter = ptr->find(str);
if(iter != ptr->end()) { // required for STLport
return iter->second;
}
}
return 13; // intentionally out of range - name not found
}
//! Find index of a string in either of 2 arrays
/*! find_match searches both arrays for a match to 's'. Both arrays
* must contain 'size' elements. The index of the match is returned.
* If no match is found, 'size' is returned.
* Ex. "Jan" returns 0, "Dec" returns 11, "Tue" returns 2.
* 'size' can be sent in with: (greg_month::max)() (which 12),
* (greg_weekday::max)() + 1 (which is 7) or date_time::NumSpecialValues */
template<class charT>
short find_match(const charT* const* short_names,
const charT* const* long_names,
short size,
const std::basic_string<charT>& s) {
for(short i = 0; i < size; ++i){
if(short_names[i] == s || long_names[i] == s){
return i;
}
}
return size; // not-found, return a value out of range
}
//! Generic function to parse a delimited date (eg: 2002-02-10)
/*! Accepted formats are: "2003-02-10" or " 2003-Feb-10" or
* "2003-Feburary-10"
* The order in which the Month, Day, & Year appear in the argument
* string can be accomodated by passing in the appropriate ymd_order_spec
*/
template<class date_type>
date_type
parse_date(const std::string& s, int order_spec = ymd_order_iso) {
std::string spec_str;
if(order_spec == ymd_order_iso) {
spec_str = "ymd";
}
else if(order_spec == ymd_order_dmy) {
spec_str = "dmy";
}
else { // (order_spec == ymd_order_us)
spec_str = "mdy";
}
typedef typename date_type::month_type month_type;
unsigned pos = 0;
unsigned short year(0), month(0), day(0);
typedef typename std::basic_string<char>::traits_type traits_type;
typedef boost::char_separator<char, traits_type> char_separator_type;
typedef boost::tokenizer<char_separator_type,
std::basic_string<char>::const_iterator,
std::basic_string<char> > tokenizer;
typedef boost::tokenizer<char_separator_type,
std::basic_string<char>::const_iterator,
std::basic_string<char> >::iterator tokenizer_iterator;
// may need more delimiters, these work for the regression tests
const char sep_char[] = {',','-','.',' ','/','\0'};
char_separator_type sep(sep_char);
tokenizer tok(s,sep);
for(tokenizer_iterator beg=tok.begin();
beg!=tok.end() && pos < spec_str.size();
++beg, ++pos) {
switch(spec_str.at(pos)) {
case 'y':
{
year = boost::lexical_cast<unsigned short>(*beg);
break;
}
case 'm':
{
month = month_str_to_ushort<month_type>(*beg);
break;
}
case 'd':
{
day = boost::lexical_cast<unsigned short>(*beg);
break;
}
default: break;
} //switch
}
return date_type(year, month, day);
}
//! Generic function to parse undelimited date (eg: 20020201)
template<class date_type>
date_type
parse_undelimited_date(const std::string& s) {
int offsets[] = {4,2,2};
int pos = 0;
//typename date_type::ymd_type ymd((year_type::min)(),1,1);
unsigned short y = 0, m = 0, d = 0;
/* The two bool arguments state that parsing will not wrap
* (only the first 8 characters will be parsed) and partial
* strings will not be parsed.
* Ex:
* "2005121" will parse 2005 & 12, but not the "1" */
boost::offset_separator osf(offsets, offsets+3, false, false);
typedef typename boost::tokenizer<boost::offset_separator,
std::basic_string<char>::const_iterator,
std::basic_string<char> > tokenizer_type;
tokenizer_type tok(s, osf);
for(typename tokenizer_type::iterator ti=tok.begin(); ti!=tok.end();++ti) {
unsigned short i = boost::lexical_cast<unsigned short>(*ti);
switch(pos) {
case 0: y = i; break;
case 1: m = i; break;
case 2: d = i; break;
default: break;
}
pos++;
}
return date_type(y,m,d);
}
//! Helper function for 'date gregorian::from_stream()'
/*! Creates a string from the iterators that reference the
* begining & end of a char[] or string. All elements are
* used in output string */
template<class date_type, class iterator_type>
inline
date_type
from_stream_type(iterator_type& beg,
iterator_type const& end,
char)
{
std::ostringstream ss;
while(beg != end) {
ss << *beg++;
}
return parse_date<date_type>(ss.str());
}
//! Helper function for 'date gregorian::from_stream()'
/*! Returns the first string found in the stream referenced by the
* begining & end iterators */
template<class date_type, class iterator_type>
inline
date_type
from_stream_type(iterator_type& beg,
iterator_type const& /* end */,
std::string const&)
{
return parse_date<date_type>(*beg);
}
/* I believe the wchar stuff would be best elsewhere, perhaps in
* parse_date<>()? In the mean time this gets us started... */
//! Helper function for 'date gregorian::from_stream()'
/*! Creates a string from the iterators that reference the
* begining & end of a wstring. All elements are
* used in output string */
template<class date_type, class iterator_type>
inline
date_type from_stream_type(iterator_type& beg,
iterator_type const& end,
wchar_t)
{
std::ostringstream ss;
#if !defined(BOOST_DATE_TIME_NO_LOCALE)
std::locale loc;
std::ctype<wchar_t> const& fac = std::use_facet<std::ctype<wchar_t> >(loc);
while(beg != end) {
ss << fac.narrow(*beg++, 'X'); // 'X' will cause exception to be thrown
}
#else
while(beg != end) {
char c = 'X'; // 'X' will cause exception to be thrown
const wchar_t wc = *beg++;
if (wc >= 0 && wc <= 127)
c = static_cast< char >(wc);
ss << c;
}
#endif
return parse_date<date_type>(ss.str());
}
#ifndef BOOST_NO_STD_WSTRING
//! Helper function for 'date gregorian::from_stream()'
/*! Creates a string from the first wstring found in the stream
* referenced by the begining & end iterators */
template<class date_type, class iterator_type>
inline
date_type
from_stream_type(iterator_type& beg,
iterator_type const& /* end */,
std::wstring const&) {
std::wstring ws = *beg;
std::ostringstream ss;
std::wstring::iterator wsb = ws.begin(), wse = ws.end();
#if !defined(BOOST_DATE_TIME_NO_LOCALE)
std::locale loc;
std::ctype<wchar_t> const& fac = std::use_facet<std::ctype<wchar_t> >(loc);
while(wsb != wse) {
ss << fac.narrow(*wsb++, 'X'); // 'X' will cause exception to be thrown
}
#else
while(wsb != wse) {
char c = 'X'; // 'X' will cause exception to be thrown
const wchar_t wc = *wsb++;
if (wc >= 0 && wc <= 127)
c = static_cast< char >(wc);
ss << c;
}
#endif
return parse_date<date_type>(ss.str());
}
#endif // BOOST_NO_STD_WSTRING
#if (defined(BOOST_MSVC) && (_MSC_VER < 1300))
// This function cannot be compiled with MSVC 6.0 due to internal compiler shorcomings
#else
//! function called by wrapper functions: date_period_from_(w)string()
template<class date_type, class charT>
period<date_type, typename date_type::duration_type>
from_simple_string_type(const std::basic_string<charT>& s){
typedef typename std::basic_string<charT>::traits_type traits_type;
typedef typename boost::char_separator<charT, traits_type> char_separator;
typedef typename boost::tokenizer<char_separator,
typename std::basic_string<charT>::const_iterator,
std::basic_string<charT> > tokenizer;
const charT sep_list[4] = {'[','/',']','\0'};
char_separator sep(sep_list);
tokenizer tokens(s, sep);
typename tokenizer::iterator tok_it = tokens.begin();
std::basic_string<charT> date_string = *tok_it;
// get 2 string iterators and generate a date from them
typename std::basic_string<charT>::iterator date_string_start = date_string.begin(),
date_string_end = date_string.end();
typedef typename std::iterator_traits<typename std::basic_string<charT>::iterator>::value_type value_type;
date_type d1 = from_stream_type<date_type>(date_string_start, date_string_end, value_type());
date_string = *(++tok_it); // next token
date_string_start = date_string.begin(), date_string_end = date_string.end();
date_type d2 = from_stream_type<date_type>(date_string_start, date_string_end, value_type());
return period<date_type, typename date_type::duration_type>(d1, d2);
}
#endif
} } //namespace date_time
#endif

View File

@@ -0,0 +1,391 @@
#ifndef DATE_TIME_DST_RULES_HPP__
#define DATE_TIME_DST_RULES_HPP__
/* Copyright (c) 2002,2003, 2007 CrystalClear Software, Inc.
* Use, modification and distribution is subject to the
* Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
* Author: Jeff Garland, Bart Garst
* $Date$
*/
/*! @file dst_rules.hpp
Contains template class to provide static dst rule calculations
*/
#include "boost/date_time/date_generators.hpp"
#include "boost/date_time/period.hpp"
#include "boost/date_time/date_defs.hpp"
#include <stdexcept>
namespace boost {
namespace date_time {
enum time_is_dst_result {is_not_in_dst, is_in_dst,
ambiguous, invalid_time_label};
//! Dynamic class used to caluclate dst transition information
template<class date_type_,
class time_duration_type_>
class dst_calculator
{
public:
typedef time_duration_type_ time_duration_type;
typedef date_type_ date_type;
//! Check the local time offset when on dst start day
/*! On this dst transition, the time label between
* the transition boundary and the boudary + the offset
* are invalid times. If before the boundary then still
* not in dst.
*@param time_of_day Time offset in the day for the local time
*@param dst_start_offset_minutes Local day offset for start of dst
*@param dst_length_minutes Number of minutes to adjust clock forward
*@retval status of time label w.r.t. dst
*/
static time_is_dst_result
process_local_dst_start_day(const time_duration_type& time_of_day,
unsigned int dst_start_offset_minutes,
long dst_length_minutes)
{
//std::cout << "here" << std::endl;
if (time_of_day < time_duration_type(0,dst_start_offset_minutes,0)) {
return is_not_in_dst;
}
long offset = dst_start_offset_minutes + dst_length_minutes;
if (time_of_day >= time_duration_type(0,offset,0)) {
return is_in_dst;
}
return invalid_time_label;
}
//! Check the local time offset when on the last day of dst
/*! This is the calculation for the DST end day. On that day times
* prior to the conversion time - dst_length (1 am in US) are still
* in dst. Times between the above and the switch time are
* ambiguous. Times after the start_offset are not in dst.
*@param time_of_day Time offset in the day for the local time
*@param dst_end_offset_minutes Local time of day for end of dst
*@retval status of time label w.r.t. dst
*/
static time_is_dst_result
process_local_dst_end_day(const time_duration_type& time_of_day,
unsigned int dst_end_offset_minutes,
long dst_length_minutes)
{
//in US this will be 60 so offset in day is 1,0,0
int offset = dst_end_offset_minutes-dst_length_minutes;
if (time_of_day < time_duration_type(0,offset,0)) {
return is_in_dst;
}
if (time_of_day >= time_duration_type(0,dst_end_offset_minutes,0)) {
return is_not_in_dst;
}
return ambiguous;
}
//! 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.
* @param current_day The day to check for dst
* @param time_of_day Time offset within the day to check
* @param dst_start_day Starting day of dst for the given locality
* @param dst_start_offset Time offset within day for dst boundary
* @param dst_end_day Ending day of dst for the given locality
* @param dst_end_offset Time offset within day given in dst for dst boundary
* @param dst_length lenght of dst adjusment
* @retval The time is either ambiguous, invalid, in dst, or not in dst
*/
static time_is_dst_result
local_is_dst(const date_type& current_day,
const time_duration_type& time_of_day,
const date_type& dst_start_day,
const time_duration_type& dst_start_offset,
const date_type& dst_end_day,
const time_duration_type& dst_end_offset,
const time_duration_type& dst_length_minutes)
{
unsigned int start_minutes =
dst_start_offset.hours() * 60 + dst_start_offset.minutes();
unsigned int end_minutes =
dst_end_offset.hours() * 60 + dst_end_offset.minutes();
long length_minutes =
dst_length_minutes.hours() * 60 + dst_length_minutes.minutes();
return local_is_dst(current_day, time_of_day,
dst_start_day, start_minutes,
dst_end_day, end_minutes,
length_minutes);
}
//! 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.
* @param current_day The day to check for dst
* @param time_of_day Time offset within the day to check
* @param dst_start_day Starting day of dst for the given locality
* @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 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
*/
static time_is_dst_result
local_is_dst(const date_type& current_day,
const time_duration_type& time_of_day,
const date_type& dst_start_day,
unsigned int dst_start_offset_minutes,
const date_type& dst_end_day,
unsigned int dst_end_offset_minutes,
long dst_length_minutes)
{
//in northern hemisphere dst is in the middle of the year
if (dst_start_day < dst_end_day) {
if ((current_day > dst_start_day) && (current_day < dst_end_day)) {
return is_in_dst;
}
if ((current_day < dst_start_day) || (current_day > dst_end_day)) {
return is_not_in_dst;
}
}
else {//southern hemisphere dst is at begining /end of year
if ((current_day < dst_start_day) && (current_day > dst_end_day)) {
return is_not_in_dst;
}
if ((current_day > dst_start_day) || (current_day < dst_end_day)) {
return is_in_dst;
}
}
if (current_day == dst_start_day) {
return process_local_dst_start_day(time_of_day,
dst_start_offset_minutes,
dst_length_minutes);
}
if (current_day == dst_end_day) {
return process_local_dst_end_day(time_of_day,
dst_end_offset_minutes,
dst_length_minutes);
}
//you should never reach this statement
return invalid_time_label;
}
};
//! 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)
{
return dst_traits::local_dst_start_day(year);
}
static date_type local_dst_end_day(year_type year)
{
return dst_traits::local_dst_end_day(year);
}
};
//! Depricated: Class to calculate dst boundaries for US time zones
/* Use dst_calc_engine instead.
* In 2007 US/Canada DST rules changed
* (http://en.wikipedia.org/wiki/Energy_Policy_Act_of_2005#Change_to_daylight_saving_time).
*/
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
{
public:
typedef time_duration_type_ time_duration_type;
typedef date_type_ date_type;
typedef typename date_type::year_type year_type;
typedef typename date_type::calendar_type calendar_type;
typedef date_time::last_kday_of_month<date_type> lkday;
typedef date_time::first_kday_of_month<date_type> fkday;
typedef date_time::nth_kday_of_month<date_type> nkday;
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_start_offset_minutes,
dst_end, dst_start_offset_minutes,
dst_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)));
}
static date_type local_dst_start_day(year_type year)
{
if (year >= year_type(2007)) {
//second sunday in march
nkday ssim(nkday::second, Sunday, gregorian::Mar);
return ssim.get_date(year);
} else {
//first sunday in april
fkday fsia(Sunday, gregorian::Apr);
return fsia.get_date(year);
}
}
static date_type local_dst_end_day(year_type year)
{
if (year >= year_type(2007)) {
//first sunday in november
fkday fsin(Sunday, gregorian::Nov);
return fsin.get_date(year);
} else {
//last sunday in october
lkday lsio(Sunday, gregorian::Oct);
return lsio.get_date(year);
}
}
static time_duration_type dst_offset()
{
return time_duration_type(0,dst_length_minutes,0);
}
private:
};
//! Used for local time adjustments in places that don't use dst
template<class date_type_, class time_duration_type_>
class null_dst_rules
{
public:
typedef time_duration_type_ time_duration_type;
typedef date_type_ date_type;
//! Calculates if the given local time is dst or not
/*! @retval Always is_not_in_dst since this is for zones without dst
*/
static time_is_dst_result local_is_dst(const date_type&,
const time_duration_type&)
{
return is_not_in_dst;
}
//! Calculates if the given utc time is in dst
static time_is_dst_result utc_is_dst(const date_type&,
const time_duration_type&)
{
return is_not_in_dst;
}
static bool is_dst_boundary_day(date_type /*d*/)
{
return false;
}
static time_duration_type dst_offset()
{
return time_duration_type(0,0,0);
}
};
} } //namespace date_time
#endif

View File

@@ -0,0 +1,170 @@
#ifndef DATE_TIME_FILETIME_FUNCTIONS_HPP__
#define DATE_TIME_FILETIME_FUNCTIONS_HPP__
/* Copyright (c) 2004 CrystalClear Software, Inc.
* Use, modification and distribution is subject to the
* Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
* Author: Jeff Garland, Bart Garst
* $Date$
*/
/*! @file filetime_functions.hpp
* Function(s) for converting between a FILETIME structure and a
* time object. This file is only available on systems that have
* BOOST_HAS_FTIME defined.
*/
#include <boost/date_time/compiler_config.hpp>
#if defined(BOOST_HAS_FTIME) // skip this file if no FILETIME
#if defined(BOOST_USE_WINDOWS_H)
# include <windows.h>
#endif
#include <boost/cstdint.hpp>
#include <boost/date_time/time.hpp>
#include <boost/date_time/date_defs.hpp>
namespace boost {
namespace date_time {
namespace winapi {
#if !defined(BOOST_USE_WINDOWS_H)
extern "C" {
struct FILETIME
{
boost::uint32_t dwLowDateTime;
boost::uint32_t dwHighDateTime;
};
struct SYSTEMTIME
{
boost::uint16_t wYear;
boost::uint16_t wMonth;
boost::uint16_t wDayOfWeek;
boost::uint16_t wDay;
boost::uint16_t wHour;
boost::uint16_t wMinute;
boost::uint16_t wSecond;
boost::uint16_t wMilliseconds;
};
__declspec(dllimport) void __stdcall GetSystemTimeAsFileTime(FILETIME* lpFileTime);
__declspec(dllimport) int __stdcall FileTimeToLocalFileTime(const FILETIME* lpFileTime, FILETIME* lpLocalFileTime);
__declspec(dllimport) void __stdcall GetSystemTime(SYSTEMTIME* lpSystemTime);
__declspec(dllimport) int __stdcall SystemTimeToFileTime(const SYSTEMTIME* lpSystemTime, FILETIME* lpFileTime);
} // extern "C"
#endif // defined(BOOST_USE_WINDOWS_H)
typedef FILETIME file_time;
typedef SYSTEMTIME system_time;
inline void get_system_time_as_file_time(file_time& ft)
{
#if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3205))
// Some runtime library implementations expect local times as the norm for ctime.
file_time ft_utc;
GetSystemTimeAsFileTime(&ft_utc);
FileTimeToLocalFileTime(&ft_utc, &ft);
#elif defined(BOOST_HAS_GETSYSTEMTIMEASFILETIME)
GetSystemTimeAsFileTime(&ft);
#else
system_time st;
GetSystemTime(&st);
SystemTimeToFileTime(&st, &ft);
#endif
}
/*!
* The function converts file_time into number of microseconds elapsed since 1970-Jan-01
*
* \note Only dates after 1970-Jan-01 are supported. Dates before will be wrapped.
*
* \note The function is templated on the FILETIME type, so that
* it can be used with both native FILETIME and the ad-hoc
* boost::date_time::winapi::file_time type.
*/
template< typename FileTimeT >
inline boost::uint64_t file_time_to_microseconds(FileTimeT const& ft)
{
/* shift is difference between 1970-Jan-01 & 1601-Jan-01
* in 100-nanosecond intervals */
const uint64_t shift = 116444736000000000ULL; // (27111902 << 32) + 3577643008
union {
FileTimeT as_file_time;
uint64_t as_integer; // 100-nanos since 1601-Jan-01
} caster;
caster.as_file_time = ft;
caster.as_integer -= shift; // filetime is now 100-nanos since 1970-Jan-01
return (caster.as_integer / 10); // truncate to microseconds
}
} // namespace winapi
//! Create a time object from an initialized FILETIME struct.
/*!
* Create a time object from an initialized FILETIME struct.
* A FILETIME struct holds 100-nanosecond units (0.0000001). When
* built with microsecond resolution the file_time's sub second value
* will be truncated. Nanosecond resolution has no truncation.
*
* \note The function is templated on the FILETIME type, so that
* it can be used with both native FILETIME and the ad-hoc
* boost::date_time::winapi::file_time type.
*/
template< typename TimeT, typename FileTimeT >
inline
TimeT time_from_ftime(const FileTimeT& ft)
{
typedef typename TimeT::date_type date_type;
typedef typename TimeT::date_duration_type date_duration_type;
typedef typename TimeT::time_duration_type time_duration_type;
// https://svn.boost.org/trac/boost/ticket/2523
// Since this function can be called with arbitrary times, including ones that
// are before 1970-Jan-01, we'll have to cast the time a bit differently,
// than it is done in the file_time_to_microseconds function. This allows to
// avoid integer wrapping for dates before 1970-Jan-01.
union {
FileTimeT as_file_time;
uint64_t as_integer; // 100-nanos since 1601-Jan-01
} caster;
caster.as_file_time = ft;
uint64_t sec = caster.as_integer / 10000000UL;
uint32_t sub_sec = (caster.as_integer % 10000000UL) // 100-nanoseconds since the last second
#if !defined(BOOST_DATE_TIME_POSIX_TIME_STD_CONFIG)
/ 10; // microseconds since the last second
#else
* 100; // nanoseconds since the last second
#endif
// split sec into usable chunks: days, hours, minutes, & seconds
const uint32_t sec_per_day = 86400; // seconds per day
uint32_t days = static_cast< uint32_t >(sec / sec_per_day);
uint32_t tmp = static_cast< uint32_t >(sec % sec_per_day);
uint32_t hours = tmp / 3600; // sec_per_hour
tmp %= 3600;
uint32_t minutes = tmp / 60; // sec_per_min
tmp %= 60;
uint32_t seconds = tmp; // seconds
date_duration_type dd(days);
date_type d = date_type(1601, Jan, 01) + dd;
return TimeT(d, time_duration_type(hours, minutes, seconds, sub_sec));
}
}} // boost::date_time
#endif // BOOST_HAS_FTIME
#endif // DATE_TIME_FILETIME_FUNCTIONS_HPP__

View File

@@ -0,0 +1,68 @@
#ifndef _GREGORIAN__CONVERSION_HPP___
#define _GREGORIAN__CONVERSION_HPP___
/* Copyright (c) 2004-2005 CrystalClear Software, Inc.
* Use, modification and distribution is subject to the
* Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
* Author: Jeff Garland, Bart Garst
* $Date$
*/
#include <cstring>
#include <string>
#include <stdexcept>
#include <boost/throw_exception.hpp>
#include <boost/date_time/c_time.hpp>
#include <boost/date_time/special_defs.hpp>
#include <boost/date_time/gregorian/gregorian_types.hpp>
namespace boost {
namespace gregorian {
//! Converts a date to a tm struct. Throws out_of_range exception if date is a special value
inline
std::tm to_tm(const date& d)
{
if (d.is_special())
{
std::string s = "tm unable to handle ";
switch (d.as_special())
{
case date_time::not_a_date_time:
s += "not-a-date-time value"; break;
case date_time::neg_infin:
s += "-infinity date value"; break;
case date_time::pos_infin:
s += "+infinity date value"; break;
default:
s += "a special date value"; break;
}
boost::throw_exception(std::out_of_range(s));
}
std::tm datetm;
std::memset(&datetm, 0, sizeof(datetm));
boost::gregorian::date::ymd_type ymd = d.year_month_day();
datetm.tm_year = ymd.year - 1900;
datetm.tm_mon = ymd.month - 1;
datetm.tm_mday = ymd.day;
datetm.tm_wday = d.day_of_week();
datetm.tm_yday = d.day_of_year() - 1;
datetm.tm_isdst = -1; // negative because not enough info to set tm_isdst
return datetm;
}
//! Converts a tm structure into a date dropping the any time values.
inline
date date_from_tm(const std::tm& datetm)
{
return date(static_cast<unsigned short>(datetm.tm_year+1900),
static_cast<unsigned short>(datetm.tm_mon+1),
static_cast<unsigned short>(datetm.tm_mday));
}
} } //namespace boost::gregorian
#endif

View File

@@ -0,0 +1,162 @@
#ifndef GREGORIAN_FORMATTERS_HPP___
#define GREGORIAN_FORMATTERS_HPP___
/* Copyright (c) 2002,2003 CrystalClear Software, Inc.
* Use, modification and distribution is subject to the
* Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
* Author: Jeff Garland, Bart Garst
* $Date$
*/
#include "boost/date_time/compiler_config.hpp"
#include "boost/date_time/gregorian/gregorian_types.hpp"
#if defined(BOOST_DATE_TIME_INCLUDE_LIMITED_HEADERS)
#include "boost/date_time/date_formatting_limited.hpp"
#else
#include "boost/date_time/date_formatting.hpp"
#endif
#include "boost/date_time/iso_format.hpp"
#include "boost/date_time/date_format_simple.hpp"
/* NOTE: "to_*_string" code for older compilers, ones that define
* BOOST_DATE_TIME_INCLUDE_LIMITED_HEADERS, is located in
* formatters_limited.hpp
*/
namespace boost {
namespace gregorian {
// wrapper function for to_simple_(w)string(date)
template<class charT>
inline
std::basic_string<charT> to_simple_string_type(const date& d) {
return date_time::date_formatter<date,date_time::simple_format<charT>,charT>::date_to_string(d);
}
//! To YYYY-mmm-DD string where mmm 3 char month name. Example: 2002-Jan-01
/*!\ingroup date_format
*/
inline std::string to_simple_string(const date& d) {
return to_simple_string_type<char>(d);
}
// wrapper function for to_simple_(w)string(date_period)
template<class charT>
inline std::basic_string<charT> to_simple_string_type(const date_period& d) {
typedef std::basic_string<charT> string_type;
charT b = '[', m = '/', e=']';
string_type d1(date_time::date_formatter<date,date_time::simple_format<charT>,charT>::date_to_string(d.begin()));
string_type d2(date_time::date_formatter<date,date_time::simple_format<charT>,charT>::date_to_string(d.last()));
return string_type(b + d1 + m + d2 + e);
}
//! Convert date period to simple string. Example: [2002-Jan-01/2002-Jan-02]
/*!\ingroup date_format
*/
inline std::string to_simple_string(const date_period& d) {
return to_simple_string_type<char>(d);
}
// wrapper function for to_iso_(w)string(date_period)
template<class charT>
inline std::basic_string<charT> to_iso_string_type(const date_period& d) {
charT sep = '/';
std::basic_string<charT> s(date_time::date_formatter<date,date_time::iso_format<charT>,charT>::date_to_string(d.begin()));
return s + sep + date_time::date_formatter<date,date_time::iso_format<charT>,charT>::date_to_string(d.last());
}
//! Date period to iso standard format CCYYMMDD/CCYYMMDD. Example: 20021225/20021231
/*!\ingroup date_format
*/
inline std::string to_iso_string(const date_period& d) {
return to_iso_string_type<char>(d);
}
// wrapper function for to_iso_extended_(w)string(date)
template<class charT>
inline std::basic_string<charT> to_iso_extended_string_type(const date& d) {
return date_time::date_formatter<date,date_time::iso_extended_format<charT>,charT>::date_to_string(d);
}
//! Convert to iso extended format string CCYY-MM-DD. Example 2002-12-31
/*!\ingroup date_format
*/
inline std::string to_iso_extended_string(const date& d) {
return to_iso_extended_string_type<char>(d);
}
// wrapper function for to_iso_(w)string(date)
template<class charT>
inline std::basic_string<charT> to_iso_string_type(const date& d) {
return date_time::date_formatter<date,date_time::iso_format<charT>,charT>::date_to_string(d);
}
//! Convert to iso standard string YYYYMMDD. Example: 20021231
/*!\ingroup date_format
*/
inline std::string to_iso_string(const date& d) {
return to_iso_string_type<char>(d);
}
// wrapper function for to_sql_(w)string(date)
template<class charT>
inline std::basic_string<charT> to_sql_string_type(const date& d)
{
date::ymd_type ymd = d.year_month_day();
std::basic_ostringstream<charT> ss;
ss << ymd.year << "-"
<< std::setw(2) << std::setfill(ss.widen('0'))
<< ymd.month.as_number() //solves problem with gcc 3.1 hanging
<< "-"
<< std::setw(2) << std::setfill(ss.widen('0'))
<< ymd.day;
return ss.str();
}
inline std::string to_sql_string(const date& d) {
return to_sql_string_type<char>(d);
}
#if !defined(BOOST_NO_STD_WSTRING)
//! Convert date period to simple string. Example: [2002-Jan-01/2002-Jan-02]
/*!\ingroup date_format
*/
inline std::wstring to_simple_wstring(const date_period& d) {
return to_simple_string_type<wchar_t>(d);
}
//! To YYYY-mmm-DD string where mmm 3 char month name. Example: 2002-Jan-01
/*!\ingroup date_format
*/
inline std::wstring to_simple_wstring(const date& d) {
return to_simple_string_type<wchar_t>(d);
}
//! Date period to iso standard format CCYYMMDD/CCYYMMDD. Example: 20021225/20021231
/*!\ingroup date_format
*/
inline std::wstring to_iso_wstring(const date_period& d) {
return to_iso_string_type<wchar_t>(d);
}
//! Convert to iso extended format string CCYY-MM-DD. Example 2002-12-31
/*!\ingroup date_format
*/
inline std::wstring to_iso_extended_wstring(const date& d) {
return to_iso_extended_string_type<wchar_t>(d);
}
//! Convert to iso standard string YYYYMMDD. Example: 20021231
/*!\ingroup date_format
*/
inline std::wstring to_iso_wstring(const date& d) {
return to_iso_string_type<wchar_t>(d);
}
inline std::wstring to_sql_wstring(const date& d) {
return to_sql_string_type<wchar_t>(d);
}
#endif // BOOST_NO_STD_WSTRING
} } //namespace gregorian
#endif

View File

@@ -0,0 +1,81 @@
#ifndef GREGORIAN_FORMATTERS_LIMITED_HPP___
#define GREGORIAN_FORMATTERS_LIMITED_HPP___
/* Copyright (c) 2002,2003 CrystalClear Software, Inc.
* Use, modification and distribution is subject to the
* Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
* Author: Jeff Garland, Bart Garst
* $Date$
*/
#include "boost/date_time/gregorian/gregorian_types.hpp"
#include "boost/date_time/date_formatting_limited.hpp"
#include "boost/date_time/iso_format.hpp"
#include "boost/date_time/date_format_simple.hpp"
#include "boost/date_time/compiler_config.hpp"
namespace boost {
namespace gregorian {
//! To YYYY-mmm-DD string where mmm 3 char month name. Example: 2002-Jan-01
/*!\ingroup date_format
*/
inline std::string to_simple_string(const date& d) {
return date_time::date_formatter<date,date_time::simple_format<char> >::date_to_string(d);
}
//! Convert date period to simple string. Example: [2002-Jan-01/2002-Jan-02]
/*!\ingroup date_format
*/
inline std::string to_simple_string(const date_period& d) {
std::string s("[");
std::string d1(date_time::date_formatter<date,date_time::simple_format<char> >::date_to_string(d.begin()));
std::string d2(date_time::date_formatter<date,date_time::simple_format<char> >::date_to_string(d.last()));
return std::string("[" + d1 + "/" + d2 + "]");
}
//! Date period to iso standard format CCYYMMDD/CCYYMMDD. Example: 20021225/20021231
/*!\ingroup date_format
*/
inline std::string to_iso_string(const date_period& d) {
std::string s(date_time::date_formatter<date,date_time::iso_format<char> >::date_to_string(d.begin()));
return s + "/" + date_time::date_formatter<date,date_time::iso_format<char> >::date_to_string(d.last());
}
//! Convert to iso extended format string CCYY-MM-DD. Example 2002-12-31
/*!\ingroup date_format
*/
inline std::string to_iso_extended_string(const date& d) {
return date_time::date_formatter<date,date_time::iso_extended_format<char> >::date_to_string(d);
}
//! Convert to iso standard string YYYYMMDD. Example: 20021231
/*!\ingroup date_format
*/
inline std::string to_iso_string(const date& d) {
return date_time::date_formatter<date,date_time::iso_format<char> >::date_to_string(d);
}
inline std::string to_sql_string(const date& d)
{
date::ymd_type ymd = d.year_month_day();
std::ostringstream ss;
ss << ymd.year << "-"
<< std::setw(2) << std::setfill('0')
<< ymd.month.as_number() //solves problem with gcc 3.1 hanging
<< "-"
<< std::setw(2) << std::setfill('0')
<< ymd.day;
return ss.str();
}
} } //namespace gregorian
#endif

View File

@@ -0,0 +1,48 @@
#ifndef GREGORIAN_GREGORIAN_CALENDAR_HPP__
#define GREGORIAN_GREGORIAN_CALENDAR_HPP__
/* Copyright (c) 2002,2003 CrystalClear Software, Inc.
* Use, modification and distribution is subject to the
* Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
* Author: Jeff Garland
* $Date$
*/
#include <boost/cstdint.hpp>
#include <boost/date_time/gregorian/greg_weekday.hpp>
#include <boost/date_time/gregorian/greg_day_of_year.hpp>
#include <boost/date_time/gregorian_calendar.hpp>
#include <boost/date_time/gregorian/greg_ymd.hpp>
#include <boost/date_time/int_adapter.hpp>
namespace boost {
namespace gregorian {
//!An internal date representation that includes infinities, not a date
typedef date_time::int_adapter<uint32_t> fancy_date_rep;
//! Gregorian calendar for this implementation, hard work in the base
class gregorian_calendar :
public date_time::gregorian_calendar_base<greg_year_month_day, fancy_date_rep::int_type> {
public:
//! Type to hold a weekday (eg: Sunday, Monday,...)
typedef greg_weekday day_of_week_type;
//! Counter type from 1 to 366 for gregorian dates.
typedef greg_day_of_year_rep day_of_year_type;
//! Internal date representation that handles infinity, not a date
typedef fancy_date_rep date_rep_type;
//! Date rep implements the traits stuff as well
typedef fancy_date_rep date_traits_type;
private:
};
} } //namespace gregorian
#endif

View File

@@ -0,0 +1,136 @@
#ifndef GREG_DATE_HPP___
#define GREG_DATE_HPP___
/* Copyright (c) 2002,2003 CrystalClear Software, Inc.
* Use, modification and distribution is subject to the
* Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
* Author: Jeff Garland
* $Date$
*/
#include <boost/throw_exception.hpp>
#include <boost/date_time/date.hpp>
#include <boost/date_time/special_defs.hpp>
#include <boost/date_time/gregorian/greg_calendar.hpp>
#include <boost/date_time/gregorian/greg_duration.hpp>
namespace boost {
namespace gregorian {
//bring special enum values into the namespace
using date_time::special_values;
using date_time::not_special;
using date_time::neg_infin;
using date_time::pos_infin;
using date_time::not_a_date_time;
using date_time::max_date_time;
using date_time::min_date_time;
//! A date type based on gregorian_calendar
/*! This class is the primary interface for programming with
greogorian dates. The is a lightweight type that can be
freely passed by value. All comparison operators are
supported.
\ingroup date_basics
*/
class date : public date_time::date<date, gregorian_calendar, date_duration>
{
public:
typedef gregorian_calendar::year_type year_type;
typedef gregorian_calendar::month_type month_type;
typedef gregorian_calendar::day_type day_type;
typedef gregorian_calendar::day_of_year_type day_of_year_type;
typedef gregorian_calendar::ymd_type ymd_type;
typedef gregorian_calendar::date_rep_type date_rep_type;
typedef gregorian_calendar::date_int_type date_int_type;
typedef date_duration duration_type;
#if !defined(DATE_TIME_NO_DEFAULT_CONSTRUCTOR)
//! Default constructor constructs with not_a_date_time
date():
date_time::date<date, gregorian_calendar, date_duration>(date_rep_type::from_special(not_a_date_time))
{}
#endif // DATE_TIME_NO_DEFAULT_CONSTRUCTOR
//! Main constructor with year, month, day
date(year_type y, month_type m, day_type d)
: date_time::date<date, gregorian_calendar, date_duration>(y, m, d)
{
if (gregorian_calendar::end_of_month_day(y, m) < d) {
boost::throw_exception(bad_day_of_month(std::string("Day of month is not valid for year")));
}
}
//! Constructor from a ymd_type structure
explicit date(const ymd_type& ymd)
: date_time::date<date, gregorian_calendar, date_duration>(ymd)
{}
//! Needed copy constructor
explicit date(const date_int_type& rhs):
date_time::date<date,gregorian_calendar, date_duration>(rhs)
{}
//! Needed copy constructor
explicit date(date_rep_type rhs):
date_time::date<date,gregorian_calendar, date_duration>(rhs)
{}
//! Constructor for infinities, not a date, max and min date
explicit date(special_values sv):
date_time::date<date, gregorian_calendar, date_duration>(date_rep_type::from_special(sv))
{
if (sv == min_date_time)
{
*this = date(1400, 1, 1);
}
if (sv == max_date_time)
{
*this = date(9999, 12, 31);
}
}
//!Return the Julian Day number for the date.
date_int_type julian_day() const
{
ymd_type ymd = year_month_day();
return gregorian_calendar::julian_day_number(ymd);
}
//!Return the day of year 1..365 or 1..366 (for leap year)
day_of_year_type day_of_year() const
{
date start_of_year(year(), 1, 1);
unsigned short doy = static_cast<unsigned short>((*this-start_of_year).days() + 1);
return day_of_year_type(doy);
}
//!Return the Modified Julian Day number for the date.
date_int_type modjulian_day() const
{
ymd_type ymd = year_month_day();
return gregorian_calendar::modjulian_day_number(ymd);
}
//!Return the iso 8601 week number 1..53
int week_number() const
{
ymd_type ymd = year_month_day();
return gregorian_calendar::week_number(ymd);
}
//! Return the day number from the calendar
date_int_type day_number() const
{
return days_;
}
//! Return the last day of the current month
date end_of_month() const
{
ymd_type ymd = year_month_day();
short eom_day = gregorian_calendar::end_of_month_day(ymd.year, ymd.month);
return date(ymd.year, ymd.month, eom_day);
}
private:
};
} } //namespace gregorian
#endif

View File

@@ -0,0 +1,57 @@
#ifndef GREG_DAY_HPP___
#define GREG_DAY_HPP___
/* Copyright (c) 2002,2003 CrystalClear Software, Inc.
* Use, modification and distribution is subject to the
* Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
* Author: Jeff Garland
* $Date$
*/
#include "boost/date_time/constrained_value.hpp"
#include <stdexcept>
#include <string>
namespace boost {
namespace gregorian {
//! Exception type for gregorian day of month (1..31)
struct bad_day_of_month : public std::out_of_range
{
bad_day_of_month() :
std::out_of_range(std::string("Day of month value is out of range 1..31"))
{}
//! Allow other classes to throw with unique string for bad day like Feb 29
bad_day_of_month(const std::string& s) :
std::out_of_range(s)
{}
};
//! Policy class that declares error handling and day of month ranges
typedef CV::simple_exception_policy<unsigned short, 1, 31, bad_day_of_month> greg_day_policies;
//! Generated represetation for gregorian day of month
typedef CV::constrained_value<greg_day_policies> greg_day_rep;
//! Represent a day of the month (range 1 - 31)
/*! This small class allows for simple conversion an integer value into
a day of the month for a standard gregorian calendar. The type
is automatically range checked so values outside of the range 1-31
will cause a bad_day_of_month exception
*/
class greg_day : public greg_day_rep {
public:
greg_day(unsigned short day_of_month) : greg_day_rep(day_of_month) {}
unsigned short as_number() const {return value_;}
operator unsigned short() const {return value_;}
private:
};
} } //namespace gregorian
#endif

View File

@@ -0,0 +1,38 @@
#ifndef GREG_DAY_OF_YEAR_HPP___
#define GREG_DAY_OF_YEAR_HPP___
/* Copyright (c) 2002,2003 CrystalClear Software, Inc.
* Use, modification and distribution is subject to the
* Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
* Author: Jeff Garland
* $Date$
*/
#include "boost/date_time/constrained_value.hpp"
#include <stdexcept>
#include <string>
namespace boost {
namespace gregorian {
//! Exception type for day of year (1..366)
struct bad_day_of_year : public std::out_of_range
{
bad_day_of_year() :
std::out_of_range(std::string("Day of year value is out of range 1..366"))
{}
};
//! A day of the year range (1..366)
typedef CV::simple_exception_policy<unsigned short,1,366,bad_day_of_year> greg_day_of_year_policies;
//! Define a range representation type for the day of the year 1..366
typedef CV::constrained_value<greg_day_of_year_policies> greg_day_of_year_rep;
} } //namespace gregorian
#endif

View File

@@ -0,0 +1,134 @@
#ifndef GREG_DURATION_HPP___
#define GREG_DURATION_HPP___
/* Copyright (c) 2002,2003 CrystalClear Software, Inc.
* Use, modification and distribution is subject to the
* Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
* Author: Jeff Garland, Bart Garst
* $Date$
*/
#include <boost/date_time/date_duration.hpp>
#include <boost/date_time/int_adapter.hpp>
#include <boost/date_time/special_defs.hpp>
namespace boost {
namespace gregorian {
//!An internal date representation that includes infinities, not a date
typedef boost::date_time::duration_traits_adapted date_duration_rep;
//! Durations in days for gregorian system
/*! \ingroup date_basics
*/
class date_duration :
public boost::date_time::date_duration< date_duration_rep >
{
typedef boost::date_time::date_duration< date_duration_rep > base_type;
public:
typedef base_type::duration_rep duration_rep;
//! Construct from a day count
explicit date_duration(duration_rep day_count = 0) : base_type(day_count) {}
//! construct from special_values
date_duration(date_time::special_values sv) : base_type(sv) {}
//! Copy constructor
date_duration(const date_duration& other) : base_type(static_cast< base_type const& >(other))
{}
//! Construct from another date_duration
date_duration(const base_type& other) : base_type(other)
{}
// Relational operators
// NOTE: Because of date_time::date_duration< T > design choice we don't use Boost.Operators here,
// because we need the class to be a direct base. Either lose EBO, or define operators by hand.
// The latter is more effecient.
bool operator== (const date_duration& rhs) const
{
return base_type::operator== (rhs);
}
bool operator!= (const date_duration& rhs) const
{
return !operator== (rhs);
}
bool operator< (const date_duration& rhs) const
{
return base_type::operator< (rhs);
}
bool operator> (const date_duration& rhs) const
{
return !(base_type::operator< (rhs) || base_type::operator== (rhs));
}
bool operator<= (const date_duration& rhs) const
{
return (base_type::operator< (rhs) || base_type::operator== (rhs));
}
bool operator>= (const date_duration& rhs) const
{
return !base_type::operator< (rhs);
}
//! Subtract another duration -- result is signed
date_duration& operator-= (const date_duration& rhs)
{
base_type::operator-= (rhs);
return *this;
}
friend date_duration operator- (date_duration rhs, date_duration const& lhs)
{
rhs -= lhs;
return rhs;
}
//! Add a duration -- result is signed
date_duration& operator+= (const date_duration& rhs)
{
base_type::operator+= (rhs);
return *this;
}
friend date_duration operator+ (date_duration rhs, date_duration const& lhs)
{
rhs += lhs;
return rhs;
}
//! unary- Allows for dd = -date_duration(2); -> dd == -2
date_duration operator- ()const
{
return date_duration(get_rep() * (-1));
}
//! Division operations on a duration with an integer.
date_duration& operator/= (int divisor)
{
base_type::operator/= (divisor);
return *this;
}
friend date_duration operator/ (date_duration rhs, int lhs)
{
rhs /= lhs;
return rhs;
}
//! Returns the smallest duration -- used by to calculate 'end'
static date_duration unit()
{
return date_duration(base_type::unit().get_rep());
}
};
//! Shorthand for date_duration
typedef date_duration days;
} } //namespace gregorian
#if defined(BOOST_DATE_TIME_OPTIONAL_GREGORIAN_TYPES)
#include <boost/date_time/date_duration_types.hpp>
#endif
#endif

View File

@@ -0,0 +1,43 @@
#ifndef GREG_DURATION_TYPES_HPP___
#define GREG_DURATION_TYPES_HPP___
/* Copyright (c) 2004 CrystalClear Software, Inc.
* Subject to Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
* Author: Jeff Garland, Bart Garst
* $Date$
*/
#include <boost/date_time/gregorian/greg_date.hpp>
#include <boost/date_time/int_adapter.hpp>
#include <boost/date_time/adjust_functors.hpp>
#include <boost/date_time/date_duration_types.hpp>
#include <boost/date_time/gregorian/greg_duration.hpp>
namespace boost {
namespace gregorian {
//! config struct for additional duration types (ie months_duration<> & years_duration<>)
struct greg_durations_config {
typedef date date_type;
typedef date_time::int_adapter<int> int_rep;
typedef date_time::month_functor<date_type> month_adjustor_type;
};
typedef date_time::months_duration<greg_durations_config> months;
typedef date_time::years_duration<greg_durations_config> years;
class weeks_duration : public date_duration {
public:
weeks_duration(duration_rep w)
: date_duration(w * 7) {}
weeks_duration(date_time::special_values sv)
: date_duration(sv) {}
};
typedef weeks_duration weeks;
}} // namespace boost::gregorian
#endif // GREG_DURATION_TYPES_HPP___

View File

@@ -0,0 +1,352 @@
#ifndef GREGORIAN_FACET_HPP___
#define GREGORIAN_FACET_HPP___
/* Copyright (c) 2002,2003 CrystalClear Software, Inc.
* Use, modification and distribution is subject to the
* Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
* Author: Jeff Garland, Bart Garst
* $Date$
*/
#include "boost/date_time/gregorian/gregorian_types.hpp"
#include "boost/date_time/date_formatting_locales.hpp" // sets BOOST_DATE_TIME_NO_LOCALE
#include "boost/date_time/gregorian/parsers.hpp"
//This file is basically commented out if locales are not supported
#ifndef BOOST_DATE_TIME_NO_LOCALE
#include <string>
#include <memory>
#include <locale>
#include <iostream>
#include <exception>
namespace boost {
namespace gregorian {
//! Configuration of the output facet template
struct greg_facet_config
{
typedef boost::gregorian::greg_month month_type;
typedef boost::date_time::special_values special_value_enum;
typedef boost::gregorian::months_of_year month_enum;
typedef boost::date_time::weekdays weekday_enum;
};
#if defined(USE_DATE_TIME_PRE_1_33_FACET_IO)
//! Create the base facet type for gregorian::date
typedef boost::date_time::date_names_put<greg_facet_config> greg_base_facet;
//! ostream operator for gregorian::date
/*! Uses the date facet to determine various output parameters including:
* - string values for the month (eg: Jan, Feb, Mar) (default: English)
* - string values for special values (eg: not-a-date-time) (default: English)
* - selection of long, short strings, or numerical month representation (default: short string)
* - month day year order (default yyyy-mmm-dd)
*/
template <class charT, class traits>
inline
std::basic_ostream<charT, traits>&
operator<<(std::basic_ostream<charT, traits>& os, const date& d)
{
typedef boost::date_time::date_names_put<greg_facet_config, charT> facet_def;
typedef boost::date_time::ostream_date_formatter<date, facet_def, charT> greg_ostream_formatter;
greg_ostream_formatter::date_put(d, os);
return os;
}
//! operator<< for gregorian::greg_month typically streaming: Jan, Feb, Mar...
/*! Uses the date facet to determine output string as well as selection of long or short strings.
* Default if no facet is installed is to output a 2 wide numeric value for the month
* eg: 01 == Jan, 02 == Feb, ... 12 == Dec.
*/
template <class charT, class traits>
inline
std::basic_ostream<charT, traits>&
operator<<(std::basic_ostream<charT, traits>& os, const greg_month& m)
{
typedef boost::date_time::date_names_put<greg_facet_config, charT> facet_def;
typedef boost::date_time::ostream_month_formatter<facet_def, charT> greg_month_formatter;
std::locale locale = os.getloc();
if (std::has_facet<facet_def>(locale)) {
const facet_def& f = std::use_facet<facet_def>(locale);
greg_month_formatter::format_month(m, os, f);
}
else { //default to numeric
charT fill_char = '0';
os << std::setw(2) << std::setfill(fill_char) << m.as_number();
}
return os;
}
//! operator<< for gregorian::greg_weekday typically streaming: Sun, Mon, Tue, ...
/*! Uses the date facet to determine output string as well as selection of long or short string.
* Default if no facet is installed is to output a 3 char english string for the
* day of the week.
*/
template <class charT, class traits>
inline
std::basic_ostream<charT, traits>&
operator<<(std::basic_ostream<charT, traits>& os, const greg_weekday& wd)
{
typedef boost::date_time::date_names_put<greg_facet_config, charT> facet_def;
typedef boost::date_time::ostream_weekday_formatter<greg_weekday, facet_def, charT> greg_weekday_formatter;
std::locale locale = os.getloc();
if (std::has_facet<facet_def>(locale)) {
const facet_def& f = std::use_facet<facet_def>(locale);
greg_weekday_formatter::format_weekday(wd, os, f, true);
}
else { //default to short English string eg: Sun, Mon, Tue, Wed...
os << wd.as_short_string();
}
return os;
}
//! operator<< for gregorian::date_period typical output: [2002-Jan-01/2002-Jan-31]
/*! Uses the date facet to determine output string as well as selection of long
* or short string fr dates.
* Default if no facet is installed is to output a 3 char english string for the
* day of the week.
*/
template <class charT, class traits>
inline
std::basic_ostream<charT, traits>&
operator<<(std::basic_ostream<charT, traits>& os, const date_period& dp)
{
os << '['; //TODO: facet or manipulator for periods?
os << dp.begin();
os << '/'; //TODO: facet or manipulator for periods?
os << dp.last();
os << ']';
return os;
}
template <class charT, class traits>
inline
std::basic_ostream<charT, traits>&
operator<<(std::basic_ostream<charT, traits>& os, const date_duration& dd)
{
//os << dd.days();
os << dd.get_rep();
return os;
}
//! operator<< for gregorian::partial_date. Output: "Jan 1"
template <class charT, class traits>
inline
std::basic_ostream<charT, traits>&
operator<<(std::basic_ostream<charT, traits>& os, const partial_date& pd)
{
os << std::setw(2) << std::setfill('0') << pd.day() << ' '
<< pd.month().as_short_string() ;
return os;
}
//! operator<< for gregorian::nth_kday_of_month. Output: "first Mon of Jun"
template <class charT, class traits>
inline
std::basic_ostream<charT, traits>&
operator<<(std::basic_ostream<charT, traits>& os,
const nth_kday_of_month& nkd)
{
os << nkd.nth_week_as_str() << ' '
<< nkd.day_of_week() << " of "
<< nkd.month().as_short_string() ;
return os;
}
//! operator<< for gregorian::first_kday_of_month. Output: "first Mon of Jun"
template <class charT, class traits>
inline
std::basic_ostream<charT, traits>&
operator<<(std::basic_ostream<charT, traits>& os,
const first_kday_of_month& fkd)
{
os << "first " << fkd.day_of_week() << " of "
<< fkd.month().as_short_string() ;
return os;
}
//! operator<< for gregorian::last_kday_of_month. Output: "last Mon of Jun"
template <class charT, class traits>
inline
std::basic_ostream<charT, traits>&
operator<<(std::basic_ostream<charT, traits>& os,
const last_kday_of_month& lkd)
{
os << "last " << lkd.day_of_week() << " of "
<< lkd.month().as_short_string() ;
return os;
}
//! operator<< for gregorian::first_kday_after. Output: "first Mon after"
template <class charT, class traits>
inline
std::basic_ostream<charT, traits>&
operator<<(std::basic_ostream<charT, traits>& os,
const first_kday_after& fka)
{
os << fka.day_of_week() << " after";
return os;
}
//! operator<< for gregorian::first_kday_before. Output: "first Mon before"
template <class charT, class traits>
inline
std::basic_ostream<charT, traits>&
operator<<(std::basic_ostream<charT, traits>& os,
const first_kday_before& fkb)
{
os << fkb.day_of_week() << " before";
return os;
}
#endif // USE_DATE_TIME_PRE_1_33_FACET_IO
/**************** Input Streaming ******************/
#if !defined(BOOST_NO_STD_ITERATOR_TRAITS)
//! operator>> for gregorian::date
template<class charT>
inline
std::basic_istream<charT>& operator>>(std::basic_istream<charT>& is, date& d)
{
std::istream_iterator<std::basic_string<charT>, charT> beg(is), eos;
d = from_stream(beg, eos);
return is;
}
#endif // BOOST_NO_STD_ITERATOR_TRAITS
//! operator>> for gregorian::date_duration
template<class charT>
inline
std::basic_istream<charT>& operator>>(std::basic_istream<charT>& is,
date_duration& dd)
{
long v;
is >> v;
dd = date_duration(v);
return is;
}
//! operator>> for gregorian::date_period
template<class charT>
inline
std::basic_istream<charT>& operator>>(std::basic_istream<charT>& is,
date_period& dp)
{
std::basic_string<charT> s;
is >> s;
dp = date_time::from_simple_string_type<date>(s);
return is;
}
//! generates a locale with the set of gregorian name-strings of type char*
BOOST_DATE_TIME_DECL std::locale generate_locale(std::locale& loc, char type);
//! Returns a pointer to a facet with a default set of names (English)
/* Necessary in the event an exception is thrown from op>> for
* weekday or month. See comments in those functions for more info */
BOOST_DATE_TIME_DECL boost::date_time::all_date_names_put<greg_facet_config, char>* create_facet_def(char type);
#ifndef BOOST_NO_STD_WSTRING
//! generates a locale with the set of gregorian name-strings of type wchar_t*
BOOST_DATE_TIME_DECL std::locale generate_locale(std::locale& loc, wchar_t type);
//! Returns a pointer to a facet with a default set of names (English)
/* Necessary in the event an exception is thrown from op>> for
* weekday or month. See comments in those functions for more info */
BOOST_DATE_TIME_DECL boost::date_time::all_date_names_put<greg_facet_config, wchar_t>* create_facet_def(wchar_t type);
#endif // BOOST_NO_STD_WSTRING
//! operator>> for gregorian::greg_month - throws exception if invalid month given
template<class charT>
inline
std::basic_istream<charT>& operator>>(std::basic_istream<charT>& is,greg_month& m)
{
typedef boost::date_time::all_date_names_put<greg_facet_config, charT> facet_def;
std::basic_string<charT> s;
is >> s;
if(!std::has_facet<facet_def>(is.getloc())) {
std::locale loc = is.getloc();
charT a = '\0';
is.imbue(generate_locale(loc, a));
}
short num = 0;
try{
const facet_def& f = std::use_facet<facet_def>(is.getloc());
num = date_time::find_match(f.get_short_month_names(),
f.get_long_month_names(),
(greg_month::max)(), s); // greg_month spans 1..12, so max returns the array size,
// which is needed by find_match
}
/* bad_cast will be thrown if the desired facet is not accessible
* so we can generate the facet. This has the drawback of using english
* names as a default. */
catch(std::bad_cast&){
charT a = '\0';
std::auto_ptr< const facet_def > f(create_facet_def(a));
num = date_time::find_match(f->get_short_month_names(),
f->get_long_month_names(),
(greg_month::max)(), s); // greg_month spans 1..12, so max returns the array size,
// which is needed by find_match
}
++num; // months numbered 1-12
m = greg_month(num);
return is;
}
//! operator>> for gregorian::greg_weekday - throws exception if invalid weekday given
template<class charT>
inline
std::basic_istream<charT>& operator>>(std::basic_istream<charT>& is,greg_weekday& wd)
{
typedef boost::date_time::all_date_names_put<greg_facet_config, charT> facet_def;
std::basic_string<charT> s;
is >> s;
if(!std::has_facet<facet_def>(is.getloc())) {
std::locale loc = is.getloc();
charT a = '\0';
is.imbue(generate_locale(loc, a));
}
short num = 0;
try{
const facet_def& f = std::use_facet<facet_def>(is.getloc());
num = date_time::find_match(f.get_short_weekday_names(),
f.get_long_weekday_names(),
(greg_weekday::max)() + 1, s); // greg_weekday spans 0..6, so increment is needed
// to form the array size which is needed by find_match
}
/* bad_cast will be thrown if the desired facet is not accessible
* so we can generate the facet. This has the drawback of using english
* names as a default. */
catch(std::bad_cast&){
charT a = '\0';
std::auto_ptr< const facet_def > f(create_facet_def(a));
num = date_time::find_match(f->get_short_weekday_names(),
f->get_long_weekday_names(),
(greg_weekday::max)() + 1, s); // greg_weekday spans 0..6, so increment is needed
// to form the array size which is needed by find_match
}
wd = greg_weekday(num); // weekdays numbered 0-6
return is;
}
} } //namespace gregorian
#endif
#endif

View File

@@ -0,0 +1,105 @@
#ifndef GREG_MONTH_HPP___
#define GREG_MONTH_HPP___
/* Copyright (c) 2002,2003 CrystalClear Software, Inc.
* Use, modification and distribution is subject to the
* Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
* Author: Jeff Garland, Bart Garst
* $Date$
*/
#include "boost/date_time/constrained_value.hpp"
#include "boost/date_time/date_defs.hpp"
#include "boost/shared_ptr.hpp"
#include "boost/date_time/compiler_config.hpp"
#include <stdexcept>
#include <string>
#include <map>
#include <algorithm>
#include <cctype>
namespace boost {
namespace gregorian {
typedef date_time::months_of_year months_of_year;
//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
{
bad_month() : std::out_of_range(std::string("Month number is out of range 1..12")) {}
};
//! Build a policy class for the greg_month_rep
typedef CV::simple_exception_policy<unsigned short, 1, 12, bad_month> greg_month_policies;
//! A constrained range that implements the gregorian_month rules
typedef CV::constrained_value<greg_month_policies> greg_month_rep;
//! Wrapper class to represent months in gregorian based calendar
class BOOST_DATE_TIME_DECL greg_month : public greg_month_rep {
public:
typedef date_time::months_of_year month_enum;
typedef std::map<std::string, unsigned short> month_map_type;
typedef boost::shared_ptr<month_map_type> month_map_ptr_type;
//! Construct a month from the months_of_year enumeration
greg_month(month_enum theMonth) :
greg_month_rep(static_cast<greg_month_rep::value_type>(theMonth)) {}
//! Construct from a short value
greg_month(unsigned short theMonth) : greg_month_rep(theMonth) {}
//! Convert the value back to a short
operator unsigned short() const {return value_;}
//! Returns month as number from 1 to 12
unsigned short as_number() const {return value_;}
month_enum as_enum() const {return static_cast<month_enum>(value_);}
const char* as_short_string() const;
const char* as_long_string() const;
#ifndef BOOST_NO_STD_WSTRING
const wchar_t* as_short_wstring() const;
const wchar_t* as_long_wstring() const;
#endif // BOOST_NO_STD_WSTRING
//! Shared pointer to a map of Month strings (Names & Abbrev) & numbers
static month_map_ptr_type get_month_map_ptr();
/* parameterized as_*_string functions are intended to be called
* from a template function: "... as_short_string(charT c='\0');" */
const char* as_short_string(char) const
{
return as_short_string();
}
const char* as_long_string(char) const
{
return as_long_string();
}
#ifndef BOOST_NO_STD_WSTRING
const wchar_t* as_short_string(wchar_t) const
{
return as_short_wstring();
}
const wchar_t* as_long_string(wchar_t) const
{
return as_long_wstring();
}
#endif // BOOST_NO_STD_WSTRING
};
} } //namespace gregorian
#endif

View File

@@ -0,0 +1,66 @@
#ifndef GREG_WEEKDAY_HPP___
#define GREG_WEEKDAY_HPP___
/* Copyright (c) 2002,2003 CrystalClear Software, Inc.
* Use, modification and distribution is subject to the
* Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
* Author: Jeff Garland, Bart Garst
* $Date$
*/
#include "boost/date_time/constrained_value.hpp"
#include "boost/date_time/date_defs.hpp"
#include "boost/date_time/compiler_config.hpp"
#include <stdexcept>
#include <string>
namespace boost {
namespace gregorian {
//bring enum values into the namespace
using date_time::Sunday;
using date_time::Monday;
using date_time::Tuesday;
using date_time::Wednesday;
using date_time::Thursday;
using date_time::Friday;
using date_time::Saturday;
//! Exception that flags that a weekday number is incorrect
struct bad_weekday : public std::out_of_range
{
bad_weekday() : std::out_of_range(std::string("Weekday is out of range 0..6")) {}
};
typedef CV::simple_exception_policy<unsigned short, 0, 6, bad_weekday> greg_weekday_policies;
typedef CV::constrained_value<greg_weekday_policies> greg_weekday_rep;
//! Represent a day within a week (range 0==Sun to 6==Sat)
class BOOST_DATE_TIME_DECL greg_weekday : public greg_weekday_rep {
public:
typedef boost::date_time::weekdays weekday_enum;
greg_weekday(unsigned short day_of_week_num) :
greg_weekday_rep(day_of_week_num)
{}
unsigned short as_number() const {return value_;}
const char* as_short_string() const;
const char* as_long_string() const;
#ifndef BOOST_NO_STD_WSTRING
const wchar_t* as_short_wstring() const;
const wchar_t* as_long_wstring() const;
#endif // BOOST_NO_STD_WSTRING
weekday_enum as_enum() const {return static_cast<weekday_enum>(value_);}
};
} } //namespace gregorian
#endif

View File

@@ -0,0 +1,53 @@
#ifndef GREG_YEAR_HPP___
#define GREG_YEAR_HPP___
/* Copyright (c) 2002,2003 CrystalClear Software, Inc.
* Use, modification and distribution is subject to the
* Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
* Author: Jeff Garland
* $Date$
*/
#include "boost/date_time/constrained_value.hpp"
#include <stdexcept>
#include <string>
namespace boost {
namespace gregorian {
//! Exception type for gregorian year
struct bad_year : public std::out_of_range
{
bad_year() :
std::out_of_range(std::string("Year is out of valid range: 1400..10000"))
{}
};
//! Policy class that declares error handling gregorian year type
typedef CV::simple_exception_policy<unsigned short, 1400, 10000, bad_year> greg_year_policies;
//! Generated representation for gregorian year
typedef CV::constrained_value<greg_year_policies> greg_year_rep;
//! Represent a day of the month (range 1900 - 10000)
/*! This small class allows for simple conversion an integer value into
a year for the gregorian calendar. This currently only allows a
range of 1900 to 10000. Both ends of the range are a bit arbitrary
at the moment, but they are the limits of current testing of the
library. As such they may be increased in the future.
*/
class greg_year : public greg_year_rep {
public:
greg_year(unsigned short year) : greg_year_rep(year) {}
operator unsigned short() const {return value_;}
private:
};
} } //namespace gregorian
#endif

View File

@@ -0,0 +1,33 @@
#ifndef DATE_TIME_GREG_YMD_HPP__
#define DATE_TIME_GREG_YMD_HPP__
/* Copyright (c) 2002,2003 CrystalClear Software, Inc.
* Use, modification and distribution is subject to the
* Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
* Author: Jeff Garland
* $Date$
*/
#include "boost/date_time/year_month_day.hpp"
#include "boost/date_time/special_defs.hpp"
#include "boost/date_time/gregorian/greg_day.hpp"
#include "boost/date_time/gregorian/greg_year.hpp"
#include "boost/date_time/gregorian/greg_month.hpp"
namespace boost {
namespace gregorian {
typedef date_time::year_month_day_base<greg_year,
greg_month,
greg_day> greg_year_month_day;
} } //namespace gregorian
#endif

View File

@@ -0,0 +1,109 @@
#ifndef _GREGORIAN_TYPES_HPP__
#define _GREGORIAN_TYPES_HPP__
/* Copyright (c) 2002,2003 CrystalClear Software, Inc.
* Use, modification and distribution is subject to the
* Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
* Author: Jeff Garland, Bart Garst
* $Date$
*/
/*! @file gregorian_types.hpp
Single file header that defines most of the types for the gregorian
date-time system.
*/
#include "boost/date_time/date.hpp"
#include "boost/date_time/period.hpp"
#include "boost/date_time/gregorian/greg_calendar.hpp"
#include "boost/date_time/gregorian/greg_duration.hpp"
#if defined(BOOST_DATE_TIME_OPTIONAL_GREGORIAN_TYPES)
#include "boost/date_time/gregorian/greg_duration_types.hpp"
#endif
#include "boost/date_time/gregorian/greg_date.hpp"
#include "boost/date_time/date_generators.hpp"
#include "boost/date_time/date_clock_device.hpp"
#include "boost/date_time/date_iterator.hpp"
#include "boost/date_time/adjust_functors.hpp"
namespace boost {
//! Gregorian date system based on date_time components
/*! This date system defines a full complement of types including
* a date, date_duration, date_period, day_clock, and a
* day_iterator.
*/
namespace gregorian {
//! Date periods for the gregorian system
/*!\ingroup date_basics
*/
typedef date_time::period<date, date_duration> date_period;
//! A unifying date_generator base type
/*! A unifying date_generator base type for:
* partial_date, nth_day_of_the_week_in_month,
* first_day_of_the_week_in_month, and last_day_of_the_week_in_month
*/
typedef date_time::year_based_generator<date> year_based_generator;
//! A date generation object type
typedef date_time::partial_date<date> partial_date;
typedef date_time::nth_kday_of_month<date> nth_kday_of_month;
typedef nth_kday_of_month nth_day_of_the_week_in_month;
typedef date_time::first_kday_of_month<date> first_kday_of_month;
typedef first_kday_of_month first_day_of_the_week_in_month;
typedef date_time::last_kday_of_month<date> last_kday_of_month;
typedef last_kday_of_month last_day_of_the_week_in_month;
typedef date_time::first_kday_after<date> first_kday_after;
typedef first_kday_after first_day_of_the_week_after;
typedef date_time::first_kday_before<date> first_kday_before;
typedef first_kday_before first_day_of_the_week_before;
//! A clock to get the current day from the local computer
/*!\ingroup date_basics
*/
typedef date_time::day_clock<date> day_clock;
//! Base date_iterator type for gregorian types.
/*!\ingroup date_basics
*/
typedef date_time::date_itr_base<date> date_iterator;
//! A day level iterator
/*!\ingroup date_basics
*/
typedef date_time::date_itr<date_time::day_functor<date>,
date> day_iterator;
//! A week level iterator
/*!\ingroup date_basics
*/
typedef date_time::date_itr<date_time::week_functor<date>,
date> week_iterator;
//! A month level iterator
/*!\ingroup date_basics
*/
typedef date_time::date_itr<date_time::month_functor<date>,
date> month_iterator;
//! A year level iterator
/*!\ingroup date_basics
*/
typedef date_time::date_itr<date_time::year_functor<date>,
date> year_iterator;
// bring in these date_generator functions from date_time namespace
using date_time::days_until_weekday;
using date_time::days_before_weekday;
using date_time::next_weekday;
using date_time::previous_weekday;
} } //namespace gregorian
#endif

View File

@@ -0,0 +1,91 @@
#ifndef GREGORIAN_PARSERS_HPP___
#define GREGORIAN_PARSERS_HPP___
/* Copyright (c) 2002,2003,2005 CrystalClear Software, Inc.
* Use, modification and distribution is subject to the
* Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
* Author: Jeff Garland, Bart Garst
* $Date$
*/
#include "boost/date_time/gregorian/gregorian_types.hpp"
#include "boost/date_time/date_parsing.hpp"
#include "boost/date_time/compiler_config.hpp"
#include "boost/date_time/parse_format_base.hpp"
#include <string>
#include <sstream>
namespace boost {
namespace gregorian {
//! Return special_value from string argument
/*! Return special_value from string argument. If argument is
* not one of the special value names (defined in src/gregorian/names.hpp),
* return 'not_special' */
BOOST_DATE_TIME_DECL special_values special_value_from_string(const std::string& s);
//! Deprecated: Use from_simple_string
inline date from_string(std::string s) {
return date_time::parse_date<date>(s);
}
//! From delimited date string where with order year-month-day eg: 2002-1-25 or 2003-Jan-25 (full month name is also accepted)
inline date from_simple_string(std::string s) {
return date_time::parse_date<date>(s, date_time::ymd_order_iso);
}
//! From delimited date string where with order year-month-day eg: 1-25-2003 or Jan-25-2003 (full month name is also accepted)
inline date from_us_string(std::string s) {
return date_time::parse_date<date>(s, date_time::ymd_order_us);
}
//! From delimited date string where with order day-month-year eg: 25-1-2002 or 25-Jan-2003 (full month name is also accepted)
inline date from_uk_string(std::string s) {
return date_time::parse_date<date>(s, date_time::ymd_order_dmy);
}
//! From iso type date string where with order year-month-day eg: 20020125
inline date from_undelimited_string(std::string s) {
return date_time::parse_undelimited_date<date>(s);
}
//! From iso type date string where with order year-month-day eg: 20020125
inline date date_from_iso_string(const std::string& s) {
return date_time::parse_undelimited_date<date>(s);
}
#if !(defined(BOOST_NO_STD_ITERATOR_TRAITS))
//! Stream should hold a date in the form of: 2002-1-25. Month number, abbrev, or name are accepted
/* Arguments passed in by-value for convertability of char[]
* to iterator_type. Calls to from_stream_type are by-reference
* since conversion is already done */
template<class iterator_type>
inline date from_stream(iterator_type beg, iterator_type end) {
if(beg == end)
{
return date(not_a_date_time);
}
typedef typename std::iterator_traits<iterator_type>::value_type value_type;
return date_time::from_stream_type<date>(beg, end, value_type());
}
#endif //BOOST_NO_STD_ITERATOR_TRAITS
#if (defined(_MSC_VER) && (_MSC_VER < 1300))
// This function cannot be compiled with MSVC 6.0 due to internal compiler shorcomings
#else
//! Function to parse a date_period from a string (eg: [2003-Oct-31/2003-Dec-25])
inline date_period date_period_from_string(const std::string& s){
return date_time::from_simple_string_type<date,char>(s);
}
# if !defined(BOOST_NO_STD_WSTRING)
//! Function to parse a date_period from a wstring (eg: [2003-Oct-31/2003-Dec-25])
inline date_period date_period_from_wstring(const std::wstring& s){
return date_time::from_simple_string_type<date,wchar_t>(s);
}
# endif // BOOST_NO_STD_WSTRING
#endif
} } //namespace gregorian
#endif

View File

@@ -0,0 +1,70 @@
#ifndef DATE_TIME_GREGORIAN_CALENDAR_HPP__
#define DATE_TIME_GREGORIAN_CALENDAR_HPP__
/* Copyright (c) 2002,2003 CrystalClear Software, Inc.
* Use, modification and distribution is subject to the
* Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
* Author: Jeff Garland
* $Date$
*/
namespace boost {
namespace date_time {
//! An implementation of the Gregorian calendar
/*! This is a parameterized implementation of a proleptic Gregorian Calendar that
can be used in the creation of date systems or just to perform calculations.
All the methods of this class are static functions, so the intent is to
never create instances of this class.
@param ymd_type_ Struct type representing the year, month, day. The ymd_type must
define a of types for the year, month, and day. These types need to be
arithmetic types.
@param date_int_type_ Underlying type for the date count. Must be an arithmetic type.
*/
template<typename ymd_type_, typename date_int_type_>
class gregorian_calendar_base {
public:
//! define a type a date split into components
typedef ymd_type_ ymd_type;
//! define a type for representing months
typedef typename ymd_type::month_type month_type;
//! define a type for representing days
typedef typename ymd_type::day_type day_type;
//! Type to hold a stand alone year value (eg: 2002)
typedef typename ymd_type::year_type year_type;
//! Define the integer type to use for internal calculations
typedef date_int_type_ date_int_type;
static unsigned short day_of_week(const ymd_type& ymd);
static int week_number(const ymd_type&ymd);
//static unsigned short day_of_year(date_int_type);
static date_int_type day_number(const ymd_type& ymd);
static date_int_type julian_day_number(const ymd_type& ymd);
static date_int_type modjulian_day_number(const ymd_type& ymd);
static ymd_type from_day_number(date_int_type);
static ymd_type from_julian_day_number(date_int_type);
static ymd_type from_modjulian_day_number(date_int_type);
static bool is_leap_year(year_type);
static unsigned short end_of_month_day(year_type y, month_type m);
static ymd_type epoch();
static unsigned short days_in_week();
};
} } //namespace
#ifndef NO_BOOST_DATE_TIME_INLINE
#include "boost/date_time/gregorian_calendar.ipp"
#endif
#endif

View File

@@ -0,0 +1,219 @@
/* Copyright (c) 2002,2003 CrystalClear Software, Inc.
* Use, modification and distribution is subject to the
* Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
* Author: Jeff Garland, Bart Garst
* $Date$
*/
#ifndef NO_BOOST_DATE_TIME_INLINE
#undef BOOST_DATE_TIME_INLINE
#define BOOST_DATE_TIME_INLINE inline
#endif
namespace boost {
namespace date_time {
//! Return the day of the week (0==Sunday, 1==Monday, etc)
/*! Converts a year-month-day into a day of the week number
*/
template<typename ymd_type_, typename date_int_type_>
BOOST_DATE_TIME_INLINE
unsigned short
gregorian_calendar_base<ymd_type_,date_int_type_>::day_of_week(const ymd_type& ymd) {
unsigned short a = static_cast<unsigned short>((14-ymd.month)/12);
unsigned short y = static_cast<unsigned short>(ymd.year - a);
unsigned short m = static_cast<unsigned short>(ymd.month + 12*a - 2);
unsigned short d = static_cast<unsigned short>((ymd.day + y + (y/4) - (y/100) + (y/400) + (31*m)/12) % 7);
//std::cout << year << "-" << month << "-" << day << " is day: " << d << "\n";
return d;
}
//!Return the iso week number for the date
/*!Implements the rules associated with the iso 8601 week number.
Basically the rule is that Week 1 of the year is the week that contains
January 4th or the week that contains the first Thursday in January.
Reference for this algorithm is the Calendar FAQ by Claus Tondering, April 2000.
*/
template<typename ymd_type_, typename date_int_type_>
BOOST_DATE_TIME_INLINE
int
gregorian_calendar_base<ymd_type_,date_int_type_>::week_number(const ymd_type& ymd) {
unsigned long julianbegin = julian_day_number(ymd_type(ymd.year,1,1));
unsigned long juliantoday = julian_day_number(ymd);
unsigned long day = (julianbegin + 3) % 7;
unsigned long week = (juliantoday + day - julianbegin + 4)/7;
if ((week >= 1) && (week <= 52)) {
return static_cast<int>(week);
}
if (week == 53) {
if((day==6) ||(day == 5 && is_leap_year(ymd.year))) {
return static_cast<int>(week); //under these circumstances week == 53.
} else {
return 1; //monday - wednesday is in week 1 of next year
}
}
//if the week is not in current year recalculate using the previous year as the beginning year
else if (week == 0) {
julianbegin = julian_day_number(ymd_type(static_cast<unsigned short>(ymd.year-1),1,1));
juliantoday = julian_day_number(ymd);
day = (julianbegin + 3) % 7;
week = (juliantoday + day - julianbegin + 4)/7;
return static_cast<int>(week);
}
return static_cast<int>(week); //not reachable -- well except if day == 5 and is_leap_year != true
}
//! Convert a ymd_type into a day number
/*! The day number is an absolute number of days since the start of count
*/
template<typename ymd_type_, typename date_int_type_>
BOOST_DATE_TIME_INLINE
date_int_type_
gregorian_calendar_base<ymd_type_,date_int_type_>::day_number(const ymd_type& ymd)
{
unsigned short a = static_cast<unsigned short>((14-ymd.month)/12);
unsigned short y = static_cast<unsigned short>(ymd.year + 4800 - a);
unsigned short m = static_cast<unsigned short>(ymd.month + 12*a - 3);
unsigned long d = ymd.day + ((153*m + 2)/5) + 365*y + (y/4) - (y/100) + (y/400) - 32045;
return static_cast<date_int_type>(d);
}
//! Convert a year-month-day into the julian day number
/*! Since this implementation uses julian day internally, this is the same as the day_number.
*/
template<typename ymd_type_, typename date_int_type_>
BOOST_DATE_TIME_INLINE
date_int_type_
gregorian_calendar_base<ymd_type_,date_int_type_>::julian_day_number(const ymd_type& ymd)
{
return day_number(ymd);
}
//! Convert year-month-day into a modified julian day number
/*! The day number is an absolute number of days.
* MJD 0 thus started on 17 Nov 1858(Gregorian) at 00:00:00 UTC
*/
template<typename ymd_type_, typename date_int_type_>
BOOST_DATE_TIME_INLINE
date_int_type_
gregorian_calendar_base<ymd_type_,date_int_type_>::modjulian_day_number(const ymd_type& ymd)
{
return julian_day_number(ymd)-2400001; //prerounded
}
//! Change a day number into a year-month-day
template<typename ymd_type_, typename date_int_type_>
BOOST_DATE_TIME_INLINE
ymd_type_
gregorian_calendar_base<ymd_type_,date_int_type_>::from_day_number(date_int_type dayNumber)
{
date_int_type a = dayNumber + 32044;
date_int_type b = (4*a + 3)/146097;
date_int_type c = a-((146097*b)/4);
date_int_type d = (4*c + 3)/1461;
date_int_type e = c - (1461*d)/4;
date_int_type m = (5*e + 2)/153;
unsigned short day = static_cast<unsigned short>(e - ((153*m + 2)/5) + 1);
unsigned short month = static_cast<unsigned short>(m + 3 - 12 * (m/10));
year_type year = static_cast<unsigned short>(100*b + d - 4800 + (m/10));
//std::cout << year << "-" << month << "-" << day << "\n";
return ymd_type(static_cast<unsigned short>(year),month,day);
}
//! Change a day number into a year-month-day
template<typename ymd_type_, typename date_int_type_>
BOOST_DATE_TIME_INLINE
ymd_type_
gregorian_calendar_base<ymd_type_,date_int_type_>::from_julian_day_number(date_int_type dayNumber)
{
date_int_type a = dayNumber + 32044;
date_int_type b = (4*a+3)/146097;
date_int_type c = a - ((146097*b)/4);
date_int_type d = (4*c + 3)/1461;
date_int_type e = c - ((1461*d)/4);
date_int_type m = (5*e + 2)/153;
unsigned short day = static_cast<unsigned short>(e - ((153*m + 2)/5) + 1);
unsigned short month = static_cast<unsigned short>(m + 3 - 12 * (m/10));
year_type year = static_cast<year_type>(100*b + d - 4800 + (m/10));
//std::cout << year << "-" << month << "-" << day << "\n";
return ymd_type(year,month,day);
}
//! Change a modified julian day number into a year-month-day
template<typename ymd_type_, typename date_int_type_>
BOOST_DATE_TIME_INLINE
ymd_type_
gregorian_calendar_base<ymd_type_,date_int_type_>::from_modjulian_day_number(date_int_type dayNumber) {
date_int_type jd = dayNumber + 2400001; //is 2400000.5 prerounded
return from_julian_day_number(jd);
}
//! Determine if the provided year is a leap year
/*!
*@return true if year is a leap year, false otherwise
*/
template<typename ymd_type_, typename date_int_type_>
BOOST_DATE_TIME_INLINE
bool
gregorian_calendar_base<ymd_type_,date_int_type_>::is_leap_year(year_type year)
{
//divisible by 4, not if divisible by 100, but true if divisible by 400
return (!(year % 4)) && ((year % 100) || (!(year % 400)));
}
//! Calculate the last day of the month
/*! Find the day which is the end of the month given year and month
* No error checking is performed.
*/
template<typename ymd_type_, typename date_int_type_>
BOOST_DATE_TIME_INLINE
unsigned short
gregorian_calendar_base<ymd_type_,date_int_type_>::end_of_month_day(year_type year,
month_type month)
{
switch (month) {
case 2:
if (is_leap_year(year)) {
return 29;
} else {
return 28;
};
case 4:
case 6:
case 9:
case 11:
return 30;
default:
return 31;
};
}
//! Provide the ymd_type specification for the calandar start
template<typename ymd_type_, typename date_int_type_>
BOOST_DATE_TIME_INLINE
ymd_type_
gregorian_calendar_base<ymd_type_,date_int_type_>::epoch()
{
return ymd_type(1400,1,1);
}
//! Defines length of a week for week calculations
template<typename ymd_type_, typename date_int_type_>
BOOST_DATE_TIME_INLINE
unsigned short
gregorian_calendar_base<ymd_type_,date_int_type_>::days_in_week()
{
return 7;
}
} } //namespace gregorian

View File

@@ -0,0 +1,509 @@
#ifndef _DATE_TIME_INT_ADAPTER_HPP__
#define _DATE_TIME_INT_ADAPTER_HPP__
/* Copyright (c) 2002,2003 CrystalClear Software, Inc.
* Use, modification and distribution is subject to the
* Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
* Author: Jeff Garland, Bart Garst
* $Date$
*/
#include "boost/config.hpp"
#include "boost/limits.hpp" //work around compilers without limits
#include "boost/date_time/special_defs.hpp"
#include "boost/date_time/locale_config.hpp"
#ifndef BOOST_DATE_TIME_NO_LOCALE
# include <ostream>
#endif
namespace boost {
namespace date_time {
//! Adapter to create integer types with +-infinity, and not a value
/*! This class is used internally in counted date/time representations.
* It adds the floating point like features of infinities and
* not a number. It also provides mathmatical operations with
* consideration to special values following these rules:
*@code
* +infinity - infinity == Not A Number (NAN)
* infinity * non-zero == infinity
* infinity * zero == NAN
* +infinity * -integer == -infinity
* infinity / infinity == NAN
* infinity * infinity == infinity
*@endcode
*/
template<typename int_type_>
class int_adapter {
public:
typedef int_type_ int_type;
int_adapter(int_type v) :
value_(v)
{}
static bool has_infinity()
{
return true;
}
static const int_adapter pos_infinity()
{
return (::std::numeric_limits<int_type>::max)();
}
static const int_adapter neg_infinity()
{
return (::std::numeric_limits<int_type>::min)();
}
static const int_adapter not_a_number()
{
return (::std::numeric_limits<int_type>::max)()-1;
}
static int_adapter max BOOST_PREVENT_MACRO_SUBSTITUTION ()
{
return (::std::numeric_limits<int_type>::max)()-2;
}
static int_adapter min BOOST_PREVENT_MACRO_SUBSTITUTION ()
{
return (::std::numeric_limits<int_type>::min)()+1;
}
static int_adapter from_special(special_values sv)
{
switch (sv) {
case not_a_date_time: return not_a_number();
case neg_infin: return neg_infinity();
case pos_infin: return pos_infinity();
case max_date_time: return (max)();
case min_date_time: return (min)();
default: return not_a_number();
}
}
static bool is_inf(int_type v)
{
return (v == neg_infinity().as_number() ||
v == pos_infinity().as_number());
}
static bool is_neg_inf(int_type v)
{
return (v == neg_infinity().as_number());
}
static bool is_pos_inf(int_type v)
{
return (v == pos_infinity().as_number());
}
static bool is_not_a_number(int_type v)
{
return (v == not_a_number().as_number());
}
//! Returns either special value type or is_not_special
static special_values to_special(int_type v)
{
if (is_not_a_number(v)) return not_a_date_time;
if (is_neg_inf(v)) return neg_infin;
if (is_pos_inf(v)) return pos_infin;
return not_special;
}
//-3 leaves room for representations of infinity and not a date
static int_type maxcount()
{
return (::std::numeric_limits<int_type>::max)()-3;
}
bool is_infinity() const
{
return (value_ == neg_infinity().as_number() ||
value_ == pos_infinity().as_number());
}
bool is_pos_infinity()const
{
return(value_ == pos_infinity().as_number());
}
bool is_neg_infinity()const
{
return(value_ == neg_infinity().as_number());
}
bool is_nan() const
{
return (value_ == not_a_number().as_number());
}
bool is_special() const
{
return(is_infinity() || is_nan());
}
bool operator==(const int_adapter& rhs) const
{
return (compare(rhs) == 0);
}
bool operator==(const int& rhs) const
{
// quiets compiler warnings
bool is_signed = std::numeric_limits<int_type>::is_signed;
if(!is_signed)
{
if(is_neg_inf(value_) && rhs == 0)
{
return false;
}
}
return (compare(rhs) == 0);
}
bool operator!=(const int_adapter& rhs) const
{
return (compare(rhs) != 0);
}
bool operator!=(const int& rhs) const
{
// quiets compiler warnings
bool is_signed = std::numeric_limits<int_type>::is_signed;
if(!is_signed)
{
if(is_neg_inf(value_) && rhs == 0)
{
return true;
}
}
return (compare(rhs) != 0);
}
bool operator<(const int_adapter& rhs) const
{
return (compare(rhs) == -1);
}
bool operator<(const int& rhs) const
{
// quiets compiler warnings
bool is_signed = std::numeric_limits<int_type>::is_signed;
if(!is_signed)
{
if(is_neg_inf(value_) && rhs == 0)
{
return true;
}
}
return (compare(rhs) == -1);
}
bool operator>(const int_adapter& rhs) const
{
return (compare(rhs) == 1);
}
int_type as_number() const
{
return value_;
}
//! Returns either special value type or is_not_special
special_values as_special() const
{
return int_adapter::to_special(value_);
}
//creates nasty ambiguities
// operator int_type() const
// {
// return value_;
// }
/*! Operator allows for adding dissimilar int_adapter types.
* The return type will match that of the the calling object's type */
template<class rhs_type>
inline
int_adapter operator+(const int_adapter<rhs_type>& rhs) const
{
if(is_special() || rhs.is_special())
{
if (is_nan() || rhs.is_nan())
{
return int_adapter::not_a_number();
}
if((is_pos_inf(value_) && rhs.is_neg_inf(rhs.as_number())) ||
(is_neg_inf(value_) && rhs.is_pos_inf(rhs.as_number())) )
{
return int_adapter::not_a_number();
}
if (is_infinity())
{
return *this;
}
if (rhs.is_pos_inf(rhs.as_number()))
{
return int_adapter::pos_infinity();
}
if (rhs.is_neg_inf(rhs.as_number()))
{
return int_adapter::neg_infinity();
}
}
return int_adapter<int_type>(value_ + static_cast<int_type>(rhs.as_number()));
}
int_adapter operator+(const int_type rhs) const
{
if(is_special())
{
if (is_nan())
{
return int_adapter<int_type>(not_a_number());
}
if (is_infinity())
{
return *this;
}
}
return int_adapter<int_type>(value_ + rhs);
}
/*! Operator allows for subtracting dissimilar int_adapter types.
* The return type will match that of the the calling object's type */
template<class rhs_type>
inline
int_adapter operator-(const int_adapter<rhs_type>& rhs)const
{
if(is_special() || rhs.is_special())
{
if (is_nan() || rhs.is_nan())
{
return int_adapter::not_a_number();
}
if((is_pos_inf(value_) && rhs.is_pos_inf(rhs.as_number())) ||
(is_neg_inf(value_) && rhs.is_neg_inf(rhs.as_number())) )
{
return int_adapter::not_a_number();
}
if (is_infinity())
{
return *this;
}
if (rhs.is_pos_inf(rhs.as_number()))
{
return int_adapter::neg_infinity();
}
if (rhs.is_neg_inf(rhs.as_number()))
{
return int_adapter::pos_infinity();
}
}
return int_adapter<int_type>(value_ - static_cast<int_type>(rhs.as_number()));
}
int_adapter operator-(const int_type rhs) const
{
if(is_special())
{
if (is_nan())
{
return int_adapter<int_type>(not_a_number());
}
if (is_infinity())
{
return *this;
}
}
return int_adapter<int_type>(value_ - rhs);
}
// should templatize this to be consistant with op +-
int_adapter operator*(const int_adapter& rhs)const
{
if(this->is_special() || rhs.is_special())
{
return mult_div_specials(rhs);
}
return int_adapter<int_type>(value_ * rhs.value_);
}
/*! Provided for cases when automatic conversion from
* 'int' to 'int_adapter' causes incorrect results. */
int_adapter operator*(const int rhs) const
{
if(is_special())
{
return mult_div_specials(rhs);
}
return int_adapter<int_type>(value_ * rhs);
}
// should templatize this to be consistant with op +-
int_adapter operator/(const int_adapter& rhs)const
{
if(this->is_special() || rhs.is_special())
{
if(is_infinity() && rhs.is_infinity())
{
return int_adapter<int_type>(not_a_number());
}
if(rhs != 0)
{
return mult_div_specials(rhs);
}
else { // let divide by zero blow itself up
return int_adapter<int_type>(value_ / rhs.value_);
}
}
return int_adapter<int_type>(value_ / rhs.value_);
}
/*! Provided for cases when automatic conversion from
* 'int' to 'int_adapter' causes incorrect results. */
int_adapter operator/(const int rhs) const
{
if(is_special() && rhs != 0)
{
return mult_div_specials(rhs);
}
return int_adapter<int_type>(value_ / rhs);
}
// should templatize this to be consistant with op +-
int_adapter operator%(const int_adapter& rhs)const
{
if(this->is_special() || rhs.is_special())
{
if(is_infinity() && rhs.is_infinity())
{
return int_adapter<int_type>(not_a_number());
}
if(rhs != 0)
{
return mult_div_specials(rhs);
}
else { // let divide by zero blow itself up
return int_adapter<int_type>(value_ % rhs.value_);
}
}
return int_adapter<int_type>(value_ % rhs.value_);
}
/*! Provided for cases when automatic conversion from
* 'int' to 'int_adapter' causes incorrect results. */
int_adapter operator%(const int rhs) const
{
if(is_special() && rhs != 0)
{
return mult_div_specials(rhs);
}
return int_adapter<int_type>(value_ % rhs);
}
private:
int_type value_;
//! returns -1, 0, 1, or 2 if 'this' is <, ==, >, or 'nan comparison' rhs
int compare(const int_adapter& rhs)const
{
if(this->is_special() || rhs.is_special())
{
if(this->is_nan() || rhs.is_nan()) {
if(this->is_nan() && rhs.is_nan()) {
return 0; // equal
}
else {
return 2; // nan
}
}
if((is_neg_inf(value_) && !is_neg_inf(rhs.value_)) ||
(is_pos_inf(rhs.value_) && !is_pos_inf(value_)) )
{
return -1; // less than
}
if((is_pos_inf(value_) && !is_pos_inf(rhs.value_)) ||
(is_neg_inf(rhs.value_) && !is_neg_inf(value_)) ) {
return 1; // greater than
}
}
if(value_ < rhs.value_) return -1;
if(value_ > rhs.value_) return 1;
// implied-> if(value_ == rhs.value_)
return 0;
}
/* When multiplying and dividing with at least 1 special value
* very simmilar rules apply. In those cases where the rules
* are different, they are handled in the respective operator
* function. */
//! Assumes at least 'this' or 'rhs' is a special value
int_adapter mult_div_specials(const int_adapter& rhs)const
{
int min_value;
// quiets compiler warnings
bool is_signed = std::numeric_limits<int_type>::is_signed;
if(is_signed) {
min_value = 0;
}
else {
min_value = 1;// there is no zero with unsigned
}
if(this->is_nan() || rhs.is_nan()) {
return int_adapter<int_type>(not_a_number());
}
if((*this > 0 && rhs > 0) || (*this < min_value && rhs < min_value)) {
return int_adapter<int_type>(pos_infinity());
}
if((*this > 0 && rhs < min_value) || (*this < min_value && rhs > 0)) {
return int_adapter<int_type>(neg_infinity());
}
//implied -> if(this->value_ == 0 || rhs.value_ == 0)
return int_adapter<int_type>(not_a_number());
}
/* Overloaded function necessary because of special
* situation where int_adapter is instantiated with
* 'unsigned' and func is called with negative int.
* It would produce incorrect results since 'unsigned'
* wraps around when initialized with a negative value */
//! Assumes 'this' is a special value
int_adapter mult_div_specials(const int& rhs) const
{
int min_value;
// quiets compiler warnings
bool is_signed = std::numeric_limits<int_type>::is_signed;
if(is_signed) {
min_value = 0;
}
else {
min_value = 1;// there is no zero with unsigned
}
if(this->is_nan()) {
return int_adapter<int_type>(not_a_number());
}
if((*this > 0 && rhs > 0) || (*this < min_value && rhs < 0)) {
return int_adapter<int_type>(pos_infinity());
}
if((*this > 0 && rhs < 0) || (*this < min_value && rhs > 0)) {
return int_adapter<int_type>(neg_infinity());
}
//implied -> if(this->value_ == 0 || rhs.value_ == 0)
return int_adapter<int_type>(not_a_number());
}
};
#ifndef BOOST_DATE_TIME_NO_LOCALE
/*! Expected output is either a numeric representation
* or a special values representation.<BR>
* Ex. "12", "+infinity", "not-a-number", etc. */
//template<class charT = char, class traits = std::traits<charT>, typename int_type>
template<class charT, class traits, typename int_type>
inline
std::basic_ostream<charT, traits>&
operator<<(std::basic_ostream<charT, traits>& os, const int_adapter<int_type>& ia)
{
if(ia.is_special()) {
// switch copied from date_names_put.hpp
switch(ia.as_special())
{
case not_a_date_time:
os << "not-a-number";
break;
case pos_infin:
os << "+infinity";
break;
case neg_infin:
os << "-infinity";
break;
default:
os << "";
}
}
else {
os << ia.as_number();
}
return os;
}
#endif
} } //namespace date_time
#endif

View File

@@ -0,0 +1,303 @@
#ifndef ISO_FORMAT_HPP___
#define ISO_FORMAT_HPP___
/* Copyright (c) 2002,2003 CrystalClear Software, Inc.
* Use, modification and distribution is subject to the
* Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
* Author: Jeff Garland, Bart Garst
* $Date$
*/
#include "boost/date_time/parse_format_base.hpp"
namespace boost {
namespace date_time {
//! Class to provide common iso formatting spec
template<class charT>
class iso_format_base {
public:
//! Describe month format -- its an integer in iso format
static month_format_spec month_format()
{
return month_as_integer;
}
//! String used printed is date is invalid
static const charT* not_a_date()
{
return "not-a-date-time";
}
//! String used to for positive infinity value
static const charT* pos_infinity()
{
return "+infinity";
}
//! String used to for positive infinity value
static const charT* neg_infinity()
{
return "-infinity";
}
//! ISO char for a year -- used in durations
static charT year_sep_char()
{
return 'Y';
}
//! ISO char for a month
static charT month_sep_char()
{
return '-';
}
//! ISO char for a day
static charT day_sep_char()
{
return '-';
}
//! char for minute
static charT hour_sep_char()
{
return ':';
}
//! char for minute
static charT minute_sep_char()
{
return ':';
}
//! char for second
static charT second_sep_char()
{
return ':';
}
//! ISO char for a period
static charT period_start_char()
{
return 'P';
}
//! Used in time in mixed strings to set start of time
static charT time_start_char()
{
return 'T';
}
//! Used in mixed strings to identify start of a week number
static charT week_start_char()
{
return 'W';
}
//! Separators for periods
static charT period_sep_char()
{
return '/';
}
//! Separator for hh:mm:ss
static charT time_sep_char()
{
return ':';
}
//! Preferred Separator for hh:mm:ss,decimal_fraction
static charT fractional_time_sep_char()
{
return ',';
}
static bool is_component_sep(charT sep)
{
switch(sep) {
case 'H':
case 'M':
case 'S':
case 'W':
case 'T':
case 'Y':
case 'D':return true;
default:
return false;
}
}
static bool is_fractional_time_sep(charT sep)
{
switch(sep) {
case ',':
case '.': return true;
default: return false;
}
}
static bool is_timezone_sep(charT sep)
{
switch(sep) {
case '+':
case '-': return true;
default: return false;
}
}
static charT element_sep_char()
{
return '-';
}
};
#ifndef BOOST_NO_STD_WSTRING
//! Class to provide common iso formatting spec
template<>
class iso_format_base<wchar_t> {
public:
//! Describe month format -- its an integer in iso format
static month_format_spec month_format()
{
return month_as_integer;
}
//! String used printed is date is invalid
static const wchar_t* not_a_date()
{
return L"not-a-date-time";
}
//! String used to for positive infinity value
static const wchar_t* pos_infinity()
{
return L"+infinity";
}
//! String used to for positive infinity value
static const wchar_t* neg_infinity()
{
return L"-infinity";
}
//! ISO char for a year -- used in durations
static wchar_t year_sep_char()
{
return 'Y';
}
//! ISO char for a month
static wchar_t month_sep_char()
{
return '-';
}
//! ISO char for a day
static wchar_t day_sep_char()
{
return '-';
}
//! char for minute
static wchar_t hour_sep_char()
{
return ':';
}
//! char for minute
static wchar_t minute_sep_char()
{
return ':';
}
//! char for second
static wchar_t second_sep_char()
{
return ':';
}
//! ISO char for a period
static wchar_t period_start_char()
{
return 'P';
}
//! Used in time in mixed strings to set start of time
static wchar_t time_start_char()
{
return 'T';
}
//! Used in mixed strings to identify start of a week number
static wchar_t week_start_char()
{
return 'W';
}
//! Separators for periods
static wchar_t period_sep_char()
{
return '/';
}
//! Separator for hh:mm:ss
static wchar_t time_sep_char()
{
return ':';
}
//! Preferred Separator for hh:mm:ss,decimal_fraction
static wchar_t fractional_time_sep_char()
{
return ',';
}
static bool is_component_sep(wchar_t sep)
{
switch(sep) {
case 'H':
case 'M':
case 'S':
case 'W':
case 'T':
case 'Y':
case 'D':return true;
default:
return false;
}
}
static bool is_fractional_time_sep(wchar_t sep)
{
switch(sep) {
case ',':
case '.': return true;
default: return false;
}
}
static bool is_timezone_sep(wchar_t sep)
{
switch(sep) {
case '+':
case '-': return true;
default: return false;
}
}
static wchar_t element_sep_char()
{
return '-';
}
};
#endif // BOOST_NO_STD_WSTRING
//! Format description for iso normal YYYYMMDD
template<class charT>
class iso_format : public iso_format_base<charT> {
public:
//! The ios standard format doesn't use char separators
static bool has_date_sep_chars()
{
return false;
}
};
//! Extended format uses seperators YYYY-MM-DD
template<class charT>
class iso_extended_format : public iso_format_base<charT> {
public:
//! Extended format needs char separators
static bool has_date_sep_chars()
{
return true;
}
};
} } //namespace date_time
#endif

View File

@@ -0,0 +1,31 @@
#ifndef DATE_TIME_LOCALE_CONFIG_HPP___
#define DATE_TIME_LOCALE_CONFIG_HPP___
/* Copyright (c) 2002-2006 CrystalClear Software, Inc.
* Use, modification and distribution is subject to the
* Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
* Author: Jeff Garland
* $Date$
*/
// This file configures whether the library will support locales and hence
// iostream based i/o. Even if a compiler has some support for locales,
// any failure to be compatible gets the compiler on the exclusion list.
//
// At the moment this is defined for MSVC 6 and any compiler that
// defines BOOST_NO_STD_LOCALE (gcc 2.95.x)
#include "boost/config.hpp" //sets BOOST_NO_STD_LOCALE
#include "boost/detail/workaround.hpp"
//This file basically becomes a noop if locales are not properly supported
#if (defined(BOOST_NO_STD_LOCALE) \
|| (BOOST_WORKAROUND( BOOST_MSVC, < 1300)) \
|| (BOOST_WORKAROUND( __BORLANDC__, BOOST_TESTED_AT( 0x581 )) ) )
#define BOOST_DATE_TIME_NO_LOCALE
#endif
#endif

View File

@@ -0,0 +1,127 @@
#ifndef DATE_TIME_HIGHRES_TIME_CLOCK_HPP___
#define DATE_TIME_HIGHRES_TIME_CLOCK_HPP___
/* Copyright (c) 2002,2003,2005 CrystalClear Software, Inc.
* Use, modification and distribution is subject to the
* Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
* Author: Jeff Garland, Bart Garst
* $Date$
*/
/*! @file microsec_time_clock.hpp
This file contains a high resolution time clock implementation.
*/
#include <boost/cstdint.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/date_time/compiler_config.hpp>
#include <boost/date_time/c_time.hpp>
#include <boost/date_time/time_clock.hpp>
#include <boost/date_time/filetime_functions.hpp>
#ifdef BOOST_DATE_TIME_HAS_HIGH_PRECISION_CLOCK
namespace boost {
namespace date_time {
//! A clock providing microsecond level resolution
/*! A high precision clock that measures the local time
* at a resolution up to microseconds and adjusts to the
* resolution of the time system. For example, for the
* a library configuration with nano second resolution,
* the last 3 places of the fractional seconds will always
* be 000 since there are 1000 nano-seconds in a micro second.
*/
template<class time_type>
class microsec_clock
{
private:
//! Type for the function used to convert time_t to tm
typedef std::tm* (*time_converter)(const std::time_t*, std::tm*);
public:
typedef typename time_type::date_type date_type;
typedef typename time_type::time_duration_type time_duration_type;
typedef typename time_duration_type::rep_type resolution_traits_type;
//! return a local time object for the given zone, based on computer clock
//JKG -- looks like we could rewrite this against universal_time
template<class time_zone_type>
static time_type local_time(shared_ptr<time_zone_type> tz_ptr)
{
typedef typename time_type::utc_time_type utc_time_type;
typedef second_clock<utc_time_type> second_clock;
// we'll need to know the utc_offset this machine has
// in order to get a utc_time_type set to utc
utc_time_type utc_time = second_clock::universal_time();
time_duration_type utc_offset = second_clock::local_time() - utc_time;
// use micro clock to get a local time with sub seconds
// and adjust it to get a true utc time reading with sub seconds
utc_time = microsec_clock<utc_time_type>::local_time() - utc_offset;
return time_type(utc_time, tz_ptr);
}
//! Returns the local time based on computer clock settings
static time_type local_time()
{
return create_time(&c_time::localtime);
}
//! Returns the UTC time based on computer settings
static time_type universal_time()
{
return create_time(&c_time::gmtime);
}
private:
static time_type create_time(time_converter converter)
{
#ifdef BOOST_HAS_GETTIMEOFDAY
timeval tv;
gettimeofday(&tv, 0); //gettimeofday does not support TZ adjust on Linux.
std::time_t t = tv.tv_sec;
boost::uint32_t sub_sec = tv.tv_usec;
#elif defined(BOOST_HAS_FTIME)
winapi::file_time ft;
winapi::get_system_time_as_file_time(ft);
uint64_t micros = winapi::file_time_to_microseconds(ft); // it will not wrap, since ft is the current time
// and cannot be before 1970-Jan-01
std::time_t t = static_cast<std::time_t>(micros / 1000000UL); // seconds since epoch
// microseconds -- static casts suppress warnings
boost::uint32_t sub_sec = static_cast<boost::uint32_t>(micros % 1000000UL);
#else
#error Internal Boost.DateTime error: BOOST_DATE_TIME_HAS_HIGH_PRECISION_CLOCK is defined, however neither gettimeofday nor FILETIME support is detected.
#endif
std::tm curr;
std::tm* curr_ptr = converter(&t, &curr);
date_type d(static_cast< typename date_type::year_type::value_type >(curr_ptr->tm_year + 1900),
static_cast< typename date_type::month_type::value_type >(curr_ptr->tm_mon + 1),
static_cast< typename date_type::day_type::value_type >(curr_ptr->tm_mday));
//The following line will adjust the fractional second tick in terms
//of the current time system. For example, if the time system
//doesn't support fractional seconds then res_adjust returns 0
//and all the fractional seconds return 0.
int adjust = static_cast< int >(resolution_traits_type::res_adjust() / 1000000);
time_duration_type td(static_cast< typename time_duration_type::hour_type >(curr_ptr->tm_hour),
static_cast< typename time_duration_type::min_type >(curr_ptr->tm_min),
static_cast< typename time_duration_type::sec_type >(curr_ptr->tm_sec),
sub_sec * adjust);
return time_type(d,td);
}
};
} } //namespace date_time
#endif //BOOST_DATE_TIME_HAS_HIGH_PRECISION_CLOCK
#endif

View File

@@ -0,0 +1,29 @@
#ifndef DATE_TIME_PARSE_FORMAT_BASE__
#define DATE_TIME_PARSE_FORMAT_BASE__
/* Copyright (c) 2002,2003 CrystalClear Software, Inc.
* Use, modification and distribution is subject to the
* Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
* Author: Jeff Garland
* $Date$
*/
namespace boost {
namespace date_time {
//! Enum for distinguishing parsing and formatting options
enum month_format_spec {month_as_integer, month_as_short_string,
month_as_long_string};
//! Enum for distinguishing the order of Month, Day, & Year.
/*! Enum for distinguishing the order in which Month, Day, & Year
* will appear in a date string */
enum ymd_order_spec {ymd_order_iso, //order is year-month-day
ymd_order_dmy, //day-month-year
ymd_order_us}; //order is month-day-year
} }//namespace date_time
#endif

View File

@@ -0,0 +1,377 @@
#ifndef DATE_TIME_PERIOD_HPP___
#define DATE_TIME_PERIOD_HPP___
/* Copyright (c) 2002,2003 CrystalClear Software, Inc.
* Use, modification and distribution is subject to the
* Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
* Author: Jeff Garland, Bart Garst
* $Date$
*/
/*! \file period.hpp
This file contain the implementation of the period abstraction. This is
basically the same idea as a range. Although this class is intended for
use in the time library, it is pretty close to general enough for other
numeric uses.
*/
#include "boost/operators.hpp"
namespace boost {
namespace date_time {
//!Provides generalized period type useful in date-time systems
/*!This template uses a class to represent a time point within the period
and another class to represent a duration. As a result, this class is
not appropriate for use when the number and duration representation
are the same (eg: in the regular number domain).
A period can be specified by providing either the begining point and
a duration or the begining point and the end point( end is NOT part
of the period but 1 unit past it. A period will be "invalid" if either
end_point <= begin_point or the given duration is <= 0. Any valid period
will return false for is_null().
Zero length periods are also considered invalid. Zero length periods are
periods where the begining and end points are the same, or, the given
duration is zero. For a zero length period, the last point will be one
unit less than the begining point.
In the case that the begin and last are the same, the period has a
length of one unit.
The best way to handle periods is usually to provide a begining point and
a duration. So, day1 + 7 days is a week period which includes all of the
first day and 6 more days (eg: Sun to Sat).
*/
template<class point_rep, class duration_rep>
class period : private
boost::less_than_comparable<period<point_rep, duration_rep>
, boost::equality_comparable< period<point_rep, duration_rep>
> >
{
public:
typedef point_rep point_type;
typedef duration_rep duration_type;
period(point_rep first_point, point_rep end_point);
period(point_rep first_point, duration_rep len);
point_rep begin() const;
point_rep end() const;
point_rep last() const;
duration_rep length() const;
bool is_null() const;
bool operator==(const period& rhs) const;
bool operator<(const period& rhs) const;
void shift(const duration_rep& d);
void expand(const duration_rep& d);
bool contains(const point_rep& point) const;
bool contains(const period& other) const;
bool intersects(const period& other) const;
bool is_adjacent(const period& other) const;
bool is_before(const point_rep& point) const;
bool is_after(const point_rep& point) const;
period intersection(const period& other) const;
period merge(const period& other) const;
period span(const period& other) const;
private:
point_rep begin_;
point_rep last_;
};
//! create a period from begin to last eg: [begin,end)
/*! If end <= begin then the period will be invalid
*/
template<class point_rep, class duration_rep>
inline
period<point_rep,duration_rep>::period(point_rep first_point,
point_rep end_point) :
begin_(first_point),
last_(end_point - duration_rep::unit())
{}
//! create a period as [begin, begin+len)
/*! If len is <= 0 then the period will be invalid
*/
template<class point_rep, class duration_rep>
inline
period<point_rep,duration_rep>::period(point_rep first_point, duration_rep len) :
begin_(first_point),
last_(first_point + len-duration_rep::unit())
{ }
//! Return the first element in the period
template<class point_rep, class duration_rep>
inline
point_rep period<point_rep,duration_rep>::begin() const
{
return begin_;
}
//! Return one past the last element
template<class point_rep, class duration_rep>
inline
point_rep period<point_rep,duration_rep>::end() const
{
return last_ + duration_rep::unit();
}
//! Return the last item in the period
template<class point_rep, class duration_rep>
inline
point_rep period<point_rep,duration_rep>::last() const
{
return last_;
}
//! True if period is ill formed (length is zero or less)
template<class point_rep, class duration_rep>
inline
bool period<point_rep,duration_rep>::is_null() const
{
return end() <= begin_;
}
//! Return the length of the period
template<class point_rep, class duration_rep>
inline
duration_rep period<point_rep,duration_rep>::length() const
{
if(last_ < begin_){ // invalid period
return last_+duration_rep::unit() - begin_;
}
else{
return end() - begin_; // normal case
}
}
//! Equality operator
template<class point_rep, class duration_rep>
inline
bool period<point_rep,duration_rep>::operator==(const period& rhs) const
{
return ((begin_ == rhs.begin_) &&
(last_ == rhs.last_));
}
//! Strict as defined by rhs.last <= lhs.last
template<class point_rep, class duration_rep>
inline
bool period<point_rep,duration_rep>::operator<(const period& rhs) const
{
return (last_ < rhs.begin_);
}
//! Shift the start and end by the specified amount
template<class point_rep, class duration_rep>
inline
void period<point_rep,duration_rep>::shift(const duration_rep& d)
{
begin_ = begin_ + d;
last_ = last_ + d;
}
/** Expands the size of the period by the duration on both ends.
*
*So before expand
*@code
*
* [-------]
* ^ ^ ^ ^ ^ ^ ^
* 1 2 3 4 5 6 7
*
*@endcode
* After expand(2)
*@code
*
* [----------------------]
* ^ ^ ^ ^ ^ ^ ^
* 1 2 3 4 5 6 7
*
*@endcode
*/
template<class point_rep, class duration_rep>
inline
void period<point_rep,duration_rep>::expand(const duration_rep& d)
{
begin_ = begin_ - d;
last_ = last_ + d;
}
//! True if the point is inside the period, zero length periods contain no points
template<class point_rep, class duration_rep>
inline
bool period<point_rep,duration_rep>::contains(const point_rep& point) const
{
return ((point >= begin_) &&
(point <= last_));
}
//! True if this period fully contains (or equals) the other period
template<class point_rep, class duration_rep>
inline
bool period<point_rep,duration_rep>::contains(const period<point_rep,duration_rep>& other) const
{
return ((begin_ <= other.begin_) && (last_ >= other.last_));
}
//! True if periods are next to each other without a gap.
/* In the example below, p1 and p2 are adjacent, but p3 is not adjacent
* with either of p1 or p2.
*@code
* [-p1-)
* [-p2-)
* [-p3-)
*@endcode
*/
template<class point_rep, class duration_rep>
inline
bool
period<point_rep,duration_rep>::is_adjacent(const period<point_rep,duration_rep>& other) const
{
return (other.begin() == end() ||
begin_ == other.end());
}
//! True if all of the period is prior or t < start
/* In the example below only point 1 would evaluate to true.
*@code
* [---------])
* ^ ^ ^ ^ ^
* 1 2 3 4 5
*
*@endcode
*/
template<class point_rep, class duration_rep>
inline
bool
period<point_rep,duration_rep>::is_after(const point_rep& t) const
{
if (is_null())
{
return false; //null period isn't after
}
return t < begin_;
}
//! True if all of the period is prior to the passed point or end <= t
/* In the example below points 4 and 5 return true.
*@code
* [---------])
* ^ ^ ^ ^ ^
* 1 2 3 4 5
*
*@endcode
*/
template<class point_rep, class duration_rep>
inline
bool
period<point_rep,duration_rep>::is_before(const point_rep& t) const
{
if (is_null())
{
return false; //null period isn't before anything
}
return last_ < t;
}
//! True if the periods overlap in any way
/* In the example below p1 intersects with p2, p4, and p6.
*@code
* [---p1---)
* [---p2---)
* [---p3---)
* [---p4---)
* [-p5-)
* [-p6-)
*@endcode
*/
template<class point_rep, class duration_rep>
inline
bool period<point_rep,duration_rep>::intersects(const period<point_rep,duration_rep>& other) const
{
return ( contains(other.begin_) ||
other.contains(begin_) ||
((other.begin_ < begin_) && (other.last_ >= begin_)));
}
//! Returns the period of intersection or invalid range no intersection
template<class point_rep, class duration_rep>
inline
period<point_rep,duration_rep>
period<point_rep,duration_rep>::intersection(const period<point_rep,duration_rep>& other) const
{
if (begin_ > other.begin_) {
if (last_ <= other.last_) { //case2
return *this;
}
//case 1
return period<point_rep,duration_rep>(begin_, other.end());
}
else {
if (last_ <= other.last_) { //case3
return period<point_rep,duration_rep>(other.begin_, this->end());
}
//case4
return other;
}
//unreachable
}
//! Returns the union of intersecting periods -- or null period
/*!
*/
template<class point_rep, class duration_rep>
inline
period<point_rep,duration_rep>
period<point_rep,duration_rep>::merge(const period<point_rep,duration_rep>& other) const
{
if (this->intersects(other)) {
if (begin_ < other.begin_) {
return period<point_rep,duration_rep>(begin_, last_ > other.last_ ? this->end() : other.end());
}
return period<point_rep,duration_rep>(other.begin_, last_ > other.last_ ? this->end() : other.end());
}
return period<point_rep,duration_rep>(begin_,begin_); // no intersect return null
}
//! Combine two periods with earliest start and latest end.
/*! Combines two periods and any gap between them such that
* start = min(p1.start, p2.start)
* end = max(p1.end , p2.end)
*@code
* [---p1---)
* [---p2---)
* result:
* [-----------p3----------)
*@endcode
*/
template<class point_rep, class duration_rep>
inline
period<point_rep,duration_rep>
period<point_rep,duration_rep>::span(const period<point_rep,duration_rep>& other) const
{
point_rep start((begin_ < other.begin_) ? begin() : other.begin());
point_rep newend((last_ < other.last_) ? other.end() : this->end());
return period<point_rep,duration_rep>(start, newend);
}
} } //namespace date_time
#endif

View File

@@ -0,0 +1,102 @@
#ifndef POSIX_TIME_CONVERSION_HPP___
#define POSIX_TIME_CONVERSION_HPP___
/* Copyright (c) 2002-2005 CrystalClear Software, Inc.
* Use, modification and distribution is subject to the
* Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
* Author: Jeff Garland, Bart Garst
* $Date$
*/
#include <cstring>
#include <boost/date_time/posix_time/ptime.hpp>
#include <boost/date_time/posix_time/posix_time_duration.hpp>
#include <boost/date_time/filetime_functions.hpp>
#include <boost/date_time/c_time.hpp>
#include <boost/date_time/time_resolution_traits.hpp> // absolute_value
#include <boost/date_time/gregorian/conversion.hpp>
namespace boost {
namespace posix_time {
//! Function that converts a time_t into a ptime.
inline
ptime from_time_t(std::time_t t)
{
ptime start(gregorian::date(1970,1,1));
return start + seconds(static_cast<long>(t));
}
//! Function that converts a ptime into a time_t
inline
std::time_t to_time_t(ptime pt)
{
time_duration dur = pt - ptime(gregorian::date(1970,1,1));
return std::time_t(dur.total_seconds());
}
//! Convert a time to a tm structure truncating any fractional seconds
inline
std::tm to_tm(const boost::posix_time::ptime& t) {
std::tm timetm = boost::gregorian::to_tm(t.date());
boost::posix_time::time_duration td = t.time_of_day();
timetm.tm_hour = td.hours();
timetm.tm_min = td.minutes();
timetm.tm_sec = td.seconds();
timetm.tm_isdst = -1; // -1 used when dst info is unknown
return timetm;
}
//! Convert a time_duration to a tm structure truncating any fractional seconds and zeroing fields for date components
inline
std::tm to_tm(const boost::posix_time::time_duration& td) {
std::tm timetm;
std::memset(&timetm, 0, sizeof(timetm));
timetm.tm_hour = date_time::absolute_value(td.hours());
timetm.tm_min = date_time::absolute_value(td.minutes());
timetm.tm_sec = date_time::absolute_value(td.seconds());
timetm.tm_isdst = -1; // -1 used when dst info is unknown
return timetm;
}
//! Convert a tm struct to a ptime ignoring is_dst flag
inline
ptime ptime_from_tm(const std::tm& timetm) {
boost::gregorian::date d = boost::gregorian::date_from_tm(timetm);
return ptime(d, time_duration(timetm.tm_hour, timetm.tm_min, timetm.tm_sec));
}
#if defined(BOOST_HAS_FTIME)
//! Function to create a time object from an initialized FILETIME struct.
/*! Function to create a time object from an initialized FILETIME struct.
* A FILETIME struct holds 100-nanosecond units (0.0000001). When
* built with microsecond resolution the FILETIME's sub second value
* will be truncated. Nanosecond resolution has no truncation.
*
* \note FILETIME is part of the Win32 API, so it is not portable to non-windows
* platforms.
*
* \note The function is templated on the FILETIME type, so that
* it can be used with both native FILETIME and the ad-hoc
* boost::date_time::winapi::file_time type.
*/
template< typename TimeT, typename FileTimeT >
inline
TimeT from_ftime(const FileTimeT& ft)
{
return boost::date_time::time_from_ftime<TimeT>(ft);
}
#endif // BOOST_HAS_FTIME
} } //namespace boost::posix_time
#endif

View File

@@ -0,0 +1,114 @@
#ifndef DATE_DURATION_OPERATORS_HPP___
#define DATE_DURATION_OPERATORS_HPP___
/* Copyright (c) 2004 CrystalClear Software, Inc.
* Subject to the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or
* http://www.boost.org/LICENSE_1_0.txt)
* Author: Jeff Garland, Bart Garst
* $Date$
*/
#include "boost/date_time/gregorian/greg_duration_types.hpp"
#include "boost/date_time/posix_time/ptime.hpp"
namespace boost {
namespace posix_time {
/*!@file date_duration_operators.hpp Operators for ptime and
* optional gregorian types. Operators use snap-to-end-of-month behavior.
* Further details on this behavior can be found in reference for
* date_time/date_duration_types.hpp and documentation for
* month and year iterators.
*/
/*! Adds a months object and a ptime. Result will be same
* day-of-month as ptime unless original day was the last day of month.
* see date_time::months_duration for more details */
inline
ptime
operator+(const ptime& t, const boost::gregorian::months& m)
{
return t + m.get_offset(t.date());
}
/*! Adds a months object to a ptime. Result will be same
* day-of-month as ptime unless original day was the last day of month.
* see date_time::months_duration for more details */
inline
ptime
operator+=(ptime& t, const boost::gregorian::months& m)
{
// get_neg_offset returns a negative duration, so we add
return t += m.get_offset(t.date());
}
/*! Subtracts a months object and a ptime. Result will be same
* day-of-month as ptime unless original day was the last day of month.
* see date_time::months_duration for more details */
inline
ptime
operator-(const ptime& t, const boost::gregorian::months& m)
{
// get_neg_offset returns a negative duration, so we add
return t + m.get_neg_offset(t.date());
}
/*! Subtracts a months object from a ptime. Result will be same
* day-of-month as ptime unless original day was the last day of month.
* see date_time::months_duration for more details */
inline
ptime
operator-=(ptime& t, const boost::gregorian::months& m)
{
return t += m.get_neg_offset(t.date());
}
// ptime & years
/*! Adds a years object and a ptime. Result will be same
* month and day-of-month as ptime unless original day was the
* last day of month. see date_time::years_duration for more details */
inline
ptime
operator+(const ptime& t, const boost::gregorian::years& y)
{
return t + y.get_offset(t.date());
}
/*! Adds a years object to a ptime. Result will be same
* month and day-of-month as ptime unless original day was the
* last day of month. see date_time::years_duration for more details */
inline
ptime
operator+=(ptime& t, const boost::gregorian::years& y)
{
return t += y.get_offset(t.date());
}
/*! Subtracts a years object and a ptime. Result will be same
* month and day-of-month as ptime unless original day was the
* last day of month. see date_time::years_duration for more details */
inline
ptime
operator-(const ptime& t, const boost::gregorian::years& y)
{
// get_neg_offset returns a negative duration, so we add
return t + y.get_neg_offset(t.date());
}
/*! Subtracts a years object from a ptime. Result will be same
* month and day-of-month as ptime unless original day was the
* last day of month. see date_time::years_duration for more details */
inline
ptime
operator-=(ptime& t, const boost::gregorian::years& y)
{
// get_neg_offset returns a negative duration, so we add
return t += y.get_neg_offset(t.date());
}
}} // namespaces
#endif // DATE_DURATION_OPERATORS_HPP___

View File

@@ -0,0 +1,178 @@
#ifndef POSIX_TIME_CONFIG_HPP___
#define POSIX_TIME_CONFIG_HPP___
/* Copyright (c) 2002,2003,2005 CrystalClear Software, Inc.
* Use, modification and distribution is subject to the
* Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
* Author: Jeff Garland, Bart Garst
* $Date$
*/
#include <cstdlib> //for MCW 7.2 std::abs(long long)
#include <boost/limits.hpp>
#include <boost/cstdint.hpp>
#include <boost/config/no_tr1/cmath.hpp>
#include <boost/date_time/time_duration.hpp>
#include <boost/date_time/time_resolution_traits.hpp>
#include <boost/date_time/gregorian/gregorian_types.hpp>
#include <boost/date_time/wrapping_int.hpp>
#include <boost/date_time/compiler_config.hpp>
namespace boost {
namespace posix_time {
//Remove the following line if you want 64 bit millisecond resolution time
//#define BOOST_GDTL_POSIX_TIME_STD_CONFIG
#ifdef BOOST_DATE_TIME_POSIX_TIME_STD_CONFIG
// set up conditional test compilations
#define BOOST_DATE_TIME_HAS_MILLISECONDS
#define BOOST_DATE_TIME_HAS_MICROSECONDS
#define BOOST_DATE_TIME_HAS_NANOSECONDS
typedef date_time::time_resolution_traits<boost::date_time::time_resolution_traits_adapted64_impl, boost::date_time::nano,
1000000000, 9 > time_res_traits;
#else
// set up conditional test compilations
#define BOOST_DATE_TIME_HAS_MILLISECONDS
#define BOOST_DATE_TIME_HAS_MICROSECONDS
#undef BOOST_DATE_TIME_HAS_NANOSECONDS
typedef date_time::time_resolution_traits<
boost::date_time::time_resolution_traits_adapted64_impl, boost::date_time::micro,
1000000, 6 > time_res_traits;
// #undef BOOST_DATE_TIME_HAS_MILLISECONDS
// #undef BOOST_DATE_TIME_HAS_MICROSECONDS
// #undef BOOST_DATE_TIME_HAS_NANOSECONDS
// typedef date_time::time_resolution_traits<boost::int64_t, boost::date_time::tenth,
// 10, 0 > time_res_traits;
#endif
//! Base time duration type
/*! \ingroup time_basics
*/
class time_duration :
public date_time::time_duration<time_duration, time_res_traits>
{
public:
typedef time_res_traits rep_type;
typedef time_res_traits::day_type day_type;
typedef time_res_traits::hour_type hour_type;
typedef time_res_traits::min_type min_type;
typedef time_res_traits::sec_type sec_type;
typedef time_res_traits::fractional_seconds_type fractional_seconds_type;
typedef time_res_traits::tick_type tick_type;
typedef time_res_traits::impl_type impl_type;
time_duration(hour_type hour,
min_type min,
sec_type sec,
fractional_seconds_type fs=0) :
date_time::time_duration<time_duration, time_res_traits>(hour,min,sec,fs)
{}
time_duration() :
date_time::time_duration<time_duration, time_res_traits>(0,0,0)
{}
//! Construct from special_values
time_duration(boost::date_time::special_values sv) :
date_time::time_duration<time_duration, time_res_traits>(sv)
{}
//Give duration access to ticks constructor -- hide from users
friend class date_time::time_duration<time_duration, time_res_traits>;
protected:
explicit time_duration(impl_type tick_count) :
date_time::time_duration<time_duration, time_res_traits>(tick_count)
{}
};
#ifdef BOOST_DATE_TIME_POSIX_TIME_STD_CONFIG
//! Simple implementation for the time rep
struct simple_time_rep
{
typedef gregorian::date date_type;
typedef time_duration time_duration_type;
simple_time_rep(date_type d, time_duration_type tod) :
day(d),
time_of_day(tod)
{
// make sure we have sane values for date & time
if(!day.is_special() && !time_of_day.is_special()){
if(time_of_day >= time_duration_type(24,0,0)) {
while(time_of_day >= time_duration_type(24,0,0)) {
day += date_type::duration_type(1);
time_of_day -= time_duration_type(24,0,0);
}
}
else if(time_of_day.is_negative()) {
while(time_of_day.is_negative()) {
day -= date_type::duration_type(1);
time_of_day += time_duration_type(24,0,0);
}
}
}
}
date_type day;
time_duration_type time_of_day;
bool is_special()const
{
return(is_pos_infinity() || is_neg_infinity() || is_not_a_date_time());
}
bool is_pos_infinity()const
{
return(day.is_pos_infinity() || time_of_day.is_pos_infinity());
}
bool is_neg_infinity()const
{
return(day.is_neg_infinity() || time_of_day.is_neg_infinity());
}
bool is_not_a_date_time()const
{
return(day.is_not_a_date() || time_of_day.is_not_a_date_time());
}
};
class posix_time_system_config
{
public:
typedef simple_time_rep time_rep_type;
typedef gregorian::date date_type;
typedef gregorian::date_duration date_duration_type;
typedef time_duration time_duration_type;
typedef time_res_traits::tick_type int_type;
typedef time_res_traits resolution_traits;
#if (defined(BOOST_DATE_TIME_NO_MEMBER_INIT)) //help bad compilers
#else
BOOST_STATIC_CONSTANT(boost::int64_t, tick_per_second = 1000000000);
#endif
};
#else
class millisec_posix_time_system_config
{
public:
typedef boost::int64_t time_rep_type;
//typedef time_res_traits::tick_type time_rep_type;
typedef gregorian::date date_type;
typedef gregorian::date_duration date_duration_type;
typedef time_duration time_duration_type;
typedef time_res_traits::tick_type int_type;
typedef time_res_traits::impl_type impl_type;
typedef time_res_traits resolution_traits;
#if (defined(BOOST_DATE_TIME_NO_MEMBER_INIT)) //help bad compilers
#else
BOOST_STATIC_CONSTANT(boost::int64_t, tick_per_second = 1000000);
#endif
};
#endif
} }//namespace posix_time
#endif

View File

@@ -0,0 +1,82 @@
#ifndef POSIX_TIME_DURATION_HPP___
#define POSIX_TIME_DURATION_HPP___
/* Copyright (c) 2002,2003 CrystalClear Software, Inc.
* Use, modification and distribution is subject to the
* Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
* Author: Jeff Garland
* $Date$
*/
#include "boost/date_time/posix_time/posix_time_config.hpp"
namespace boost {
namespace posix_time {
//! Allows expression of durations as an hour count
/*! \ingroup time_basics
*/
class hours : public time_duration
{
public:
explicit hours(long h) :
time_duration(static_cast<hour_type>(h),0,0)
{}
};
//! Allows expression of durations as a minute count
/*! \ingroup time_basics
*/
class minutes : public time_duration
{
public:
explicit minutes(long m) :
time_duration(0,static_cast<min_type>(m),0)
{}
};
//! Allows expression of durations as a seconds count
/*! \ingroup time_basics
*/
class seconds : public time_duration
{
public:
explicit seconds(long s) :
time_duration(0,0,static_cast<sec_type>(s))
{}
};
//! Allows expression of durations as milli seconds
/*! \ingroup time_basics
*/
typedef date_time::subsecond_duration<time_duration,1000> millisec;
typedef date_time::subsecond_duration<time_duration,1000> milliseconds;
//! Allows expression of durations as micro seconds
/*! \ingroup time_basics
*/
typedef date_time::subsecond_duration<time_duration,1000000> microsec;
typedef date_time::subsecond_duration<time_duration,1000000> microseconds;
//This is probably not needed anymore...
#if defined(BOOST_DATE_TIME_HAS_NANOSECONDS)
//! Allows expression of durations as nano seconds
/*! \ingroup time_basics
*/
typedef date_time::subsecond_duration<time_duration,1000000000> nanosec;
typedef date_time::subsecond_duration<time_duration,1000000000> nanoseconds;
#endif
} }//namespace posix_time
#endif

View File

@@ -0,0 +1,68 @@
#ifndef POSIX_TIME_SYSTEM_HPP___
#define POSIX_TIME_SYSTEM_HPP___
/* Copyright (c) 2002,2003 CrystalClear Software, Inc.
* Use, modification and distribution is subject to the
* Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
* Author: Jeff Garland
* $Date$
*/
#include "boost/date_time/posix_time/posix_time_config.hpp"
#include "boost/date_time/time_system_split.hpp"
#include "boost/date_time/time_system_counted.hpp"
#include "boost/date_time/compiler_config.hpp"
namespace boost {
namespace posix_time {
#ifdef BOOST_DATE_TIME_POSIX_TIME_STD_CONFIG
#if (defined(BOOST_DATE_TIME_NO_MEMBER_INIT)) //help bad compilers
typedef date_time::split_timedate_system<posix_time_system_config, 1000000000> posix_time_system;
#else
typedef date_time::split_timedate_system<posix_time_system_config> posix_time_system;
#endif
#else
typedef date_time::counted_time_rep<millisec_posix_time_system_config> int64_time_rep;
typedef date_time::counted_time_system<int64_time_rep> posix_time_system;
#endif
} }//namespace posix_time
#endif

View File

@@ -0,0 +1,55 @@
/* Copyright (c) 2002,2003 CrystalClear Software, Inc.
* Use, modification and distribution is subject to the
* Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
* Author: Jeff Garland
*/
#ifndef POSIX_TIME_TYPES_HPP___
#define POSIX_TIME_TYPES_HPP___
#include "boost/date_time/time_clock.hpp"
#include "boost/date_time/microsec_time_clock.hpp"
#include "boost/date_time/posix_time/ptime.hpp"
#if defined(BOOST_DATE_TIME_OPTIONAL_GREGORIAN_TYPES)
#include "boost/date_time/posix_time/date_duration_operators.hpp"
#endif
#include "boost/date_time/posix_time/posix_time_duration.hpp"
#include "boost/date_time/posix_time/posix_time_system.hpp"
#include "boost/date_time/posix_time/time_period.hpp"
#include "boost/date_time/time_iterator.hpp"
#include "boost/date_time/dst_rules.hpp"
namespace boost {
//!Defines a non-adjusted time system with nano-second resolution and stable calculation properties
namespace posix_time {
//! Iterator over a defined time duration
/*! \ingroup time_basics
*/
typedef date_time::time_itr<ptime> time_iterator;
//! A time clock that has a resolution of one second
/*! \ingroup time_basics
*/
typedef date_time::second_clock<ptime> second_clock;
#ifdef BOOST_DATE_TIME_HAS_HIGH_PRECISION_CLOCK
//! A time clock that has a resolution of one microsecond
/*! \ingroup time_basics
*/
typedef date_time::microsec_clock<ptime> microsec_clock;
#endif
//! Define a dst null dst rule for the posix_time system
typedef date_time::null_dst_rules<ptime::date_type, time_duration> no_dst;
//! Define US dst rule calculator for the posix_time system
typedef date_time::us_dst_rules<ptime::date_type, time_duration> us_dst;
} } //namespace posix_time
#endif

View File

@@ -0,0 +1,65 @@
#ifndef POSIX_PTIME_HPP___
#define POSIX_PTIME_HPP___
/* Copyright (c) 2002,2003 CrystalClear Software, Inc.
* Use, modification and distribution is subject to the
* Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
* Author: Jeff Garland
* $Date$
*/
#include "boost/date_time/posix_time/posix_time_system.hpp"
#include "boost/date_time/time.hpp"
namespace boost {
namespace posix_time {
//bring special enum values into the namespace
using date_time::special_values;
using date_time::not_special;
using date_time::neg_infin;
using date_time::pos_infin;
using date_time::not_a_date_time;
using date_time::max_date_time;
using date_time::min_date_time;
//! Time type with no timezone or other adjustments
/*! \ingroup time_basics
*/
class ptime : public date_time::base_time<ptime, posix_time_system>
{
public:
typedef posix_time_system time_system_type;
typedef time_system_type::time_rep_type time_rep_type;
typedef time_system_type::time_duration_type time_duration_type;
typedef ptime time_type;
//! Construct with date and offset in day
ptime(gregorian::date d,time_duration_type td) : date_time::base_time<time_type,time_system_type>(d,td)
{}
//! Construct a time at start of the given day (midnight)
explicit ptime(gregorian::date d) : date_time::base_time<time_type,time_system_type>(d,time_duration_type(0,0,0))
{}
//! Copy from time_rep
ptime(const time_rep_type& rhs):
date_time::base_time<time_type,time_system_type>(rhs)
{}
//! Construct from special value
ptime(const special_values sv) : date_time::base_time<time_type,time_system_type>(sv)
{}
#if !defined(DATE_TIME_NO_DEFAULT_CONSTRUCTOR)
// Default constructor constructs to not_a_date_time
ptime() : date_time::base_time<time_type,time_system_type>(gregorian::date(not_a_date_time), time_duration_type(not_a_date_time))
{}
#endif // DATE_TIME_NO_DEFAULT_CONSTRUCTOR
};
} }//namespace posix_time
#endif

View File

@@ -0,0 +1,29 @@
#ifndef POSIX_TIME_PERIOD_HPP___
#define POSIX_TIME_PERIOD_HPP___
/* Copyright (c) 2002,2003 CrystalClear Software, Inc.
* Use, modification and distribution is subject to the
* Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
* Author: Jeff Garland
* $Date$
*/
#include "boost/date_time/period.hpp"
#include "boost/date_time/posix_time/posix_time_duration.hpp"
#include "boost/date_time/posix_time/ptime.hpp"
namespace boost {
namespace posix_time {
//! Time period type
/*! \ingroup time_basics
*/
typedef date_time::period<ptime, time_duration> time_period;
} }//namespace posix_time
#endif

View File

@@ -0,0 +1,25 @@
#ifndef DATE_TIME_SPECIAL_DEFS_HPP__
#define DATE_TIME_SPECIAL_DEFS_HPP__
/* Copyright (c) 2002,2003 CrystalClear Software, Inc.
* Use, modification and distribution is subject to the
* Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
* Author: Jeff Garland
* $Date$
*/
namespace boost {
namespace date_time {
enum special_values {not_a_date_time,
neg_infin, pos_infin,
min_date_time, max_date_time,
not_special, NumSpecialValues};
} } //namespace date_time
#endif

View File

@@ -0,0 +1,193 @@
#ifndef DATE_TIME_TIME_HPP___
#define DATE_TIME_TIME_HPP___
/* Copyright (c) 2002,2003,2005 CrystalClear Software, Inc.
* Use, modification and distribution is subject to the
* Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
* Author: Jeff Garland, Bart Garst
* $Date$
*/
/*! @file time.hpp
This file contains the interface for the time associated classes.
*/
#include <string>
#include <boost/operators.hpp>
#include <boost/date_time/time_defs.hpp>
#include <boost/date_time/special_defs.hpp>
namespace boost {
namespace date_time {
//! Representation of a precise moment in time, including the date.
/*!
This class is a skeleton for the interface of a temporal type
with a resolution that is higher than a day. It is intended that
this class be the base class and that the actual time
class be derived using the BN pattern. In this way, the derived
class can make decisions such as 'should there be a default constructor'
and what should it set its value to, should there be optional constructors
say allowing only an time_durations that generate a time from a clock,etc.
So, in fact multiple time types can be created for a time_system with
different construction policies, and all of them can perform basic
operations by only writing a copy constructor. Finally, compiler
errors are also shorter.
The real behavior of the time class is provided by the time_system
template parameter. This class must provide all the logic
for addition, subtraction, as well as define all the interface
types.
*/
template <class T, class time_system>
class base_time : private
boost::less_than_comparable<T
, boost::equality_comparable<T
> >
{
public:
// A tag for type categorization. Can be used to detect Boost.DateTime time points in generic code.
typedef void _is_boost_date_time_time_point;
typedef T time_type;
typedef typename time_system::time_rep_type time_rep_type;
typedef typename time_system::date_type date_type;
typedef typename time_system::date_duration_type date_duration_type;
typedef typename time_system::time_duration_type time_duration_type;
//typedef typename time_system::hms_type hms_type;
base_time(const date_type& day,
const time_duration_type& td,
dst_flags dst=not_dst) :
time_(time_system::get_time_rep(day, td, dst))
{}
base_time(special_values sv) :
time_(time_system::get_time_rep(sv))
{}
base_time(const time_rep_type& rhs) :
time_(rhs)
{}
date_type date() const
{
return time_system::get_date(time_);
}
time_duration_type time_of_day() const
{
return time_system::get_time_of_day(time_);
}
/*! Optional bool parameter will return time zone as an offset
* (ie "+07:00"). Empty string is returned for classes that do
* not use a time_zone */
std::string zone_name(bool /*as_offset*/=false) const
{
return time_system::zone_name(time_);
}
/*! Optional bool parameter will return time zone as an offset
* (ie "+07:00"). Empty string is returned for classes that do
* not use a time_zone */
std::string zone_abbrev(bool /*as_offset*/=false) const
{
return time_system::zone_name(time_);
}
//! An empty string is returned for classes that do not use a time_zone
std::string zone_as_posix_string() const
{
return std::string();
}
//! check to see if date is not a value
bool is_not_a_date_time() const
{
return time_.is_not_a_date_time();
}
//! check to see if date is one of the infinity values
bool is_infinity() const
{
return (is_pos_infinity() || is_neg_infinity());
}
//! check to see if date is greater than all possible dates
bool is_pos_infinity() const
{
return time_.is_pos_infinity();
}
//! check to see if date is greater than all possible dates
bool is_neg_infinity() const
{
return time_.is_neg_infinity();
}
//! check to see if time is a special value
bool is_special() const
{
return(is_not_a_date_time() || is_infinity());
}
//!Equality operator -- others generated by boost::equality_comparable
bool operator==(const time_type& rhs) const
{
return time_system::is_equal(time_,rhs.time_);
}
//!Equality operator -- others generated by boost::less_than_comparable
bool operator<(const time_type& rhs) const
{
return time_system::is_less(time_,rhs.time_);
}
//! difference between two times
time_duration_type operator-(const time_type& rhs) const
{
return time_system::subtract_times(time_, rhs.time_);
}
//! add date durations
time_type operator+(const date_duration_type& dd) const
{
return time_system::add_days(time_, dd);
}
time_type operator+=(const date_duration_type& dd)
{
time_ = (time_system::get_time_rep(date() + dd, time_of_day()));
return time_type(time_);
}
//! subtract date durations
time_type operator-(const date_duration_type& dd) const
{
return time_system::subtract_days(time_, dd);
}
time_type operator-=(const date_duration_type& dd)
{
time_ = (time_system::get_time_rep(date() - dd, time_of_day()));
return time_type(time_);
}
//! add time durations
time_type operator+(const time_duration_type& td) const
{
return time_type(time_system::add_time_duration(time_, td));
}
time_type operator+=(const time_duration_type& td)
{
time_ = (time_system::get_time_rep(date(), time_of_day() + td));
return time_type(time_);
}
//! subtract time durations
time_type operator-(const time_duration_type& rhs) const
{
return time_system::subtract_time_duration(time_, rhs);
}
time_type operator-=(const time_duration_type& td)
{
time_ = (time_system::get_time_rep(date(), time_of_day() - td));
return time_type(time_);
}
protected:
time_rep_type time_;
};
} } //namespace date_time::boost
#endif

View File

@@ -0,0 +1,83 @@
#ifndef DATE_TIME_TIME_CLOCK_HPP___
#define DATE_TIME_TIME_CLOCK_HPP___
/* Copyright (c) 2002,2003,2005 CrystalClear Software, Inc.
* Use, modification and distribution is subject to the
* Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
* Author: Jeff Garland, Bart Garst
* $Date$
*/
/*! @file time_clock.hpp
This file contains the interface for clock devices.
*/
#include "boost/date_time/c_time.hpp"
#include "boost/shared_ptr.hpp"
namespace boost {
namespace date_time {
//! A clock providing time level services based on C time_t capabilities
/*! This clock provides resolution to the 1 second level
*/
template<class time_type>
class second_clock
{
public:
typedef typename time_type::date_type date_type;
typedef typename time_type::time_duration_type time_duration_type;
static time_type local_time()
{
::std::time_t t;
::std::time(&t);
::std::tm curr, *curr_ptr;
//curr_ptr = ::std::localtime(&t);
curr_ptr = c_time::localtime(&t, &curr);
return create_time(curr_ptr);
}
//! Get the current day in universal date as a ymd_type
static time_type universal_time()
{
::std::time_t t;
::std::time(&t);
::std::tm curr, *curr_ptr;
//curr_ptr = ::std::gmtime(&t);
curr_ptr = c_time::gmtime(&t, &curr);
return create_time(curr_ptr);
}
template<class time_zone_type>
static time_type local_time(boost::shared_ptr<time_zone_type> tz_ptr)
{
typedef typename time_type::utc_time_type utc_time_type;
utc_time_type utc_time = second_clock<utc_time_type>::universal_time();
return time_type(utc_time, tz_ptr);
}
private:
static time_type create_time(::std::tm* current)
{
date_type d(static_cast<unsigned short>(current->tm_year + 1900),
static_cast<unsigned short>(current->tm_mon + 1),
static_cast<unsigned short>(current->tm_mday));
time_duration_type td(current->tm_hour,
current->tm_min,
current->tm_sec);
return time_type(d,td);
}
};
} } //namespace date_time
#endif

View File

@@ -0,0 +1,43 @@
#ifndef DATE_TIME_TIME_PRECISION_LIMITS_HPP
#define DATE_TIME_TIME_PRECISION_LIMITS_HPP
/* Copyright (c) 2002,2003 CrystalClear Software, Inc.
* Use, modification and distribution is subject to the
* Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
* Author: Jeff Garland
* $Date$
*/
/*! \file time_defs.hpp
This file contains nice definitions for handling the resoluion of various time
reprsentations.
*/
namespace boost {
namespace date_time {
//!Defines some nice types for handling time level resolutions
enum time_resolutions {
sec,
tenth,
hundreth, // deprecated misspelled version of hundredth
hundredth = hundreth,
milli,
ten_thousandth,
micro,
nano,
NumResolutions
};
//! Flags for daylight savings or summer time
enum dst_flags {not_dst, is_dst, calculate};
} } //namespace date_time
#endif

View File

@@ -0,0 +1,295 @@
#ifndef DATE_TIME_TIME_DURATION_HPP___
#define DATE_TIME_TIME_DURATION_HPP___
/* Copyright (c) 2002,2003 CrystalClear Software, Inc.
* Use, modification and distribution is subject to the
* Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
* Author: Jeff Garland, Bart Garst
* $Date$
*/
#include <boost/cstdint.hpp>
#include <boost/operators.hpp>
#include <boost/static_assert.hpp>
#include <boost/date_time/time_defs.hpp>
#include <boost/date_time/special_defs.hpp>
#include <boost/date_time/compiler_config.hpp>
namespace boost {
namespace date_time {
//! Represents some amount of elapsed time measure to a given resolution
/*! This class represents a standard set of capabilities for all
counted time durations. Time duration implementations should derive
from this class passing their type as the first template parameter.
This design allows the subclass duration types to provide custom
construction policies or other custom features not provided here.
@param T The subclass type
@param rep_type The time resolution traits for this duration type.
*/
template<class T, typename rep_type>
class time_duration : private
boost::less_than_comparable<T
, boost::equality_comparable<T
> >
/* dividable, addable, and subtractable operator templates
* won't work with this class (MSVC++ 6.0). return type
* from '+=' is different than expected return type
* from '+'. multipliable probably wont work
* either (haven't tried) */
{
public:
// A tag for type categorization. Can be used to detect Boost.DateTime duration types in generic code.
typedef void _is_boost_date_time_duration;
typedef T duration_type; //the subclass
typedef rep_type traits_type;
typedef typename rep_type::day_type day_type;
typedef typename rep_type::hour_type hour_type;
typedef typename rep_type::min_type min_type;
typedef typename rep_type::sec_type sec_type;
typedef typename rep_type::fractional_seconds_type fractional_seconds_type;
typedef typename rep_type::tick_type tick_type;
typedef typename rep_type::impl_type impl_type;
time_duration() : ticks_(0) {}
time_duration(hour_type hours_in,
min_type minutes_in,
sec_type seconds_in=0,
fractional_seconds_type frac_sec_in = 0) :
ticks_(rep_type::to_tick_count(hours_in,minutes_in,seconds_in,frac_sec_in))
{}
// copy constructor required for dividable<>
//! Construct from another time_duration (Copy constructor)
time_duration(const time_duration<T, rep_type>& other)
: ticks_(other.ticks_)
{}
//! Construct from special_values
time_duration(special_values sv) : ticks_(impl_type::from_special(sv))
{}
//! Returns smallest representable duration
static duration_type unit()
{
return duration_type(0,0,0,1);
}
//! Return the number of ticks in a second
static tick_type ticks_per_second()
{
return rep_type::res_adjust();
}
//! Provide the resolution of this duration type
static time_resolutions resolution()
{
return rep_type::resolution();
}
//! Returns number of hours in the duration
hour_type hours() const
{
return static_cast<hour_type>(ticks() / (3600*ticks_per_second()));
}
//! Returns normalized number of minutes
min_type minutes() const
{
return static_cast<min_type>((ticks() / (60*ticks_per_second())) % 60);
}
//! Returns normalized number of seconds (0..60)
sec_type seconds() const
{
return static_cast<sec_type>((ticks()/ticks_per_second()) % 60);
}
//! Returns total number of seconds truncating any fractional seconds
sec_type total_seconds() const
{
return static_cast<sec_type>(ticks() / ticks_per_second());
}
//! Returns total number of milliseconds truncating any fractional seconds
tick_type total_milliseconds() const
{
if (ticks_per_second() < 1000) {
return ticks() * (static_cast<tick_type>(1000) / ticks_per_second());
}
return ticks() / (ticks_per_second() / static_cast<tick_type>(1000)) ;
}
//! Returns total number of nanoseconds truncating any sub millisecond values
tick_type total_nanoseconds() const
{
if (ticks_per_second() < 1000000000) {
return ticks() * (static_cast<tick_type>(1000000000) / ticks_per_second());
}
return ticks() / (ticks_per_second() / static_cast<tick_type>(1000000000)) ;
}
//! Returns total number of microseconds truncating any sub microsecond values
tick_type total_microseconds() const
{
if (ticks_per_second() < 1000000) {
return ticks() * (static_cast<tick_type>(1000000) / ticks_per_second());
}
return ticks() / (ticks_per_second() / static_cast<tick_type>(1000000)) ;
}
//! Returns count of fractional seconds at given resolution
fractional_seconds_type fractional_seconds() const
{
return (ticks() % ticks_per_second());
}
//! Returns number of possible digits in fractional seconds
static unsigned short num_fractional_digits()
{
return rep_type::num_fractional_digits();
}
duration_type invert_sign() const
{
return duration_type(ticks_ * (-1));
}
bool is_negative() const
{
return ticks_ < 0;
}
bool operator<(const time_duration& rhs) const
{
return ticks_ < rhs.ticks_;
}
bool operator==(const time_duration& rhs) const
{
return ticks_ == rhs.ticks_;
}
//! unary- Allows for time_duration td = -td1
duration_type operator-()const
{
return duration_type(ticks_ * (-1));
}
duration_type operator-(const duration_type& d) const
{
return duration_type(ticks_ - d.ticks_);
}
duration_type operator+(const duration_type& d) const
{
return duration_type(ticks_ + d.ticks_);
}
duration_type operator/(int divisor) const
{
return duration_type(ticks_ / divisor);
}
duration_type operator-=(const duration_type& d)
{
ticks_ = ticks_ - d.ticks_;
return duration_type(ticks_);
}
duration_type operator+=(const duration_type& d)
{
ticks_ = ticks_ + d.ticks_;
return duration_type(ticks_);
}
//! Division operations on a duration with an integer.
duration_type operator/=(int divisor)
{
ticks_ = ticks_ / divisor;
return duration_type(ticks_);
}
//! Multiplication operations an a duration with an integer
duration_type operator*(int rhs) const
{
return duration_type(ticks_ * rhs);
}
duration_type operator*=(int divisor)
{
ticks_ = ticks_ * divisor;
return duration_type(ticks_);
}
tick_type ticks() const
{
return traits_type::as_number(ticks_);
}
//! Is ticks_ a special value?
bool is_special()const
{
if(traits_type::is_adapted())
{
return ticks_.is_special();
}
else{
return false;
}
}
//! Is duration pos-infinity
bool is_pos_infinity()const
{
if(traits_type::is_adapted())
{
return ticks_.is_pos_infinity();
}
else{
return false;
}
}
//! Is duration neg-infinity
bool is_neg_infinity()const
{
if(traits_type::is_adapted())
{
return ticks_.is_neg_infinity();
}
else{
return false;
}
}
//! Is duration not-a-date-time
bool is_not_a_date_time()const
{
if(traits_type::is_adapted())
{
return ticks_.is_nan();
}
else{
return false;
}
}
//! Used for special_values output
impl_type get_rep()const
{
return ticks_;
}
protected:
explicit time_duration(impl_type in) : ticks_(in) {}
impl_type ticks_;
};
//! Template for instantiating derived adjusting durations
/* These templates are designed to work with multiples of
* 10 for frac_of_second and resoultion adjustment
*/
template<class base_duration, boost::int64_t frac_of_second>
class subsecond_duration : public base_duration
{
public:
typedef typename base_duration::impl_type impl_type;
typedef typename base_duration::traits_type traits_type;
private:
// To avoid integer overflow we precompute the duration resolution conversion coefficient (ticket #3471)
BOOST_STATIC_ASSERT_MSG((traits_type::ticks_per_second >= frac_of_second ? traits_type::ticks_per_second % frac_of_second : frac_of_second % traits_type::ticks_per_second) == 0,\
"The base duration resolution must be a multiple of the subsecond duration resolution");
BOOST_STATIC_CONSTANT(boost::int64_t, adjustment_ratio = (traits_type::ticks_per_second >= frac_of_second ? traits_type::ticks_per_second / frac_of_second : frac_of_second / traits_type::ticks_per_second));
public:
explicit subsecond_duration(boost::int64_t ss) :
base_duration(impl_type(traits_type::ticks_per_second >= frac_of_second ? ss * adjustment_ratio : ss / adjustment_ratio))
{
}
};
} } //namespace date_time
#endif

View File

@@ -0,0 +1,52 @@
#ifndef DATE_TIME_TIME_ITERATOR_HPP___
#define DATE_TIME_TIME_ITERATOR_HPP___
/* Copyright (c) 2002,2003 CrystalClear Software, Inc.
* Use, modification and distribution is subject to the
* Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
* Author: Jeff Garland, Bart Garst
* $Date$
*/
namespace boost {
namespace date_time {
//! Simple time iterator skeleton class
template<class time_type>
class time_itr {
public:
typedef typename time_type::time_duration_type time_duration_type;
time_itr(time_type t, time_duration_type d) : current_(t), offset_(d) {}
time_itr& operator++()
{
current_ = current_ + offset_;
return *this;
}
time_itr& operator--()
{
current_ = current_ - offset_;
return *this;
}
time_type operator*() {return current_;}
time_type* operator->() {return &current_;}
bool operator< (const time_type& t) {return current_ < t;}
bool operator<= (const time_type& t) {return current_ <= t;}
bool operator!= (const time_type& t) {return current_ != t;}
bool operator== (const time_type& t) {return current_ == t;}
bool operator> (const time_type& t) {return current_ > t;}
bool operator>= (const time_type& t) {return current_ >= t;}
private:
time_type current_;
time_duration_type offset_;
};
} }//namespace date_time
#endif

View File

@@ -0,0 +1,144 @@
#ifndef DATE_TIME_TIME_RESOLUTION_TRAITS_HPP
#define DATE_TIME_TIME_RESOLUTION_TRAITS_HPP
/* Copyright (c) 2002,2003 CrystalClear Software, Inc.
* Use, modification and distribution is subject to the
* Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
* Author: Jeff Garland, Bart Garst
* $Date$
*/
#include <boost/cstdint.hpp>
#include <boost/date_time/time_defs.hpp>
#include <boost/date_time/int_adapter.hpp>
#include <boost/date_time/compiler_config.hpp>
namespace boost {
namespace date_time {
//! Simple function to calculate absolute value of a numeric type
template <typename T>
// JDG [7/6/02 made a template],
// moved here from time_duration.hpp 2003-Sept-4.
inline T absolute_value(T x)
{
return x < 0 ? -x : x;
}
//! traits struct for time_resolution_traits implementation type
struct time_resolution_traits_bi32_impl {
typedef boost::int32_t int_type;
typedef boost::int32_t impl_type;
static int_type as_number(impl_type i){ return i;}
//! Used to determine if implemented type is int_adapter or int
static bool is_adapted() { return false;}
};
//! traits struct for time_resolution_traits implementation type
struct time_resolution_traits_adapted32_impl {
typedef boost::int32_t int_type;
typedef boost::date_time::int_adapter<boost::int32_t> impl_type;
static int_type as_number(impl_type i){ return i.as_number();}
//! Used to determine if implemented type is int_adapter or int
static bool is_adapted() { return true;}
};
//! traits struct for time_resolution_traits implementation type
struct time_resolution_traits_bi64_impl {
typedef boost::int64_t int_type;
typedef boost::int64_t impl_type;
static int_type as_number(impl_type i){ return i;}
//! Used to determine if implemented type is int_adapter or int
static bool is_adapted() { return false;}
};
//! traits struct for time_resolution_traits implementation type
struct time_resolution_traits_adapted64_impl {
typedef boost::int64_t int_type;
typedef boost::date_time::int_adapter<boost::int64_t> impl_type;
static int_type as_number(impl_type i){ return i.as_number();}
//! Used to determine if implemented type is int_adapter or int
static bool is_adapted() { return true;}
};
template<typename frac_sec_type,
time_resolutions res,
#if (defined(BOOST_MSVC) && (_MSC_VER < 1300))
boost::int64_t resolution_adjust,
#else
typename frac_sec_type::int_type resolution_adjust,
#endif
unsigned short frac_digits,
typename var_type = boost::int32_t >
class time_resolution_traits {
public:
typedef typename frac_sec_type::int_type fractional_seconds_type;
typedef typename frac_sec_type::int_type tick_type;
typedef typename frac_sec_type::impl_type impl_type;
typedef var_type day_type;
typedef var_type hour_type;
typedef var_type min_type;
typedef var_type sec_type;
// bring in function from frac_sec_type traits structs
static fractional_seconds_type as_number(impl_type i)
{
return frac_sec_type::as_number(i);
}
static bool is_adapted()
{
return frac_sec_type::is_adapted();
}
//Would like this to be frac_sec_type, but some compilers complain
#if (defined(BOOST_MSVC) && (_MSC_VER < 1300))
BOOST_STATIC_CONSTANT(boost::int64_t, ticks_per_second = resolution_adjust);
#else
BOOST_STATIC_CONSTANT(fractional_seconds_type, ticks_per_second = resolution_adjust);
#endif
static time_resolutions resolution()
{
return res;
}
static unsigned short num_fractional_digits()
{
return frac_digits;
}
static fractional_seconds_type res_adjust()
{
return resolution_adjust;
}
//! Any negative argument results in a negative tick_count
static tick_type to_tick_count(hour_type hours,
min_type minutes,
sec_type seconds,
fractional_seconds_type fs)
{
if(hours < 0 || minutes < 0 || seconds < 0 || fs < 0)
{
hours = absolute_value(hours);
minutes = absolute_value(minutes);
seconds = absolute_value(seconds);
fs = absolute_value(fs);
return (((((fractional_seconds_type(hours)*3600)
+ (fractional_seconds_type(minutes)*60)
+ seconds)*res_adjust()) + fs) * -1);
}
return (((fractional_seconds_type(hours)*3600)
+ (fractional_seconds_type(minutes)*60)
+ seconds)*res_adjust()) + fs;
}
};
typedef time_resolution_traits<time_resolution_traits_adapted32_impl, milli, 1000, 3 > milli_res;
typedef time_resolution_traits<time_resolution_traits_adapted64_impl, micro, 1000000, 6 > micro_res;
typedef time_resolution_traits<time_resolution_traits_adapted64_impl, nano, 1000000000, 9 > nano_res;
} } //namespace date_time
#endif

View File

@@ -0,0 +1,254 @@
#ifndef DATE_TIME_TIME_SYSTEM_COUNTED_HPP
#define DATE_TIME_TIME_SYSTEM_COUNTED_HPP
/* Copyright (c) 2002,2003 CrystalClear Software, Inc.
* Use, modification and distribution is subject to the
* Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
* Author: Jeff Garland, Bart Garst
* $Date$
*/
#include "boost/date_time/time_defs.hpp"
#include <string>
namespace boost {
namespace date_time {
//! Time representation that uses a single integer count
template<class config>
struct counted_time_rep
{
typedef typename config::int_type int_type;
typedef typename config::date_type date_type;
typedef typename config::impl_type impl_type;
typedef typename date_type::duration_type date_duration_type;
typedef typename date_type::calendar_type calendar_type;
typedef typename date_type::ymd_type ymd_type;
typedef typename config::time_duration_type time_duration_type;
typedef typename config::resolution_traits resolution_traits;
counted_time_rep(const date_type& d, const time_duration_type& time_of_day)
: time_count_(1)
{
if(d.is_infinity() || d.is_not_a_date() || time_of_day.is_special()) {
time_count_ = time_of_day.get_rep() + d.day_count();
//std::cout << time_count_ << std::endl;
}
else {
time_count_ = (d.day_number() * frac_sec_per_day()) + time_of_day.ticks();
}
}
explicit counted_time_rep(int_type count) :
time_count_(count)
{}
explicit counted_time_rep(impl_type count) :
time_count_(count)
{}
date_type date() const
{
if(time_count_.is_special()) {
return date_type(time_count_.as_special());
}
else {
typename calendar_type::date_int_type dc = static_cast<typename calendar_type::date_int_type>(day_count());
//std::cout << "time_rep here:" << dc << std::endl;
ymd_type ymd = calendar_type::from_day_number(dc);
return date_type(ymd);
}
}
//int_type day_count() const
unsigned long day_count() const
{
/* resolution_traits::as_number returns a boost::int64_t &
* frac_sec_per_day is also a boost::int64_t so, naturally,
* the division operation returns a boost::int64_t.
* The static_cast to an unsigned long is ok (results in no data loss)
* because frac_sec_per_day is either the number of
* microseconds per day, or the number of nanoseconds per day.
* Worst case scenario: resolution_traits::as_number returns the
* maximum value an int64_t can hold and frac_sec_per_day
* is microseconds per day (lowest possible value).
* The division operation will then return a value of 106751991 -
* easily fitting in an unsigned long.
*/
return static_cast<unsigned long>(resolution_traits::as_number(time_count_) / frac_sec_per_day());
}
int_type time_count() const
{
return resolution_traits::as_number(time_count_);
}
int_type tod() const
{
return resolution_traits::as_number(time_count_) % frac_sec_per_day();
}
static int_type frac_sec_per_day()
{
int_type seconds_per_day = 60*60*24;
int_type fractional_sec_per_sec(resolution_traits::res_adjust());
return seconds_per_day*fractional_sec_per_sec;
}
bool is_pos_infinity()const
{
return impl_type::is_pos_inf(time_count_.as_number());
}
bool is_neg_infinity()const
{
return impl_type::is_neg_inf(time_count_.as_number());
}
bool is_not_a_date_time()const
{
return impl_type::is_not_a_number(time_count_.as_number());
}
bool is_special()const
{
return time_count_.is_special();
}
impl_type get_rep()const
{
return time_count_;
}
private:
impl_type time_count_;
};
//! An unadjusted time system implementation.
template<class time_rep>
class counted_time_system
{
public:
typedef time_rep time_rep_type;
typedef typename time_rep_type::impl_type impl_type;
typedef typename time_rep_type::time_duration_type time_duration_type;
typedef typename time_duration_type::fractional_seconds_type fractional_seconds_type;
typedef typename time_rep_type::date_type date_type;
typedef typename time_rep_type::date_duration_type date_duration_type;
template<class T> static void unused_var(const T&) {}
static time_rep_type get_time_rep(const date_type& day,
const time_duration_type& tod,
date_time::dst_flags dst=not_dst)
{
unused_var(dst);
return time_rep_type(day, tod);
}
static time_rep_type get_time_rep(special_values sv)
{
switch (sv) {
case not_a_date_time:
return time_rep_type(date_type(not_a_date_time),
time_duration_type(not_a_date_time));
case pos_infin:
return time_rep_type(date_type(pos_infin),
time_duration_type(pos_infin));
case neg_infin:
return time_rep_type(date_type(neg_infin),
time_duration_type(neg_infin));
case max_date_time: {
time_duration_type td = time_duration_type(24,0,0,0) - time_duration_type(0,0,0,1);
return time_rep_type(date_type(max_date_time), td);
}
case min_date_time:
return time_rep_type(date_type(min_date_time), time_duration_type(0,0,0,0));
default:
return time_rep_type(date_type(not_a_date_time),
time_duration_type(not_a_date_time));
}
}
static date_type get_date(const time_rep_type& val)
{
return val.date();
}
static time_duration_type get_time_of_day(const time_rep_type& val)
{
if(val.is_special()) {
return time_duration_type(val.get_rep().as_special());
}
else{
return time_duration_type(0,0,0,val.tod());
}
}
static std::string zone_name(const time_rep_type&)
{
return "";
}
static bool is_equal(const time_rep_type& lhs, const time_rep_type& rhs)
{
return (lhs.time_count() == rhs.time_count());
}
static bool is_less(const time_rep_type& lhs, const time_rep_type& rhs)
{
return (lhs.time_count() < rhs.time_count());
}
static time_rep_type add_days(const time_rep_type& base,
const date_duration_type& dd)
{
if(base.is_special() || dd.is_special()) {
return(time_rep_type(base.get_rep() + dd.get_rep()));
}
else {
return time_rep_type(base.time_count() + (dd.days() * time_rep_type::frac_sec_per_day()));
}
}
static time_rep_type subtract_days(const time_rep_type& base,
const date_duration_type& dd)
{
if(base.is_special() || dd.is_special()) {
return(time_rep_type(base.get_rep() - dd.get_rep()));
}
else{
return time_rep_type(base.time_count() - (dd.days() * time_rep_type::frac_sec_per_day()));
}
}
static time_rep_type subtract_time_duration(const time_rep_type& base,
const time_duration_type& td)
{
if(base.is_special() || td.is_special()) {
return(time_rep_type(base.get_rep() - td.get_rep()));
}
else {
return time_rep_type(base.time_count() - td.ticks());
}
}
static time_rep_type add_time_duration(const time_rep_type& base,
time_duration_type td)
{
if(base.is_special() || td.is_special()) {
return(time_rep_type(base.get_rep() + td.get_rep()));
}
else {
return time_rep_type(base.time_count() + td.ticks());
}
}
static time_duration_type subtract_times(const time_rep_type& lhs,
const time_rep_type& rhs)
{
if(lhs.is_special() || rhs.is_special()) {
return(time_duration_type(
impl_type::to_special((lhs.get_rep() - rhs.get_rep()).as_number())));
}
else {
fractional_seconds_type fs = lhs.time_count() - rhs.time_count();
return time_duration_type(0,0,0,fs);
}
}
};
} } //namespace date_time
#endif

View File

@@ -0,0 +1,207 @@
#ifndef DATE_TIME_TIME_SYSTEM_SPLIT_HPP
#define DATE_TIME_TIME_SYSTEM_SPLIT_HPP
/* Copyright (c) 2002,2003,2005 CrystalClear Software, Inc.
* Use, modification and distribution is subject to the
* Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
* Author: Jeff Garland, Bart Garst
* $Date$
*/
#include <string>
#include "boost/date_time/compiler_config.hpp"
#include "boost/date_time/special_defs.hpp"
namespace boost {
namespace date_time {
//! An unadjusted time system implementation.
#if (defined(BOOST_DATE_TIME_NO_MEMBER_INIT))
template<typename config, boost::int32_t ticks_per_second>
#else
template<typename config>
#endif
class split_timedate_system
{
public:
typedef typename config::time_rep_type time_rep_type;
typedef typename config::date_type date_type;
typedef typename config::time_duration_type time_duration_type;
typedef typename config::date_duration_type date_duration_type;
typedef typename config::int_type int_type;
typedef typename config::resolution_traits resolution_traits;
//86400 is number of seconds in a day...
#if (defined(BOOST_DATE_TIME_NO_MEMBER_INIT))
typedef date_time::wrapping_int<int_type, INT64_C(86400) * ticks_per_second > wrap_int_type;
#else
private:
BOOST_STATIC_CONSTANT(int_type, ticks_per_day = INT64_C(86400) * config::tick_per_second);
public:
# if BOOST_WORKAROUND( __BORLANDC__, BOOST_TESTED_AT(0X581) )
typedef date_time::wrapping_int< split_timedate_system::int_type, split_timedate_system::ticks_per_day> wrap_int_type;
# else
typedef date_time::wrapping_int<int_type, ticks_per_day> wrap_int_type;
#endif
#endif
static time_rep_type get_time_rep(special_values sv)
{
switch (sv) {
case not_a_date_time:
return time_rep_type(date_type(not_a_date_time),
time_duration_type(not_a_date_time));
case pos_infin:
return time_rep_type(date_type(pos_infin),
time_duration_type(pos_infin));
case neg_infin:
return time_rep_type(date_type(neg_infin),
time_duration_type(neg_infin));
case max_date_time: {
time_duration_type td = time_duration_type(24,0,0,0) - time_duration_type(0,0,0,1);
return time_rep_type(date_type(max_date_time), td);
}
case min_date_time:
return time_rep_type(date_type(min_date_time), time_duration_type(0,0,0,0));
default:
return time_rep_type(date_type(not_a_date_time),
time_duration_type(not_a_date_time));
}
}
static time_rep_type get_time_rep(const date_type& day,
const time_duration_type& tod,
date_time::dst_flags /* dst */ = not_dst)
{
if(day.is_special() || tod.is_special()) {
if(day.is_not_a_date() || tod.is_not_a_date_time()) {
return time_rep_type(date_type(not_a_date_time),
time_duration_type(not_a_date_time));
}
else if(day.is_pos_infinity()) {
if(tod.is_neg_infinity()) {
return time_rep_type(date_type(not_a_date_time),
time_duration_type(not_a_date_time));
}
else {
return time_rep_type(day, time_duration_type(pos_infin));
}
}
else if(day.is_neg_infinity()) {
if(tod.is_pos_infinity()) {
return time_rep_type(date_type(not_a_date_time),
time_duration_type(not_a_date_time));
}
else {
return time_rep_type(day, time_duration_type(neg_infin));
}
}
else if(tod.is_pos_infinity()) {
if(day.is_neg_infinity()) {
return time_rep_type(date_type(not_a_date_time),
time_duration_type(not_a_date_time));
}
else {
return time_rep_type(date_type(pos_infin), tod);
}
}
else if(tod.is_neg_infinity()) {
if(day.is_pos_infinity()) {
return time_rep_type(date_type(not_a_date_time),
time_duration_type(not_a_date_time));
}
else {
return time_rep_type(date_type(neg_infin), tod);
}
}
}
return time_rep_type(day, tod);
}
static date_type get_date(const time_rep_type& val)
{
return date_type(val.day);
}
static time_duration_type get_time_of_day(const time_rep_type& val)
{
return time_duration_type(val.time_of_day);
}
static std::string zone_name(const time_rep_type&)
{
return std::string();
}
static bool is_equal(const time_rep_type& lhs, const time_rep_type& rhs)
{
return ((lhs.day == rhs.day) && (lhs.time_of_day == rhs.time_of_day));
}
static bool is_less(const time_rep_type& lhs, const time_rep_type& rhs)
{
if (lhs.day < rhs.day) return true;
if (lhs.day > rhs.day) return false;
return (lhs.time_of_day < rhs.time_of_day);
}
static time_rep_type add_days(const time_rep_type& base,
const date_duration_type& dd)
{
return time_rep_type(base.day+dd, base.time_of_day);
}
static time_rep_type subtract_days(const time_rep_type& base,
const date_duration_type& dd)
{
return split_timedate_system::get_time_rep(base.day-dd, base.time_of_day);
}
static time_rep_type subtract_time_duration(const time_rep_type& base,
const time_duration_type& td)
{
if(base.day.is_special() || td.is_special())
{
return split_timedate_system::get_time_rep(base.day, -td);
}
if (td.is_negative()) {
time_duration_type td1 = td.invert_sign();
return add_time_duration(base,td1);
}
wrap_int_type day_offset(base.time_of_day.ticks());
date_duration_type day_overflow(static_cast<typename date_duration_type::duration_rep_type>(day_offset.subtract(td.ticks())));
return time_rep_type(base.day-day_overflow,
time_duration_type(0,0,0,day_offset.as_int()));
}
static time_rep_type add_time_duration(const time_rep_type& base,
time_duration_type td)
{
if(base.day.is_special() || td.is_special()) {
return split_timedate_system::get_time_rep(base.day, td);
}
if (td.is_negative()) {
time_duration_type td1 = td.invert_sign();
return subtract_time_duration(base,td1);
}
wrap_int_type day_offset(base.time_of_day.ticks());
date_duration_type day_overflow(static_cast< typename date_duration_type::duration_rep_type >(day_offset.add(td.ticks())));
return time_rep_type(base.day+day_overflow,
time_duration_type(0,0,0,day_offset.as_int()));
}
static time_duration_type subtract_times(const time_rep_type& lhs,
const time_rep_type& rhs)
{
date_duration_type dd = lhs.day - rhs.day;
time_duration_type td(dd.days()*24,0,0); //days * 24 hours
time_duration_type td2 = lhs.time_of_day - rhs.time_of_day;
return td+td2;
// return time_rep_type(base.day-dd, base.time_of_day);
}
};
} } //namespace date_time
#endif

View File

@@ -0,0 +1,169 @@
#ifndef _DATE_TIME_WRAPPING_INT_HPP__
#define _DATE_TIME_WRAPPING_INT_HPP__
/* Copyright (c) 2002,2003,2005 CrystalClear Software, Inc.
* Use, modification and distribution is subject to the
* Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
* Author: Jeff Garland, Bart Garst
* $Date$
*/
namespace boost {
namespace date_time {
//! A wrapping integer used to support time durations (WARNING: only instantiate with a signed type)
/*! In composite date and time types this type is used to
* wrap at the day boundary.
* Ex:
* A wrapping_int<short, 10> will roll over after nine, and
* roll under below zero. This gives a range of [0,9]
*
* NOTE: it is strongly recommended that wrapping_int2 be used
* instead of wrapping_int as wrapping_int is to be depricated
* at some point soon.
*
* Also Note that warnings will occur if instantiated with an
* unsigned type. Only a signed type should be used!
*/
template<typename int_type_, int_type_ wrap_val>
class wrapping_int {
public:
typedef int_type_ int_type;
//typedef overflow_type_ overflow_type;
static int_type wrap_value() {return wrap_val;}
//!Add, return true if wrapped
wrapping_int(int_type v) : value_(v) {}
//! Explicit converion method
int_type as_int() const {return value_;}
operator int_type() const {return value_;}
//!Add, return number of wraps performed
/*! The sign of the returned value will indicate which direction the
* wraps went. Ex: add a negative number and wrapping under could occur,
* this would be indicated by a negative return value. If wrapping over
* took place, a positive value would be returned */
template< typename IntT >
IntT add(IntT v)
{
int_type remainder = static_cast<int_type>(v % (wrap_val));
IntT overflow = static_cast<IntT>(v / (wrap_val));
value_ = static_cast<int_type>(value_ + remainder);
return calculate_wrap(overflow);
}
//! Subtract will return '+d' if wrapping under took place ('d' is the number of wraps)
/*! The sign of the returned value will indicate which direction the
* wraps went (positive indicates wrap under, negative indicates wrap over).
* Ex: subtract a negative number and wrapping over could
* occur, this would be indicated by a negative return value. If
* wrapping under took place, a positive value would be returned. */
template< typename IntT >
IntT subtract(IntT v)
{
int_type remainder = static_cast<int_type>(v % (wrap_val));
IntT underflow = static_cast<IntT>(-(v / (wrap_val)));
value_ = static_cast<int_type>(value_ - remainder);
return calculate_wrap(underflow) * -1;
}
private:
int_type value_;
template< typename IntT >
IntT calculate_wrap(IntT wrap)
{
if ((value_) >= wrap_val)
{
++wrap;
value_ -= (wrap_val);
}
else if(value_ < 0)
{
--wrap;
value_ += (wrap_val);
}
return wrap;
}
};
//! A wrapping integer used to wrap around at the top (WARNING: only instantiate with a signed type)
/*! Bad name, quick impl to fix a bug -- fix later!!
* This allows the wrap to restart at a value other than 0.
*/
template<typename int_type_, int_type_ wrap_min, int_type_ wrap_max>
class wrapping_int2 {
public:
typedef int_type_ int_type;
static int_type wrap_value() {return wrap_max;}
static int_type min_value() {return wrap_min;}
/*! If initializing value is out of range of [wrap_min, wrap_max],
* value will be initialized to closest of min or max */
wrapping_int2(int_type v) : value_(v) {
if(value_ < wrap_min)
{
value_ = wrap_min;
}
if(value_ > wrap_max)
{
value_ = wrap_max;
}
}
//! Explicit converion method
int_type as_int() const {return value_;}
operator int_type() const {return value_;}
//!Add, return number of wraps performed
/*! The sign of the returned value will indicate which direction the
* wraps went. Ex: add a negative number and wrapping under could occur,
* this would be indicated by a negative return value. If wrapping over
* took place, a positive value would be returned */
template< typename IntT >
IntT add(IntT v)
{
int_type remainder = static_cast<int_type>(v % (wrap_max - wrap_min + 1));
IntT overflow = static_cast<IntT>(v / (wrap_max - wrap_min + 1));
value_ = static_cast<int_type>(value_ + remainder);
return calculate_wrap(overflow);
}
//! Subtract will return '-d' if wrapping under took place ('d' is the number of wraps)
/*! The sign of the returned value will indicate which direction the
* wraps went. Ex: subtract a negative number and wrapping over could
* occur, this would be indicated by a positive return value. If
* wrapping under took place, a negative value would be returned */
template< typename IntT >
IntT subtract(IntT v)
{
int_type remainder = static_cast<int_type>(v % (wrap_max - wrap_min + 1));
IntT underflow = static_cast<IntT>(-(v / (wrap_max - wrap_min + 1)));
value_ = static_cast<int_type>(value_ - remainder);
return calculate_wrap(underflow);
}
private:
int_type value_;
template< typename IntT >
IntT calculate_wrap(IntT wrap)
{
if ((value_) > wrap_max)
{
++wrap;
value_ -= (wrap_max - wrap_min + 1);
}
else if((value_) < wrap_min)
{
--wrap;
value_ += (wrap_max - wrap_min + 1);
}
return wrap;
}
};
} } //namespace date_time
#endif

View File

@@ -0,0 +1,45 @@
#ifndef YearMonthDayBase_HPP__
#define YearMonthDayBase_HPP__
/* Copyright (c) 2002,2003 CrystalClear Software, Inc.
* Use, modification and distribution is subject to the
* Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
* Author: Jeff Garland
* $Date$
*/
namespace boost {
namespace date_time {
//! Allow rapid creation of ymd triples of different types
template<typename YearType, typename MonthType, typename DayType>
struct year_month_day_base {
year_month_day_base(YearType year,
MonthType month,
DayType day);
YearType year;
MonthType month;
DayType day;
typedef YearType year_type;
typedef MonthType month_type;
typedef DayType day_type;
};
//! A basic constructor
template<typename YearType, typename MonthType, typename DayType>
inline
year_month_day_base<YearType,MonthType,DayType>::year_month_day_base(YearType y,
MonthType m,
DayType d) :
year(y),
month(m),
day(d)
{}
} }//namespace date_time
#endif