1
0
mirror of https://git.suyu.dev/suyu/suyu synced 2025-09-10 16:26:32 -05:00

Initial commit

This commit is contained in:
Crimson-Hawk
2024-03-05 16:42:40 +08:00
commit f1e4595ebf
39576 changed files with 7006612 additions and 0 deletions

View File

@@ -0,0 +1,17 @@
#ifndef BOOST_DATE_TIME_ALL_HPP___
#define BOOST_DATE_TIME_ALL_HPP___
/* Copyright (c) 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$
*/
// See www.boost.org/libs/date_time for documentation.
//gregorian and posix time included by indirectly
#include "boost/date_time/local_time/local_time.hpp"
#endif // BOOST_DATE_TIME_ALL_HPP___

View File

@@ -0,0 +1,164 @@
#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&) const
{
return duration_type(f_);
}
duration_type get_neg_offset(const date_type&) const
{
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;
wrap_int2 wi(ymd.month);
//calc the year wrap around, add() returns 0 or 1 if wrapped
const typename ymd_type::year_type year(static_cast<typename ymd_type::year_type::value_type>(ymd.year + wi.add(f_)));
// 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;
wrap_int2 wi(ymd.month);
//calc the year wrap around, add() returns 0 or 1 if wrapped
const typename ymd_type::year_type year(static_cast<typename ymd_type::year_type::value_type>(ymd.year + wi.subtract(f_)));
//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&) const
{
return duration_type(f_*static_cast<int>(calendar_type::days_in_week()));
}
duration_type get_neg_offset(const date_type&) const
{
return duration_type(-f_*static_cast<int>(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,72 @@
#ifndef DATE_TIME_C_LOCAL_TIME_ADJUSTOR_HPP__
#define DATE_TIME_C_LOCAL_TIME_ADJUSTOR_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_local_time_adjustor.hpp
Time adjustment calculations based on machine
*/
#include <stdexcept>
#include <boost/throw_exception.hpp>
#include <boost/date_time/compiler_config.hpp>
#include <boost/date_time/c_time.hpp>
#include <boost/numeric/conversion/cast.hpp>
namespace boost {
namespace date_time {
//! Adjust to / from utc using the C API
/*! Warning!!! This class assumes that timezone settings of the
* machine are correct. This can be a very dangerous assumption.
*/
template<class time_type>
class c_local_adjustor {
public:
typedef typename time_type::time_duration_type time_duration_type;
typedef typename time_type::date_type date_type;
typedef typename date_type::duration_type date_duration_type;
//! Convert a utc time to local time
static time_type utc_to_local(const time_type& t)
{
date_type time_t_start_day(1970,1,1);
time_type time_t_start_time(time_t_start_day,time_duration_type(0,0,0));
if (t < time_t_start_time) {
boost::throw_exception(std::out_of_range("Cannot convert dates prior to Jan 1, 1970"));
BOOST_DATE_TIME_UNREACHABLE_EXPRESSION(return time_t_start_time); // should never reach
}
date_duration_type dd = t.date() - time_t_start_day;
time_duration_type td = t.time_of_day();
uint64_t t2 = static_cast<uint64_t>(dd.days())*86400 +
static_cast<uint64_t>(td.hours())*3600 +
static_cast<uint64_t>(td.minutes())*60 +
td.seconds();
// detect y2038 issue and throw instead of proceed with bad time
std::time_t tv = boost::numeric_cast<std::time_t>(t2);
std::tm tms, *tms_ptr;
tms_ptr = c_time::localtime(&tv, &tms);
date_type d(static_cast<unsigned short>(tms_ptr->tm_year + 1900),
static_cast<unsigned short>(tms_ptr->tm_mon + 1),
static_cast<unsigned short>(tms_ptr->tm_mday));
time_duration_type td2(tms_ptr->tm_hour,
tms_ptr->tm_min,
tms_ptr->tm_sec,
t.time_of_day().fractional_seconds());
return time_type(d,td2);
}
};
} } //namespace date_time
#endif

View File

@@ -0,0 +1,128 @@
#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(__clang__) // Clang has to be checked before MSVC
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
#elif (defined(_MSC_VER) && (_MSC_VER >= 1400))
#pragma warning(push) // preserve warning settings
#pragma warning(disable : 4996) // disable depricated localtime/gmtime warning on vc8
#endif
//! 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(__clang__) // Clang has to be checked before MSVC
#pragma clang diagnostic pop
#elif (defined(_MSC_VER) && (_MSC_VER >= 1400))
#pragma warning(pop) // restore warnings to previous state
#endif
#endif // BOOST_DATE_TIME_HAS_REENTRANT_STD_FUNCTIONS
};
}} // namespaces
#endif // DATE_TIME_C_TIME_HPP___

View File

@@ -0,0 +1,137 @@
#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>
// 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
#if (defined(BOOST_NO_INCLASS_MEMBER_INITIALIZATION) || BOOST_WORKAROUND( BOOST_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(BOOST_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(BOOST_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( BOOST_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
#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
#if defined(BOOST_NO_CXX11_NULLPTR)
# define BOOST_DATE_TIME_NULLPTR 0
#else
# define BOOST_DATE_TIME_NULLPTR nullptr
#endif
#endif

View File

@@ -0,0 +1,129 @@
#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/type_traits/conditional.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 BOOST_SYMBOL_VISIBLE constrained_value {
public:
typedef typename value_policies::value_type value_type;
// typedef except_type exception_type;
BOOST_CXX14_CONSTEXPR constrained_value(value_type value) : value_((min)())
{
assign(value);
}
BOOST_CXX14_CONSTEXPR constrained_value& operator=(value_type v)
{
assign(v);
return *this;
}
//! Return the max allowed value (traits method)
static BOOST_CONSTEXPR value_type
max BOOST_PREVENT_MACRO_SUBSTITUTION () {return (value_policies::max)();}
//! Return the min allowed value (traits method)
static BOOST_CONSTEXPR value_type
min BOOST_PREVENT_MACRO_SUBSTITUTION () {return (value_policies::min)();}
//! Coerce into the representation type
BOOST_CXX14_CONSTEXPR operator value_type() const {return value_;}
protected:
value_type value_;
private:
BOOST_CXX14_CONSTEXPR 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 BOOST_SYMBOL_VISIBLE simple_exception_policy
{
struct BOOST_SYMBOL_VISIBLE 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 conditional<
is_base_of< std::exception, exception_type >::value,
exception_type,
exception_wrapper
>::type actual_exception_type;
public:
typedef rep_type value_type;
static BOOST_CONSTEXPR rep_type
min BOOST_PREVENT_MACRO_SUBSTITUTION () { return min_value; }
static BOOST_CONSTEXPR 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,209 @@
#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/compiler_config.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 BOOST_SYMBOL_VISIBLE 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;
BOOST_CXX14_CONSTEXPR date(year_type y, month_type m, day_type d)
: days_(calendar::day_number(ymd_type(y, m, d)))
{}
BOOST_CXX14_CONSTEXPR date(const ymd_type& ymd)
: days_(calendar::day_number(ymd))
{}
//let the compiler write copy, assignment, and destructor
BOOST_CXX14_CONSTEXPR year_type year() const
{
ymd_type ymd = calendar::from_day_number(days_);
return ymd.year;
}
BOOST_CXX14_CONSTEXPR month_type month() const
{
ymd_type ymd = calendar::from_day_number(days_);
return ymd.month;
}
BOOST_CXX14_CONSTEXPR day_type day() const
{
ymd_type ymd = calendar::from_day_number(days_);
return ymd.day;
}
BOOST_CXX14_CONSTEXPR day_of_week_type day_of_week() const
{
ymd_type ymd = calendar::from_day_number(days_);
return calendar::day_of_week(ymd);
}
BOOST_CXX14_CONSTEXPR ymd_type year_month_day() const
{
return calendar::from_day_number(days_);
}
BOOST_CONSTEXPR bool operator<(const date_type& rhs) const
{
return days_ < rhs.days_;
}
BOOST_CONSTEXPR bool operator==(const date_type& rhs) const
{
return days_ == rhs.days_;
}
//! check to see if date is a special value
BOOST_CONSTEXPR bool is_special()const
{
return(is_not_a_date() || is_infinity());
}
//! check to see if date is not a value
BOOST_CONSTEXPR 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
BOOST_CONSTEXPR bool is_infinity() const
{
return traits_type::is_inf(days_);
}
//! check to see if date is greater than all possible dates
BOOST_CONSTEXPR bool is_pos_infinity() const
{
return traits_type::is_pos_inf(days_);
}
//! check to see if date is greater than all possible dates
BOOST_CONSTEXPR 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
BOOST_CXX14_CONSTEXPR special_values as_special() const
{
return traits_type::to_special(days_);
}
BOOST_CXX14_CONSTEXPR 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());
}
}
BOOST_CXX14_CONSTEXPR 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()));
}
BOOST_CXX14_CONSTEXPR date_type operator-=(const duration_type& dd)
{
*this = *this - dd;
return date_type(days_);
}
BOOST_CONSTEXPR date_rep_type day_count() const
{
return days_;
}
//allow internal access from operators
BOOST_CXX14_CONSTEXPR 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()));
}
BOOST_CXX14_CONSTEXPR 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.
*/
BOOST_CONSTEXPR explicit date(date_int_type days) : days_(days) {}
BOOST_CXX14_CONSTEXPR 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>
#include <boost/date_time/compiler_config.hpp>
#include <boost/date_time/int_adapter.hpp>
namespace boost {
namespace date_time {
//! Duration type with date level resolution
template<class duration_rep_traits>
class BOOST_SYMBOL_VISIBLE 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
BOOST_CXX14_CONSTEXPR explicit date_duration(duration_rep day_count) : days_(day_count) {}
/*! construct from special_values - only works when
* instantiated with duration_traits_adapted */
BOOST_CXX14_CONSTEXPR date_duration(special_values sv) :
days_(duration_rep::from_special(sv))
{}
//! returns days_ as it's instantiated type - used for streaming
BOOST_CXX14_CONSTEXPR duration_rep get_rep()const
{
return days_;
}
BOOST_CXX14_CONSTEXPR special_values as_special() const
{
return days_.as_special();
}
BOOST_CXX14_CONSTEXPR bool is_special()const
{
return days_.is_special();
}
//! returns days as value, not object.
BOOST_CXX14_CONSTEXPR duration_rep_type days() const
{
return duration_rep_traits::as_number(days_);
}
//! Returns the smallest duration -- used by to calculate 'end'
static BOOST_CXX14_CONSTEXPR date_duration unit()
{
return date_duration<duration_rep_traits>(1);
}
//! Equality
BOOST_CXX14_CONSTEXPR bool operator==(const date_duration& rhs) const
{
return days_ == rhs.days_;
}
//! Less
BOOST_CXX14_CONSTEXPR 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
BOOST_CXX14_CONSTEXPR date_duration& operator-=(const date_duration& rhs)
{
//days_ -= rhs.days_;
days_ = days_ - rhs.days_;
return *this;
}
//! Add a duration -- result is signed
BOOST_CXX14_CONSTEXPR date_duration& operator+=(const date_duration& rhs)
{
days_ = days_ + rhs.days_;
return *this;
}
//! unary- Allows for dd = -date_duration(2); -> dd == -2
BOOST_CXX14_CONSTEXPR date_duration operator-() const
{
return date_duration<duration_rep_traits>(get_rep() * (-1));
}
//! Division operations on a duration with an integer.
BOOST_CXX14_CONSTEXPR date_duration& operator/=(int divisor)
{
days_ = days_ / divisor;
return *this;
}
//! return sign information
BOOST_CXX14_CONSTEXPR 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 BOOST_SYMBOL_VISIBLE duration_traits_long
{
typedef long int_type;
typedef long impl_type;
static BOOST_CXX14_CONSTEXPR 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 BOOST_SYMBOL_VISIBLE duration_traits_adapted
{
typedef long int_type;
typedef boost::date_time::int_adapter<long> impl_type;
static BOOST_CXX14_CONSTEXPR int_type as_number(impl_type i) { return i.as_number(); }
};
} } //namspace date_time
#endif

View File

@@ -0,0 +1,265 @@
#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/compiler_config.hpp>
#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 BOOST_SYMBOL_VISIBLE weeks_duration : public date_duration<duration_config> {
public:
BOOST_CXX14_CONSTEXPR weeks_duration(typename duration_config::impl_type w)
: date_duration<duration_config>(w * 7) {}
BOOST_CXX14_CONSTEXPR weeks_duration(special_values sv)
: date_duration<duration_config>(sv) {}
};
// predeclare
template<class t>
class BOOST_SYMBOL_VISIBLE 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 BOOST_SYMBOL_VISIBLE 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:
BOOST_CXX14_CONSTEXPR months_duration(int_rep num) : _m(num) {}
BOOST_CXX14_CONSTEXPR 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
BOOST_CXX14_CONSTEXPR 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));
}
BOOST_CXX14_CONSTEXPR 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));
}
BOOST_CONSTEXPR bool operator==(const months_type& rhs) const
{
return(_m == rhs._m);
}
BOOST_CONSTEXPR bool operator!=(const months_type& rhs) const
{
return(_m != rhs._m);
}
BOOST_CXX14_CONSTEXPR months_type operator+(const months_type& rhs)const
{
return months_type(_m + rhs._m);
}
BOOST_CXX14_CONSTEXPR months_type& operator+=(const months_type& rhs)
{
_m = _m + rhs._m;
return *this;
}
BOOST_CXX14_CONSTEXPR months_type operator-(const months_type& rhs)const
{
return months_type(_m - rhs._m);
}
BOOST_CXX14_CONSTEXPR months_type& operator-=(const months_type& rhs)
{
_m = _m - rhs._m;
return *this;
}
BOOST_CXX14_CONSTEXPR months_type operator*(const int_type rhs)const
{
return months_type(_m * rhs);
}
BOOST_CXX14_CONSTEXPR months_type& operator*=(const int_type rhs)
{
_m = _m * rhs;
return *this;
}
BOOST_CXX14_CONSTEXPR months_type operator/(const int_type rhs)const
{
return months_type(_m / rhs);
}
BOOST_CXX14_CONSTEXPR months_type& operator/=(const int_type rhs)
{
_m = _m / rhs;
return *this;
}
BOOST_CXX14_CONSTEXPR months_type operator+(const years_type& y)const
{
return months_type(y.number_of_years() * 12 + _m);
}
BOOST_CXX14_CONSTEXPR months_type& operator+=(const years_type& y)
{
_m = y.number_of_years() * 12 + _m;
return *this;
}
BOOST_CXX14_CONSTEXPR months_type operator-(const years_type& y) const
{
return months_type(_m - y.number_of_years() * 12);
}
BOOST_CXX14_CONSTEXPR months_type& operator-=(const years_type& y)
{
_m = _m - y.number_of_years() * 12;
return *this;
}
//
BOOST_CXX14_CONSTEXPR friend date_type operator+(const date_type& d, const months_type& m)
{
return d + m.get_offset(d);
}
BOOST_CXX14_CONSTEXPR friend date_type operator+=(date_type& d, const months_type& m)
{
return d += m.get_offset(d);
}
BOOST_CXX14_CONSTEXPR 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);
}
BOOST_CXX14_CONSTEXPR 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 BOOST_SYMBOL_VISIBLE 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:
BOOST_CXX14_CONSTEXPR years_duration(int_rep num) : _y(num) {}
BOOST_CXX14_CONSTEXPR years_duration(special_values sv) : _y(sv)
{
_y = int_rep::from_special(sv);
}
BOOST_CXX14_CONSTEXPR int_rep number_of_years() const { return _y; }
//! returns a negative duration
BOOST_CXX14_CONSTEXPR 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));
}
BOOST_CXX14_CONSTEXPR 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));
}
BOOST_CXX14_CONSTEXPR bool operator==(const years_type& rhs) const
{
return(_y == rhs._y);
}
bool operator!=(const years_type& rhs) const
{
return(_y != rhs._y);
}
BOOST_CXX14_CONSTEXPR years_type operator+(const years_type& rhs)const
{
return years_type(_y + rhs._y);
}
BOOST_CXX14_CONSTEXPR years_type& operator+=(const years_type& rhs)
{
_y = _y + rhs._y;
return *this;
}
BOOST_CXX14_CONSTEXPR years_type operator-(const years_type& rhs)const
{
return years_type(_y - rhs._y);
}
BOOST_CXX14_CONSTEXPR years_type& operator-=(const years_type& rhs)
{
_y = _y - rhs._y;
return *this;
}
BOOST_CXX14_CONSTEXPR years_type operator*(const int_type rhs)const
{
return years_type(_y * rhs);
}
BOOST_CXX14_CONSTEXPR years_type& operator*=(const int_type rhs)
{
_y = _y * rhs;
return *this;
}
BOOST_CXX14_CONSTEXPR years_type operator/(const int_type rhs)const
{
return years_type(_y / rhs);
}
BOOST_CXX14_CONSTEXPR years_type& operator/=(const int_type rhs)
{
_y = _y / rhs;
return *this;
}
BOOST_CXX14_CONSTEXPR months_type operator+(const months_type& m) const
{
return(months_type(_y * 12 + m.number_of_months()));
}
BOOST_CXX14_CONSTEXPR months_type operator-(const months_type& m) const
{
return(months_type(_y * 12 - m.number_of_months()));
}
//
BOOST_CXX14_CONSTEXPR friend date_type operator+(const date_type& d, const years_type& y)
{
return d + y.get_offset(d);
}
BOOST_CXX14_CONSTEXPR friend date_type operator+=(date_type& d, const years_type& y)
{
return d += y.get_offset(d);
}
BOOST_CXX14_CONSTEXPR 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);
}
BOOST_CXX14_CONSTEXPR 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,766 @@
#ifndef _DATE_TIME_DATE_FACET__HPP___
#define _DATE_TIME_DATE_FACET__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: Martin Andrian, Jeff Garland, Bart Garst
* $Date$
*/
#include <iterator> // ostreambuf_iterator
#include <locale>
#include <string>
#include <vector>
#include <boost/throw_exception.hpp>
#include <boost/algorithm/string/replace.hpp>
#include <boost/date_time/compiler_config.hpp>
#include <boost/date_time/period.hpp>
#include <boost/date_time/special_defs.hpp>
#include <boost/date_time/special_values_formatter.hpp>
#include <boost/date_time/period_formatter.hpp>
#include <boost/date_time/period_parser.hpp>
#include <boost/date_time/date_generator_formatter.hpp>
#include <boost/date_time/date_generator_parser.hpp>
#include <boost/date_time/format_date_parser.hpp>
namespace boost { namespace date_time {
/*! Class that provides format based I/O facet for date types.
*
* This class allows the formatting of dates by using format string.
* Format strings are:
*
* - %A => long_weekday_format - Full name Ex: Tuesday
* - %a => short_weekday_format - Three letter abbreviation Ex: Tue
* - %B => long_month_format - Full name Ex: October
* - %b => short_month_format - Three letter abbreviation Ex: Oct
* - %x => standard_format_specifier - defined by the locale
* - %Y-%b-%d => default_date_format - YYYY-Mon-dd
*
* Default month format == %b
* Default weekday format == %a
*/
template <class date_type,
class CharT,
class OutItrT = std::ostreambuf_iterator<CharT, std::char_traits<CharT> > >
class BOOST_SYMBOL_VISIBLE date_facet : public std::locale::facet {
public:
typedef typename date_type::duration_type duration_type;
// greg_weekday is gregorian_calendar::day_of_week_type
typedef typename date_type::day_of_week_type day_of_week_type;
typedef typename date_type::day_type day_type;
typedef typename date_type::month_type month_type;
typedef boost::date_time::period<date_type,duration_type> period_type;
typedef std::basic_string<CharT> string_type;
typedef CharT char_type;
typedef boost::date_time::period_formatter<CharT> period_formatter_type;
typedef boost::date_time::special_values_formatter<CharT> special_values_formatter_type;
typedef std::vector<std::basic_string<CharT> > input_collection_type;
// used for the output of the date_generators
typedef date_generator_formatter<date_type, CharT> date_gen_formatter_type;
typedef partial_date<date_type> partial_date_type;
typedef nth_kday_of_month<date_type> nth_kday_type;
typedef first_kday_of_month<date_type> first_kday_type;
typedef last_kday_of_month<date_type> last_kday_type;
typedef first_kday_after<date_type> kday_after_type;
typedef first_kday_before<date_type> kday_before_type;
static const char_type long_weekday_format[3];
static const char_type short_weekday_format[3];
static const char_type long_month_format[3];
static const char_type short_month_format[3];
static const char_type default_period_separator[4];
static const char_type standard_format_specifier[3];
static const char_type iso_format_specifier[7];
static const char_type iso_format_extended_specifier[9];
static const char_type default_date_format[9]; // YYYY-Mon-DD
static std::locale::id id;
#if defined (__SUNPRO_CC) && defined (_RWSTD_VER)
std::locale::id& __get_id (void) const { return id; }
#endif
explicit date_facet(::size_t a_ref = 0)
: std::locale::facet(a_ref),
//m_format(standard_format_specifier)
m_format(default_date_format),
m_month_format(short_month_format),
m_weekday_format(short_weekday_format)
{}
explicit date_facet(const char_type* format_str,
const input_collection_type& short_names,
::size_t ref_count = 0)
: std::locale::facet(ref_count),
m_format(format_str),
m_month_format(short_month_format),
m_weekday_format(short_weekday_format),
m_month_short_names(short_names)
{}
explicit date_facet(const char_type* format_str,
period_formatter_type per_formatter = period_formatter_type(),
special_values_formatter_type sv_formatter = special_values_formatter_type(),
date_gen_formatter_type dg_formatter = date_gen_formatter_type(),
::size_t ref_count = 0)
: std::locale::facet(ref_count),
m_format(format_str),
m_month_format(short_month_format),
m_weekday_format(short_weekday_format),
m_period_formatter(per_formatter),
m_date_gen_formatter(dg_formatter),
m_special_values_formatter(sv_formatter)
{}
void format(const char_type* const format_str) {
m_format = format_str;
}
virtual void set_iso_format()
{
m_format = iso_format_specifier;
}
virtual void set_iso_extended_format()
{
m_format = iso_format_extended_specifier;
}
void month_format(const char_type* const format_str) {
m_month_format = format_str;
}
void weekday_format(const char_type* const format_str) {
m_weekday_format = format_str;
}
void period_formatter(period_formatter_type per_formatter) {
m_period_formatter= per_formatter;
}
void special_values_formatter(const special_values_formatter_type& svf)
{
m_special_values_formatter = svf;
}
void short_weekday_names(const input_collection_type& short_names)
{
m_weekday_short_names = short_names;
}
void long_weekday_names(const input_collection_type& long_names)
{
m_weekday_long_names = long_names;
}
void short_month_names(const input_collection_type& short_names)
{
m_month_short_names = short_names;
}
void long_month_names(const input_collection_type& long_names)
{
m_month_long_names = long_names;
}
void date_gen_phrase_strings(const input_collection_type& new_strings,
typename date_gen_formatter_type::phrase_elements beg_pos=date_gen_formatter_type::first)
{
m_date_gen_formatter.elements(new_strings, beg_pos);
}
OutItrT put(OutItrT next,
std::ios_base& a_ios,
char_type fill_char,
const date_type& d) const
{
if (d.is_special()) {
return do_put_special(next, a_ios, fill_char, d.as_special());
}
//The following line of code required the date to support a to_tm function
return do_put_tm(next, a_ios, fill_char, to_tm(d), m_format);
}
OutItrT put(OutItrT next,
std::ios_base& a_ios,
char_type fill_char,
const duration_type& dd) const
{
if (dd.is_special()) {
return do_put_special(next, a_ios, fill_char, dd.get_rep().as_special());
}
typedef std::num_put<CharT, OutItrT> num_put;
if (std::has_facet<num_put>(a_ios.getloc())) {
return std::use_facet<num_put>(a_ios.getloc()).put(next, a_ios, fill_char, dd.get_rep().as_number());
}
else {
num_put* f = new num_put();
std::locale l = std::locale(a_ios.getloc(), f);
a_ios.imbue(l);
return f->put(next, a_ios, fill_char, dd.get_rep().as_number());
}
}
OutItrT put(OutItrT next,
std::ios_base& a_ios,
char_type fill_char,
const month_type& m) const
{
//if (d.is_special()) {
// return do_put_special(next, a_ios, fill_char, d.as_special());
//}
//The following line of code required the date to support a to_tm function
std::tm dtm;
std::memset(&dtm, 0, sizeof(dtm));
dtm.tm_mon = m - 1;
return do_put_tm(next, a_ios, fill_char, dtm, m_month_format);
}
//! puts the day of month
OutItrT put(OutItrT next,
std::ios_base& a_ios,
char_type fill_char,
const day_type& day) const
{
std::tm dtm;
std::memset(&dtm, 0, sizeof(dtm));
dtm.tm_mday = day.as_number();
char_type tmp[3] = {'%','d'};
string_type temp_format(tmp);
return do_put_tm(next, a_ios, fill_char, dtm, temp_format);
}
OutItrT put(OutItrT next,
std::ios_base& a_ios,
char_type fill_char,
const day_of_week_type& dow) const
{
//if (d.is_special()) {
// return do_put_special(next, a_ios, fill_char, d.as_special());
//}
//The following line of code required the date to support a to_tm function
std::tm dtm;
std::memset(&dtm, 0, sizeof(dtm));
dtm.tm_wday = dow;
return do_put_tm(next, a_ios, fill_char, dtm, m_weekday_format);
}
OutItrT put(OutItrT next,
std::ios_base& a_ios,
char_type fill_char,
const period_type& p) const
{
return m_period_formatter.put_period(next, a_ios, fill_char, p, *this);
}
OutItrT put(OutItrT next,
std::ios_base& a_ios,
char_type fill_char,
const partial_date_type& pd) const
{
return m_date_gen_formatter.put_partial_date(next, a_ios, fill_char, pd, *this);
}
OutItrT put(OutItrT next,
std::ios_base& a_ios,
char_type fill_char,
const nth_kday_type& nkd) const
{
return m_date_gen_formatter.put_nth_kday(next, a_ios, fill_char, nkd, *this);
}
OutItrT put(OutItrT next,
std::ios_base& a_ios,
char_type fill_char,
const first_kday_type& fkd) const
{
return m_date_gen_formatter.put_first_kday(next, a_ios, fill_char, fkd, *this);
}
OutItrT put(OutItrT next,
std::ios_base& a_ios,
char_type fill_char,
const last_kday_type& lkd) const
{
return m_date_gen_formatter.put_last_kday(next, a_ios, fill_char, lkd, *this);
}
OutItrT put(OutItrT next,
std::ios_base& a_ios,
char_type fill_char,
const kday_before_type& fkb) const
{
return m_date_gen_formatter.put_kday_before(next, a_ios, fill_char, fkb, *this);
}
OutItrT put(OutItrT next,
std::ios_base& a_ios,
char_type fill_char,
const kday_after_type& fka) const
{
return m_date_gen_formatter.put_kday_after(next, a_ios, fill_char, fka, *this);
}
protected:
virtual OutItrT do_put_special(OutItrT next,
std::ios_base& /*a_ios*/,
char_type /*fill_char*/,
const boost::date_time::special_values sv) const
{
m_special_values_formatter.put_special(next, sv);
return next;
}
virtual OutItrT do_put_tm(OutItrT next,
std::ios_base& a_ios,
char_type fill_char,
const tm& tm_value,
string_type a_format) const
{
// update format string with custom names
if (!m_weekday_long_names.empty()) {
boost::algorithm::replace_all(a_format,
long_weekday_format,
m_weekday_long_names[tm_value.tm_wday]);
}
if (!m_weekday_short_names.empty()) {
boost::algorithm::replace_all(a_format,
short_weekday_format,
m_weekday_short_names[tm_value.tm_wday]);
}
if (!m_month_long_names.empty()) {
boost::algorithm::replace_all(a_format,
long_month_format,
m_month_long_names[tm_value.tm_mon]);
}
if (!m_month_short_names.empty()) {
boost::algorithm::replace_all(a_format,
short_month_format,
m_month_short_names[tm_value.tm_mon]);
}
// use time_put facet to create final string
const char_type* p_format = a_format.c_str();
return std::use_facet<std::time_put<CharT> >(a_ios.getloc()).put(next, a_ios,
fill_char,
&tm_value,
p_format,
p_format + a_format.size());
}
protected:
string_type m_format;
string_type m_month_format;
string_type m_weekday_format;
period_formatter_type m_period_formatter;
date_gen_formatter_type m_date_gen_formatter;
special_values_formatter_type m_special_values_formatter;
input_collection_type m_month_short_names;
input_collection_type m_month_long_names;
input_collection_type m_weekday_short_names;
input_collection_type m_weekday_long_names;
private:
};
template <class date_type, class CharT, class OutItrT>
std::locale::id date_facet<date_type, CharT, OutItrT>::id;
template <class date_type, class CharT, class OutItrT>
const typename date_facet<date_type, CharT, OutItrT>::char_type
date_facet<date_type, CharT, OutItrT>::long_weekday_format[3] = {'%','A'};
template <class date_type, class CharT, class OutItrT>
const typename date_facet<date_type, CharT, OutItrT>::char_type
date_facet<date_type, CharT, OutItrT>::short_weekday_format[3] = {'%','a'};
template <class date_type, class CharT, class OutItrT>
const typename date_facet<date_type, CharT, OutItrT>::char_type
date_facet<date_type, CharT, OutItrT>::long_month_format[3] = {'%','B'};
template <class date_type, class CharT, class OutItrT>
const typename date_facet<date_type, CharT, OutItrT>::char_type
date_facet<date_type, CharT, OutItrT>::short_month_format[3] = {'%','b'};
template <class date_type, class CharT, class OutItrT>
const typename date_facet<date_type, CharT, OutItrT>::char_type
date_facet<date_type, CharT, OutItrT>::default_period_separator[4] = { ' ', '/', ' '};
template <class date_type, class CharT, class OutItrT>
const typename date_facet<date_type, CharT, OutItrT>::char_type
date_facet<date_type, CharT, OutItrT>::standard_format_specifier[3] =
{'%', 'x' };
template <class date_type, class CharT, class OutItrT>
const typename date_facet<date_type, CharT, OutItrT>::char_type
date_facet<date_type, CharT, OutItrT>::iso_format_specifier[7] =
{'%', 'Y', '%', 'm', '%', 'd' };
template <class date_type, class CharT, class OutItrT>
const typename date_facet<date_type, CharT, OutItrT>::char_type
date_facet<date_type, CharT, OutItrT>::iso_format_extended_specifier[9] =
{'%', 'Y', '-', '%', 'm', '-', '%', 'd' };
template <class date_type, class CharT, class OutItrT>
const typename date_facet<date_type, CharT, OutItrT>::char_type
date_facet<date_type, CharT, OutItrT>::default_date_format[9] =
{'%','Y','-','%','b','-','%','d'};
//! Input facet
template <class date_type,
class CharT,
class InItrT = std::istreambuf_iterator<CharT, std::char_traits<CharT> > >
class BOOST_SYMBOL_VISIBLE date_input_facet : public std::locale::facet {
public:
typedef typename date_type::duration_type duration_type;
// greg_weekday is gregorian_calendar::day_of_week_type
typedef typename date_type::day_of_week_type day_of_week_type;
typedef typename date_type::day_type day_type;
typedef typename date_type::month_type month_type;
typedef typename date_type::year_type year_type;
typedef boost::date_time::period<date_type,duration_type> period_type;
typedef std::basic_string<CharT> string_type;
typedef CharT char_type;
typedef boost::date_time::period_parser<date_type, CharT> period_parser_type;
typedef boost::date_time::special_values_parser<date_type,CharT> special_values_parser_type;
typedef std::vector<std::basic_string<CharT> > input_collection_type;
typedef format_date_parser<date_type, CharT> format_date_parser_type;
// date_generators stuff goes here
typedef date_generator_parser<date_type, CharT> date_gen_parser_type;
typedef partial_date<date_type> partial_date_type;
typedef nth_kday_of_month<date_type> nth_kday_type;
typedef first_kday_of_month<date_type> first_kday_type;
typedef last_kday_of_month<date_type> last_kday_type;
typedef first_kday_after<date_type> kday_after_type;
typedef first_kday_before<date_type> kday_before_type;
static const char_type long_weekday_format[3];
static const char_type short_weekday_format[3];
static const char_type long_month_format[3];
static const char_type short_month_format[3];
static const char_type four_digit_year_format[3];
static const char_type two_digit_year_format[3];
static const char_type default_period_separator[4];
static const char_type standard_format_specifier[3];
static const char_type iso_format_specifier[7];
static const char_type iso_format_extended_specifier[9];
static const char_type default_date_format[9]; // YYYY-Mon-DD
static std::locale::id id;
explicit date_input_facet(::size_t a_ref = 0)
: std::locale::facet(a_ref),
m_format(default_date_format),
m_month_format(short_month_format),
m_weekday_format(short_weekday_format),
m_year_format(four_digit_year_format),
m_parser(m_format, std::locale::classic())
// default period_parser & special_values_parser used
{}
explicit date_input_facet(const string_type& format_str,
::size_t a_ref = 0)
: std::locale::facet(a_ref),
m_format(format_str),
m_month_format(short_month_format),
m_weekday_format(short_weekday_format),
m_year_format(four_digit_year_format),
m_parser(m_format, std::locale::classic())
// default period_parser & special_values_parser used
{}
explicit date_input_facet(const string_type& format_str,
const format_date_parser_type& date_parser,
const special_values_parser_type& sv_parser,
const period_parser_type& per_parser,
const date_gen_parser_type& date_gen_parser,
::size_t ref_count = 0)
: std::locale::facet(ref_count),
m_format(format_str),
m_month_format(short_month_format),
m_weekday_format(short_weekday_format),
m_year_format(four_digit_year_format),
m_parser(date_parser),
m_date_gen_parser(date_gen_parser),
m_period_parser(per_parser),
m_sv_parser(sv_parser)
{}
void format(const char_type* const format_str) {
m_format = format_str;
}
virtual void set_iso_format()
{
m_format = iso_format_specifier;
}
virtual void set_iso_extended_format()
{
m_format = iso_format_extended_specifier;
}
void month_format(const char_type* const format_str) {
m_month_format = format_str;
}
void weekday_format(const char_type* const format_str) {
m_weekday_format = format_str;
}
void year_format(const char_type* const format_str) {
m_year_format = format_str;
}
void period_parser(period_parser_type per_parser) {
m_period_parser = per_parser;
}
void short_weekday_names(const input_collection_type& weekday_names)
{
m_parser.short_weekday_names(weekday_names);
}
void long_weekday_names(const input_collection_type& weekday_names)
{
m_parser.long_weekday_names(weekday_names);
}
void short_month_names(const input_collection_type& month_names)
{
m_parser.short_month_names(month_names);
}
void long_month_names(const input_collection_type& month_names)
{
m_parser.long_month_names(month_names);
}
void date_gen_element_strings(const input_collection_type& col)
{
m_date_gen_parser.element_strings(col);
}
void date_gen_element_strings(const string_type& first,
const string_type& second,
const string_type& third,
const string_type& fourth,
const string_type& fifth,
const string_type& last,
const string_type& before,
const string_type& after,
const string_type& of)
{
m_date_gen_parser.element_strings(first,second,third,fourth,fifth,last,before,after,of);
}
void special_values_parser(special_values_parser_type sv_parser)
{
m_sv_parser = sv_parser;
}
InItrT get(InItrT& from,
InItrT& to,
std::ios_base& /*a_ios*/,
date_type& d) const
{
d = m_parser.parse_date(from, to, m_format, m_sv_parser);
return from;
}
InItrT get(InItrT& from,
InItrT& to,
std::ios_base& /*a_ios*/,
month_type& m) const
{
m = m_parser.parse_month(from, to, m_month_format);
return from;
}
InItrT get(InItrT& from,
InItrT& to,
std::ios_base& /*a_ios*/,
day_of_week_type& wd) const
{
wd = m_parser.parse_weekday(from, to, m_weekday_format);
return from;
}
//! Expects 1 or 2 digit day range: 1-31
InItrT get(InItrT& from,
InItrT& to,
std::ios_base& /*a_ios*/,
day_type& d) const
{
d = m_parser.parse_var_day_of_month(from, to);
return from;
}
InItrT get(InItrT& from,
InItrT& to,
std::ios_base& /*a_ios*/,
year_type& y) const
{
y = m_parser.parse_year(from, to, m_year_format);
return from;
}
InItrT get(InItrT& from,
InItrT& to,
std::ios_base& a_ios,
duration_type& dd) const
{
// skip leading whitespace
while(std::isspace(*from) && from != to) { ++from; }
/* num_get.get() will always consume the first character if it
* is a sign indicator (+/-). Special value strings may begin
* with one of these signs so we'll need a copy of it
* in case num_get.get() fails. */
char_type c = '\0';
// TODO Are these characters somewhere in the locale?
if(*from == '-' || *from == '+') {
c = *from;
}
typedef std::num_get<CharT, InItrT> num_get;
typename duration_type::duration_rep_type val = 0;
std::ios_base::iostate err = std::ios_base::goodbit;
if (std::has_facet<num_get>(a_ios.getloc())) {
from = std::use_facet<num_get>(a_ios.getloc()).get(from, to, a_ios, err, val);
}
else {
num_get* ng = new num_get();
std::locale l = std::locale(a_ios.getloc(), ng);
a_ios.imbue(l);
from = ng->get(from, to, a_ios, err, val);
}
if(err & std::ios_base::failbit){
typedef typename special_values_parser_type::match_results match_results;
match_results mr;
if(c == '-' || c == '+') { // was the first character consumed?
mr.cache += c;
}
m_sv_parser.match(from, to, mr);
if(mr.current_match == match_results::PARSE_ERROR) {
boost::throw_exception(std::ios_base::failure("Parse failed. No match found for '" + mr.cache + "'"));
BOOST_DATE_TIME_UNREACHABLE_EXPRESSION(return from); // should never reach
}
dd = duration_type(static_cast<special_values>(mr.current_match));
}
else {
dd = duration_type(val);
}
return from;
}
InItrT get(InItrT& from,
InItrT& to,
std::ios_base& a_ios,
period_type& p) const
{
p = m_period_parser.get_period(from, to, a_ios, p, duration_type::unit(), *this);
return from;
}
InItrT get(InItrT& from,
InItrT& to,
std::ios_base& a_ios,
nth_kday_type& nkd) const
{
nkd = m_date_gen_parser.get_nth_kday_type(from, to, a_ios, *this);
return from;
}
InItrT get(InItrT& from,
InItrT& to,
std::ios_base& a_ios,
partial_date_type& pd) const
{
pd = m_date_gen_parser.get_partial_date_type(from, to, a_ios, *this);
return from;
}
InItrT get(InItrT& from,
InItrT& to,
std::ios_base& a_ios,
first_kday_type& fkd) const
{
fkd = m_date_gen_parser.get_first_kday_type(from, to, a_ios, *this);
return from;
}
InItrT get(InItrT& from,
InItrT& to,
std::ios_base& a_ios,
last_kday_type& lkd) const
{
lkd = m_date_gen_parser.get_last_kday_type(from, to, a_ios, *this);
return from;
}
InItrT get(InItrT& from,
InItrT& to,
std::ios_base& a_ios,
kday_before_type& fkb) const
{
fkb = m_date_gen_parser.get_kday_before_type(from, to, a_ios, *this);
return from;
}
InItrT get(InItrT& from,
InItrT& to,
std::ios_base& a_ios,
kday_after_type& fka) const
{
fka = m_date_gen_parser.get_kday_after_type(from, to, a_ios, *this);
return from;
}
protected:
string_type m_format;
string_type m_month_format;
string_type m_weekday_format;
string_type m_year_format;
format_date_parser_type m_parser;
date_gen_parser_type m_date_gen_parser;
period_parser_type m_period_parser;
special_values_parser_type m_sv_parser;
private:
};
template <class date_type, class CharT, class OutItrT>
std::locale::id date_input_facet<date_type, CharT, OutItrT>::id;
template <class date_type, class CharT, class OutItrT>
const typename date_input_facet<date_type, CharT, OutItrT>::char_type
date_input_facet<date_type, CharT, OutItrT>::long_weekday_format[3] = {'%','A'};
template <class date_type, class CharT, class OutItrT>
const typename date_input_facet<date_type, CharT, OutItrT>::char_type
date_input_facet<date_type, CharT, OutItrT>::short_weekday_format[3] = {'%','a'};
template <class date_type, class CharT, class OutItrT>
const typename date_input_facet<date_type, CharT, OutItrT>::char_type
date_input_facet<date_type, CharT, OutItrT>::long_month_format[3] = {'%','B'};
template <class date_type, class CharT, class OutItrT>
const typename date_input_facet<date_type, CharT, OutItrT>::char_type
date_input_facet<date_type, CharT, OutItrT>::short_month_format[3] = {'%','b'};
template <class date_type, class CharT, class OutItrT>
const typename date_input_facet<date_type, CharT, OutItrT>::char_type
date_input_facet<date_type, CharT, OutItrT>::four_digit_year_format[3] = {'%','Y'};
template <class date_type, class CharT, class OutItrT>
const typename date_input_facet<date_type, CharT, OutItrT>::char_type
date_input_facet<date_type, CharT, OutItrT>::two_digit_year_format[3] = {'%','y'};
template <class date_type, class CharT, class OutItrT>
const typename date_input_facet<date_type, CharT, OutItrT>::char_type
date_input_facet<date_type, CharT, OutItrT>::default_period_separator[4] = { ' ', '/', ' '};
template <class date_type, class CharT, class OutItrT>
const typename date_input_facet<date_type, CharT, OutItrT>::char_type
date_input_facet<date_type, CharT, OutItrT>::standard_format_specifier[3] =
{'%', 'x' };
template <class date_type, class CharT, class OutItrT>
const typename date_input_facet<date_type, CharT, OutItrT>::char_type
date_input_facet<date_type, CharT, OutItrT>::iso_format_specifier[7] =
{'%', 'Y', '%', 'm', '%', 'd' };
template <class date_type, class CharT, class OutItrT>
const typename date_input_facet<date_type, CharT, OutItrT>::char_type
date_input_facet<date_type, CharT, OutItrT>::iso_format_extended_specifier[9] =
{'%', 'Y', '-', '%', 'm', '-', '%', 'd' };
template <class date_type, class CharT, class OutItrT>
const typename date_input_facet<date_type, CharT, OutItrT>::char_type
date_input_facet<date_type, CharT, OutItrT>::default_date_format[9] =
{'%','Y','-','%','b','-','%','d'};
} } // namespaces
#endif

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,137 @@
#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 <boost/io/ios_state.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:
{
boost::io::basic_ios_fill_saver<charT> ifs(os);
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,234 @@
#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 <boost/io/ios_state.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:
{
boost::io::basic_ios_fill_saver<charT> ifs(os);
os << std::setw(2) << std::setfill(os.widen('0')) << 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)
{
boost::io::basic_ios_fill_saver<charT> ifs(os);
std::ostreambuf_iterator<charT> oitr(os);
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(os.widen('0'))
<< 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(os.widen('0'))
<< 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(os.widen('0'))
<< 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,265 @@
#ifndef _DATE_TIME_DATE_GENERATOR_FORMATTER__HPP___
#define _DATE_TIME_DATE_GENERATOR_FORMATTER__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$
*/
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include "boost/date_time/date_generators.hpp"
namespace boost {
namespace date_time {
//! Formats date_generators for output
/*! Formatting of date_generators follows specific orders for the
* various types of date_generators.
* - partial_date => "dd Month"
* - nth_day_of_the_week_in_month => "nth weekday of month"
* - first_day_of_the_week_in_month => "first weekday of month"
* - last_day_of_the_week_in_month => "last weekday of month"
* - first_day_of_the_week_after => "weekday after"
* - first_day_of_the_week_before => "weekday before"
* While the order of the elements in these phrases cannot be changed,
* the elements themselves can be. Weekday and Month get their formats
* and names from the date_facet. The remaining elements are stored in
* the date_generator_formatter and can be customized upon construction
* or via a member function. The default elements are those shown in the
* examples above.
*/
template <class date_type, class CharT, class OutItrT = std::ostreambuf_iterator<CharT, std::char_traits<CharT> > >
class date_generator_formatter {
public:
typedef partial_date<date_type> partial_date_type;
typedef nth_kday_of_month<date_type> nth_kday_type;
typedef first_kday_of_month<date_type> first_kday_type;
typedef last_kday_of_month<date_type> last_kday_type;
typedef first_kday_after<date_type> kday_after_type;
typedef first_kday_before<date_type> kday_before_type;
typedef CharT char_type;
typedef std::basic_string<char_type> string_type;
typedef std::vector<string_type> collection_type;
static const char_type first_string[6];
static const char_type second_string[7];
static const char_type third_string[6];
static const char_type fourth_string[7];
static const char_type fifth_string[6];
static const char_type last_string[5];
static const char_type before_string[8];
static const char_type after_string[6];
static const char_type of_string[3];
enum phrase_elements {first=0, second, third, fourth, fifth, last,
before, after, of, number_of_phrase_elements};
//! Default format elements used
date_generator_formatter()
{
phrase_strings.reserve(number_of_phrase_elements);
phrase_strings.push_back(string_type(first_string));
phrase_strings.push_back(string_type(second_string));
phrase_strings.push_back(string_type(third_string));
phrase_strings.push_back(string_type(fourth_string));
phrase_strings.push_back(string_type(fifth_string));
phrase_strings.push_back(string_type(last_string));
phrase_strings.push_back(string_type(before_string));
phrase_strings.push_back(string_type(after_string));
phrase_strings.push_back(string_type(of_string));
}
//! Constructor that allows for a custom set of phrase elements
date_generator_formatter(const string_type& first_str,
const string_type& second_str,
const string_type& third_str,
const string_type& fourth_str,
const string_type& fifth_str,
const string_type& last_str,
const string_type& before_str,
const string_type& after_str,
const string_type& of_str)
{
phrase_strings.reserve(number_of_phrase_elements);
phrase_strings.push_back(first_str);
phrase_strings.push_back(second_str);
phrase_strings.push_back(third_str);
phrase_strings.push_back(fourth_str);
phrase_strings.push_back(fifth_str);
phrase_strings.push_back(last_str);
phrase_strings.push_back(before_str);
phrase_strings.push_back(after_str);
phrase_strings.push_back(of_str);
}
//! Replace the set of phrase elements with those contained in new_strings
/*! The order of the strings in the given collection is important.
* They must follow:
* - first, second, third, fourth, fifth, last, before, after, of.
*
* It is not necessary to send in a complete set if only a few
* elements are to be replaced as long as the correct beg_pos is used.
*
* Ex: To keep the default first through fifth elements, but replace
* the rest with a collection of:
* - "final", "prior", "following", "in".
* The beg_pos of date_generator_formatter::last would be used.
*/
void elements(const collection_type& new_strings,
phrase_elements beg_pos=first)
{
if(beg_pos < number_of_phrase_elements) {
typename collection_type::iterator itr = phrase_strings.begin();
itr += beg_pos;
std::copy(new_strings.begin(), new_strings.end(),
itr);
//phrase_strings.begin());
}
}
//!Put a partial_date => "dd Month"
template<class facet_type>
OutItrT put_partial_date(OutItrT next, std::ios_base& a_ios,
CharT a_fill, const partial_date_type& pd,
const facet_type& facet) const
{
facet.put(next, a_ios, a_fill, pd.day());
next = a_fill; //TODO change this ???
facet.put(next, a_ios, a_fill, pd.month());
return next;
}
//! Put an nth_day_of_the_week_in_month => "nth weekday of month"
template<class facet_type>
OutItrT put_nth_kday(OutItrT next, std::ios_base& a_ios,
CharT a_fill, const nth_kday_type& nkd,
const facet_type& facet) const
{
put_string(next, phrase_strings[nkd.nth_week() -1]);
next = a_fill; //TODO change this ???
facet.put(next, a_ios, a_fill, nkd.day_of_week());
next = a_fill; //TODO change this ???
put_string(next, string_type(of_string));
next = a_fill; //TODO change this ???
facet.put(next, a_ios, a_fill, nkd.month());
return next;
}
//! Put a first_day_of_the_week_in_month => "first weekday of month"
template<class facet_type>
OutItrT put_first_kday(OutItrT next, std::ios_base& a_ios,
CharT a_fill, const first_kday_type& fkd,
const facet_type& facet) const
{
put_string(next, phrase_strings[first]);
next = a_fill; //TODO change this ???
facet.put(next, a_ios, a_fill, fkd.day_of_week());
next = a_fill; //TODO change this ???
put_string(next, string_type(of_string));
next = a_fill; //TODO change this ???
facet.put(next, a_ios, a_fill, fkd.month());
return next;
}
//! Put a last_day_of_the_week_in_month => "last weekday of month"
template<class facet_type>
OutItrT put_last_kday(OutItrT next, std::ios_base& a_ios,
CharT a_fill, const last_kday_type& lkd,
const facet_type& facet) const
{
put_string(next, phrase_strings[last]);
next = a_fill; //TODO change this ???
facet.put(next, a_ios, a_fill, lkd.day_of_week());
next = a_fill; //TODO change this ???
put_string(next, string_type(of_string));
next = a_fill; //TODO change this ???
facet.put(next, a_ios, a_fill, lkd.month());
return next;
}
//! Put a first_day_of_the_week_before => "weekday before"
template<class facet_type>
OutItrT put_kday_before(OutItrT next, std::ios_base& a_ios,
CharT a_fill, const kday_before_type& fkb,
const facet_type& facet) const
{
facet.put(next, a_ios, a_fill, fkb.day_of_week());
next = a_fill; //TODO change this ???
put_string(next, phrase_strings[before]);
return next;
}
//! Put a first_day_of_the_week_after => "weekday after"
template<class facet_type>
OutItrT put_kday_after(OutItrT next, std::ios_base& a_ios,
CharT a_fill, const kday_after_type& fka,
const facet_type& facet) const
{
facet.put(next, a_ios, a_fill, fka.day_of_week());
next = a_fill; //TODO change this ???
put_string(next, phrase_strings[after]);
return next;
}
private:
collection_type phrase_strings;
//! helper function to put the various member string into stream
OutItrT put_string(OutItrT next, const string_type& str) const
{
typename string_type::const_iterator itr = str.begin();
while(itr != str.end()) {
*next = *itr;
++itr;
++next;
}
return next;
}
};
template<class date_type, class CharT, class OutItrT>
const typename date_generator_formatter<date_type, CharT, OutItrT>::char_type
date_generator_formatter<date_type, CharT, OutItrT>::first_string[6] =
{'f','i','r','s','t'};
template<class date_type, class CharT, class OutItrT>
const typename date_generator_formatter<date_type, CharT, OutItrT>::char_type
date_generator_formatter<date_type, CharT, OutItrT>::second_string[7] =
{'s','e','c','o','n','d'};
template<class date_type, class CharT, class OutItrT>
const typename date_generator_formatter<date_type, CharT, OutItrT>::char_type
date_generator_formatter<date_type, CharT, OutItrT>::third_string[6] =
{'t','h','i','r','d'};
template<class date_type, class CharT, class OutItrT>
const typename date_generator_formatter<date_type, CharT, OutItrT>::char_type
date_generator_formatter<date_type, CharT, OutItrT>::fourth_string[7] =
{'f','o','u','r','t','h'};
template<class date_type, class CharT, class OutItrT>
const typename date_generator_formatter<date_type, CharT, OutItrT>::char_type
date_generator_formatter<date_type, CharT, OutItrT>::fifth_string[6] =
{'f','i','f','t','h'};
template<class date_type, class CharT, class OutItrT>
const typename date_generator_formatter<date_type, CharT, OutItrT>::char_type
date_generator_formatter<date_type, CharT, OutItrT>::last_string[5] =
{'l','a','s','t'};
template<class date_type, class CharT, class OutItrT>
const typename date_generator_formatter<date_type, CharT, OutItrT>::char_type
date_generator_formatter<date_type, CharT, OutItrT>::before_string[8] =
{'b','e','f','o','r','e'};
template<class date_type, class CharT, class OutItrT>
const typename date_generator_formatter<date_type, CharT, OutItrT>::char_type
date_generator_formatter<date_type, CharT, OutItrT>::after_string[6] =
{'a','f','t','e','r'};
template<class date_type, class CharT, class OutItrT>
const typename date_generator_formatter<date_type, CharT, OutItrT>::char_type
date_generator_formatter<date_type, CharT, OutItrT>::of_string[3] =
{'o','f'};
} } // namespaces
#endif // _DATE_TIME_DATE_GENERATOR_FORMATTER__HPP___

View File

@@ -0,0 +1,330 @@
#ifndef DATE_TIME_DATE_GENERATOR_PARSER_HPP__
#define DATE_TIME_DATE_GENERATOR_PARSER_HPP__
/* Copyright (c) 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 <vector>
#include <iterator> // istreambuf_iterator
#include <boost/throw_exception.hpp>
#include <boost/date_time/compiler_config.hpp>
#include <boost/date_time/string_parse_tree.hpp>
#include <boost/date_time/date_generators.hpp>
#include <boost/date_time/format_date_parser.hpp>
namespace boost { namespace date_time {
//! Class for date_generator parsing
/*! The elements of a date_generator "phrase" are parsed from the input stream in a
* particular order. All elements are required and the order in which they appear
* cannot change, however, the elements themselves can be changed. The default
* elements and their order are as follows:
*
* - partial_date => "dd Month"
* - nth_day_of_the_week_in_month => "nth weekday of month"
* - first_day_of_the_week_in_month => "first weekday of month"
* - last_day_of_the_week_in_month => "last weekday of month"
* - first_day_of_the_week_after => "weekday after"
* - first_day_of_the_week_before => "weekday before"
*
* Weekday and Month names and formats are handled via the date_input_facet.
*
*/
template<class date_type, typename charT>
class date_generator_parser
{
public:
typedef std::basic_string<charT> string_type;
typedef std::istreambuf_iterator<charT> stream_itr_type;
typedef typename date_type::month_type month_type;
typedef typename date_type::day_of_week_type day_of_week_type;
typedef typename date_type::day_type day_type;
typedef string_parse_tree<charT> parse_tree_type;
typedef typename parse_tree_type::parse_match_result_type match_results;
typedef std::vector<std::basic_string<charT> > collection_type;
typedef partial_date<date_type> partial_date_type;
typedef nth_kday_of_month<date_type> nth_kday_type;
typedef first_kday_of_month<date_type> first_kday_type;
typedef last_kday_of_month<date_type> last_kday_type;
typedef first_kday_after<date_type> kday_after_type;
typedef first_kday_before<date_type> kday_before_type;
typedef charT char_type;
static const char_type first_string[6];
static const char_type second_string[7];
static const char_type third_string[6];
static const char_type fourth_string[7];
static const char_type fifth_string[6];
static const char_type last_string[5];
static const char_type before_string[8];
static const char_type after_string[6];
static const char_type of_string[3];
enum phrase_elements {first=0, second, third, fourth, fifth, last,
before, after, of, number_of_phrase_elements};
//! Creates a date_generator_parser with the default set of "element_strings"
date_generator_parser()
{
element_strings(string_type(first_string),
string_type(second_string),
string_type(third_string),
string_type(fourth_string),
string_type(fifth_string),
string_type(last_string),
string_type(before_string),
string_type(after_string),
string_type(of_string));
}
//! Creates a date_generator_parser using a user defined set of element strings
date_generator_parser(const string_type& first_str,
const string_type& second_str,
const string_type& third_str,
const string_type& fourth_str,
const string_type& fifth_str,
const string_type& last_str,
const string_type& before_str,
const string_type& after_str,
const string_type& of_str)
{
element_strings(first_str, second_str, third_str, fourth_str, fifth_str,
last_str, before_str, after_str, of_str);
}
//! Replace strings that determine nth week for generator
void element_strings(const string_type& first_str,
const string_type& second_str,
const string_type& third_str,
const string_type& fourth_str,
const string_type& fifth_str,
const string_type& last_str,
const string_type& before_str,
const string_type& after_str,
const string_type& of_str)
{
collection_type phrases;
phrases.push_back(first_str);
phrases.push_back(second_str);
phrases.push_back(third_str);
phrases.push_back(fourth_str);
phrases.push_back(fifth_str);
phrases.push_back(last_str);
phrases.push_back(before_str);
phrases.push_back(after_str);
phrases.push_back(of_str);
m_element_strings = parse_tree_type(phrases, this->first); // enum first
}
void element_strings(const collection_type& col)
{
m_element_strings = parse_tree_type(col, this->first); // enum first
}
//! returns partial_date parsed from stream
template<class facet_type>
partial_date_type
get_partial_date_type(stream_itr_type& sitr,
stream_itr_type& stream_end,
std::ios_base& a_ios,
const facet_type& facet) const
{
// skip leading whitespace
while(std::isspace(*sitr) && sitr != stream_end) { ++sitr; }
day_type d(1);
month_type m(1);
facet.get(sitr, stream_end, a_ios, d);
facet.get(sitr, stream_end, a_ios, m);
return partial_date_type(d,m);
}
//! returns nth_kday_of_week parsed from stream
template<class facet_type>
nth_kday_type
get_nth_kday_type(stream_itr_type& sitr,
stream_itr_type& stream_end,
std::ios_base& a_ios,
const facet_type& facet) const
{
// skip leading whitespace
while(std::isspace(*sitr) && sitr != stream_end) { ++sitr; }
typename nth_kday_type::week_num wn;
day_of_week_type wd(0); // no default constructor
month_type m(1); // no default constructor
match_results mr = m_element_strings.match(sitr, stream_end);
switch(mr.current_match) {
case first : { wn = nth_kday_type::first; break; }
case second : { wn = nth_kday_type::second; break; }
case third : { wn = nth_kday_type::third; break; }
case fourth : { wn = nth_kday_type::fourth; break; }
case fifth : { wn = nth_kday_type::fifth; break; }
default:
{
boost::throw_exception(std::ios_base::failure("Parse failed. No match found for '" + mr.cache + "'"));
BOOST_DATE_TIME_UNREACHABLE_EXPRESSION(wn = nth_kday_type::first);
}
} // week num
facet.get(sitr, stream_end, a_ios, wd); // day_of_week
extract_element(sitr, stream_end, of); // "of" element
facet.get(sitr, stream_end, a_ios, m); // month
return nth_kday_type(wn, wd, m);
}
//! returns first_kday_of_week parsed from stream
template<class facet_type>
first_kday_type
get_first_kday_type(stream_itr_type& sitr,
stream_itr_type& stream_end,
std::ios_base& a_ios,
const facet_type& facet) const
{
// skip leading whitespace
while(std::isspace(*sitr) && sitr != stream_end) { ++sitr; }
day_of_week_type wd(0); // no default constructor
month_type m(1); // no default constructor
extract_element(sitr, stream_end, first); // "first" element
facet.get(sitr, stream_end, a_ios, wd); // day_of_week
extract_element(sitr, stream_end, of); // "of" element
facet.get(sitr, stream_end, a_ios, m); // month
return first_kday_type(wd, m);
}
//! returns last_kday_of_week parsed from stream
template<class facet_type>
last_kday_type
get_last_kday_type(stream_itr_type& sitr,
stream_itr_type& stream_end,
std::ios_base& a_ios,
const facet_type& facet) const
{
// skip leading whitespace
while(std::isspace(*sitr) && sitr != stream_end) { ++sitr; }
day_of_week_type wd(0); // no default constructor
month_type m(1); // no default constructor
extract_element(sitr, stream_end, last); // "last" element
facet.get(sitr, stream_end, a_ios, wd); // day_of_week
extract_element(sitr, stream_end, of); // "of" element
facet.get(sitr, stream_end, a_ios, m); // month
return last_kday_type(wd, m);
}
//! returns first_kday_of_week parsed from stream
template<class facet_type>
kday_before_type
get_kday_before_type(stream_itr_type& sitr,
stream_itr_type& stream_end,
std::ios_base& a_ios,
const facet_type& facet) const
{
// skip leading whitespace
while(std::isspace(*sitr) && sitr != stream_end) { ++sitr; }
day_of_week_type wd(0); // no default constructor
facet.get(sitr, stream_end, a_ios, wd); // day_of_week
extract_element(sitr, stream_end, before);// "before" element
return kday_before_type(wd);
}
//! returns first_kday_of_week parsed from stream
template<class facet_type>
kday_after_type
get_kday_after_type(stream_itr_type& sitr,
stream_itr_type& stream_end,
std::ios_base& a_ios,
const facet_type& facet) const
{
// skip leading whitespace
while(std::isspace(*sitr) && sitr != stream_end) { ++sitr; }
day_of_week_type wd(0); // no default constructor
facet.get(sitr, stream_end, a_ios, wd); // day_of_week
extract_element(sitr, stream_end, after); // "after" element
return kday_after_type(wd);
}
private:
parse_tree_type m_element_strings;
//! Extracts phrase element from input. Throws ios_base::failure on error.
void extract_element(stream_itr_type& sitr,
stream_itr_type& stream_end,
typename date_generator_parser::phrase_elements ele) const
{
// skip leading whitespace
while(std::isspace(*sitr) && sitr != stream_end) { ++sitr; }
match_results mr = m_element_strings.match(sitr, stream_end);
if(mr.current_match != ele) {
boost::throw_exception(std::ios_base::failure("Parse failed. No match found for '" + mr.cache + "'"));
}
}
};
template<class date_type, class CharT>
const typename date_generator_parser<date_type, CharT>::char_type
date_generator_parser<date_type, CharT>::first_string[6] =
{'f','i','r','s','t'};
template<class date_type, class CharT>
const typename date_generator_parser<date_type, CharT>::char_type
date_generator_parser<date_type, CharT>::second_string[7] =
{'s','e','c','o','n','d'};
template<class date_type, class CharT>
const typename date_generator_parser<date_type, CharT>::char_type
date_generator_parser<date_type, CharT>::third_string[6] =
{'t','h','i','r','d'};
template<class date_type, class CharT>
const typename date_generator_parser<date_type, CharT>::char_type
date_generator_parser<date_type, CharT>::fourth_string[7] =
{'f','o','u','r','t','h'};
template<class date_type, class CharT>
const typename date_generator_parser<date_type, CharT>::char_type
date_generator_parser<date_type, CharT>::fifth_string[6] =
{'f','i','f','t','h'};
template<class date_type, class CharT>
const typename date_generator_parser<date_type, CharT>::char_type
date_generator_parser<date_type, CharT>::last_string[5] =
{'l','a','s','t'};
template<class date_type, class CharT>
const typename date_generator_parser<date_type, CharT>::char_type
date_generator_parser<date_type, CharT>::before_string[8] =
{'b','e','f','o','r','e'};
template<class date_type, class CharT>
const typename date_generator_parser<date_type, CharT>::char_type
date_generator_parser<date_type, CharT>::after_string[6] =
{'a','f','t','e','r'};
template<class date_type, class CharT>
const typename date_generator_parser<date_type, CharT>::char_type
date_generator_parser<date_type, CharT>::of_string[3] =
{'o','f'};
} } //namespace
#endif // DATE_TIME_DATE_GENERATOR_PARSER_HPP__

View File

@@ -0,0 +1,514 @@
#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 <sstream>
#include <stdexcept>
#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.
@tparam 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 BOOST_OVERRIDE
{
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" */
std::string to_string() const BOOST_OVERRIDE
{
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.
inline const char* nth_as_str(int ele)
{
static const char* const _nth_as_str[] = {"out of range", "first", "second",
"third", "fourth", "fifth"};
if(ele >= 1 && ele <= 5) {
return _nth_as_str[ele];
}
else {
return _nth_as_str[0];
}
}
//! 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 Wednesday 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 BOOST_OVERRIDE
{
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. */
std::string to_string() const BOOST_OVERRIDE
{
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 BOOST_OVERRIDE
{
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. */
std::string to_string() const BOOST_OVERRIDE
{
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.
* @tparam 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 BOOST_OVERRIDE
{
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. */
std::string to_string() const BOOST_OVERRIDE
{
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;
const date_type& operator*() const {return current_;}
const date_type* operator->() const {return &current_;}
bool operator< (const date_type& d) const {return current_ < d;}
bool operator<= (const date_type& d) const {return current_ <= d;}
bool operator> (const date_type& d) const {return current_ > d;}
bool operator>= (const date_type& d) const {return current_ >= d;}
bool operator== (const date_type& d) const {return current_ == d;}
bool operator!= (const date_type& d) const {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,321 @@
#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/compiler_config.hpp>
#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 BOOST_SYMBOL_VISIBLE 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 BOOST_SYMBOL_VISIBLE 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,342 @@
#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 <map>
#include <string>
#include <sstream>
#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>
#include <boost/date_time/period.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.
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);
//c++98 support
#if defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX)
static std::map<std::string, unsigned short> month_map;
typedef std::map<std::string, unsigned short>::value_type vtype;
if( month_map.empty() ) {
month_map.insert( vtype("jan", static_cast<unsigned short>(1)) );
month_map.insert( vtype("january", static_cast<unsigned short>(1)) );
month_map.insert( vtype("feb", static_cast<unsigned short>(2)) );
month_map.insert( vtype("february", static_cast<unsigned short>(2)) );
month_map.insert( vtype("mar", static_cast<unsigned short>(3)) );
month_map.insert( vtype("march", static_cast<unsigned short>(3)) );
month_map.insert( vtype("apr", static_cast<unsigned short>(4)) );
month_map.insert( vtype("april", static_cast<unsigned short>(4)) );
month_map.insert( vtype("may", static_cast<unsigned short>(5)) );
month_map.insert( vtype("jun", static_cast<unsigned short>(6)) );
month_map.insert( vtype("june", static_cast<unsigned short>(6)) );
month_map.insert( vtype("jul", static_cast<unsigned short>(7)) );
month_map.insert( vtype("july", static_cast<unsigned short>(7)) );
month_map.insert( vtype("aug", static_cast<unsigned short>(8)) );
month_map.insert( vtype("august", static_cast<unsigned short>(8)) );
month_map.insert( vtype("sep", static_cast<unsigned short>(9)) );
month_map.insert( vtype("september", static_cast<unsigned short>(9)) );
month_map.insert( vtype("oct", static_cast<unsigned short>(10)) );
month_map.insert( vtype("october", static_cast<unsigned short>(10)) );
month_map.insert( vtype("nov", static_cast<unsigned short>(11)) );
month_map.insert( vtype("november", static_cast<unsigned short>(11)) );
month_map.insert( vtype("dec", static_cast<unsigned short>(12)) );
month_map.insert( vtype("december", static_cast<unsigned short>(12)) );
}
#else //c+11 and beyond
static std::map<std::string, unsigned short> month_map =
{ { "jan", static_cast<unsigned short>(1) }, { "january", static_cast<unsigned short>(1) },
{ "feb", static_cast<unsigned short>(2) }, { "february", static_cast<unsigned short>(2) },
{ "mar", static_cast<unsigned short>(3) }, { "march", static_cast<unsigned short>(3) },
{ "apr", static_cast<unsigned short>(4) }, { "april", static_cast<unsigned short>(4) },
{ "may", static_cast<unsigned short>(5) },
{ "jun", static_cast<unsigned short>(6) }, { "june", static_cast<unsigned short>(6) },
{ "jul", static_cast<unsigned short>(7) }, { "july", static_cast<unsigned short>(7) },
{ "aug", static_cast<unsigned short>(8) }, { "august", static_cast<unsigned short>(8) },
{ "sep", static_cast<unsigned short>(9) }, { "september", static_cast<unsigned short>(9) },
{ "oct", static_cast<unsigned short>(10) }, { "october", static_cast<unsigned short>(10)},
{ "nov", static_cast<unsigned short>(11) }, { "november", static_cast<unsigned short>(11)},
{ "dec", static_cast<unsigned short>(12) }, { "december", static_cast<unsigned short>(12)}
};
#endif
std::map<std::string, unsigned short>::const_iterator mitr = month_map.find( str );
if ( mitr != month_map.end() ) {
return mitr->second;
}
}
return 13; // intentionally out of range - name not found
}
//! 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_minutes length 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)
{
unsigned int start_minutes = static_cast<unsigned>(
dst_start_offset.hours() * 60 + dst_start_offset.minutes());
unsigned int end_minutes = static_cast<unsigned>(
dst_end_offset.hours() * 60 + dst_end_offset.minutes());
long length_minutes = static_cast<long>(
dst_length.hours() * 60 + dst_length.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, date_time::Mar);
return ssim.get_date(year);
} else {
//first sunday in april
fkday fsia(Sunday, date_time::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, date_time::Nov);
return fsin.get_date(year);
} else {
//last sunday in october
lkday lsio(Sunday, date_time::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,75 @@
/* 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
*/
#ifndef DATE_TIME_DATE_DST_TRANSITION_DAY_GEN_HPP__
#define DATE_TIME_DATE_DST_TRANSITION_DAY_GEN_HPP__
#include <string>
namespace boost {
namespace date_time {
//! Defines base interface for calculating start and end date of daylight savings
template<class date_type>
class dst_day_calc_rule
{
public:
typedef typename date_type::year_type year_type;
virtual ~dst_day_calc_rule() {}
virtual date_type start_day(year_type y) const=0;
virtual std::string start_rule_as_string() const=0;
virtual date_type end_day(year_type y) const=0;
virtual std::string end_rule_as_string() const=0;
};
//! Canonical form for a class that provides day rule calculation
/*! This class is used to generate specific sets of dst rules
*
*@tparam spec Provides a specifiction of the function object types used
* to generate start and end days of daylight savings as well
* as the date type.
*/
template<class spec>
class day_calc_dst_rule : public dst_day_calc_rule<typename spec::date_type>
{
public:
typedef typename spec::date_type date_type;
typedef typename date_type::year_type year_type;
typedef typename spec::start_rule start_rule;
typedef typename spec::end_rule end_rule;
day_calc_dst_rule(start_rule dst_start,
end_rule dst_end) :
dst_start_(dst_start),
dst_end_(dst_end)
{}
virtual date_type start_day(year_type y) const
{
return dst_start_.get_date(y);
}
virtual std::string start_rule_as_string() const
{
return dst_start_.to_string();
}
virtual date_type end_day(year_type y) const
{
return dst_end_.get_date(y);
}
virtual std::string end_rule_as_string() const
{
return dst_end_.to_string();
}
private:
start_rule dst_start_;
end_rule dst_end_;
};
} }//namespace
#endif

View File

@@ -0,0 +1,84 @@
#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
#include <boost/cstdint.hpp>
#include <boost/date_time/time.hpp>
#include <boost/date_time/date_defs.hpp>
namespace boost {
namespace date_time {
//! 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::detail::winapi::FILETIME_ 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 microsec_clock::file_time_to_microseconds function. This allows to
// avoid integer wrapping for dates before 1970-Jan-01.
// 100-nanos since 1601-Jan-01
uint64_t ft_as_integer = (static_cast< uint64_t >(ft.dwHighDateTime) << 32) | static_cast< uint64_t >(ft.dwLowDateTime);
uint64_t sec = ft_as_integer / 10000000UL;
uint32_t sub_sec = static_cast< uint32_t >(ft_as_integer % 10000000UL) // 100-nanoseconds since the last second
#if !defined(BOOST_DATE_TIME_POSIX_TIME_STD_CONFIG)
/ 10U; // microseconds since the last second
#else
* 100U; // 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,42 @@
#ifndef _BOOST_DATE_TIME_FIND_MATCH_HPP___
#define _BOOST_DATE_TIME_FIND_MATCH_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>
namespace boost {
namespace date_time {
//! 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
}
} } //namespace date_time
#endif

View File

@@ -0,0 +1,724 @@
#ifndef DATE_TIME_FORMAT_DATE_PARSER_HPP__
#define DATE_TIME_FORMAT_DATE_PARSER_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 "boost/lexical_cast.hpp"
#include "boost/date_time/string_parse_tree.hpp"
#include "boost/date_time/strings_from_facet.hpp"
#include "boost/date_time/special_values_parser.hpp"
#include <string>
#include <vector>
#include <sstream>
#include <iterator>
#ifndef BOOST_NO_STDC_NAMESPACE
# include <cctype>
#else
# include <ctype.h>
#endif
#ifdef BOOST_NO_STDC_NAMESPACE
namespace std {
using ::isspace;
using ::isdigit;
}
#endif
namespace boost { namespace date_time {
//! Helper function for parsing fixed length strings into integers
/*! Will consume 'length' number of characters from stream. Consumed
* character are transfered to parse_match_result struct.
* Returns '-1' if no number can be parsed or incorrect number of
* digits in stream. */
template<typename int_type, typename charT>
inline
int_type
fixed_string_to_int(std::istreambuf_iterator<charT>& itr,
std::istreambuf_iterator<charT>& stream_end,
parse_match_result<charT>& mr,
unsigned int length,
const charT& fill_char)
{
//typedef std::basic_string<charT> string_type;
unsigned int j = 0;
//string_type s;
while (j < length && itr != stream_end &&
(std::isdigit(*itr) || *itr == fill_char)) {
if(*itr == fill_char) {
/* Since a fill_char can be anything, we convert it to a zero.
* lexical_cast will behave predictably when zero is used as fill. */
mr.cache += ('0');
}
else {
mr.cache += (*itr);
}
itr++;
j++;
}
int_type i = static_cast<int_type>(-1);
// mr.cache will hold leading zeros. size() tells us when input is too short.
if(mr.cache.size() < length) {
return i;
}
try {
i = boost::lexical_cast<int_type>(mr.cache);
}catch(bad_lexical_cast&){
// we want to return -1 if the cast fails so nothing to do here
}
return i;
}
//! Helper function for parsing fixed length strings into integers
/*! Will consume 'length' number of characters from stream. Consumed
* character are transfered to parse_match_result struct.
* Returns '-1' if no number can be parsed or incorrect number of
* digits in stream. */
template<typename int_type, typename charT>
inline
int_type
fixed_string_to_int(std::istreambuf_iterator<charT>& itr,
std::istreambuf_iterator<charT>& stream_end,
parse_match_result<charT>& mr,
unsigned int length)
{
return fixed_string_to_int<int_type, charT>(itr, stream_end, mr, length, '0');
}
//! Helper function for parsing varied length strings into integers
/*! Will consume 'max_length' characters from stream only if those
* characters are digits. Returns '-1' if no number can be parsed.
* Will not parse a number preceeded by a '+' or '-'. */
template<typename int_type, typename charT>
inline
int_type
var_string_to_int(std::istreambuf_iterator<charT>& itr,
const std::istreambuf_iterator<charT>& stream_end,
unsigned int max_length)
{
typedef std::basic_string<charT> string_type;
unsigned int j = 0;
string_type s;
while (itr != stream_end && (j < max_length) && std::isdigit(*itr)) {
s += (*itr);
++itr;
++j;
}
int_type i = static_cast<int_type>(-1);
if(!s.empty()) {
i = boost::lexical_cast<int_type>(s);
}
return i;
}
//! Class with generic date parsing using a format string
/*! The following is the set of recognized format specifiers
- %a - Short weekday name
- %A - Long weekday name
- %b - Abbreviated month name
- %B - Full month name
- %d - Day of the month as decimal 01 to 31
- %j - Day of year as decimal from 001 to 366
- %m - Month name as a decimal 01 to 12
- %U - Week number 00 to 53 with first Sunday as the first day of week 1?
- %w - Weekday as decimal number 0 to 6 where Sunday == 0
- %W - Week number 00 to 53 where Monday is first day of week 1
- %x - facet default date representation
- %y - Year without the century - eg: 04 for 2004
- %Y - Year with century
The weekday specifiers (%a and %A) do not add to the date construction,
but they provide a way to skip over the weekday names for formats that
provide them.
todo -- Another interesting feature that this approach could provide is
an option to fill in any missing fields with the current values
from the clock. So if you have %m-%d the parser would detect
the missing year value and fill it in using the clock.
todo -- What to do with the %x. %x in the classic facet is just bad...
*/
template<class date_type, typename charT>
class format_date_parser
{
public:
typedef std::basic_string<charT> string_type;
typedef std::basic_istringstream<charT> stringstream_type;
typedef std::istreambuf_iterator<charT> stream_itr_type;
typedef typename string_type::const_iterator const_itr;
typedef typename date_type::year_type year_type;
typedef typename date_type::month_type month_type;
typedef typename date_type::day_type day_type;
typedef typename date_type::duration_type duration_type;
typedef typename date_type::day_of_week_type day_of_week_type;
typedef typename date_type::day_of_year_type day_of_year_type;
typedef string_parse_tree<charT> parse_tree_type;
typedef typename parse_tree_type::parse_match_result_type match_results;
typedef std::vector<std::basic_string<charT> > input_collection_type;
// TODO sv_parser uses its default constructor - write the others
format_date_parser(const string_type& format_str,
const input_collection_type& month_short_names,
const input_collection_type& month_long_names,
const input_collection_type& weekday_short_names,
const input_collection_type& weekday_long_names) :
m_format(format_str),
m_month_short_names(month_short_names, 1),
m_month_long_names(month_long_names, 1),
m_weekday_short_names(weekday_short_names),
m_weekday_long_names(weekday_long_names)
{}
format_date_parser(const string_type& format_str,
const std::locale& locale) :
m_format(format_str),
m_month_short_names(gather_month_strings<charT>(locale), 1),
m_month_long_names(gather_month_strings<charT>(locale, false), 1),
m_weekday_short_names(gather_weekday_strings<charT>(locale)),
m_weekday_long_names(gather_weekday_strings<charT>(locale, false))
{}
format_date_parser(const format_date_parser<date_type,charT>& fdp)
{
this->m_format = fdp.m_format;
this->m_month_short_names = fdp.m_month_short_names;
this->m_month_long_names = fdp.m_month_long_names;
this->m_weekday_short_names = fdp.m_weekday_short_names;
this->m_weekday_long_names = fdp.m_weekday_long_names;
}
string_type format() const
{
return m_format;
}
void format(string_type format_str)
{
m_format = format_str;
}
void short_month_names(const input_collection_type& month_names)
{
m_month_short_names = parse_tree_type(month_names, 1);
}
void long_month_names(const input_collection_type& month_names)
{
m_month_long_names = parse_tree_type(month_names, 1);
}
void short_weekday_names(const input_collection_type& weekday_names)
{
m_weekday_short_names = parse_tree_type(weekday_names);
}
void long_weekday_names(const input_collection_type& weekday_names)
{
m_weekday_long_names = parse_tree_type(weekday_names);
}
date_type
parse_date(const string_type& value,
const string_type& format_str,
const special_values_parser<date_type,charT>& sv_parser) const
{
stringstream_type ss(value);
stream_itr_type sitr(ss);
stream_itr_type stream_end;
return parse_date(sitr, stream_end, format_str, sv_parser);
}
date_type
parse_date(std::istreambuf_iterator<charT>& sitr,
std::istreambuf_iterator<charT>& stream_end,
const special_values_parser<date_type,charT>& sv_parser) const
{
return parse_date(sitr, stream_end, m_format, sv_parser);
}
/*! Of all the objects that the format_date_parser can parse, only a
* date can be a special value. Therefore, only parse_date checks
* for special_values. */
date_type
parse_date(std::istreambuf_iterator<charT>& sitr,
std::istreambuf_iterator<charT>& stream_end,
string_type format_str,
const special_values_parser<date_type,charT>& sv_parser) const
{
bool use_current_char = false;
// skip leading whitespace
while(std::isspace(*sitr) && sitr != stream_end) { ++sitr; }
short year(0), month(0), day(0), day_of_year(0);// wkday(0);
/* Initialized the following to their minimum values. These intermediate
* objects are used so we get specific exceptions when part of the input
* is unparsable.
* Ex: "205-Jan-15" will throw a bad_year, "2005-Jsn-15"- bad_month, etc.*/
year_type t_year(1400);
month_type t_month(1);
day_type t_day(1);
day_of_week_type wkday(0);
const_itr itr(format_str.begin());
while (itr != format_str.end() && (sitr != stream_end)) {
if (*itr == '%') {
if ( ++itr == format_str.end())
break;
if (*itr != '%') {
switch(*itr) {
case 'a':
{
//this value is just throw away. It could be used for
//error checking potentially, but it isn't helpful in
//actually constructing the date - we just need to get it
//out of the stream
match_results mr = m_weekday_short_names.match(sitr, stream_end);
if(mr.current_match == match_results::PARSE_ERROR) {
// check special_values
if(sv_parser.match(sitr, stream_end, mr)) {
return date_type(static_cast<special_values>(mr.current_match));
}
}
wkday = mr.current_match;
if (mr.has_remaining()) {
use_current_char = true;
}
break;
}
case 'A':
{
//this value is just throw away. It could be used for
//error checking potentially, but it isn't helpful in
//actually constructing the date - we just need to get it
//out of the stream
match_results mr = m_weekday_long_names.match(sitr, stream_end);
if(mr.current_match == match_results::PARSE_ERROR) {
// check special_values
if(sv_parser.match(sitr, stream_end, mr)) {
return date_type(static_cast<special_values>(mr.current_match));
}
}
wkday = mr.current_match;
if (mr.has_remaining()) {
use_current_char = true;
}
break;
}
case 'b':
{
match_results mr = m_month_short_names.match(sitr, stream_end);
if(mr.current_match == match_results::PARSE_ERROR) {
// check special_values
if(sv_parser.match(sitr, stream_end, mr)) {
return date_type(static_cast<special_values>(mr.current_match));
}
}
t_month = month_type(mr.current_match);
if (mr.has_remaining()) {
use_current_char = true;
}
break;
}
case 'B':
{
match_results mr = m_month_long_names.match(sitr, stream_end);
if(mr.current_match == match_results::PARSE_ERROR) {
// check special_values
if(sv_parser.match(sitr, stream_end, mr)) {
return date_type(static_cast<special_values>(mr.current_match));
}
}
t_month = month_type(mr.current_match);
if (mr.has_remaining()) {
use_current_char = true;
}
break;
}
case 'd':
{
match_results mr;
day = fixed_string_to_int<short, charT>(sitr, stream_end, mr, 2);
if(day == -1) {
if(sv_parser.match(sitr, stream_end, mr)) {
return date_type(static_cast<special_values>(mr.current_match));
}
}
t_day = day_type(day);
break;
}
case 'e':
{
match_results mr;
day = fixed_string_to_int<short, charT>(sitr, stream_end, mr, 2, ' ');
if(day == -1) {
if(sv_parser.match(sitr, stream_end, mr)) {
return date_type(static_cast<special_values>(mr.current_match));
}
}
t_day = day_type(day);
break;
}
case 'j':
{
match_results mr;
day_of_year = fixed_string_to_int<short, charT>(sitr, stream_end, mr, 3);
if(day_of_year == -1) {
if(sv_parser.match(sitr, stream_end, mr)) {
return date_type(static_cast<special_values>(mr.current_match));
}
}
// these next two lines are so we get an exception with bad input
day_of_year_type t_day_of_year(1);
t_day_of_year = day_of_year_type(day_of_year);
break;
}
case 'm':
{
match_results mr;
month = fixed_string_to_int<short, charT>(sitr, stream_end, mr, 2);
if(month == -1) {
if(sv_parser.match(sitr, stream_end, mr)) {
return date_type(static_cast<special_values>(mr.current_match));
}
}
t_month = month_type(month);
break;
}
case 'Y':
{
match_results mr;
year = fixed_string_to_int<short, charT>(sitr, stream_end, mr, 4);
if(year == -1) {
if(sv_parser.match(sitr, stream_end, mr)) {
return date_type(static_cast<special_values>(mr.current_match));
}
}
t_year = year_type(year);
break;
}
case 'y':
{
match_results mr;
year = fixed_string_to_int<short, charT>(sitr, stream_end, mr, 2);
if(year == -1) {
if(sv_parser.match(sitr, stream_end, mr)) {
return date_type(static_cast<special_values>(mr.current_match));
}
}
year += 2000; //make 2 digit years in this century
t_year = year_type(year);
break;
}
default:
{} //ignore those we don't understand
}//switch
}
else { // itr == '%', second consecutive
sitr++;
}
itr++; //advance past format specifier
}
else { //skip past chars in format and in buffer
itr++;
if (use_current_char) {
use_current_char = false;
}
else {
sitr++;
}
}
}
if (day_of_year > 0) {
date_type d(static_cast<unsigned short>(year-1),12,31); //end of prior year
return d + duration_type(day_of_year);
}
return date_type(t_year, t_month, t_day); // exceptions were thrown earlier
// if input was no good
}
//! Throws bad_month if unable to parse
month_type
parse_month(std::istreambuf_iterator<charT>& sitr,
std::istreambuf_iterator<charT>& stream_end,
string_type format_str) const
{
match_results mr;
return parse_month(sitr, stream_end, format_str, mr);
}
//! Throws bad_month if unable to parse
month_type
parse_month(std::istreambuf_iterator<charT>& sitr,
std::istreambuf_iterator<charT>& stream_end,
string_type format_str,
match_results& mr) const
{
bool use_current_char = false;
// skip leading whitespace
while(std::isspace(*sitr) && sitr != stream_end) { ++sitr; }
short month(0);
const_itr itr(format_str.begin());
while (itr != format_str.end() && (sitr != stream_end)) {
if (*itr == '%') {
if ( ++itr == format_str.end())
break;
if (*itr != '%') {
switch(*itr) {
case 'b':
{
mr = m_month_short_names.match(sitr, stream_end);
month = mr.current_match;
if (mr.has_remaining()) {
use_current_char = true;
}
break;
}
case 'B':
{
mr = m_month_long_names.match(sitr, stream_end);
month = mr.current_match;
if (mr.has_remaining()) {
use_current_char = true;
}
break;
}
case 'm':
{
month = var_string_to_int<short, charT>(sitr, stream_end, 2);
// var_string_to_int returns -1 if parse failed. That will
// cause a bad_month exception to be thrown so we do nothing here
break;
}
default:
{} //ignore those we don't understand
}//switch
}
else { // itr == '%', second consecutive
sitr++;
}
itr++; //advance past format specifier
}
else { //skip past chars in format and in buffer
itr++;
if (use_current_char) {
use_current_char = false;
}
else {
sitr++;
}
}
}
return month_type(month); // throws bad_month exception when values are zero
}
//! Expects 1 or 2 digits 1-31. Throws bad_day_of_month if unable to parse
day_type
parse_var_day_of_month(std::istreambuf_iterator<charT>& sitr,
std::istreambuf_iterator<charT>& stream_end) const
{
// skip leading whitespace
while(std::isspace(*sitr) && sitr != stream_end) { ++sitr; }
return day_type(var_string_to_int<short, charT>(sitr, stream_end, 2));
}
//! Expects 2 digits 01-31. Throws bad_day_of_month if unable to parse
day_type
parse_day_of_month(std::istreambuf_iterator<charT>& sitr,
std::istreambuf_iterator<charT>& stream_end) const
{
// skip leading whitespace
while(std::isspace(*sitr) && sitr != stream_end) { ++sitr; }
//return day_type(var_string_to_int<short, charT>(sitr, stream_end, 2));
match_results mr;
return day_type(fixed_string_to_int<short, charT>(sitr, stream_end, mr, 2));
}
day_of_week_type
parse_weekday(std::istreambuf_iterator<charT>& sitr,
std::istreambuf_iterator<charT>& stream_end,
string_type format_str) const
{
match_results mr;
return parse_weekday(sitr, stream_end, format_str, mr);
}
day_of_week_type
parse_weekday(std::istreambuf_iterator<charT>& sitr,
std::istreambuf_iterator<charT>& stream_end,
string_type format_str,
match_results& mr) const
{
bool use_current_char = false;
// skip leading whitespace
while(std::isspace(*sitr) && sitr != stream_end) { ++sitr; }
short wkday(0);
const_itr itr(format_str.begin());
while (itr != format_str.end() && (sitr != stream_end)) {
if (*itr == '%') {
if ( ++itr == format_str.end())
break;
if (*itr != '%') {
switch(*itr) {
case 'a':
{
//this value is just throw away. It could be used for
//error checking potentially, but it isn't helpful in
//actually constructing the date - we just need to get it
//out of the stream
mr = m_weekday_short_names.match(sitr, stream_end);
wkday = mr.current_match;
if (mr.has_remaining()) {
use_current_char = true;
}
break;
}
case 'A':
{
//this value is just throw away. It could be used for
//error checking potentially, but it isn't helpful in
//actually constructing the date - we just need to get it
//out of the stream
mr = m_weekday_long_names.match(sitr, stream_end);
wkday = mr.current_match;
if (mr.has_remaining()) {
use_current_char = true;
}
break;
}
case 'w':
{
// weekday as number 0-6, Sunday == 0
wkday = var_string_to_int<short, charT>(sitr, stream_end, 2);
break;
}
default:
{} //ignore those we don't understand
}//switch
}
else { // itr == '%', second consecutive
sitr++;
}
itr++; //advance past format specifier
}
else { //skip past chars in format and in buffer
itr++;
if (use_current_char) {
use_current_char = false;
}
else {
sitr++;
}
}
}
return day_of_week_type(wkday); // throws bad_day_of_month exception
// when values are zero
}
//! throws bad_year if unable to parse
year_type
parse_year(std::istreambuf_iterator<charT>& sitr,
std::istreambuf_iterator<charT>& stream_end,
string_type format_str) const
{
match_results mr;
return parse_year(sitr, stream_end, format_str, mr);
}
//! throws bad_year if unable to parse
year_type
parse_year(std::istreambuf_iterator<charT>& sitr,
std::istreambuf_iterator<charT>& stream_end,
string_type format_str,
match_results& mr) const
{
// skip leading whitespace
while(std::isspace(*sitr) && sitr != stream_end) { ++sitr; }
unsigned short year(0);
const_itr itr(format_str.begin());
while (itr != format_str.end() && (sitr != stream_end)) {
if (*itr == '%') {
if ( ++itr == format_str.end())
break;
if (*itr != '%') {
//match_results mr;
switch(*itr) {
case 'Y':
{
// year from 4 digit string
year = fixed_string_to_int<short, charT>(sitr, stream_end, mr, 4);
break;
}
case 'y':
{
// year from 2 digit string (no century)
year = fixed_string_to_int<short, charT>(sitr, stream_end, mr, 2);
year += 2000; //make 2 digit years in this century
break;
}
default:
{} //ignore those we don't understand
}//switch
}
else { // itr == '%', second consecutive
sitr++;
}
itr++; //advance past format specifier
}
else { //skip past chars in format and in buffer
itr++;
sitr++;
}
}
return year_type(year); // throws bad_year exception when values are zero
}
private:
string_type m_format;
parse_tree_type m_month_short_names;
parse_tree_type m_month_long_names;
parse_tree_type m_weekday_short_names;
parse_tree_type m_weekday_long_names;
};
} } //namespace
#endif

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,49 @@
#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/compiler_config.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 BOOST_SYMBOL_VISIBLE 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,145 @@
#ifndef GREG_DATE_HPP___
#define GREG_DATE_HPP___
/* Copyright (c) 2002,2003, 2020 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/compiler_config.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 BOOST_SYMBOL_VISIBLE 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
BOOST_CXX14_CONSTEXPR 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
BOOST_CXX14_CONSTEXPR 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
BOOST_CXX14_CONSTEXPR explicit date(const ymd_type& ymd)
: date_time::date<date, gregorian_calendar, date_duration>(ymd)
{}
//! Needed copy constructor
BOOST_CXX14_CONSTEXPR explicit date(const date_int_type& rhs):
date_time::date<date,gregorian_calendar, date_duration>(rhs)
{}
//! Needed copy constructor
BOOST_CXX14_CONSTEXPR 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
BOOST_CXX14_CONSTEXPR 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.
BOOST_CXX14_CONSTEXPR 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)
BOOST_CXX14_CONSTEXPR 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.
BOOST_CXX14_CONSTEXPR 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
BOOST_CXX14_CONSTEXPR int week_number() const
{
ymd_type ymd = year_month_day();
return gregorian_calendar::week_number(ymd);
}
//! Return the day number from the calendar
BOOST_CXX14_CONSTEXPR date_int_type day_number() const
{
return days_;
}
//! Return the last day of the current month
BOOST_CXX14_CONSTEXPR date end_of_month() const
{
ymd_type ymd = year_month_day();
unsigned short eom_day = gregorian_calendar::end_of_month_day(ymd.year, ymd.month);
return date(ymd.year, ymd.month, eom_day);
}
friend BOOST_CXX14_CONSTEXPR
bool operator==(const date& lhs, const date& rhs);
private:
};
inline BOOST_CXX14_CONSTEXPR
bool operator==(const date& lhs, const date& rhs)
{
return lhs.days_ == rhs.days_;
}
} } //namespace gregorian
#endif

View File

@@ -0,0 +1,58 @@
#ifndef GREG_DAY_HPP___
#define GREG_DAY_HPP___
/* Copyright (c) 2002,2003,2020 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 <boost/date_time/compiler_config.hpp>
#include <stdexcept>
#include <string>
namespace boost {
namespace gregorian {
//! Exception type for gregorian day of month (1..31)
struct BOOST_SYMBOL_VISIBLE 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 BOOST_SYMBOL_VISIBLE greg_day : public greg_day_rep {
public:
BOOST_CXX14_CONSTEXPR greg_day(value_type day_of_month) : greg_day_rep(day_of_month) {}
BOOST_CXX14_CONSTEXPR value_type as_number() const {return value_;}
BOOST_CXX14_CONSTEXPR operator value_type() const {return value_;}
private:
};
} } //namespace gregorian
#endif

View File

@@ -0,0 +1,39 @@
#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 <boost/date_time/compiler_config.hpp>
#include <stdexcept>
#include <string>
namespace boost {
namespace gregorian {
//! Exception type for day of year (1..366)
struct BOOST_SYMBOL_VISIBLE 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,147 @@
#ifndef GREG_DURATION_HPP___
#define GREG_DURATION_HPP___
/* Copyright (c) 2002,2003, 2020 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/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 BOOST_SYMBOL_VISIBLE 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
BOOST_CXX14_CONSTEXPR explicit
date_duration(duration_rep day_count = 0) : base_type(day_count) {}
//! construct from special_values
BOOST_CXX14_CONSTEXPR
date_duration(date_time::special_values sv) : base_type(sv) {}
//! Construct from another date_duration
BOOST_CXX14_CONSTEXPR
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.
BOOST_CXX14_CONSTEXPR bool operator== (const date_duration& rhs) const
{
return base_type::operator== (rhs);
}
BOOST_CXX14_CONSTEXPR bool operator!= (const date_duration& rhs) const
{
return !operator== (rhs);
}
BOOST_CXX14_CONSTEXPR bool operator< (const date_duration& rhs) const
{
return base_type::operator< (rhs);
}
BOOST_CXX14_CONSTEXPR bool operator> (const date_duration& rhs) const
{
return !(base_type::operator< (rhs) || base_type::operator== (rhs));
}
BOOST_CXX14_CONSTEXPR bool operator<= (const date_duration& rhs) const
{
return (base_type::operator< (rhs) || base_type::operator== (rhs));
}
BOOST_CXX14_CONSTEXPR bool operator>= (const date_duration& rhs) const
{
return !base_type::operator< (rhs);
}
//! Subtract another duration -- result is signed
BOOST_CXX14_CONSTEXPR date_duration& operator-= (const date_duration& rhs)
{
base_type::operator-= (rhs);
return *this;
}
BOOST_CXX14_CONSTEXPR friend
date_duration operator- (date_duration rhs, date_duration const& lhs);
//! Add a duration -- result is signed
BOOST_CXX14_CONSTEXPR date_duration& operator+= (const date_duration& rhs)
{
base_type::operator+= (rhs);
return *this;
}
BOOST_CXX14_CONSTEXPR friend
date_duration operator+ (date_duration rhs, date_duration const& lhs);
//! unary- Allows for dd = -date_duration(2); -> dd == -2
BOOST_CXX14_CONSTEXPR date_duration operator- ()const
{
return date_duration(get_rep() * (-1));
}
//! Division operations on a duration with an integer.
BOOST_CXX14_CONSTEXPR date_duration& operator/= (int divisor)
{
base_type::operator/= (divisor);
return *this;
}
BOOST_CXX14_CONSTEXPR friend date_duration operator/ (date_duration rhs, int lhs);
//! Returns the smallest duration -- used by to calculate 'end'
static BOOST_CXX14_CONSTEXPR date_duration unit()
{
return date_duration(base_type::unit().get_rep());
}
};
inline BOOST_CXX14_CONSTEXPR
date_duration operator- (date_duration rhs, date_duration const& lhs)
{
rhs -= lhs;
return rhs;
}
inline BOOST_CXX14_CONSTEXPR
date_duration operator+ (date_duration rhs, date_duration const& lhs)
{
rhs += lhs;
return rhs;
}
inline BOOST_CXX14_CONSTEXPR date_duration operator/ (date_duration rhs, int lhs)
{
rhs /= lhs;
return rhs;
}
//! 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,44 @@
#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/compiler_config.hpp>
#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 BOOST_SYMBOL_VISIBLE 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 BOOST_SYMBOL_VISIBLE weeks_duration : public date_duration {
public:
BOOST_CXX14_CONSTEXPR weeks_duration(duration_rep w)
: date_duration(w * 7) {}
BOOST_CXX14_CONSTEXPR 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,374 @@
#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/compiler_config.hpp>
#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>
#include <boost/io/ios_state.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 BOOST_SYMBOL_VISIBLE 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
boost::io::basic_ios_fill_saver<charT> ifs(os);
os << std::setw(2) << std::setfill(os.widen('0')) << 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)
{
boost::io::basic_ios_fill_saver<charT> ifs(os);
os << std::setw(2) << std::setfill(os.widen('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';
#if defined(BOOST_NO_CXX11_SMART_PTR)
std::auto_ptr< const facet_def > f(create_facet_def(a));
#else
std::unique_ptr< const facet_def > f(create_facet_def(a));
#endif
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';
#if defined(BOOST_NO_CXX11_SMART_PTR)
std::auto_ptr< const facet_def > f(create_facet_def(a));
#else
std::unique_ptr< const facet_def > f(create_facet_def(a));
#endif
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,133 @@
#ifndef GREG_MONTH_HPP___
#define GREG_MONTH_HPP___
/* Copyright (c) 2002,2003, 2020 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 {
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 BOOST_SYMBOL_VISIBLE 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_SYMBOL_VISIBLE greg_month : public greg_month_rep {
public:
typedef date_time::months_of_year month_enum;
//! Construct a month from the months_of_year enumeration
BOOST_CXX14_CONSTEXPR greg_month(month_enum theMonth) :
greg_month_rep(static_cast<greg_month_rep::value_type>(theMonth)) {}
//! Construct from a short value
BOOST_CXX14_CONSTEXPR greg_month(value_type theMonth) : greg_month_rep(theMonth) {}
//! Convert the value back to a short
BOOST_CXX14_CONSTEXPR operator value_type() const {return value_;}
//! Returns month as number from 1 to 12
BOOST_CXX14_CONSTEXPR value_type as_number() const {return value_;}
BOOST_CXX14_CONSTEXPR month_enum as_enum() const {return static_cast<month_enum>(value_);}
//! Returns 3 char english string for the month ex: Jan, Feb, Mar, Apr
const char*
as_short_string() const
{
static const char* const short_month_names[NumMonths]
= {"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec", "NAM"};
return short_month_names[value_-1];
}
//! Returns full name of month as string in english ex: January, February
const char*
as_long_string() const
{
static const char* const long_month_names[NumMonths]
= {"January","February","March","April","May","June","July","August",
"September","October","November","December","NotAMonth"};
return long_month_names[value_-1];
}
#ifndef BOOST_NO_STD_WSTRING
//! Returns 3 wchar_t english string for the month ex: Jan, Feb, Mar, Apr
const wchar_t*
as_short_wstring() const
{
static const wchar_t* const w_short_month_names[NumMonths]
= {L"Jan",L"Feb",L"Mar",L"Apr",L"May",L"Jun",L"Jul",L"Aug",L"Sep",L"Oct",
L"Nov",L"Dec",L"NAM"};
return w_short_month_names[value_-1];
}
//! Returns full name of month as wchar_t string in english ex: January, February
const wchar_t*
as_long_wstring() const
{
static const wchar_t* const w_long_month_names[NumMonths]
= {L"January",L"February",L"March",L"April",L"May",L"June",L"July",L"August",
L"September",L"October",L"November",L"December",L"NotAMonth"};
return w_long_month_names[value_-1];
}
#endif // BOOST_NO_STD_WSTRING
/* 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,524 @@
#ifndef GREGORIAN_SERIALIZE_HPP___
#define GREGORIAN_SERIALIZE_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 "boost/date_time/gregorian/gregorian_types.hpp"
#include "boost/date_time/gregorian/parsers.hpp"
#include "boost/core/nvp.hpp"
namespace boost {
namespace gregorian {
std::string to_iso_string(const date&);
}
namespace serialization {
// A macro to split serialize functions into save & load functions.
// It is here to avoid dependency on Boost.Serialization just for the
// BOOST_SERIALIZATION_SPLIT_FREE macro
#define BOOST_DATE_TIME_SPLIT_FREE(T) \
template<class Archive> \
inline void serialize(Archive & ar, \
T & t, \
const unsigned int file_version) \
{ \
split_free(ar, t, file_version); \
}
/*! Method that does serialization for gregorian::date -- splits to load/save
*/
BOOST_DATE_TIME_SPLIT_FREE(::boost::gregorian::date)
BOOST_DATE_TIME_SPLIT_FREE(::boost::gregorian::date_duration)
BOOST_DATE_TIME_SPLIT_FREE(::boost::gregorian::date_duration::duration_rep)
BOOST_DATE_TIME_SPLIT_FREE(::boost::gregorian::date_period)
BOOST_DATE_TIME_SPLIT_FREE(::boost::gregorian::greg_year)
BOOST_DATE_TIME_SPLIT_FREE(::boost::gregorian::greg_month)
BOOST_DATE_TIME_SPLIT_FREE(::boost::gregorian::greg_day)
BOOST_DATE_TIME_SPLIT_FREE(::boost::gregorian::greg_weekday)
BOOST_DATE_TIME_SPLIT_FREE(::boost::gregorian::partial_date)
BOOST_DATE_TIME_SPLIT_FREE(::boost::gregorian::nth_kday_of_month)
BOOST_DATE_TIME_SPLIT_FREE(::boost::gregorian::first_kday_of_month)
BOOST_DATE_TIME_SPLIT_FREE(::boost::gregorian::last_kday_of_month)
BOOST_DATE_TIME_SPLIT_FREE(::boost::gregorian::first_kday_before)
BOOST_DATE_TIME_SPLIT_FREE(::boost::gregorian::first_kday_after)
#undef BOOST_DATE_TIME_SPLIT_FREE
//! Function to save gregorian::date objects using serialization lib
/*! Dates are serialized into a string for transport and storage.
* While it would be more efficient to store the internal
* integer used to manipulate the dates, it is an unstable solution.
*/
template<class Archive>
void save(Archive & ar,
const ::boost::gregorian::date & d,
unsigned int /* version */)
{
std::string ds = to_iso_string(d);
ar & make_nvp("date", ds);
}
//! Function to load gregorian::date objects using serialization lib
/*! Dates are serialized into a string for transport and storage.
* While it would be more efficient to store the internal
* integer used to manipulate the dates, it is an unstable solution.
*/
template<class Archive>
void load(Archive & ar,
::boost::gregorian::date & d,
unsigned int /*version*/)
{
std::string ds;
ar & make_nvp("date", ds);
try{
d = ::boost::gregorian::from_undelimited_string(ds);
}catch(bad_lexical_cast&) {
gregorian::special_values sv = gregorian::special_value_from_string(ds);
if(sv == gregorian::not_special) {
throw; // no match found, rethrow original exception
}
else {
d = gregorian::date(sv);
}
}
}
//!override needed b/c no default constructor
template<class Archive>
inline void load_construct_data(Archive & /*ar*/,
::boost::gregorian::date* dp,
const unsigned int /*file_version*/)
{
// retrieve data from archive required to construct new
// invoke inplace constructor to initialize instance of date
::new(dp) ::boost::gregorian::date(::boost::gregorian::not_a_date_time);
}
/**** date_duration ****/
//! Function to save gregorian::date_duration objects using serialization lib
template<class Archive>
void save(Archive & ar, const gregorian::date_duration & dd,
unsigned int /*version*/)
{
typename gregorian::date_duration::duration_rep dr = dd.get_rep();
ar & make_nvp("date_duration", dr);
}
//! Function to load gregorian::date_duration objects using serialization lib
template<class Archive>
void load(Archive & ar, gregorian::date_duration & dd, unsigned int /*version*/)
{
typename gregorian::date_duration::duration_rep dr(0);
ar & make_nvp("date_duration", dr);
dd = gregorian::date_duration(dr);
}
//!override needed b/c no default constructor
template<class Archive>
inline void load_construct_data(Archive & /*ar*/, gregorian::date_duration* dd,
const unsigned int /*file_version*/)
{
::new(dd) gregorian::date_duration(gregorian::not_a_date_time);
}
/**** date_duration::duration_rep (most likely int_adapter) ****/
//! helper unction to save date_duration objects using serialization lib
template<class Archive>
void save(Archive & ar, const gregorian::date_duration::duration_rep & dr,
unsigned int /*version*/)
{
typename gregorian::date_duration::duration_rep::int_type it = dr.as_number();
ar & make_nvp("date_duration_duration_rep", it);
}
//! helper function to load date_duration objects using serialization lib
template<class Archive>
void load(Archive & ar, gregorian::date_duration::duration_rep & dr, unsigned int /*version*/)
{
typename gregorian::date_duration::duration_rep::int_type it(0);
ar & make_nvp("date_duration_duration_rep", it);
dr = gregorian::date_duration::duration_rep::int_type(it);
}
//!override needed b/c no default constructor
template<class Archive>
inline void load_construct_data(Archive & /*ar*/, gregorian::date_duration::duration_rep* dr,
const unsigned int /*file_version*/)
{
::new(dr) gregorian::date_duration::duration_rep(0);
}
/**** date_period ****/
//! Function to save gregorian::date_period objects using serialization lib
/*! date_period objects are broken down into 2 parts for serialization:
* the begining date object and the end date object
*/
template<class Archive>
void save(Archive & ar, const gregorian::date_period& dp,
unsigned int /*version*/)
{
gregorian::date d1 = dp.begin();
gregorian::date d2 = dp.end();
ar & make_nvp("date_period_begin_date", d1);
ar & make_nvp("date_period_end_date", d2);
}
//! Function to load gregorian::date_period objects using serialization lib
/*! date_period objects are broken down into 2 parts for serialization:
* the begining date object and the end date object
*/
template<class Archive>
void load(Archive & ar, gregorian::date_period& dp, unsigned int /*version*/)
{
gregorian::date d1(gregorian::not_a_date_time);
gregorian::date d2(gregorian::not_a_date_time);
ar & make_nvp("date_period_begin_date", d1);
ar & make_nvp("date_period_end_date", d2);
dp = gregorian::date_period(d1,d2);
}
//!override needed b/c no default constructor
template<class Archive>
inline void load_construct_data(Archive & /*ar*/, gregorian::date_period* dp,
const unsigned int /*file_version*/)
{
gregorian::date d(gregorian::not_a_date_time);
gregorian::date_duration dd(1);
::new(dp) gregorian::date_period(d,dd);
}
/**** greg_year ****/
//! Function to save gregorian::greg_year objects using serialization lib
template<class Archive>
void save(Archive & ar, const gregorian::greg_year& gy,
unsigned int /*version*/)
{
unsigned short us = gy;
ar & make_nvp("greg_year", us);
}
//! Function to load gregorian::greg_year objects using serialization lib
template<class Archive>
void load(Archive & ar, gregorian::greg_year& gy, unsigned int /*version*/)
{
unsigned short us;
ar & make_nvp("greg_year", us);
gy = gregorian::greg_year(us);
}
//!override needed b/c no default constructor
template<class Archive>
inline void load_construct_data(Archive & /*ar*/, gregorian::greg_year* gy,
const unsigned int /*file_version*/)
{
::new(gy) gregorian::greg_year(1900);
}
/**** greg_month ****/
//! Function to save gregorian::greg_month objects using serialization lib
template<class Archive>
void save(Archive & ar, const gregorian::greg_month& gm,
unsigned int /*version*/)
{
unsigned short us = gm.as_number();
ar & make_nvp("greg_month", us);
}
//! Function to load gregorian::greg_month objects using serialization lib
template<class Archive>
void load(Archive & ar, gregorian::greg_month& gm, unsigned int /*version*/)
{
unsigned short us;
ar & make_nvp("greg_month", us);
gm = gregorian::greg_month(us);
}
//!override needed b/c no default constructor
template<class Archive>
inline void load_construct_data(Archive & /*ar*/, gregorian::greg_month* gm,
const unsigned int /*file_version*/)
{
::new(gm) gregorian::greg_month(1);
}
/**** greg_day ****/
//! Function to save gregorian::greg_day objects using serialization lib
template<class Archive>
void save(Archive & ar, const gregorian::greg_day& gd,
unsigned int /*version*/)
{
unsigned short us = gd.as_number();
ar & make_nvp("greg_day", us);
}
//! Function to load gregorian::greg_day objects using serialization lib
template<class Archive>
void load(Archive & ar, gregorian::greg_day& gd, unsigned int /*version*/)
{
unsigned short us;
ar & make_nvp("greg_day", us);
gd = gregorian::greg_day(us);
}
//!override needed b/c no default constructor
template<class Archive>
inline void load_construct_data(Archive & /*ar*/, gregorian::greg_day* gd,
const unsigned int /*file_version*/)
{
::new(gd) gregorian::greg_day(1);
}
/**** greg_weekday ****/
//! Function to save gregorian::greg_weekday objects using serialization lib
template<class Archive>
void save(Archive & ar, const gregorian::greg_weekday& gd,
unsigned int /*version*/)
{
unsigned short us = gd.as_number();
ar & make_nvp("greg_weekday", us);
}
//! Function to load gregorian::greg_weekday objects using serialization lib
template<class Archive>
void load(Archive & ar, gregorian::greg_weekday& gd, unsigned int /*version*/)
{
unsigned short us;
ar & make_nvp("greg_weekday", us);
gd = gregorian::greg_weekday(us);
}
//!override needed b/c no default constructor
template<class Archive>
inline void load_construct_data(Archive & /*ar*/, gregorian::greg_weekday* gd,
const unsigned int /*file_version*/)
{
::new(gd) gregorian::greg_weekday(1);
}
/**** date_generators ****/
/**** partial_date ****/
//! Function to save gregorian::partial_date objects using serialization lib
/*! partial_date objects are broken down into 2 parts for serialization:
* the day (typically greg_day) and month (typically greg_month) objects
*/
template<class Archive>
void save(Archive & ar, const gregorian::partial_date& pd,
unsigned int /*version*/)
{
gregorian::greg_day gd(pd.day());
gregorian::greg_month gm(pd.month().as_number());
ar & make_nvp("partial_date_day", gd);
ar & make_nvp("partial_date_month", gm);
}
//! Function to load gregorian::partial_date objects using serialization lib
/*! partial_date objects are broken down into 2 parts for serialization:
* the day (greg_day) and month (greg_month) objects
*/
template<class Archive>
void load(Archive & ar, gregorian::partial_date& pd, unsigned int /*version*/)
{
gregorian::greg_day gd(1);
gregorian::greg_month gm(1);
ar & make_nvp("partial_date_day", gd);
ar & make_nvp("partial_date_month", gm);
pd = gregorian::partial_date(gd,gm);
}
//!override needed b/c no default constructor
template<class Archive>
inline void load_construct_data(Archive & /*ar*/, gregorian::partial_date* pd,
const unsigned int /*file_version*/)
{
gregorian::greg_month gm(1);
gregorian::greg_day gd(1);
::new(pd) gregorian::partial_date(gd,gm);
}
/**** nth_kday_of_month ****/
//! Function to save nth_day_of_the_week_in_month objects using serialization lib
/*! nth_day_of_the_week_in_month objects are broken down into 3 parts for
* serialization: the week number, the day of the week, and the month
*/
template<class Archive>
void save(Archive & ar, const gregorian::nth_kday_of_month& nkd,
unsigned int /*version*/)
{
typename gregorian::nth_kday_of_month::week_num wn(nkd.nth_week());
typename gregorian::nth_kday_of_month::day_of_week_type d(nkd.day_of_week().as_number());
typename gregorian::nth_kday_of_month::month_type m(nkd.month().as_number());
ar & make_nvp("nth_kday_of_month_week_num", wn);
ar & make_nvp("nth_kday_of_month_day_of_week", d);
ar & make_nvp("nth_kday_of_month_month", m);
}
//! Function to load nth_day_of_the_week_in_month objects using serialization lib
/*! nth_day_of_the_week_in_month objects are broken down into 3 parts for
* serialization: the week number, the day of the week, and the month
*/
template<class Archive>
void load(Archive & ar, gregorian::nth_kday_of_month& nkd, unsigned int /*version*/)
{
typename gregorian::nth_kday_of_month::week_num wn(gregorian::nth_kday_of_month::first);
typename gregorian::nth_kday_of_month::day_of_week_type d(gregorian::Monday);
typename gregorian::nth_kday_of_month::month_type m(gregorian::Jan);
ar & make_nvp("nth_kday_of_month_week_num", wn);
ar & make_nvp("nth_kday_of_month_day_of_week", d);
ar & make_nvp("nth_kday_of_month_month", m);
nkd = gregorian::nth_kday_of_month(wn,d,m);
}
//!override needed b/c no default constructor
template<class Archive>
inline void load_construct_data(Archive & /*ar*/,
gregorian::nth_kday_of_month* nkd,
const unsigned int /*file_version*/)
{
// values used are not significant
::new(nkd) gregorian::nth_kday_of_month(gregorian::nth_kday_of_month::first,
gregorian::Monday,gregorian::Jan);
}
/**** first_kday_of_month ****/
//! Function to save first_day_of_the_week_in_month objects using serialization lib
/*! first_day_of_the_week_in_month objects are broken down into 2 parts for
* serialization: the day of the week, and the month
*/
template<class Archive>
void save(Archive & ar, const gregorian::first_kday_of_month& fkd,
unsigned int /*version*/)
{
typename gregorian::first_kday_of_month::day_of_week_type d(fkd.day_of_week().as_number());
typename gregorian::first_kday_of_month::month_type m(fkd.month().as_number());
ar & make_nvp("first_kday_of_month_day_of_week", d);
ar & make_nvp("first_kday_of_month_month", m);
}
//! Function to load first_day_of_the_week_in_month objects using serialization lib
/*! first_day_of_the_week_in_month objects are broken down into 2 parts for
* serialization: the day of the week, and the month
*/
template<class Archive>
void load(Archive & ar, gregorian::first_kday_of_month& fkd, unsigned int /*version*/)
{
typename gregorian::first_kday_of_month::day_of_week_type d(gregorian::Monday);
typename gregorian::first_kday_of_month::month_type m(gregorian::Jan);
ar & make_nvp("first_kday_of_month_day_of_week", d);
ar & make_nvp("first_kday_of_month_month", m);
fkd = gregorian::first_kday_of_month(d,m);
}
//!override needed b/c no default constructor
template<class Archive>
inline void load_construct_data(Archive & /*ar*/,
gregorian::first_kday_of_month* fkd,
const unsigned int /*file_version*/)
{
// values used are not significant
::new(fkd) gregorian::first_kday_of_month(gregorian::Monday,gregorian::Jan);
}
/**** last_kday_of_month ****/
//! Function to save last_day_of_the_week_in_month objects using serialization lib
/*! last_day_of_the_week_in_month objects are broken down into 2 parts for
* serialization: the day of the week, and the month
*/
template<class Archive>
void save(Archive & ar, const gregorian::last_kday_of_month& lkd,
unsigned int /*version*/)
{
typename gregorian::last_kday_of_month::day_of_week_type d(lkd.day_of_week().as_number());
typename gregorian::last_kday_of_month::month_type m(lkd.month().as_number());
ar & make_nvp("last_kday_of_month_day_of_week", d);
ar & make_nvp("last_kday_of_month_month", m);
}
//! Function to load last_day_of_the_week_in_month objects using serialization lib
/*! last_day_of_the_week_in_month objects are broken down into 2 parts for
* serialization: the day of the week, and the month
*/
template<class Archive>
void load(Archive & ar, gregorian::last_kday_of_month& lkd, unsigned int /*version*/)
{
typename gregorian::last_kday_of_month::day_of_week_type d(gregorian::Monday);
typename gregorian::last_kday_of_month::month_type m(gregorian::Jan);
ar & make_nvp("last_kday_of_month_day_of_week", d);
ar & make_nvp("last_kday_of_month_month", m);
lkd = gregorian::last_kday_of_month(d,m);
}
//!override needed b/c no default constructor
template<class Archive>
inline void load_construct_data(Archive & /*ar*/,
gregorian::last_kday_of_month* lkd,
const unsigned int /*file_version*/)
{
// values used are not significant
::new(lkd) gregorian::last_kday_of_month(gregorian::Monday,gregorian::Jan);
}
/**** first_kday_before ****/
//! Function to save first_day_of_the_week_before objects using serialization lib
template<class Archive>
void save(Archive & ar, const gregorian::first_kday_before& fkdb,
unsigned int /*version*/)
{
typename gregorian::first_kday_before::day_of_week_type d(fkdb.day_of_week().as_number());
ar & make_nvp("first_kday_before_day_of_week", d);
}
//! Function to load first_day_of_the_week_before objects using serialization lib
template<class Archive>
void load(Archive & ar, gregorian::first_kday_before& fkdb, unsigned int /*version*/)
{
typename gregorian::first_kday_before::day_of_week_type d(gregorian::Monday);
ar & make_nvp("first_kday_before_day_of_week", d);
fkdb = gregorian::first_kday_before(d);
}
//!override needed b/c no default constructor
template<class Archive>
inline void load_construct_data(Archive & /*ar*/,
gregorian::first_kday_before* fkdb,
const unsigned int /*file_version*/)
{
// values used are not significant
::new(fkdb) gregorian::first_kday_before(gregorian::Monday);
}
/**** first_kday_after ****/
//! Function to save first_day_of_the_week_after objects using serialization lib
template<class Archive>
void save(Archive & ar, const gregorian::first_kday_after& fkda,
unsigned int /*version*/)
{
typename gregorian::first_kday_after::day_of_week_type d(fkda.day_of_week().as_number());
ar & make_nvp("first_kday_after_day_of_week", d);
}
//! Function to load first_day_of_the_week_after objects using serialization lib
template<class Archive>
void load(Archive & ar, gregorian::first_kday_after& fkda, unsigned int /*version*/)
{
typename gregorian::first_kday_after::day_of_week_type d(gregorian::Monday);
ar & make_nvp("first_kday_after_day_of_week", d);
fkda = gregorian::first_kday_after(d);
}
//!override needed b/c no default constructor
template<class Archive>
inline void load_construct_data(Archive & /*ar*/,
gregorian::first_kday_after* fkda,
const unsigned int /*file_version*/)
{
// values used are not significant
::new(fkda) gregorian::first_kday_after(gregorian::Monday);
}
} // namespace serialization
} // namespace boost
#endif

View File

@@ -0,0 +1,100 @@
#ifndef GREG_WEEKDAY_HPP___
#define GREG_WEEKDAY_HPP___
/* Copyright (c) 2002,2003,2020 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 BOOST_SYMBOL_VISIBLE 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_SYMBOL_VISIBLE greg_weekday : public greg_weekday_rep {
public:
typedef boost::date_time::weekdays weekday_enum;
BOOST_CXX14_CONSTEXPR greg_weekday(value_type day_of_week_num) :
greg_weekday_rep(day_of_week_num)
{}
BOOST_CXX14_CONSTEXPR value_type as_number() const {return value_;}
BOOST_CXX14_CONSTEXPR weekday_enum as_enum() const {return static_cast<weekday_enum>(value_);}
//! Return a 3 digit english string of the day of week (eg: Sun)
const char* as_short_string() const
{
static const char* const short_weekday_names[]
= {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
return short_weekday_names[value_];
}
//! Return a point to a long english string representing day of week
const char* as_long_string() const
{
static const char* const long_weekday_names[]
= {"Sunday","Monday","Tuesday","Wednesday", "Thursday", "Friday", "Saturday"};
return long_weekday_names[value_];
}
#ifndef BOOST_NO_STD_WSTRING
//! Return a 3 digit english wchar_t string of the day of week (eg: Sun)
const wchar_t* as_short_wstring() const
{
static const wchar_t* const w_short_weekday_names[]={L"Sun", L"Mon", L"Tue",
L"Wed", L"Thu", L"Fri", L"Sat"};
return w_short_weekday_names[value_];
}
//! Return a point to a long english wchar_t string representing day of week
const wchar_t* as_long_wstring() const
{
static const wchar_t* const w_long_weekday_names[]= {L"Sunday",L"Monday",L"Tuesday",
L"Wednesday", L"Thursday",
L"Friday", L"Saturday"};
return w_long_weekday_names[value_];
}
#endif // BOOST_NO_STD_WSTRING
};
} } //namespace gregorian
#endif

View File

@@ -0,0 +1,52 @@
#ifndef GREG_YEAR_HPP___
#define GREG_YEAR_HPP___
/* Copyright (c) 2002,2003, 2020 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/compiler_config.hpp>
#include <boost/date_time/constrained_value.hpp>
#include <stdexcept>
#include <string>
namespace boost {
namespace gregorian {
//! Exception type for gregorian year
struct BOOST_SYMBOL_VISIBLE bad_year : public std::out_of_range
{
bad_year() :
std::out_of_range(std::string("Year is out of valid range: 1400..9999"))
{}
};
//! Policy class that declares error handling gregorian year type
typedef CV::simple_exception_policy<unsigned short, 1400, 9999, bad_year> greg_year_policies;
//! Generated representation for gregorian year
typedef CV::constrained_value<greg_year_policies> greg_year_rep;
//! Represent a year (range 1400 - 9999)
/*! This small class allows for simple conversion an integer value into
a year for the gregorian calendar. This currently only allows a
range of 1400 to 9999. 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 BOOST_SYMBOL_VISIBLE greg_year : public greg_year_rep {
public:
BOOST_CXX14_CONSTEXPR greg_year(value_type year) : greg_year_rep(year) {}
BOOST_CXX14_CONSTEXPR operator value_type() const {return value_;}
};
} } //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,38 @@
#ifndef GREGORIAN_HPP__
#define GREGORIAN_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$
*/
/*! @file gregorian.hpp
Single file header that provides overall include for all elements of
the gregorian date-time system. This includes the various types
defined, but also other functions for formatting and parsing.
*/
#include "boost/date_time/compiler_config.hpp"
#include "boost/date_time/gregorian/gregorian_types.hpp"
#include "boost/date_time/gregorian/conversion.hpp"
#if defined(BOOST_DATE_TIME_INCLUDE_LIMITED_HEADERS)
#include "boost/date_time/gregorian/formatters_limited.hpp"
#else
#include "boost/date_time/gregorian/formatters.hpp"
#endif
#if defined(USE_DATE_TIME_PRE_1_33_FACET_IO)
#include "boost/date_time/gregorian/greg_facet.hpp"
#else
#include "boost/date_time/gregorian/gregorian_io.hpp"
#endif // USE_DATE_TIME_PRE_1_33_FACET_IO
#include "boost/date_time/gregorian/parsers.hpp"
#endif

View File

@@ -0,0 +1,784 @@
#ifndef DATE_TIME_GREGORIAN_IO_HPP__
#define DATE_TIME_GREGORIAN_IO_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 <locale>
#include <iostream>
#include <iterator> // i/ostreambuf_iterator
#include <boost/io/ios_state.hpp>
#include <boost/date_time/date_facet.hpp>
#include <boost/date_time/period_parser.hpp>
#include <boost/date_time/period_formatter.hpp>
#include <boost/date_time/special_values_parser.hpp>
#include <boost/date_time/special_values_formatter.hpp>
#include <boost/date_time/gregorian/gregorian_types.hpp>
#include <boost/date_time/gregorian/conversion.hpp> // to_tm will be needed in the facets
namespace boost {
namespace gregorian {
typedef boost::date_time::period_formatter<wchar_t> wperiod_formatter;
typedef boost::date_time::period_formatter<char> period_formatter;
typedef boost::date_time::date_facet<date,wchar_t> wdate_facet;
typedef boost::date_time::date_facet<date,char> date_facet;
typedef boost::date_time::period_parser<date,char> period_parser;
typedef boost::date_time::period_parser<date,wchar_t> wperiod_parser;
typedef boost::date_time::special_values_formatter<char> special_values_formatter;
typedef boost::date_time::special_values_formatter<wchar_t> wspecial_values_formatter;
typedef boost::date_time::special_values_parser<date,char> special_values_parser;
typedef boost::date_time::special_values_parser<date,wchar_t> wspecial_values_parser;
typedef boost::date_time::date_input_facet<date,char> date_input_facet;
typedef boost::date_time::date_input_facet<date,wchar_t> wdate_input_facet;
template <class CharT, class TraitsT>
inline std::basic_ostream<CharT, TraitsT>&
operator<<(std::basic_ostream<CharT, TraitsT>& os, const boost::gregorian::date& d) {
boost::io::ios_flags_saver iflags(os);
typedef boost::date_time::date_facet<date, CharT> custom_date_facet;
std::ostreambuf_iterator<CharT> output_itr(os);
if (std::has_facet<custom_date_facet>(os.getloc()))
std::use_facet<custom_date_facet>(os.getloc()).put(output_itr, os, os.fill(), d);
else {
//instantiate a custom facet for dealing with dates since the user
//has not put one in the stream so far. This is for efficiency
//since we would always need to reconstruct for every date
//if the locale did not already exist. Of course this will be overridden
//if the user imbues at some later point. With the default settings
//for the facet the resulting format will be the same as the
//std::time_facet settings.
custom_date_facet* f = new custom_date_facet();
std::locale l = std::locale(os.getloc(), f);
os.imbue(l);
f->put(output_itr, os, os.fill(), d);
}
return os;
}
//! input operator for date
template <class CharT, class Traits>
inline
std::basic_istream<CharT, Traits>&
operator>>(std::basic_istream<CharT, Traits>& is, date& d)
{
boost::io::ios_flags_saver iflags(is);
typename std::basic_istream<CharT, Traits>::sentry strm_sentry(is, false);
if (strm_sentry) {
try {
typedef typename date_time::date_input_facet<date, CharT> date_input_facet_local;
std::istreambuf_iterator<CharT,Traits> sit(is), str_end;
if(std::has_facet<date_input_facet_local>(is.getloc())) {
std::use_facet<date_input_facet_local>(is.getloc()).get(sit, str_end, is, d);
}
else {
date_input_facet_local* f = new date_input_facet_local();
std::locale l = std::locale(is.getloc(), f);
is.imbue(l);
f->get(sit, str_end, is, d);
}
}
catch(...) {
// mask tells us what exceptions are turned on
std::ios_base::iostate exception_mask = is.exceptions();
// if the user wants exceptions on failbit, we'll rethrow our
// date_time exception & set the failbit
if(std::ios_base::failbit & exception_mask) {
try { is.setstate(std::ios_base::failbit); }
catch(std::ios_base::failure&) {} // ignore this one
throw; // rethrow original exception
}
else {
// if the user want's to fail quietly, we simply set the failbit
is.setstate(std::ios_base::failbit);
}
}
}
return is;
}
template <class CharT, class TraitsT>
inline std::basic_ostream<CharT, TraitsT>&
operator<<(std::basic_ostream<CharT, TraitsT>& os, const boost::gregorian::date_duration& dd) {
boost::io::ios_flags_saver iflags(os);
typedef boost::date_time::date_facet<date, CharT> custom_date_facet;
std::ostreambuf_iterator<CharT> output_itr(os);
if (std::has_facet<custom_date_facet>(os.getloc()))
std::use_facet<custom_date_facet>(os.getloc()).put(output_itr, os, os.fill(), dd);
else {
custom_date_facet* f = new custom_date_facet();
std::locale l = std::locale(os.getloc(), f);
os.imbue(l);
f->put(output_itr, os, os.fill(), dd);
}
return os;
}
//! input operator for date_duration
template <class CharT, class Traits>
inline
std::basic_istream<CharT, Traits>&
operator>>(std::basic_istream<CharT, Traits>& is, date_duration& dd)
{
boost::io::ios_flags_saver iflags(is);
typename std::basic_istream<CharT, Traits>::sentry strm_sentry(is, false);
if (strm_sentry) {
try {
typedef typename date_time::date_input_facet<date, CharT> date_input_facet_local;
std::istreambuf_iterator<CharT,Traits> sit(is), str_end;
if(std::has_facet<date_input_facet_local>(is.getloc())) {
std::use_facet<date_input_facet_local>(is.getloc()).get(sit, str_end, is, dd);
}
else {
date_input_facet_local* f = new date_input_facet_local();
std::locale l = std::locale(is.getloc(), f);
is.imbue(l);
f->get(sit, str_end, is, dd);
}
}
catch(...) {
std::ios_base::iostate exception_mask = is.exceptions();
if(std::ios_base::failbit & exception_mask) {
try { is.setstate(std::ios_base::failbit); }
catch(std::ios_base::failure&) {}
throw; // rethrow original exception
}
else {
is.setstate(std::ios_base::failbit);
}
}
}
return is;
}
template <class CharT, class TraitsT>
inline std::basic_ostream<CharT, TraitsT>&
operator<<(std::basic_ostream<CharT, TraitsT>& os, const boost::gregorian::date_period& dp) {
boost::io::ios_flags_saver iflags(os);
typedef boost::date_time::date_facet<date, CharT> custom_date_facet;
std::ostreambuf_iterator<CharT> output_itr(os);
if (std::has_facet<custom_date_facet>(os.getloc()))
std::use_facet<custom_date_facet>(os.getloc()).put(output_itr, os, os.fill(), dp);
else {
//instantiate a custom facet for dealing with date periods since the user
//has not put one in the stream so far. This is for efficiency
//since we would always need to reconstruct for every time period
//if the local did not already exist. Of course this will be overridden
//if the user imbues at some later point. With the default settings
//for the facet the resulting format will be the same as the
//std::time_facet settings.
custom_date_facet* f = new custom_date_facet();
std::locale l = std::locale(os.getloc(), f);
os.imbue(l);
f->put(output_itr, os, os.fill(), dp);
}
return os;
}
//! input operator for date_period
template <class CharT, class Traits>
inline
std::basic_istream<CharT, Traits>&
operator>>(std::basic_istream<CharT, Traits>& is, date_period& dp)
{
boost::io::ios_flags_saver iflags(is);
typename std::basic_istream<CharT, Traits>::sentry strm_sentry(is, false);
if (strm_sentry) {
try {
typedef typename date_time::date_input_facet<date, CharT> date_input_facet_local;
std::istreambuf_iterator<CharT,Traits> sit(is), str_end;
if(std::has_facet<date_input_facet_local>(is.getloc())) {
std::use_facet<date_input_facet_local>(is.getloc()).get(sit, str_end, is, dp);
}
else {
date_input_facet_local* f = new date_input_facet_local();
std::locale l = std::locale(is.getloc(), f);
is.imbue(l);
f->get(sit, str_end, is, dp);
}
}
catch(...) {
std::ios_base::iostate exception_mask = is.exceptions();
if(std::ios_base::failbit & exception_mask) {
try { is.setstate(std::ios_base::failbit); }
catch(std::ios_base::failure&) {}
throw; // rethrow original exception
}
else {
is.setstate(std::ios_base::failbit);
}
}
}
return is;
}
/********** small gregorian types **********/
template <class CharT, class TraitsT>
inline std::basic_ostream<CharT, TraitsT>&
operator<<(std::basic_ostream<CharT, TraitsT>& os, const boost::gregorian::greg_month& gm) {
boost::io::ios_flags_saver iflags(os);
typedef boost::date_time::date_facet<date, CharT> custom_date_facet;
std::ostreambuf_iterator<CharT> output_itr(os);
if (std::has_facet<custom_date_facet>(os.getloc()))
std::use_facet<custom_date_facet>(os.getloc()).put(output_itr, os, os.fill(), gm);
else {
custom_date_facet* f = new custom_date_facet();//-> 10/1074199752/32 because year & day not initialized in put(...)
//custom_date_facet* f = new custom_date_facet("%B");
std::locale l = std::locale(os.getloc(), f);
os.imbue(l);
f->put(output_itr, os, os.fill(), gm);
}
return os;
}
//! input operator for greg_month
template <class CharT, class Traits>
inline
std::basic_istream<CharT, Traits>&
operator>>(std::basic_istream<CharT, Traits>& is, greg_month& m)
{
boost::io::ios_flags_saver iflags(is);
typename std::basic_istream<CharT, Traits>::sentry strm_sentry(is, false);
if (strm_sentry) {
try {
typedef typename date_time::date_input_facet<date, CharT> date_input_facet_local;
std::istreambuf_iterator<CharT,Traits> sit(is), str_end;
if(std::has_facet<date_input_facet_local>(is.getloc())) {
std::use_facet<date_input_facet_local>(is.getloc()).get(sit, str_end, is, m);
}
else {
date_input_facet_local* f = new date_input_facet_local();
std::locale l = std::locale(is.getloc(), f);
is.imbue(l);
f->get(sit, str_end, is, m);
}
}
catch(...) {
std::ios_base::iostate exception_mask = is.exceptions();
if(std::ios_base::failbit & exception_mask) {
try { is.setstate(std::ios_base::failbit); }
catch(std::ios_base::failure&) {}
throw; // rethrow original exception
}
else {
is.setstate(std::ios_base::failbit);
}
}
}
return is;
}
template <class CharT, class TraitsT>
inline std::basic_ostream<CharT, TraitsT>&
operator<<(std::basic_ostream<CharT, TraitsT>& os, const boost::gregorian::greg_weekday& gw) {
boost::io::ios_flags_saver iflags(os);
typedef boost::date_time::date_facet<date, CharT> custom_date_facet;
std::ostreambuf_iterator<CharT> output_itr(os);
if (std::has_facet<custom_date_facet>(os.getloc()))
std::use_facet<custom_date_facet>(os.getloc()).put(output_itr, os, os.fill(), gw);
else {
custom_date_facet* f = new custom_date_facet();
std::locale l = std::locale(os.getloc(), f);
os.imbue(l);
f->put(output_itr, os, os.fill(), gw);
}
return os;
}
//! input operator for greg_weekday
template <class CharT, class Traits>
inline
std::basic_istream<CharT, Traits>&
operator>>(std::basic_istream<CharT, Traits>& is, greg_weekday& wd)
{
boost::io::ios_flags_saver iflags(is);
typename std::basic_istream<CharT, Traits>::sentry strm_sentry(is, false);
if (strm_sentry) {
try {
typedef typename date_time::date_input_facet<date, CharT> date_input_facet_local;
std::istreambuf_iterator<CharT,Traits> sit(is), str_end;
if(std::has_facet<date_input_facet_local>(is.getloc())) {
std::use_facet<date_input_facet_local>(is.getloc()).get(sit, str_end, is, wd);
}
else {
date_input_facet_local* f = new date_input_facet_local();
std::locale l = std::locale(is.getloc(), f);
is.imbue(l);
f->get(sit, str_end, is, wd);
}
}
catch(...) {
std::ios_base::iostate exception_mask = is.exceptions();
if(std::ios_base::failbit & exception_mask) {
try { is.setstate(std::ios_base::failbit); }
catch(std::ios_base::failure&) {}
throw; // rethrow original exception
}
else {
is.setstate(std::ios_base::failbit);
}
}
}
return is;
}
//NOTE: output operator for greg_day was not necessary
//! input operator for greg_day
template <class CharT, class Traits>
inline
std::basic_istream<CharT, Traits>&
operator>>(std::basic_istream<CharT, Traits>& is, greg_day& gd)
{
boost::io::ios_flags_saver iflags(is);
typename std::basic_istream<CharT, Traits>::sentry strm_sentry(is, false);
if (strm_sentry) {
try {
typedef typename date_time::date_input_facet<date, CharT> date_input_facet_local;
std::istreambuf_iterator<CharT,Traits> sit(is), str_end;
if(std::has_facet<date_input_facet_local>(is.getloc())) {
std::use_facet<date_input_facet_local>(is.getloc()).get(sit, str_end, is, gd);
}
else {
date_input_facet_local* f = new date_input_facet_local();
std::locale l = std::locale(is.getloc(), f);
is.imbue(l);
f->get(sit, str_end, is, gd);
}
}
catch(...) {
std::ios_base::iostate exception_mask = is.exceptions();
if(std::ios_base::failbit & exception_mask) {
try { is.setstate(std::ios_base::failbit); }
catch(std::ios_base::failure&) {}
throw; // rethrow original exception
}
else {
is.setstate(std::ios_base::failbit);
}
}
}
return is;
}
//NOTE: output operator for greg_year was not necessary
//! input operator for greg_year
template <class CharT, class Traits>
inline
std::basic_istream<CharT, Traits>&
operator>>(std::basic_istream<CharT, Traits>& is, greg_year& gy)
{
boost::io::ios_flags_saver iflags(is);
typename std::basic_istream<CharT, Traits>::sentry strm_sentry(is, false);
if (strm_sentry) {
try {
typedef typename date_time::date_input_facet<date, CharT> date_input_facet_local;
std::istreambuf_iterator<CharT,Traits> sit(is), str_end;
if(std::has_facet<date_input_facet_local>(is.getloc())) {
std::use_facet<date_input_facet_local>(is.getloc()).get(sit, str_end, is, gy);
}
else {
date_input_facet_local* f = new date_input_facet_local();
std::locale l = std::locale(is.getloc(), f);
is.imbue(l);
f->get(sit, str_end, is, gy);
}
}
catch(...) {
std::ios_base::iostate exception_mask = is.exceptions();
if(std::ios_base::failbit & exception_mask) {
try { is.setstate(std::ios_base::failbit); }
catch(std::ios_base::failure&) {}
throw; // rethrow original exception
}
else {
is.setstate(std::ios_base::failbit);
}
}
}
return is;
}
/********** date generator types **********/
template <class CharT, class TraitsT>
inline std::basic_ostream<CharT, TraitsT>&
operator<<(std::basic_ostream<CharT, TraitsT>& os, const boost::gregorian::partial_date& pd) {
boost::io::ios_flags_saver iflags(os);
typedef boost::date_time::date_facet<date, CharT> custom_date_facet;
std::ostreambuf_iterator<CharT> output_itr(os);
if (std::has_facet<custom_date_facet>(os.getloc()))
std::use_facet<custom_date_facet>(os.getloc()).put(output_itr, os, os.fill(), pd);
else {
custom_date_facet* f = new custom_date_facet();
std::locale l = std::locale(os.getloc(), f);
os.imbue(l);
f->put(output_itr, os, os.fill(), pd);
}
return os;
}
//! input operator for partial_date
template <class CharT, class Traits>
inline
std::basic_istream<CharT, Traits>&
operator>>(std::basic_istream<CharT, Traits>& is, partial_date& pd)
{
boost::io::ios_flags_saver iflags(is);
typename std::basic_istream<CharT, Traits>::sentry strm_sentry(is, false);
if (strm_sentry) {
try {
typedef typename date_time::date_input_facet<date, CharT> date_input_facet_local;
std::istreambuf_iterator<CharT,Traits> sit(is), str_end;
if(std::has_facet<date_input_facet_local>(is.getloc())) {
std::use_facet<date_input_facet_local>(is.getloc()).get(sit, str_end, is, pd);
}
else {
date_input_facet_local* f = new date_input_facet_local();
std::locale l = std::locale(is.getloc(), f);
is.imbue(l);
f->get(sit, str_end, is, pd);
}
}
catch(...) {
std::ios_base::iostate exception_mask = is.exceptions();
if(std::ios_base::failbit & exception_mask) {
try { is.setstate(std::ios_base::failbit); }
catch(std::ios_base::failure&) {}
throw; // rethrow original exception
}
else {
is.setstate(std::ios_base::failbit);
}
}
}
return is;
}
template <class CharT, class TraitsT>
inline std::basic_ostream<CharT, TraitsT>&
operator<<(std::basic_ostream<CharT, TraitsT>& os, const boost::gregorian::nth_day_of_the_week_in_month& nkd) {
boost::io::ios_flags_saver iflags(os);
typedef boost::date_time::date_facet<date, CharT> custom_date_facet;
std::ostreambuf_iterator<CharT> output_itr(os);
if (std::has_facet<custom_date_facet>(os.getloc()))
std::use_facet<custom_date_facet>(os.getloc()).put(output_itr, os, os.fill(), nkd);
else {
custom_date_facet* f = new custom_date_facet();
std::locale l = std::locale(os.getloc(), f);
os.imbue(l);
f->put(output_itr, os, os.fill(), nkd);
}
return os;
}
//! input operator for nth_day_of_the_week_in_month
template <class CharT, class Traits>
inline
std::basic_istream<CharT, Traits>&
operator>>(std::basic_istream<CharT, Traits>& is,
nth_day_of_the_week_in_month& nday)
{
boost::io::ios_flags_saver iflags(is);
typename std::basic_istream<CharT, Traits>::sentry strm_sentry(is, false);
if (strm_sentry) {
try {
typedef typename date_time::date_input_facet<date, CharT> date_input_facet_local;
std::istreambuf_iterator<CharT,Traits> sit(is), str_end;
if(std::has_facet<date_input_facet_local>(is.getloc())) {
std::use_facet<date_input_facet_local>(is.getloc()).get(sit, str_end, is, nday);
}
else {
date_input_facet_local* f = new date_input_facet_local();
std::locale l = std::locale(is.getloc(), f);
is.imbue(l);
f->get(sit, str_end, is, nday);
}
}
catch(...) {
std::ios_base::iostate exception_mask = is.exceptions();
if(std::ios_base::failbit & exception_mask) {
try { is.setstate(std::ios_base::failbit); }
catch(std::ios_base::failure&) {}
throw; // rethrow original exception
}
else {
is.setstate(std::ios_base::failbit);
}
}
}
return is;
}
template <class CharT, class TraitsT>
inline std::basic_ostream<CharT, TraitsT>&
operator<<(std::basic_ostream<CharT, TraitsT>& os, const boost::gregorian::first_day_of_the_week_in_month& fkd) {
boost::io::ios_flags_saver iflags(os);
typedef boost::date_time::date_facet<date, CharT> custom_date_facet;
std::ostreambuf_iterator<CharT> output_itr(os);
if (std::has_facet<custom_date_facet>(os.getloc()))
std::use_facet<custom_date_facet>(os.getloc()).put(output_itr, os, os.fill(), fkd);
else {
custom_date_facet* f = new custom_date_facet();
std::locale l = std::locale(os.getloc(), f);
os.imbue(l);
f->put(output_itr, os, os.fill(), fkd);
}
return os;
}
//! input operator for first_day_of_the_week_in_month
template <class CharT, class Traits>
inline
std::basic_istream<CharT, Traits>&
operator>>(std::basic_istream<CharT, Traits>& is,
first_day_of_the_week_in_month& fkd)
{
boost::io::ios_flags_saver iflags(is);
typename std::basic_istream<CharT, Traits>::sentry strm_sentry(is, false);
if (strm_sentry) {
try {
typedef typename date_time::date_input_facet<date, CharT> date_input_facet_local;
std::istreambuf_iterator<CharT,Traits> sit(is), str_end;
if(std::has_facet<date_input_facet_local>(is.getloc())) {
std::use_facet<date_input_facet_local>(is.getloc()).get(sit, str_end, is, fkd);
}
else {
date_input_facet_local* f = new date_input_facet_local();
std::locale l = std::locale(is.getloc(), f);
is.imbue(l);
f->get(sit, str_end, is, fkd);
}
}
catch(...) {
std::ios_base::iostate exception_mask = is.exceptions();
if(std::ios_base::failbit & exception_mask) {
try { is.setstate(std::ios_base::failbit); }
catch(std::ios_base::failure&) {}
throw; // rethrow original exception
}
else {
is.setstate(std::ios_base::failbit);
}
}
}
return is;
}
template <class CharT, class TraitsT>
inline std::basic_ostream<CharT, TraitsT>&
operator<<(std::basic_ostream<CharT, TraitsT>& os, const boost::gregorian::last_day_of_the_week_in_month& lkd) {
boost::io::ios_flags_saver iflags(os);
typedef boost::date_time::date_facet<date, CharT> custom_date_facet;
std::ostreambuf_iterator<CharT> output_itr(os);
if (std::has_facet<custom_date_facet>(os.getloc()))
std::use_facet<custom_date_facet>(os.getloc()).put(output_itr, os, os.fill(), lkd);
else {
custom_date_facet* f = new custom_date_facet();
std::locale l = std::locale(os.getloc(), f);
os.imbue(l);
f->put(output_itr, os, os.fill(), lkd);
}
return os;
}
//! input operator for last_day_of_the_week_in_month
template <class CharT, class Traits>
inline
std::basic_istream<CharT, Traits>&
operator>>(std::basic_istream<CharT, Traits>& is,
last_day_of_the_week_in_month& lkd)
{
boost::io::ios_flags_saver iflags(is);
typename std::basic_istream<CharT, Traits>::sentry strm_sentry(is, false);
if (strm_sentry) {
try {
typedef typename date_time::date_input_facet<date, CharT> date_input_facet_local;
std::istreambuf_iterator<CharT,Traits> sit(is), str_end;
if(std::has_facet<date_input_facet_local>(is.getloc())) {
std::use_facet<date_input_facet_local>(is.getloc()).get(sit, str_end, is, lkd);
}
else {
date_input_facet_local* f = new date_input_facet_local();
std::locale l = std::locale(is.getloc(), f);
is.imbue(l);
f->get(sit, str_end, is, lkd);
}
}
catch(...) {
std::ios_base::iostate exception_mask = is.exceptions();
if(std::ios_base::failbit & exception_mask) {
try { is.setstate(std::ios_base::failbit); }
catch(std::ios_base::failure&) {}
throw; // rethrow original exception
}
else {
is.setstate(std::ios_base::failbit);
}
}
}
return is;
}
template <class CharT, class TraitsT>
inline std::basic_ostream<CharT, TraitsT>&
operator<<(std::basic_ostream<CharT, TraitsT>& os, const boost::gregorian::first_day_of_the_week_after& fda) {
boost::io::ios_flags_saver iflags(os);
typedef boost::date_time::date_facet<date, CharT> custom_date_facet;
std::ostreambuf_iterator<CharT> output_itr(os);
if (std::has_facet<custom_date_facet>(os.getloc())) {
std::use_facet<custom_date_facet>(os.getloc()).put(output_itr, os, os.fill(), fda);
}
else {
custom_date_facet* f = new custom_date_facet();
std::locale l = std::locale(os.getloc(), f);
os.imbue(l);
f->put(output_itr, os, os.fill(), fda);
}
return os;
}
//! input operator for first_day_of_the_week_after
template <class CharT, class Traits>
inline
std::basic_istream<CharT, Traits>&
operator>>(std::basic_istream<CharT, Traits>& is,
first_day_of_the_week_after& fka)
{
boost::io::ios_flags_saver iflags(is);
typename std::basic_istream<CharT, Traits>::sentry strm_sentry(is, false);
if (strm_sentry) {
try {
typedef typename date_time::date_input_facet<date, CharT> date_input_facet_local;
std::istreambuf_iterator<CharT,Traits> sit(is), str_end;
if(std::has_facet<date_input_facet_local>(is.getloc())) {
std::use_facet<date_input_facet_local>(is.getloc()).get(sit, str_end, is, fka);
}
else {
date_input_facet_local* f = new date_input_facet_local();
std::locale l = std::locale(is.getloc(), f);
is.imbue(l);
f->get(sit, str_end, is, fka);
}
}
catch(...) {
std::ios_base::iostate exception_mask = is.exceptions();
if(std::ios_base::failbit & exception_mask) {
try { is.setstate(std::ios_base::failbit); }
catch(std::ios_base::failure&) {}
throw; // rethrow original exception
}
else {
is.setstate(std::ios_base::failbit);
}
}
}
return is;
}
template <class CharT, class TraitsT>
inline std::basic_ostream<CharT, TraitsT>&
operator<<(std::basic_ostream<CharT, TraitsT>& os, const boost::gregorian::first_day_of_the_week_before& fdb) {
boost::io::ios_flags_saver iflags(os);
typedef boost::date_time::date_facet<date, CharT> custom_date_facet;
std::ostreambuf_iterator<CharT> output_itr(os);
if (std::has_facet<custom_date_facet>(os.getloc())) {
std::use_facet<custom_date_facet>(os.getloc()).put(output_itr, os, os.fill(), fdb);
}
else {
custom_date_facet* f = new custom_date_facet();
std::locale l = std::locale(os.getloc(), f);
os.imbue(l);
f->put(output_itr, os, os.fill(), fdb);
}
return os;
}
//! input operator for first_day_of_the_week_before
template <class CharT, class Traits>
inline
std::basic_istream<CharT, Traits>&
operator>>(std::basic_istream<CharT, Traits>& is,
first_day_of_the_week_before& fkb)
{
boost::io::ios_flags_saver iflags(is);
typename std::basic_istream<CharT, Traits>::sentry strm_sentry(is, false);
if (strm_sentry) {
try {
typedef typename date_time::date_input_facet<date, CharT> date_input_facet_local;
std::istreambuf_iterator<CharT,Traits> sit(is), str_end;
if(std::has_facet<date_input_facet_local>(is.getloc())) {
std::use_facet<date_input_facet_local>(is.getloc()).get(sit, str_end, is, fkb);
}
else {
date_input_facet_local* f = new date_input_facet_local();
std::locale l = std::locale(is.getloc(), f);
is.imbue(l);
f->get(sit, str_end, is, fkb);
}
}
catch(...) {
std::ios_base::iostate exception_mask = is.exceptions();
if(std::ios_base::failbit & exception_mask) {
try { is.setstate(std::ios_base::failbit); }
catch(std::ios_base::failure&) {}
throw; // rethrow original exception
}
else {
is.setstate(std::ios_base::failbit);
}
}
}
return is;
}
} } // namespaces
#endif // DATE_TIME_GREGORIAN_IO_HPP__

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,110 @@
#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 <boost/date_time/special_defs.hpp>
#include <boost/date_time/find_match.hpp>
#include <string>
#include <iterator>
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 names.hpp),
* return 'not_special' */
inline
date_time::special_values
special_value_from_string(const std::string& s) {
static const char* const special_value_names[date_time::NumSpecialValues]
= {"not-a-date-time","-infinity","+infinity","min_date_time",
"max_date_time","not_special"};
short i = date_time::find_match(special_value_names,
special_value_names,
date_time::NumSpecialValues,
s);
if(i >= date_time::NumSpecialValues) { // match not found
return date_time::not_special;
}
else {
return static_cast<date_time::special_values>(i);
}
}
//! Deprecated: Use from_simple_string
inline date from_string(const 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(const 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(const 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(const 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(const 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,69 @@
#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$
*/
#include <boost/date_time/compiler_config.hpp>
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.
@tparam 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.
@tparam date_int_type_ Underlying type for the date count. Must be an arithmetic type.
*/
template<typename ymd_type_, typename date_int_type_>
class BOOST_SYMBOL_VISIBLE 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 BOOST_CXX14_CONSTEXPR unsigned short day_of_week(const ymd_type& ymd);
static BOOST_CXX14_CONSTEXPR int week_number(const ymd_type&ymd);
static BOOST_CXX14_CONSTEXPR date_int_type day_number(const ymd_type& ymd);
static BOOST_CXX14_CONSTEXPR date_int_type julian_day_number(const ymd_type& ymd);
static BOOST_CXX14_CONSTEXPR date_int_type modjulian_day_number(const ymd_type& ymd);
static BOOST_CXX14_CONSTEXPR ymd_type from_day_number(date_int_type);
static BOOST_CXX14_CONSTEXPR ymd_type from_julian_day_number(date_int_type);
static BOOST_CXX14_CONSTEXPR ymd_type from_modjulian_day_number(date_int_type);
static BOOST_CXX14_CONSTEXPR bool is_leap_year(year_type);
static BOOST_CXX14_CONSTEXPR unsigned short end_of_month_day(year_type y, month_type m);
static BOOST_CXX14_CONSTEXPR ymd_type epoch();
static BOOST_CXX14_CONSTEXPR unsigned short days_in_week();
};
} } //namespace
#include "boost/date_time/gregorian_calendar.ipp"
#endif

View File

@@ -0,0 +1,224 @@
/* 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 {
//! 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_CXX14_CONSTEXPR
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_CXX14_CONSTEXPR
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_CXX14_CONSTEXPR
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 = static_cast<unsigned long>(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_CXX14_CONSTEXPR
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_CXX14_CONSTEXPR
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_CXX14_CONSTEXPR
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_CXX14_CONSTEXPR
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_CXX14_CONSTEXPR
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_CXX14_CONSTEXPR
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_CXX14_CONSTEXPR
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 calendar start
template<typename ymd_type_, typename date_int_type_>
BOOST_CXX14_CONSTEXPR
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_CXX14_CONSTEXPR
inline
unsigned short
gregorian_calendar_base<ymd_type_,date_int_type_>::days_in_week()
{
return 7;
}
} } //namespace gregorian

View File

@@ -0,0 +1,516 @@
#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
#if defined(BOOST_MSVC)
#pragma warning(push)
// conditional expression is constant
#pragma warning(disable: 4127)
#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;
BOOST_CXX14_CONSTEXPR int_adapter(int_type v) :
value_(v)
{}
static BOOST_CONSTEXPR bool has_infinity()
{
return true;
}
static BOOST_CONSTEXPR int_adapter pos_infinity()
{
return (::std::numeric_limits<int_type>::max)();
}
static BOOST_CONSTEXPR int_adapter neg_infinity()
{
return (::std::numeric_limits<int_type>::min)();
}
static BOOST_CONSTEXPR int_adapter not_a_number()
{
return (::std::numeric_limits<int_type>::max)()-1;
}
static BOOST_CONSTEXPR int_adapter max BOOST_PREVENT_MACRO_SUBSTITUTION ()
{
return (::std::numeric_limits<int_type>::max)()-2;
}
static BOOST_CONSTEXPR int_adapter min BOOST_PREVENT_MACRO_SUBSTITUTION ()
{
return (::std::numeric_limits<int_type>::min)()+1;
}
static BOOST_CXX14_CONSTEXPR 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 BOOST_CONSTEXPR bool is_inf(int_type v)
{
return (v == neg_infinity().as_number() ||
v == pos_infinity().as_number());
}
static BOOST_CXX14_CONSTEXPR bool is_neg_inf(int_type v)
{
return (v == neg_infinity().as_number());
}
static BOOST_CXX14_CONSTEXPR bool is_pos_inf(int_type v)
{
return (v == pos_infinity().as_number());
}
static BOOST_CXX14_CONSTEXPR 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 BOOST_CXX14_CONSTEXPR 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 BOOST_CONSTEXPR int_type maxcount()
{
return (::std::numeric_limits<int_type>::max)()-3;
}
BOOST_CONSTEXPR bool is_infinity() const
{
return (value_ == neg_infinity().as_number() ||
value_ == pos_infinity().as_number());
}
BOOST_CONSTEXPR bool is_pos_infinity()const
{
return(value_ == pos_infinity().as_number());
}
BOOST_CONSTEXPR bool is_neg_infinity()const
{
return(value_ == neg_infinity().as_number());
}
BOOST_CONSTEXPR bool is_nan() const
{
return (value_ == not_a_number().as_number());
}
BOOST_CONSTEXPR bool is_special() const
{
return(is_infinity() || is_nan());
}
BOOST_CONSTEXPR bool operator==(const int_adapter& rhs) const
{
return (compare(rhs) == 0);
}
BOOST_CXX14_CONSTEXPR bool operator==(const int& rhs) const
{
if(!std::numeric_limits<int_type>::is_signed)
{
if(is_neg_inf(value_) && rhs == 0)
{
return false;
}
}
return (compare(rhs) == 0);
}
BOOST_CONSTEXPR bool operator!=(const int_adapter& rhs) const
{
return (compare(rhs) != 0);
}
BOOST_CXX14_CONSTEXPR bool operator!=(const int& rhs) const
{
if(!std::numeric_limits<int_type>::is_signed)
{
if(is_neg_inf(value_) && rhs == 0)
{
return true;
}
}
return (compare(rhs) != 0);
}
BOOST_CONSTEXPR bool operator<(const int_adapter& rhs) const
{
return (compare(rhs) == -1);
}
BOOST_CXX14_CONSTEXPR bool operator<(const int& rhs) const
{
// quiets compiler warnings
if(!std::numeric_limits<int_type>::is_signed)
{
if(is_neg_inf(value_) && rhs == 0)
{
return true;
}
}
return (compare(rhs) == -1);
}
BOOST_CONSTEXPR bool operator>(const int_adapter& rhs) const
{
return (compare(rhs) == 1);
}
BOOST_CONSTEXPR int_type as_number() const
{
return value_;
}
//! Returns either special value type or is_not_special
BOOST_CONSTEXPR 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>
BOOST_CXX14_CONSTEXPR
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()));
}
BOOST_CXX14_CONSTEXPR
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>
BOOST_CXX14_CONSTEXPR
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()));
}
BOOST_CXX14_CONSTEXPR
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 +-
BOOST_CXX14_CONSTEXPR
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. */
BOOST_CXX14_CONSTEXPR
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 +-
BOOST_CXX14_CONSTEXPR
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_); //NOLINT
}
}
return int_adapter<int_type>(value_ / rhs.value_);
}
/*! Provided for cases when automatic conversion from
* 'int' to 'int_adapter' causes incorrect results. */
BOOST_CXX14_CONSTEXPR
int_adapter operator/(const int rhs) const
{
if(is_special() && rhs != 0)
{
return mult_div_specials(rhs);
}
// let divide by zero blow itself up like int
return int_adapter<int_type>(value_ / rhs); //NOLINT
}
// should templatize this to be consistant with op +-
BOOST_CXX14_CONSTEXPR
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_); //NOLINT
}
}
return int_adapter<int_type>(value_ % rhs.value_);
}
/*! Provided for cases when automatic conversion from
* 'int' to 'int_adapter' causes incorrect results. */
BOOST_CXX14_CONSTEXPR
int_adapter operator%(const int rhs) const
{
if(is_special() && rhs != 0)
{
return mult_div_specials(rhs);
}
// let divide by zero blow itself up
return int_adapter<int_type>(value_ % rhs); //NOLINT
}
private:
int_type value_;
//! returns -1, 0, 1, or 2 if 'this' is <, ==, >, or 'nan comparison' rhs
BOOST_CXX14_CONSTEXPR
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
BOOST_CXX14_CONSTEXPR
int_adapter mult_div_specials(const int_adapter& rhs) const
{
if(this->is_nan() || rhs.is_nan()) {
return int_adapter<int_type>(not_a_number());
}
BOOST_CONSTEXPR_OR_CONST int min_value = std::numeric_limits<int_type>::is_signed ? 0 : 1;
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
BOOST_CXX14_CONSTEXPR
int_adapter mult_div_specials(const int& rhs) const
{
if(this->is_nan()) {
return int_adapter<int_type>(not_a_number());
}
BOOST_CONSTEXPR_OR_CONST int min_value = std::numeric_limits<int_type>::is_signed ? 0 : 1;
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
#if defined(BOOST_MSVC)
#pragma warning(pop)
#endif
#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,34 @@
#ifndef DATE_TIME_LOCAL_TIME_CONVERSION_HPP__
#define DATE_TIME_LOCAL_TIME_CONVERSION_HPP__
/* Copyright (c) 2003-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/posix_time/conversion.hpp"
#include "boost/date_time/c_time.hpp"
#include "boost/date_time/local_time/local_date_time.hpp"
namespace boost {
namespace local_time {
//! Function that creates a tm struct from a local_date_time
inline
std::tm to_tm(const local_date_time& lt) {
std::tm lt_tm = posix_time::to_tm(lt.local_time());
if(lt.is_dst()){
lt_tm.tm_isdst = 1;
}
else{
lt_tm.tm_isdst = 0;
}
return lt_tm;
}
}} // namespaces
#endif // DATE_TIME_LOCAL_TIME_CONVERSION_HPP__

View File

@@ -0,0 +1,168 @@
#ifndef LOCAL_TIME_CUSTOM_TIME_ZONE_HPP__
#define LOCAL_TIME_CUSTOM_TIME_ZONE_HPP__
/* Copyright (c) 2003-2005 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/time_zone_base.hpp"
#include "boost/date_time/time_zone_names.hpp"
#include "boost/date_time/posix_time/posix_time.hpp"
#include "boost/date_time/local_time/dst_transition_day_rules.hpp"
#include "boost/date_time/string_convert.hpp"
//#include "boost/date_time/special_defs.hpp"
#include "boost/shared_ptr.hpp"
namespace boost {
namespace local_time {
//typedef boost::date_time::time_zone_names time_zone_names;
typedef boost::date_time::dst_adjustment_offsets<boost::posix_time::time_duration> dst_adjustment_offsets;
//typedef boost::date_time::time_zone_base<boost::posix_time::ptime> time_zone;
typedef boost::shared_ptr<dst_calc_rule> dst_calc_rule_ptr;
//! A real time zone
template<class CharT>
class custom_time_zone_base : public date_time::time_zone_base<posix_time::ptime,CharT> {
public:
typedef boost::posix_time::time_duration time_duration_type;
typedef date_time::time_zone_base<posix_time::ptime,CharT> base_type;
typedef typename base_type::string_type string_type;
typedef typename base_type::stringstream_type stringstream_type;
typedef date_time::time_zone_names_base<CharT> time_zone_names;
typedef CharT char_type;
custom_time_zone_base(const time_zone_names& zone_names,
const time_duration_type& utc_offset,
const dst_adjustment_offsets& dst_shift,
boost::shared_ptr<dst_calc_rule> calc_rule) :
zone_names_(zone_names),
base_utc_offset_(utc_offset),
dst_offsets_(dst_shift),
dst_calc_rules_(calc_rule)
{}
virtual ~custom_time_zone_base() {}
virtual string_type dst_zone_abbrev() const
{
return zone_names_.dst_zone_abbrev();
}
virtual string_type std_zone_abbrev() const
{
return zone_names_.std_zone_abbrev();
}
virtual string_type dst_zone_name() const
{
return zone_names_.dst_zone_name();
}
virtual string_type std_zone_name() const
{
return zone_names_.std_zone_name();
}
//! True if zone uses daylight savings adjustments
virtual bool has_dst() const
{
return (bool) dst_calc_rules_; //if calc_rule is set the tz has dst
}
//! Local time that DST starts -- NADT if has_dst is false
virtual posix_time::ptime dst_local_start_time(gregorian::greg_year y) const
{
gregorian::date d(gregorian::not_a_date_time);
if (dst_calc_rules_) {
d = dst_calc_rules_->start_day(y);
}
return posix_time::ptime(d, dst_offsets_.dst_start_offset_);
}
//! Local time that DST ends -- NADT if has_dst is false
virtual posix_time::ptime dst_local_end_time(gregorian::greg_year y) const
{
gregorian::date d(gregorian::not_a_date_time);
if (dst_calc_rules_) {
d = dst_calc_rules_->end_day(y);
}
return posix_time::ptime(d, dst_offsets_.dst_end_offset_);
}
//! Base offset from UTC for zone (eg: -07:30:00)
virtual time_duration_type base_utc_offset() const
{
return base_utc_offset_;
}
//! Adjustment forward or back made while DST is in effect
virtual time_duration_type dst_offset() const
{
return dst_offsets_.dst_adjust_;
}
//! Returns a POSIX time_zone string for this object
virtual string_type to_posix_string() const
{
// std offset dst [offset],start[/time],end[/time] - w/o spaces
stringstream_type ss;
ss.fill('0');
boost::shared_ptr<dst_calc_rule> no_rules;
// std
ss << std_zone_abbrev();
// offset
if(base_utc_offset().is_negative()) {
// inverting the sign guarantees we get two digits
ss << '-' << std::setw(2) << base_utc_offset().invert_sign().hours();
}
else {
ss << '+' << std::setw(2) << base_utc_offset().hours();
}
if(base_utc_offset().minutes() != 0 || base_utc_offset().seconds() != 0) {
ss << ':' << std::setw(2) << base_utc_offset().minutes();
if(base_utc_offset().seconds() != 0) {
ss << ':' << std::setw(2) << base_utc_offset().seconds();
}
}
if(dst_calc_rules_ != no_rules) {
// dst
ss << dst_zone_abbrev();
// dst offset
if(dst_offset().is_negative()) {
// inverting the sign guarantees we get two digits
ss << '-' << std::setw(2) << dst_offset().invert_sign().hours();
}
else {
ss << '+' << std::setw(2) << dst_offset().hours();
}
if(dst_offset().minutes() != 0 || dst_offset().seconds() != 0) {
ss << ':' << std::setw(2) << dst_offset().minutes();
if(dst_offset().seconds() != 0) {
ss << ':' << std::setw(2) << dst_offset().seconds();
}
}
// start/time
ss << ',' << date_time::convert_string_type<char, char_type>(dst_calc_rules_->start_rule_as_string()) << '/'
<< std::setw(2) << dst_offsets_.dst_start_offset_.hours() << ':'
<< std::setw(2) << dst_offsets_.dst_start_offset_.minutes();
if(dst_offsets_.dst_start_offset_.seconds() != 0) {
ss << ':' << std::setw(2) << dst_offsets_.dst_start_offset_.seconds();
}
// end/time
ss << ',' << date_time::convert_string_type<char, char_type>(dst_calc_rules_->end_rule_as_string()) << '/'
<< std::setw(2) << dst_offsets_.dst_end_offset_.hours() << ':'
<< std::setw(2) << dst_offsets_.dst_end_offset_.minutes();
if(dst_offsets_.dst_end_offset_.seconds() != 0) {
ss << ':' << std::setw(2) << dst_offsets_.dst_end_offset_.seconds();
}
}
return ss.str();
}
private:
time_zone_names zone_names_;
time_duration_type base_utc_offset_;
dst_adjustment_offsets dst_offsets_;
boost::shared_ptr<dst_calc_rule> dst_calc_rules_;
};
typedef custom_time_zone_base<char> custom_time_zone;
} }//namespace
#endif

View File

@@ -0,0 +1,115 @@
#ifndef LOCAL_TIME_DATE_DURATION_OPERATORS_HPP___
#define LOCAL_TIME_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/local_time/local_date_time.hpp"
namespace boost {
namespace local_time {
/*!@file date_duration_operators.hpp Operators for local_date_time 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 local_date_time. Result will be same
* day-of-month as local_date_time unless original day was the last day of month.
* see date_time::months_duration for more details */
inline
local_date_time
operator+(const local_date_time& t, const boost::gregorian::months& m)
{
return t + m.get_offset(t.utc_time().date());
}
/*! Adds a months object to a local_date_time. Result will be same
* day-of-month as local_date_time unless original day was the last day of month.
* see date_time::months_duration for more details */
inline
local_date_time
operator+=(local_date_time& t, const boost::gregorian::months& m)
{
return t += m.get_offset(t.utc_time().date());
}
/*! Subtracts a months object and a local_date_time. Result will be same
* day-of-month as local_date_time unless original day was the last day of month.
* see date_time::months_duration for more details */
inline
local_date_time
operator-(const local_date_time& t, const boost::gregorian::months& m)
{
// get_neg_offset returns a negative duration, so we add
return t + m.get_neg_offset(t.utc_time().date());
}
/*! Subtracts a months object from a local_date_time. Result will be same
* day-of-month as local_date_time unless original day was the last day of month.
* see date_time::months_duration for more details */
inline
local_date_time
operator-=(local_date_time& t, const boost::gregorian::months& m)
{
// get_neg_offset returns a negative duration, so we add
return t += m.get_neg_offset(t.utc_time().date());
}
// local_date_time & years
/*! Adds a years object and a local_date_time. Result will be same
* month and day-of-month as local_date_time unless original day was the
* last day of month. see date_time::years_duration for more details */
inline
local_date_time
operator+(const local_date_time& t, const boost::gregorian::years& y)
{
return t + y.get_offset(t.utc_time().date());
}
/*! Adds a years object to a local_date_time. Result will be same
* month and day-of-month as local_date_time unless original day was the
* last day of month. see date_time::years_duration for more details */
inline
local_date_time
operator+=(local_date_time& t, const boost::gregorian::years& y)
{
return t += y.get_offset(t.utc_time().date());
}
/*! Subtracts a years object and a local_date_time. Result will be same
* month and day-of-month as local_date_time unless original day was the
* last day of month. see date_time::years_duration for more details */
inline
local_date_time
operator-(const local_date_time& t, const boost::gregorian::years& y)
{
// get_neg_offset returns a negative duration, so we add
return t + y.get_neg_offset(t.utc_time().date());
}
/*! Subtracts a years object from a local_date_time. Result will be same
* month and day-of-month as local_date_time unless original day was the
* last day of month. see date_time::years_duration for more details */
inline
local_date_time
operator-=(local_date_time& t, const boost::gregorian::years& y)
{
// get_neg_offset returns a negative duration, so we add
return t += y.get_neg_offset(t.utc_time().date());
}
}} // namespaces
#endif // LOCAL_TIME_DATE_DURATION_OPERATORS_HPP___

View File

@@ -0,0 +1,77 @@
#ifndef LOCAL_TIME_DST_TRANSITION_DAY_RULES_HPP__
#define LOCAL_TIME_DST_TRANSITION_DAY_RULES_HPP__
/* Copyright (c) 2003-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/gregorian_types.hpp"
#include "boost/date_time/dst_transition_generators.hpp"
namespace boost {
namespace local_time {
//! Provides rule of the form starting Apr 30 ending Oct 21
typedef date_time::dst_day_calc_rule<gregorian::date> dst_calc_rule;
struct partial_date_rule_spec
{
typedef gregorian::date date_type;
typedef gregorian::partial_date start_rule;
typedef gregorian::partial_date end_rule;
};
//! Provides rule of the form first Sunday in April, last Saturday in Oct
typedef date_time::day_calc_dst_rule<partial_date_rule_spec> partial_date_dst_rule;
struct first_last_rule_spec
{
typedef gregorian::date date_type;
typedef gregorian::first_kday_of_month start_rule;
typedef gregorian::last_kday_of_month end_rule;
};
//! Provides rule of the form first Sunday in April, last Saturday in Oct
typedef date_time::day_calc_dst_rule<first_last_rule_spec> first_last_dst_rule;
struct last_last_rule_spec
{
typedef gregorian::date date_type;
typedef gregorian::last_kday_of_month start_rule;
typedef gregorian::last_kday_of_month end_rule;
};
//! Provides rule of the form last Sunday in April, last Saturday in Oct
typedef date_time::day_calc_dst_rule<last_last_rule_spec> last_last_dst_rule;
struct nth_last_rule_spec
{
typedef gregorian::date date_type;
typedef gregorian::nth_kday_of_month start_rule;
typedef gregorian::last_kday_of_month end_rule;
};
//! Provides rule in form of [1st|2nd|3rd|4th] Sunday in April, last Sunday in Oct
typedef date_time::day_calc_dst_rule<nth_last_rule_spec> nth_last_dst_rule;
struct nth_kday_rule_spec
{
typedef gregorian::date date_type;
typedef gregorian::nth_kday_of_month start_rule;
typedef gregorian::nth_kday_of_month end_rule;
};
//! Provides rule in form of [1st|2nd|3rd|4th] Sunday in April/October
typedef date_time::day_calc_dst_rule<nth_kday_rule_spec> nth_kday_dst_rule;
//! Provides rule in form of [1st|2nd|3rd|4th] Sunday in April/October
typedef date_time::day_calc_dst_rule<nth_kday_rule_spec> nth_day_of_the_week_in_month_dst_rule;
} }//namespace
#endif

View File

@@ -0,0 +1,529 @@
#ifndef LOCAL_TIME_LOCAL_DATE_TIME_HPP__
#define LOCAL_TIME_LOCAL_DATE_TIME_HPP__
/* Copyright (c) 2003-2005 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 <string>
#include <iomanip>
#include <sstream>
#include <stdexcept>
#include <boost/shared_ptr.hpp>
#include <boost/throw_exception.hpp>
#include <boost/date_time/time.hpp>
#include <boost/date_time/posix_time/posix_time.hpp> //todo remove?
#include <boost/date_time/compiler_config.hpp>
#include <boost/date_time/dst_rules.hpp>
#include <boost/date_time/time_zone_base.hpp>
#include <boost/date_time/special_defs.hpp>
#include <boost/date_time/time_resolution_traits.hpp> // absolute_value
namespace boost {
namespace local_time {
//! simple exception for reporting when STD or DST cannot be determined
struct BOOST_SYMBOL_VISIBLE ambiguous_result : public std::logic_error
{
ambiguous_result (std::string const& msg = std::string()) :
std::logic_error(std::string("Daylight Savings Results are ambiguous: " + msg)) {}
};
//! simple exception for when time label given cannot exist
struct BOOST_SYMBOL_VISIBLE time_label_invalid : public std::logic_error
{
time_label_invalid (std::string const& msg = std::string()) :
std::logic_error(std::string("Time label given is invalid: " + msg)) {}
};
struct BOOST_SYMBOL_VISIBLE dst_not_valid: public std::logic_error
{
dst_not_valid(std::string const& msg = std::string()) :
std::logic_error(std::string("is_dst flag does not match resulting dst for time label given: " + msg)) {}
};
//TODO: I think these should be in local_date_time_base and not
// necessarily brought into the namespace
using date_time::time_is_dst_result;
using date_time::is_in_dst;
using date_time::is_not_in_dst;
using date_time::ambiguous;
using date_time::invalid_time_label;
//! Representation of "wall-clock" time in a particular time zone
/*! Representation of "wall-clock" time in a particular time zone
* Local_date_time_base holds a time value (date and time offset from 00:00)
* along with a time zone. The time value is stored as UTC and conversions
* to wall clock time are made as needed. This approach allows for
* operations between wall-clock times in different time zones, and
* daylight savings time considerations, to be made. Time zones are
* required to be in the form of a boost::shared_ptr<time_zone_base>.
*/
template<class utc_time_=posix_time::ptime,
class tz_type=date_time::time_zone_base<utc_time_,char> >
class BOOST_SYMBOL_VISIBLE local_date_time_base : public date_time::base_time<utc_time_,
boost::posix_time::posix_time_system> {
public:
typedef utc_time_ utc_time_type;
typedef typename utc_time_type::time_duration_type time_duration_type;
typedef typename utc_time_type::date_type date_type;
typedef typename date_type::duration_type date_duration_type;
typedef typename utc_time_type::time_system_type time_system_type;
/*! This constructor interprets the passed time as a UTC time.
* So, for example, if the passed timezone is UTC-5 then the
* time will be adjusted back 5 hours. The time zone allows for
* automatic calculation of whether the particular time is adjusted for
* daylight savings, etc.
* If the time zone shared pointer is null then time stays unadjusted.
*@param t A UTC time
*@param tz Timezone for to adjust the UTC time to.
*/
local_date_time_base(utc_time_type t,
boost::shared_ptr<tz_type> tz) :
date_time::base_time<utc_time_type, time_system_type>(t),
zone_(tz)
{
// param was already utc so nothing more to do
}
/*! This constructs a local time -- the passed time information
* understood to be in the passed tz. The DST flag must be passed
* to indicate whether the time is in daylight savings or not.
* @throws -- time_label_invalid if the time passed does not exist in
* the given locale. The non-existent case occurs typically
* during the shift-back from daylight savings time. When
* the clock is shifted forward a range of times
* (2 am to 3 am in the US) is skipped and hence is invalid.
* @throws -- dst_not_valid if the DST flag is passed for a period
* where DST is not active.
*/
local_date_time_base(date_type d,
time_duration_type td,
boost::shared_ptr<tz_type> tz,
bool dst_flag) : //necessary for constr_adj()
date_time::base_time<utc_time_type,time_system_type>(construction_adjustment(utc_time_type(d, td), tz, dst_flag)),
zone_(tz)
{
if(tz != boost::shared_ptr<tz_type>() && tz->has_dst()){
// d & td are already local so we use them
time_is_dst_result result = check_dst(d, td, tz);
bool in_dst = (result == is_in_dst); // less processing than is_dst()
// ambig occurs at end, invalid at start
if(result == invalid_time_label){
// Ex: 2:15am local on trans-in day in nyc, dst_flag irrelevant
std::ostringstream ss;
ss << "time given: " << d << ' ' << td;
boost::throw_exception(time_label_invalid(ss.str()));
}
else if(result != ambiguous && in_dst != dst_flag){
// is dst_flag accurate?
// Ex: false flag in NYC in June
std::ostringstream ss;
ss.setf(std::ios_base::boolalpha);
ss << "flag given: dst=" << dst_flag << ", dst calculated: dst=" << in_dst;
boost::throw_exception(dst_not_valid(ss.str()));
}
// everything checks out and conversion to utc already done
}
}
//TODO maybe not the right set...Ignore the last 2 for now...
enum DST_CALC_OPTIONS { EXCEPTION_ON_ERROR, NOT_DATE_TIME_ON_ERROR };
//ASSUME_DST_ON_ERROR, ASSUME_NOT_DST_ON_ERROR };
/*! This constructs a local time -- the passed time information
* understood to be in the passed tz. The DST flag is calculated
* according to the specified rule.
*/
local_date_time_base(date_type d,
time_duration_type td,
boost::shared_ptr<tz_type> tz,
DST_CALC_OPTIONS calc_option) :
// dummy value - time_ is set in constructor code
date_time::base_time<utc_time_type,time_system_type>(utc_time_type(d,td)),
zone_(tz)
{
time_is_dst_result result = check_dst(d, td, tz);
if(result == ambiguous) {
if(calc_option == EXCEPTION_ON_ERROR){
std::ostringstream ss;
ss << "time given: " << d << ' ' << td;
boost::throw_exception(ambiguous_result(ss.str()));
}
else{ // NADT on error
this->time_ = posix_time::posix_time_system::get_time_rep(date_type(date_time::not_a_date_time), time_duration_type(date_time::not_a_date_time));
}
}
else if(result == invalid_time_label){
if(calc_option == EXCEPTION_ON_ERROR){
std::ostringstream ss;
ss << "time given: " << d << ' ' << td;
boost::throw_exception(time_label_invalid(ss.str()));
}
else{ // NADT on error
this->time_ = posix_time::posix_time_system::get_time_rep(date_type(date_time::not_a_date_time), time_duration_type(date_time::not_a_date_time));
}
}
else if(result == is_in_dst){
utc_time_type t =
construction_adjustment(utc_time_type(d, td), tz, true);
this->time_ = posix_time::posix_time_system::get_time_rep(t.date(),
t.time_of_day());
}
else{
utc_time_type t =
construction_adjustment(utc_time_type(d, td), tz, false);
this->time_ = posix_time::posix_time_system::get_time_rep(t.date(),
t.time_of_day());
}
}
//! Determines if given time label is in daylight savings for given zone
/*! Determines if given time label is in daylight savings for given zone.
* Takes a date and time_duration representing a local time, along
* with time zone, and returns a time_is_dst_result object as result.
*/
static time_is_dst_result check_dst(date_type d,
time_duration_type td,
boost::shared_ptr<tz_type> tz)
{
if(tz != boost::shared_ptr<tz_type>() && tz->has_dst()) {
typedef typename date_time::dst_calculator<date_type, time_duration_type> dst_calculator;
return dst_calculator::local_is_dst(
d, td,
tz->dst_local_start_time(d.year()).date(),
tz->dst_local_start_time(d.year()).time_of_day(),
tz->dst_local_end_time(d.year()).date(),
tz->dst_local_end_time(d.year()).time_of_day(),
tz->dst_offset()
);
}
else{
return is_not_in_dst;
}
}
//! Simple destructor, releases time zone if last referrer
~local_date_time_base() {}
//! Copy constructor
local_date_time_base(const local_date_time_base& rhs) :
date_time::base_time<utc_time_type, time_system_type>(rhs),
zone_(rhs.zone_)
{}
//! Special values constructor
explicit local_date_time_base(const boost::date_time::special_values sv,
boost::shared_ptr<tz_type> tz = boost::shared_ptr<tz_type>()) :
date_time::base_time<utc_time_type, time_system_type>(utc_time_type(sv)),
zone_(tz)
{}
//! returns time zone associated with calling instance
boost::shared_ptr<tz_type> zone() const
{
return zone_;
}
//! returns false is time_zone is NULL and if time value is a special_value
bool is_dst() const
{
if(zone_ != boost::shared_ptr<tz_type>() && zone_->has_dst() && !this->is_special()) {
// check_dst takes a local time, *this is utc
utc_time_type lt(this->time_);
lt += zone_->base_utc_offset();
// dst_offset only needs to be considered with ambiguous time labels
// make that adjustment there
switch(check_dst(lt.date(), lt.time_of_day(), zone_)){
case is_not_in_dst:
return false;
case is_in_dst:
return true;
case ambiguous:
if(lt + zone_->dst_offset() < zone_->dst_local_end_time(lt.date().year())) {
return true;
}
break;
case invalid_time_label:
if(lt >= zone_->dst_local_start_time(lt.date().year())) {
return true;
}
break;
}
}
return false;
}
//! Returns object's time value as a utc representation
utc_time_type utc_time() const
{
return utc_time_type(this->time_);
}
//! Returns object's time value as a local representation
utc_time_type local_time() const
{
if(zone_ != boost::shared_ptr<tz_type>()){
utc_time_type lt = this->utc_time() + zone_->base_utc_offset();
if (is_dst()) {
lt += zone_->dst_offset();
}
return lt;
}
return utc_time_type(this->time_);
}
//! Returns string in the form "2003-Aug-20 05:00:00 EDT"
/*! Returns string in the form "2003-Aug-20 05:00:00 EDT". If
* time_zone is NULL the time zone abbreviation will be "UTC". The time
* zone abbrev will not be included if calling object is a special_value*/
std::string to_string() const
{
//TODO is this a temporary function ???
std::ostringstream ss;
if(this->is_special()){
ss << utc_time();
return ss.str();
}
if(zone_ == boost::shared_ptr<tz_type>()) {
ss << utc_time() << " UTC";
return ss.str();
}
bool is_dst_ = is_dst();
utc_time_type lt = this->utc_time() + zone_->base_utc_offset();
if (is_dst_) {
lt += zone_->dst_offset();
}
ss << local_time() << " ";
if (is_dst()) {
ss << zone_->dst_zone_abbrev();
}
else {
ss << zone_->std_zone_abbrev();
}
return ss.str();
}
/*! returns a local_date_time_base in the given time zone with the
* optional time_duration added. */
local_date_time_base local_time_in(boost::shared_ptr<tz_type> new_tz,
time_duration_type td=time_duration_type(0,0,0)) const
{
return local_date_time_base(utc_time_type(this->time_) + td, new_tz);
}
//! Returns name of associated time zone or "Coordinated Universal Time".
/*! Optional bool parameter will return time zone as an offset
* (ie "+07:00" extended iso format). Empty string is returned for
* classes that do not use a time_zone */
std::string zone_name(bool as_offset=false) const
{
if(zone_ == boost::shared_ptr<tz_type>()) {
if(as_offset) {
return std::string("Z");
}
else {
return std::string("Coordinated Universal Time");
}
}
if (is_dst()) {
if(as_offset) {
time_duration_type td = zone_->base_utc_offset();
td += zone_->dst_offset();
return zone_as_offset(td, ":");
}
else {
return zone_->dst_zone_name();
}
}
else {
if(as_offset) {
time_duration_type td = zone_->base_utc_offset();
return zone_as_offset(td, ":");
}
else {
return zone_->std_zone_name();
}
}
}
//! Returns abbreviation of associated time zone or "UTC".
/*! Optional bool parameter will return time zone as an offset
* (ie "+0700" iso format). Empty string is returned for classes
* that do not use a time_zone */
std::string zone_abbrev(bool as_offset=false) const
{
if(zone_ == boost::shared_ptr<tz_type>()) {
if(as_offset) {
return std::string("Z");
}
else {
return std::string("UTC");
}
}
if (is_dst()) {
if(as_offset) {
time_duration_type td = zone_->base_utc_offset();
td += zone_->dst_offset();
return zone_as_offset(td, "");
}
else {
return zone_->dst_zone_abbrev();
}
}
else {
if(as_offset) {
time_duration_type td = zone_->base_utc_offset();
return zone_as_offset(td, "");
}
else {
return zone_->std_zone_abbrev();
}
}
}
//! returns a posix_time_zone string for the associated time_zone. If no time_zone, "UTC+00" is returned.
std::string zone_as_posix_string() const
{
if(zone_ == shared_ptr<tz_type>()) {
return std::string("UTC+00");
}
return zone_->to_posix_string();
}
//! Equality comparison operator
/*bool operator==(const date_time::base_time<boost::posix_time::ptime,boost::posix_time::posix_time_system>& rhs) const
{ // fails due to rhs.time_ being protected
return date_time::base_time<boost::posix_time::ptime,boost::posix_time::posix_time_system>::operator==(rhs);
//return this->time_ == rhs.time_;
}*/
//! Equality comparison operator
bool operator==(const local_date_time_base& rhs) const
{
return time_system_type::is_equal(this->time_, rhs.time_);
}
//! Non-Equality comparison operator
bool operator!=(const local_date_time_base& rhs) const
{
return !(*this == rhs);
}
//! Less than comparison operator
bool operator<(const local_date_time_base& rhs) const
{
return time_system_type::is_less(this->time_, rhs.time_);
}
//! Less than or equal to comparison operator
bool operator<=(const local_date_time_base& rhs) const
{
return (*this < rhs || *this == rhs);
}
//! Greater than comparison operator
bool operator>(const local_date_time_base& rhs) const
{
return !(*this <= rhs);
}
//! Greater than or equal to comparison operator
bool operator>=(const local_date_time_base& rhs) const
{
return (*this > rhs || *this == rhs);
}
//! Local_date_time + date_duration
local_date_time_base operator+(const date_duration_type& dd) const
{
return local_date_time_base(time_system_type::add_days(this->time_,dd), zone_);
}
//! Local_date_time += date_duration
local_date_time_base operator+=(const date_duration_type& dd)
{
this->time_ = time_system_type::add_days(this->time_,dd);
return *this;
}
//! Local_date_time - date_duration
local_date_time_base operator-(const date_duration_type& dd) const
{
return local_date_time_base(time_system_type::subtract_days(this->time_,dd), zone_);
}
//! Local_date_time -= date_duration
local_date_time_base operator-=(const date_duration_type& dd)
{
this->time_ = time_system_type::subtract_days(this->time_,dd);
return *this;
}
//! Local_date_time + time_duration
local_date_time_base operator+(const time_duration_type& td) const
{
return local_date_time_base(time_system_type::add_time_duration(this->time_,td), zone_);
}
//! Local_date_time += time_duration
local_date_time_base operator+=(const time_duration_type& td)
{
this->time_ = time_system_type::add_time_duration(this->time_,td);
return *this;
}
//! Local_date_time - time_duration
local_date_time_base operator-(const time_duration_type& td) const
{
return local_date_time_base(time_system_type::subtract_time_duration(this->time_,td), zone_);
}
//! Local_date_time -= time_duration
local_date_time_base operator-=(const time_duration_type& td)
{
this->time_ = time_system_type::subtract_time_duration(this->time_,td);
return *this;
}
//! local_date_time -= local_date_time --> time_duration_type
time_duration_type operator-(const local_date_time_base& rhs) const
{
return utc_time_type(this->time_) - utc_time_type(rhs.time_);
}
private:
boost::shared_ptr<tz_type> zone_;
//bool is_dst_;
/*! Adjust the passed in time to UTC?
*/
utc_time_type construction_adjustment(utc_time_type t,
boost::shared_ptr<tz_type> z,
bool dst_flag)
{
if(z != boost::shared_ptr<tz_type>()) {
if(dst_flag && z->has_dst()) {
t -= z->dst_offset();
} // else no adjust
t -= z->base_utc_offset();
}
return t;
}
/*! Simple formatting code -- todo remove this?
*/
std::string zone_as_offset(const time_duration_type& td,
const std::string& separator) const
{
std::ostringstream ss;
if(td.is_negative()) {
// a negative duration is represented as "-[h]h:mm"
// we require two digits for the hour. A positive duration
// with the %H flag will always give two digits
ss << "-";
}
else {
ss << "+";
}
ss << std::setw(2) << std::setfill('0')
<< date_time::absolute_value(td.hours())
<< separator
<< std::setw(2) << std::setfill('0')
<< date_time::absolute_value(td.minutes());
return ss.str();
}
};
//!Use the default parameters to define local_date_time
typedef local_date_time_base<> local_date_time;
} }
#endif

View File

@@ -0,0 +1,24 @@
#ifndef LOCAL_TIME_LOCAL_TIME_HPP__
#define LOCAL_TIME_LOCAL_TIME_HPP__
/* Copyright (c) 2003-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/posix_time/posix_time.hpp"
#include "boost/date_time/local_time/local_date_time.hpp"
#include "boost/date_time/local_time/local_time_types.hpp"
#if !defined(USE_DATE_TIME_PRE_1_33_FACET_IO)
#include "boost/date_time/local_time/local_time_io.hpp"
#endif // USE_DATE_TIME_PRE_1_33_FACET_IO
#include "boost/date_time/local_time/posix_time_zone.hpp"
#include "boost/date_time/local_time/custom_time_zone.hpp"
#include "boost/date_time/local_time/tz_database.hpp"
#include "boost/date_time/local_time/conversion.hpp"
#include "boost/date_time/time_zone_base.hpp"
#endif

View File

@@ -0,0 +1,187 @@
#ifndef BOOST_DATE_TIME_LOCAL_TIME_IO_HPP__
#define BOOST_DATE_TIME_LOCAL_TIME_IO_HPP__
/* Copyright (c) 2003-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 <string>
#include <locale>
#include <iostream>
#include <iterator> // i/ostreambuf_iterator
#include <boost/io/ios_state.hpp>
#include <boost/date_time/special_defs.hpp>
#include <boost/date_time/time_facet.hpp>
#include <boost/date_time/string_convert.hpp>
#include <boost/date_time/local_time/local_time_types.hpp>
#include <boost/date_time/local_time/local_date_time.hpp>
#include <boost/date_time/local_time/posix_time_zone.hpp>
#include <boost/date_time/local_time/conversion.hpp> // to_tm will be needed in the facets
namespace boost {
namespace local_time {
typedef boost::date_time::time_facet<local_date_time, wchar_t> wlocal_time_facet;
typedef boost::date_time::time_facet<local_date_time, char> local_time_facet;
typedef boost::date_time::time_input_facet<local_date_time::utc_time_type,wchar_t> wlocal_time_input_facet;
typedef boost::date_time::time_input_facet<local_date_time::utc_time_type,char> local_time_input_facet;
//! operator<< for local_date_time - see local_time docs for formatting details
template<class CharT, class TraitsT>
inline
std::basic_ostream<CharT, TraitsT>&
operator<<(std::basic_ostream<CharT, TraitsT>& os, const local_date_time& ldt)
{
boost::io::ios_flags_saver iflags(os);
typedef local_date_time time_type;//::utc_time_type typename
typedef date_time::time_facet<time_type, CharT> custom_time_facet;
std::ostreambuf_iterator<CharT> oitr(os);
if(std::has_facet<custom_time_facet>(os.getloc())) {
std::use_facet<custom_time_facet>(os.getloc()).put(oitr,
os,
os.fill(),
ldt);
}
else {
custom_time_facet* f = new custom_time_facet();
std::locale l = std::locale(os.getloc(), f);
os.imbue(l);
f->put(oitr, os, os.fill(), ldt);
}
return os;
}
//! input operator for local_date_time
template <class CharT, class Traits>
inline
std::basic_istream<CharT, Traits>&
operator>>(std::basic_istream<CharT, Traits>& is, local_date_time& ldt)
{
boost::io::ios_flags_saver iflags(is);
typename std::basic_istream<CharT, Traits>::sentry strm_sentry(is, false);
if (strm_sentry) {
try {
typedef typename local_date_time::utc_time_type utc_time_type;
typedef typename date_time::time_input_facet<utc_time_type, CharT> time_input_facet;
// intermediate objects
std::basic_string<CharT> tz_str;
utc_time_type pt(not_a_date_time);
std::istreambuf_iterator<CharT,Traits> sit(is), str_end;
if(std::has_facet<time_input_facet>(is.getloc())) {
std::use_facet<time_input_facet>(is.getloc()).get_local_time(sit, str_end, is, pt, tz_str);
}
else {
time_input_facet* f = new time_input_facet();
std::locale l = std::locale(is.getloc(), f);
is.imbue(l);
f->get_local_time(sit, str_end, is, pt, tz_str);
}
if(tz_str.empty()) {
time_zone_ptr null_ptr;
// a null time_zone_ptr creates a local_date_time that is UTC
ldt = local_date_time(pt, null_ptr);
}
else {
time_zone_ptr tz_ptr(new posix_time_zone(date_time::convert_string_type<CharT,char>(tz_str)));
// the "date & time" constructor expects the time label to *not* be utc.
// a posix_tz_string also expects the time label to *not* be utc.
ldt = local_date_time(pt.date(), pt.time_of_day(), tz_ptr, local_date_time::EXCEPTION_ON_ERROR);
}
}
catch(...) {
// mask tells us what exceptions are turned on
std::ios_base::iostate exception_mask = is.exceptions();
// if the user wants exceptions on failbit, we'll rethrow our
// date_time exception & set the failbit
if(std::ios_base::failbit & exception_mask) {
try { is.setstate(std::ios_base::failbit); }
catch(std::ios_base::failure&) {} // ignore this one
throw; // rethrow original exception
}
else {
// if the user want's to fail quietly, we simply set the failbit
is.setstate(std::ios_base::failbit);
}
}
}
return is;
}
//! output operator for local_time_period
template <class CharT, class TraitsT>
inline
std::basic_ostream<CharT, TraitsT>&
operator<<(std::basic_ostream<CharT, TraitsT>& os,
const boost::local_time::local_time_period& p) {
boost::io::ios_flags_saver iflags(os);
typedef boost::date_time::time_facet<local_date_time, CharT> custom_facet;
std::ostreambuf_iterator<CharT> oitr(os);
if (std::has_facet<custom_facet>(os.getloc())) {
std::use_facet<custom_facet>(os.getloc()).put(oitr, os, os.fill(), p);
}
else {
//instantiate a custom facet for dealing with periods since the user
//has not put one in the stream so far. This is for efficiency
//since we would always need to reconstruct for every time period
//if the local did not already exist. Of course this will be overridden
//if the user imbues as some later point.
custom_facet* f = new custom_facet();
std::locale l = std::locale(os.getloc(), f);
os.imbue(l);
f->put(oitr, os, os.fill(), p);
}
return os;
}
//! input operator for local_time_period
template <class CharT, class Traits>
inline
std::basic_istream<CharT, Traits>&
operator>>(std::basic_istream<CharT, Traits>& is, boost::local_time::local_time_period& tp)
{
boost::io::ios_flags_saver iflags(is);
typename std::basic_istream<CharT, Traits>::sentry strm_sentry(is, false);
if (strm_sentry) {
try {
typedef typename date_time::time_input_facet<local_date_time, CharT> time_input_facet;
std::istreambuf_iterator<CharT,Traits> sit(is), str_end;
if(std::has_facet<time_input_facet>(is.getloc())) {
std::use_facet<time_input_facet>(is.getloc()).get(sit, str_end, is, tp);
}
else {
time_input_facet* f = new time_input_facet();
std::locale l = std::locale(is.getloc(), f);
is.imbue(l);
f->get(sit, str_end, is, tp);
}
}
catch(...) {
std::ios_base::iostate exception_mask = is.exceptions();
if(std::ios_base::failbit & exception_mask) {
try { is.setstate(std::ios_base::failbit); }
catch(std::ios_base::failure&) {}
throw; // rethrow original exception
}
else {
is.setstate(std::ios_base::failbit);
}
}
}
return is;
}
} } // namespaces
#endif // BOOST_DATE_TIME_LOCAL_TIME_IO_HPP__

View File

@@ -0,0 +1,52 @@
#ifndef LOCAL_TIME_LOCAL_TIME_TYPES_HPP__
#define LOCAL_TIME_LOCAL_TIME_TYPES_HPP__
/* Copyright (c) 2003-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/local_time/local_date_time.hpp"
#include "boost/date_time/period.hpp"
#include "boost/date_time/time_iterator.hpp"
#include "boost/date_time/compiler_config.hpp"
#if defined(BOOST_DATE_TIME_OPTIONAL_GREGORIAN_TYPES)
#include "boost/date_time/local_time/date_duration_operators.hpp"
#endif //BOOST_DATE_TIME_OPTIONAL_GREGORIAN_TYPES
#include "boost/date_time/local_time/custom_time_zone.hpp"
namespace boost {
namespace local_time {
typedef boost::date_time::period<local_date_time,
boost::posix_time::time_duration> local_time_period;
typedef date_time::time_itr<local_date_time> local_time_iterator;
typedef date_time::second_clock<local_date_time> local_sec_clock;
typedef date_time::microsec_clock<local_date_time> local_microsec_clock;
typedef date_time::time_zone_base<posix_time::ptime, char> time_zone;
typedef date_time::time_zone_base<posix_time::ptime, wchar_t> wtime_zone;
//! Shared Pointer for custom_time_zone and posix_time_zone objects
typedef boost::shared_ptr<time_zone> time_zone_ptr;
typedef boost::shared_ptr<wtime_zone> wtime_zone_ptr;
typedef date_time::time_zone_names_base<char> time_zone_names;
typedef date_time::time_zone_names_base<wchar_t> wtime_zone_names;
//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;
}} // namespaces
#endif // LOCAL_TIME_LOCAL_TIME_TYPES_HPP__

View File

@@ -0,0 +1,475 @@
#ifndef _DATE_TIME_POSIX_TIME_ZONE__
#define _DATE_TIME_POSIX_TIME_ZONE__
/* Copyright (c) 2003-2005 CrystalClear Software, Inc.
* Subject to the Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
* Author: Jeff Garland, Bart Garst
* $Date$
*/
#include <string>
#include <sstream>
#include <stdexcept>
#include <boost/tokenizer.hpp>
#include <boost/throw_exception.hpp>
#include <boost/date_time/compiler_config.hpp>
#include <boost/date_time/gregorian/gregorian.hpp>
#include <boost/date_time/time_zone_names.hpp>
#include <boost/date_time/time_zone_base.hpp>
#include <boost/date_time/local_time/dst_transition_day_rules.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/date_time/string_convert.hpp>
#include <boost/date_time/time_parsing.hpp>
namespace boost{
namespace local_time{
//! simple exception for UTC and Daylight savings start/end offsets
struct BOOST_SYMBOL_VISIBLE bad_offset : public std::out_of_range
{
bad_offset(std::string const& msg = std::string()) :
std::out_of_range(std::string("Offset out of range: " + msg)) {}
};
//! simple exception for UTC daylight savings adjustment
struct BOOST_SYMBOL_VISIBLE bad_adjustment : public std::out_of_range
{
bad_adjustment(std::string const& msg = std::string()) :
std::out_of_range(std::string("Adjustment out of range: " + msg)) {}
};
typedef boost::date_time::dst_adjustment_offsets<boost::posix_time::time_duration> dst_adjustment_offsets;
//! A time zone class constructed from a POSIX time zone string
/*! A POSIX time zone string takes the form of:<br>
* "std offset dst [offset],start[/time],end[/time]" (w/no spaces)
* 'std' specifies the abbrev of the time zone.<br>
* 'offset' is the offset from UTC.<br>
* 'dst' specifies the abbrev of the time zone during daylight savings time.<br>
* The second offset is how many hours changed during DST. Default=1<br>
* 'start' and'end' are the dates when DST goes into (and out of) effect.<br>
* 'offset' takes the form of: [+|-]hh[:mm[:ss]] {h=0-23, m/s=0-59}<br>
* 'time' and 'offset' take the same form. Time defaults=02:00:00<br>
* 'start' and 'end' can be one of three forms:<br>
* Mm.w.d {month=1-12, week=1-5 (5 is always last), day=0-6}<br>
* Jn {n=1-365 Feb29 is never counted}<br>
* n {n=0-365 Feb29 is counted in leap years}<br>
* Example "PST-5PDT01:00:00,M4.1.0/02:00:00,M10.1.0/02:00:00"
* <br>
* Exceptions will be thrown under these conditions:<br>
* An invalid date spec (see date class)<br>
* A boost::local_time::bad_offset exception will be thrown for:<br>
* A DST start or end offset that is negative or more than 24 hours<br>
* A UTC zone that is greater than +14 or less than -12 hours<br>
* A boost::local_time::bad_adjustment exception will be thrown for:<br>
* A DST adjustment that is 24 hours or more (positive or negative)<br>
*
* Note that UTC zone offsets can be greater than +12:
* http://www.worldtimezone.com/utc/utc+1200.html
*/
template<class CharT>
class BOOST_SYMBOL_VISIBLE posix_time_zone_base : public date_time::time_zone_base<posix_time::ptime,CharT> {
public:
typedef boost::posix_time::time_duration time_duration_type;
typedef date_time::time_zone_names_base<CharT> time_zone_names;
typedef date_time::time_zone_base<posix_time::ptime,CharT> base_type;
typedef typename base_type::string_type string_type;
typedef CharT char_type;
typedef typename base_type::stringstream_type stringstream_type;
typedef boost::char_separator<char_type, std::char_traits<char_type> > char_separator_type;
typedef boost::tokenizer<char_separator_type,
typename string_type::const_iterator,
string_type> tokenizer_type;
typedef typename tokenizer_type::iterator tokenizer_iterator_type;
//! Construct from a POSIX time zone string
posix_time_zone_base(const string_type& s) :
//zone_names_("std_name","std_abbrev","no-dst","no-dst"),
zone_names_(),
has_dst_(false),
base_utc_offset_(posix_time::hours(0)),
dst_offsets_(posix_time::hours(0),posix_time::hours(0),posix_time::hours(0)),
dst_calc_rules_()
{
#ifdef __HP_aCC
// Work around bug in aC++ compiler: see QXCR1000880488 in the
// HP bug tracking system
const char_type sep_chars[2] = {',',0};
#else
const char_type sep_chars[2] = {','};
#endif
char_separator_type sep(sep_chars);
tokenizer_type tokens(s, sep);
tokenizer_iterator_type it = tokens.begin(), end = tokens.end();
if (it == end)
BOOST_THROW_EXCEPTION(std::invalid_argument("Could not parse time zone name"));
calc_zone(*it++);
if(has_dst_)
{
if (it == end)
BOOST_THROW_EXCEPTION(std::invalid_argument("Could not parse DST begin time"));
string_type dst_begin = *it++;
if (it == end)
BOOST_THROW_EXCEPTION(std::invalid_argument("Could not parse DST end time"));
string_type dst_end = *it;
calc_rules(dst_begin, dst_end);
}
}
virtual ~posix_time_zone_base() {}
//!String for the zone when not in daylight savings (eg: EST)
virtual string_type std_zone_abbrev()const
{
return zone_names_.std_zone_abbrev();
}
//!String for the timezone when in daylight savings (eg: EDT)
/*! For those time zones that have no DST, an empty string is used */
virtual string_type dst_zone_abbrev() const
{
return zone_names_.dst_zone_abbrev();
}
//!String for the zone when not in daylight savings (eg: Eastern Standard Time)
/*! The full STD name is not extracted from the posix time zone string.
* Therefore, the STD abbreviation is used in it's place */
virtual string_type std_zone_name()const
{
return zone_names_.std_zone_name();
}
//!String for the timezone when in daylight savings (eg: Eastern Daylight Time)
/*! The full DST name is not extracted from the posix time zone string.
* Therefore, the STD abbreviation is used in it's place. For time zones
* that have no DST, an empty string is used */
virtual string_type dst_zone_name()const
{
return zone_names_.dst_zone_name();
}
//! True if zone uses daylight savings adjustments otherwise false
virtual bool has_dst()const
{
return has_dst_;
}
//! Local time that DST starts -- NADT if has_dst is false
virtual posix_time::ptime dst_local_start_time(gregorian::greg_year y)const
{
gregorian::date d(gregorian::not_a_date_time);
if(has_dst_)
{
d = dst_calc_rules_->start_day(y);
}
return posix_time::ptime(d, dst_offsets_.dst_start_offset_);
}
//! Local time that DST ends -- NADT if has_dst is false
virtual posix_time::ptime dst_local_end_time(gregorian::greg_year y)const
{
gregorian::date d(gregorian::not_a_date_time);
if(has_dst_)
{
d = dst_calc_rules_->end_day(y);
}
return posix_time::ptime(d, dst_offsets_.dst_end_offset_);
}
//! Base offset from UTC for zone (eg: -07:30:00)
virtual time_duration_type base_utc_offset()const
{
return base_utc_offset_;
}
//! Adjustment forward or back made while DST is in effect
virtual time_duration_type dst_offset()const
{
return dst_offsets_.dst_adjust_;
}
//! Returns a POSIX time_zone string for this object
virtual string_type to_posix_string() const
{
// std offset dst [offset],start[/time],end[/time] - w/o spaces
stringstream_type ss;
ss.fill('0');
boost::shared_ptr<dst_calc_rule> no_rules;
// std
ss << std_zone_abbrev();
// offset
if(base_utc_offset().is_negative()) {
// inverting the sign guarantees we get two digits
ss << '-' << std::setw(2) << base_utc_offset().invert_sign().hours();
}
else {
ss << '+' << std::setw(2) << base_utc_offset().hours();
}
if(base_utc_offset().minutes() != 0 || base_utc_offset().seconds() != 0) {
ss << ':' << std::setw(2) << base_utc_offset().minutes();
if(base_utc_offset().seconds() != 0) {
ss << ':' << std::setw(2) << base_utc_offset().seconds();
}
}
if(dst_calc_rules_ != no_rules) {
// dst
ss << dst_zone_abbrev();
// dst offset
if(dst_offset().is_negative()) {
// inverting the sign guarantees we get two digits
ss << '-' << std::setw(2) << dst_offset().invert_sign().hours();
}
else {
ss << '+' << std::setw(2) << dst_offset().hours();
}
if(dst_offset().minutes() != 0 || dst_offset().seconds() != 0) {
ss << ':' << std::setw(2) << dst_offset().minutes();
if(dst_offset().seconds() != 0) {
ss << ':' << std::setw(2) << dst_offset().seconds();
}
}
// start/time
ss << ',' << date_time::convert_string_type<char, char_type>(dst_calc_rules_->start_rule_as_string()) << '/'
<< std::setw(2) << dst_offsets_.dst_start_offset_.hours() << ':'
<< std::setw(2) << dst_offsets_.dst_start_offset_.minutes();
if(dst_offsets_.dst_start_offset_.seconds() != 0) {
ss << ':' << std::setw(2) << dst_offsets_.dst_start_offset_.seconds();
}
// end/time
ss << ',' << date_time::convert_string_type<char, char_type>(dst_calc_rules_->end_rule_as_string()) << '/'
<< std::setw(2) << dst_offsets_.dst_end_offset_.hours() << ':'
<< std::setw(2) << dst_offsets_.dst_end_offset_.minutes();
if(dst_offsets_.dst_end_offset_.seconds() != 0) {
ss << ':' << std::setw(2) << dst_offsets_.dst_end_offset_.seconds();
}
}
return ss.str();
}
private:
time_zone_names zone_names_;
bool has_dst_;
time_duration_type base_utc_offset_;
dst_adjustment_offsets dst_offsets_;
boost::shared_ptr<dst_calc_rule> dst_calc_rules_;
/*! Extract time zone abbreviations for STD & DST as well
* as the offsets for the time shift that occurs and how
* much of a shift. At this time full time zone names are
* NOT extracted so the abbreviations are used in their place */
void calc_zone(const string_type& obj){
const char_type empty_string[2] = {'\0'};
stringstream_type ss(empty_string);
typename string_type::const_pointer sit = obj.c_str(), obj_end = sit + obj.size();
string_type l_std_zone_abbrev, l_dst_zone_abbrev;
// get 'std' name/abbrev
while(std::isalpha(*sit)){
ss << *sit++;
}
l_std_zone_abbrev = ss.str();
ss.str(empty_string);
// get UTC offset
if(sit != obj_end){
// get duration
while(sit != obj_end && !std::isalpha(*sit)){
ss << *sit++;
}
base_utc_offset_ = date_time::str_from_delimited_time_duration<time_duration_type,char_type>(ss.str());
ss.str(empty_string);
// base offset must be within range of -12 hours to +14 hours
if(base_utc_offset_ < time_duration_type(-12,0,0) ||
base_utc_offset_ > time_duration_type(14,0,0))
{
boost::throw_exception(bad_offset(posix_time::to_simple_string(base_utc_offset_)));
}
}
// get DST data if given
if(sit != obj_end){
has_dst_ = true;
// get 'dst' name/abbrev
while(sit != obj_end && std::isalpha(*sit)){
ss << *sit++;
}
l_dst_zone_abbrev = ss.str();
ss.str(empty_string);
// get DST offset if given
if(sit != obj_end){
// get duration
while(sit != obj_end && !std::isalpha(*sit)){
ss << *sit++;
}
dst_offsets_.dst_adjust_ = date_time::str_from_delimited_time_duration<time_duration_type,char_type>(ss.str());
ss.str(empty_string);
}
else{ // default DST offset
dst_offsets_.dst_adjust_ = posix_time::hours(1);
}
// adjustment must be within +|- 1 day
if(dst_offsets_.dst_adjust_ <= time_duration_type(-24,0,0) ||
dst_offsets_.dst_adjust_ >= time_duration_type(24,0,0))
{
boost::throw_exception(bad_adjustment(posix_time::to_simple_string(dst_offsets_.dst_adjust_)));
}
}
// full names not extracted so abbrevs used in their place
zone_names_ = time_zone_names(l_std_zone_abbrev, l_std_zone_abbrev, l_dst_zone_abbrev, l_dst_zone_abbrev);
}
void calc_rules(const string_type& start, const string_type& end){
#ifdef __HP_aCC
// Work around bug in aC++ compiler: see QXCR1000880488 in the
// HP bug tracking system
const char_type sep_chars[2] = {'/',0};
#else
const char_type sep_chars[2] = {'/'};
#endif
char_separator_type sep(sep_chars);
tokenizer_type st_tok(start, sep);
tokenizer_type et_tok(end, sep);
tokenizer_iterator_type sit = st_tok.begin();
tokenizer_iterator_type eit = et_tok.begin();
// generate date spec
char_type x = string_type(*sit).at(0);
if(x == 'M'){
M_func(*sit, *eit);
}
else if(x == 'J'){
julian_no_leap(*sit, *eit);
}
else{
julian_day(*sit, *eit);
}
++sit;
++eit;
// generate durations
// starting offset
if(sit != st_tok.end()){
dst_offsets_.dst_start_offset_ = date_time::str_from_delimited_time_duration<time_duration_type,char_type>(*sit);
}
else{
// default
dst_offsets_.dst_start_offset_ = posix_time::hours(2);
}
// start/end offsets must fall on given date
if(dst_offsets_.dst_start_offset_ < time_duration_type(0,0,0) ||
dst_offsets_.dst_start_offset_ >= time_duration_type(24,0,0))
{
boost::throw_exception(bad_offset(posix_time::to_simple_string(dst_offsets_.dst_start_offset_)));
}
// ending offset
if(eit != et_tok.end()){
dst_offsets_.dst_end_offset_ = date_time::str_from_delimited_time_duration<time_duration_type,char_type>(*eit);
}
else{
// default
dst_offsets_.dst_end_offset_ = posix_time::hours(2);
}
// start/end offsets must fall on given date
if(dst_offsets_.dst_end_offset_ < time_duration_type(0,0,0) ||
dst_offsets_.dst_end_offset_ >= time_duration_type(24,0,0))
{
boost::throw_exception(bad_offset(posix_time::to_simple_string(dst_offsets_.dst_end_offset_)));
}
}
/* Parses out a start/end date spec from a posix time zone string.
* Date specs come in three possible formats, this function handles
* the 'M' spec. Ex "M2.2.4" => 2nd month, 2nd week, 4th day .
*/
void M_func(const string_type& s, const string_type& e){
typedef gregorian::nth_kday_of_month nkday;
unsigned short sm=0,sw=0,sd=0,em=0,ew=0,ed=0; // start/end month,week,day
#ifdef __HP_aCC
// Work around bug in aC++ compiler: see QXCR1000880488 in the
// HP bug tracking system
const char_type sep_chars[3] = {'M','.',0};
#else
const char_type sep_chars[3] = {'M','.'};
#endif
char_separator_type sep(sep_chars);
tokenizer_type stok(s, sep), etok(e, sep);
tokenizer_iterator_type it = stok.begin();
sm = lexical_cast<unsigned short>(*it++);
sw = lexical_cast<unsigned short>(*it++);
sd = lexical_cast<unsigned short>(*it);
it = etok.begin();
em = lexical_cast<unsigned short>(*it++);
ew = lexical_cast<unsigned short>(*it++);
ed = lexical_cast<unsigned short>(*it);
dst_calc_rules_ = shared_ptr<dst_calc_rule>(
new nth_kday_dst_rule(
nth_last_dst_rule::start_rule(
static_cast<nkday::week_num>(sw),sd,sm),
nth_last_dst_rule::start_rule(
static_cast<nkday::week_num>(ew),ed,em)
)
);
}
//! Julian day. Feb29 is never counted, even in leap years
// expects range of 1-365
void julian_no_leap(const string_type& s, const string_type& e){
typedef gregorian::gregorian_calendar calendar;
const unsigned short year = 2001; // Non-leap year
unsigned short sm=1;
int sd=0;
sd = lexical_cast<int>(s.substr(1)); // skip 'J'
while(sd >= calendar::end_of_month_day(year,sm)){
sd -= calendar::end_of_month_day(year,sm++);
}
unsigned short em=1;
int ed=0;
ed = lexical_cast<int>(e.substr(1)); // skip 'J'
while(ed > calendar::end_of_month_day(year,em)){
ed -= calendar::end_of_month_day(year,em++);
}
dst_calc_rules_ = shared_ptr<dst_calc_rule>(
new partial_date_dst_rule(
partial_date_dst_rule::start_rule(
static_cast<unsigned short>(sd), static_cast<date_time::months_of_year>(sm)),
partial_date_dst_rule::end_rule(
static_cast<unsigned short>(ed), static_cast<date_time::months_of_year>(em))
)
);
}
//! Julian day. Feb29 is always counted, but exception thrown in non-leap years
// expects range of 0-365
void julian_day(const string_type& s, const string_type& e){
int sd=0, ed=0;
sd = lexical_cast<int>(s);
ed = lexical_cast<int>(e);
dst_calc_rules_ = shared_ptr<dst_calc_rule>(
new partial_date_dst_rule(
partial_date_dst_rule::start_rule(++sd),// args are 0-365
partial_date_dst_rule::end_rule(++ed) // pd expects 1-366
)
);
}
//! helper function used when throwing exceptions
static std::string td_as_string(const time_duration_type& td)
{
std::string s;
#if defined(USE_DATE_TIME_PRE_1_33_FACET_IO)
s = posix_time::to_simple_string(td);
#else
std::stringstream ss;
ss << td;
s = ss.str();
#endif
return s;
}
};
typedef posix_time_zone_base<char> posix_time_zone;
} } // namespace boost::local_time
#endif // _DATE_TIME_POSIX_TIME_ZONE__

View File

@@ -0,0 +1,32 @@
#ifndef BOOST_DATE_TIME_TZ_DATABASE_HPP__
#define BOOST_DATE_TIME_TZ_DATABASE_HPP__
/* Copyright (c) 2003-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 <string>
#include "boost/date_time/local_time/custom_time_zone.hpp"
#include "boost/date_time/local_time/dst_transition_day_rules.hpp"
#include "boost/date_time/tz_db_base.hpp"
namespace boost {
namespace local_time {
using date_time::data_not_accessible;
using date_time::bad_field_count;
//! Object populated with boost::shared_ptr<time_zone_base> objects
/*! Object populated with boost::shared_ptr<time_zone_base> objects
* Database is populated from specs stored in external csv file. See
* date_time::tz_db_base for greater detail */
typedef date_time::tz_db_base<custom_time_zone, nth_kday_dst_rule> tz_database;
}} // namespace
#endif // BOOST_DATE_TIME_TZ_DATABASE_HPP__

View File

@@ -0,0 +1,218 @@
#ifndef DATE_TIME_LOCAL_TIME_ADJUSTOR_HPP__
#define DATE_TIME_LOCAL_TIME_ADJUSTOR_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 local_time_adjustor.hpp
Time adjustment calculations for local times
*/
#include <stdexcept>
#include <boost/throw_exception.hpp>
#include <boost/date_time/compiler_config.hpp>
#include <boost/date_time/date_generators.hpp>
#include <boost/date_time/dst_rules.hpp>
#include <boost/date_time/time_defs.hpp> // boost::date_time::dst_flags
#include <boost/date_time/special_defs.hpp> // not_a_date_time
namespace boost {
namespace date_time {
//! Provides a base offset adjustment from utc
template<class time_duration_type,
short hours, unsigned short minutes = 0>
class utc_adjustment
{
public:
static time_duration_type local_to_utc_base_offset()
{
time_duration_type td(hours,minutes,0);
return td.invert_sign();
}
static time_duration_type utc_to_local_base_offset()
{
return time_duration_type(hours,minutes,0);
}
};
//! Allow sliding utc adjustment with fixed dst rules
template<class time_type, class dst_rules>
class dynamic_local_time_adjustor : public dst_rules
{
public:
typedef typename time_type::time_duration_type time_duration_type;
typedef typename time_type::date_type date_type;
dynamic_local_time_adjustor(time_duration_type utc_offset) :
utc_offset_(utc_offset)
{}
//! Presumes local time
time_duration_type utc_offset(bool is_dst)
{
if (is_dst) {
return utc_offset_ + this->dst_offset();
}
else {
return utc_offset_;
}
}
private:
time_duration_type utc_offset_;
};
//! Embed the rules for local time adjustments at compile time
template<class time_type, class dst_rules, class utc_offset_rules>
class static_local_time_adjustor: public dst_rules, public utc_offset_rules
{
public:
typedef typename time_type::time_duration_type time_duration_type;
typedef typename time_type::date_type date_type;
//! Calculates the offset from a utc time to local based on dst and utc offset
/*! @param t UTC time to calculate offset to local time
* This adjustment depends on the following observations about the
* workings of the DST boundary offset. Since UTC time labels are
* monotonically increasing we can determine if a given local time
* is in DST or not and therefore adjust the offset appropriately.
*
* The logic is as follows. Starting with UTC time use the offset to
* create a label for an non-dst adjusted local time. Then call
* dst_rules::local_is_dst with the non adjust local time. The
* results of this function will either unabiguously decide that
* the initial local time is in dst or return an illegal or
* ambiguous result. An illegal result only occurs at the end
* of dst (where labels are skipped) and indicates that dst has
* ended. An ambiguous result means that we need to recheck by
* making a dst adjustment and then rechecking. If the dst offset
* is added to the utc time and the recheck proves non-ambiguous
* then we are past the boundary. If it is still ambiguous then
* we are ahead of the boundary and dst is still in effect.
*
* TODO -- check if all dst offsets are positive. If not then
* the algorithm needs to check for this and reverse the
* illegal/ambiguous logic.
*/
static time_duration_type utc_to_local_offset(const time_type& t)
{
//get initial local time guess by applying utc offset
time_type initial = t + utc_offset_rules::utc_to_local_base_offset();
time_is_dst_result dst_flag =
dst_rules::local_is_dst(initial.date(), initial.time_of_day());
switch(dst_flag) {
case is_in_dst: return utc_offset_rules::utc_to_local_base_offset() + dst_rules::dst_offset();
case is_not_in_dst: return utc_offset_rules::utc_to_local_base_offset();
case invalid_time_label:return utc_offset_rules::utc_to_local_base_offset() + dst_rules::dst_offset();
case ambiguous: {
time_type retry = initial + dst_rules::dst_offset();
dst_flag = dst_rules::local_is_dst(retry.date(), retry.time_of_day());
//if still ambibuous then the utc time still translates to a dst time
if (dst_flag == ambiguous) {
return utc_offset_rules::utc_to_local_base_offset() + dst_rules::dst_offset();
}
// we are past the dst boundary
else {
return utc_offset_rules::utc_to_local_base_offset();
}
}
}//case
//TODO better exception type
boost::throw_exception(std::out_of_range("Unreachable case"));
BOOST_DATE_TIME_UNREACHABLE_EXPRESSION(return time_duration_type(not_a_date_time)); // should never reach
}
//! Get the offset to UTC given a local time
static time_duration_type local_to_utc_offset(const time_type& t,
date_time::dst_flags dst=date_time::calculate)
{
switch (dst) {
case is_dst:
return utc_offset_rules::local_to_utc_base_offset() - dst_rules::dst_offset();
case not_dst:
return utc_offset_rules::local_to_utc_base_offset();
case calculate:
time_is_dst_result res =
dst_rules::local_is_dst(t.date(), t.time_of_day());
switch(res) {
case is_in_dst: return utc_offset_rules::local_to_utc_base_offset() - dst_rules::dst_offset();
case is_not_in_dst: return utc_offset_rules::local_to_utc_base_offset();
case ambiguous: return utc_offset_rules::local_to_utc_base_offset();
case invalid_time_label: break;
}
}
boost::throw_exception(std::out_of_range("Time label invalid"));
BOOST_DATE_TIME_UNREACHABLE_EXPRESSION(return time_duration_type(not_a_date_time)); // should never reach
}
private:
};
void dummy_to_prevent_msvc6_ice(); //why ask why?
//! Template that simplifies the creation of local time calculator
/*! Use this template to create the timezone to utc convertors as required.
*
* This class will also work for other regions that don't use dst and
* have a utc offset which is an integral number of hours.
*
* <b>Template Parameters</b>
* -time_type -- Time class to use
* -utc_offset -- Number hours local time is adjust from utc
* -use_dst -- true (default) if region uses dst, false otherwise
* For example:
* @code
* //eastern timezone is utc-5
typedef date_time::local_adjustor<ptime, -5, us_dst> us_eastern;
typedef date_time::local_adjustor<ptime, -6, us_dst> us_central;
typedef date_time::local_adjustor<ptime, -7, us_dst> us_mountain;
typedef date_time::local_adjustor<ptime, -8, us_dst> us_pacific;
typedef date_time::local_adjustor<ptime, -7, no_dst> us_arizona;
@endcode
*/
template<class time_type, short utc_offset, class dst_rule>
class local_adjustor
{
public:
typedef typename time_type::time_duration_type time_duration_type;
typedef typename time_type::date_type date_type;
typedef static_local_time_adjustor<time_type,
dst_rule,
utc_adjustment<time_duration_type,
utc_offset> > dst_adjustor;
//! Convert a utc time to local time
static time_type utc_to_local(const time_type& t)
{
time_duration_type td = dst_adjustor::utc_to_local_offset(t);
return t + td;
}
//! Convert a local time to utc
static time_type local_to_utc(const time_type& t,
date_time::dst_flags dst=date_time::calculate)
{
time_duration_type td = dst_adjustor::local_to_utc_offset(t, dst);
return t + td;
}
};
} } //namespace date_time
#endif

View File

@@ -0,0 +1,193 @@
#ifndef DATE_TIME_LOCAL_TIMEZONE_DEFS_HPP__
#define DATE_TIME_LOCAL_TIMEZONE_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$
*/
#include "boost/date_time/dst_rules.hpp"
namespace boost {
namespace date_time {
// Configurations for common dst rules cases:
// See http://www.wharton.co.uk/Support/sup_dst.htm for more
// information on how various locales use dst rules
//! Specification for daylight savings start rules in US
/*! This class is used to configure dst_calc_engine template typically
as follows:
@code
using namespace boost::gregorian;
using namespace boost::posix_time;
typedef us_dst_trait<date> us_dst_traits;
typedef boost::date_time::dst_calc_engine<date, time_duration,
us_dst_traits>
us_dst_calc;
//calculate the 2002 transition day of USA April 7 2002
date dst_start = us_dst_calc::local_dst_start_day(2002);
//calculate the 2002 transition day of USA Oct 27 2002
date dst_end = us_dst_calc::local_dst_end_day(2002);
//check if a local time is in dst or not -- posible answers
//are yes, no, invalid time label, ambiguous
ptime t(...some time...);
if (us_dst::local_is_dst(t.date(), t.time_of_day())
== boost::date_time::is_not_in_dst)
{
}
@endcode
This generates a type suitable for the calculation of dst
transitions for the United States. Of course other templates
can be used for other locales.
*/
template<class date_type>
struct us_dst_trait
{
typedef typename date_type::day_of_week_type day_of_week_type;
typedef typename date_type::month_type month_type;
typedef typename date_type::year_type year_type;
typedef date_time::nth_kday_of_month<date_type> start_rule_functor;
typedef date_time::first_kday_of_month<date_type> end_rule_functor;
typedef date_time::first_kday_of_month<date_type> start_rule_functor_pre2007;
typedef date_time::last_kday_of_month<date_type> end_rule_functor_pre2007;
static day_of_week_type start_day(year_type) {return Sunday;}
static month_type start_month(year_type y)
{
if (y < 2007) return Apr;
return Mar;
}
static day_of_week_type end_day(year_type) {return Sunday;}
static month_type end_month(year_type y)
{
if (y < 2007) return Oct;
return Nov;
}
static date_type local_dst_start_day(year_type year)
{
if (year < 2007) {
start_rule_functor_pre2007 start1(start_day(year),
start_month(year));
return start1.get_date(year);
}
start_rule_functor start(start_rule_functor::second,
start_day(year),
start_month(year));
return start.get_date(year);
}
static date_type local_dst_end_day(year_type year)
{
if (year < 2007) {
end_rule_functor_pre2007 end_rule(end_day(year),
end_month(year));
return end_rule.get_date(year);
}
end_rule_functor end(end_day(year),
end_month(year));
return end.get_date(year);
}
static int dst_start_offset_minutes() { return 120;}
static int dst_end_offset_minutes() { return 120; }
static int dst_shift_length_minutes() { return 60; }
};
//!Rules for daylight savings start in the EU (Last Sun in Mar)
/*!These amount to the following:
- Start of dst day is last Sunday in March
- End day of dst is last Sunday in Oct
- Going forward switch time is 2:00 am (offset 120 minutes)
- Going back switch time is 3:00 am (off set 180 minutes)
- Shift duration is one hour (60 minutes)
*/
template<class date_type>
struct eu_dst_trait
{
typedef typename date_type::day_of_week_type day_of_week_type;
typedef typename date_type::month_type month_type;
typedef typename date_type::year_type year_type;
typedef date_time::last_kday_of_month<date_type> start_rule_functor;
typedef date_time::last_kday_of_month<date_type> end_rule_functor;
static day_of_week_type start_day(year_type) {return Sunday;}
static month_type start_month(year_type) {return Mar;}
static day_of_week_type end_day(year_type) {return Sunday;}
static month_type end_month(year_type) {return Oct;}
static int dst_start_offset_minutes() { return 120;}
static int dst_end_offset_minutes() { return 180; }
static int dst_shift_length_minutes() { return 60; }
static date_type local_dst_start_day(year_type year)
{
start_rule_functor start(start_day(year),
start_month(year));
return start.get_date(year);
}
static date_type local_dst_end_day(year_type year)
{
end_rule_functor end(end_day(year),
end_month(year));
return end.get_date(year);
}
};
//! Alternative dst traits for some parts of the United Kingdom
/* Several places in the UK use EU start and end rules for the
day, but different local conversion times (eg: forward change at 1:00
am local and backward change at 2:00 am dst instead of 2:00am
forward and 3:00am back for the EU).
*/
template<class date_type>
struct uk_dst_trait : public eu_dst_trait<date_type>
{
static int dst_start_offset_minutes() { return 60;}
static int dst_end_offset_minutes() { return 120; }
static int dst_shift_length_minutes() { return 60; }
};
//Rules for Adelaide Australia
template<class date_type>
struct acst_dst_trait
{
typedef typename date_type::day_of_week_type day_of_week_type;
typedef typename date_type::month_type month_type;
typedef typename date_type::year_type year_type;
typedef date_time::last_kday_of_month<date_type> start_rule_functor;
typedef date_time::last_kday_of_month<date_type> end_rule_functor;
static day_of_week_type start_day(year_type) {return Sunday;}
static month_type start_month(year_type) {return Oct;}
static day_of_week_type end_day(year_type) {return Sunday;}
static month_type end_month(year_type) {return Mar;}
static int dst_start_offset_minutes() { return 120;}
static int dst_end_offset_minutes() { return 180; }
static int dst_shift_length_minutes() { return 60; }
static date_type local_dst_start_day(year_type year)
{
start_rule_functor start(start_day(year),
start_month(year));
return start.get_date(year);
}
static date_type local_dst_end_day(year_type year)
{
end_rule_functor end(end_day(year),
end_month(year));
return end.get_date(year);
}
};
} } //namespace boost::date_time
#endif

View File

@@ -0,0 +1,33 @@
#ifndef DATE_TIME_LOCALE_CONFIG_HPP___
#define DATE_TIME_LOCALE_CONFIG_HPP___
/* Copyright (c) 2002-2020 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/config/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( BOOST_BORLANDC, BOOST_TESTED_AT( 0x581 )) ) \
|| (BOOST_WORKAROUND( BOOST_XLCPP_ZOS, BOOST_TESTED_AT( 0x42010000 )) ) /* <cctype> "shadows" the locale enabled overloads from <locale> */ \
)
#define BOOST_DATE_TIME_NO_LOCALE
#endif
#endif

View File

@@ -0,0 +1,158 @@
#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>
#if defined(BOOST_HAS_FTIME)
#include <boost/winapi/time.hpp>
#endif
#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)
boost::winapi::FILETIME_ ft;
boost::winapi::GetSystemTimeAsFileTime(&ft);
#if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3205))
// Some runtime library implementations expect local times as the norm for ctime functions.
{
boost::winapi::FILETIME_ local_ft;
boost::winapi::FileTimeToLocalFileTime(&ft, &local_ft);
ft = local_ft;
}
#endif
boost::uint64_t micros = 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);
}
#if defined(BOOST_HAS_FTIME)
/*!
* 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.
*/
static boost::uint64_t file_time_to_microseconds(boost::winapi::FILETIME_ const& ft)
{
// shift is difference between 1970-Jan-01 & 1601-Jan-01
// in 100-nanosecond units
const boost::uint64_t shift = 116444736000000000ULL; // (27111902 << 32) + 3577643008
// 100-nanos since 1601-Jan-01
boost::uint64_t ft_as_integer = (static_cast< boost::uint64_t >(ft.dwHighDateTime) << 32) | static_cast< boost::uint64_t >(ft.dwLowDateTime);
ft_as_integer -= shift; // filetime is now 100-nanos since 1970-Jan-01
return (ft_as_integer / 10U); // truncate to microseconds
}
#endif
};
} } //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,375 @@
#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>
#include <boost/date_time/compiler_config.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 BOOST_SYMBOL_VISIBLE 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;
BOOST_CXX14_CONSTEXPR period(point_rep first_point, point_rep end_point);
BOOST_CXX14_CONSTEXPR period(point_rep first_point, duration_rep len);
BOOST_CXX14_CONSTEXPR point_rep begin() const;
BOOST_CXX14_CONSTEXPR point_rep end() const;
BOOST_CXX14_CONSTEXPR point_rep last() const;
BOOST_CXX14_CONSTEXPR duration_rep length() const;
BOOST_CXX14_CONSTEXPR bool is_null() const;
BOOST_CXX14_CONSTEXPR bool operator==(const period& rhs) const;
BOOST_CXX14_CONSTEXPR bool operator<(const period& rhs) const;
BOOST_CXX14_CONSTEXPR void shift(const duration_rep& d);
BOOST_CXX14_CONSTEXPR void expand(const duration_rep& d);
BOOST_CXX14_CONSTEXPR bool contains(const point_rep& point) const;
BOOST_CXX14_CONSTEXPR bool contains(const period& other) const;
BOOST_CXX14_CONSTEXPR bool intersects(const period& other) const;
BOOST_CXX14_CONSTEXPR bool is_adjacent(const period& other) const;
BOOST_CXX14_CONSTEXPR bool is_before(const point_rep& point) const;
BOOST_CXX14_CONSTEXPR bool is_after(const point_rep& point) const;
BOOST_CXX14_CONSTEXPR period intersection(const period& other) const;
BOOST_CXX14_CONSTEXPR period merge(const period& other) const;
BOOST_CXX14_CONSTEXPR 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 BOOST_CXX14_CONSTEXPR
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 BOOST_CXX14_CONSTEXPR
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 BOOST_CXX14_CONSTEXPR
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 BOOST_CXX14_CONSTEXPR
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 BOOST_CXX14_CONSTEXPR
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 BOOST_CXX14_CONSTEXPR
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 BOOST_CXX14_CONSTEXPR
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 BOOST_CXX14_CONSTEXPR
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 BOOST_CXX14_CONSTEXPR
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 BOOST_CXX14_CONSTEXPR
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 BOOST_CXX14_CONSTEXPR
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 BOOST_CXX14_CONSTEXPR
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 BOOST_CXX14_CONSTEXPR
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 BOOST_CXX14_CONSTEXPR
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 BOOST_CXX14_CONSTEXPR
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 BOOST_CXX14_CONSTEXPR
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 BOOST_CXX14_CONSTEXPR
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 BOOST_CXX14_CONSTEXPR
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 BOOST_CXX14_CONSTEXPR
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 BOOST_CXX14_CONSTEXPR
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,200 @@
#ifndef DATETIME_PERIOD_FORMATTER_HPP___
#define DATETIME_PERIOD_FORMATTER_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 <iosfwd>
#include <string>
#include <vector>
#include <iterator>
namespace boost { namespace date_time {
//! Not a facet, but a class used to specify and control period formats
/*! Provides settings for the following:
* - period_separator -- default '/'
* - period_open_start_delimeter -- default '['
* - period_open_range_end_delimeter -- default ')'
* - period_closed_range_end_delimeter -- default ']'
* - display_as_open_range, display_as_closed_range -- default closed_range
*
* Thus the default formatting for a period is as follows:
*@code
* [period.start()/period.last()]
*@endcode
* So for a typical date_period this would be
*@code
* [2004-Jan-04/2004-Feb-01]
*@endcode
* where the date formatting is controlled by the date facet
*/
template <class CharT, class OutItrT = std::ostreambuf_iterator<CharT, std::char_traits<CharT> > >
class period_formatter {
public:
typedef std::basic_string<CharT> string_type;
typedef CharT char_type;
typedef typename std::basic_string<char_type>::const_iterator const_itr_type;
typedef std::vector<std::basic_string<CharT> > collection_type;
static const char_type default_period_separator[2];
static const char_type default_period_start_delimeter[2];
static const char_type default_period_open_range_end_delimeter[2];
static const char_type default_period_closed_range_end_delimeter[2];
enum range_display_options { AS_OPEN_RANGE, AS_CLOSED_RANGE };
//! Constructor that sets up period formatter options -- default should suffice most cases.
period_formatter(range_display_options range_option_in = AS_CLOSED_RANGE,
const char_type* const period_separator = default_period_separator,
const char_type* const period_start_delimeter = default_period_start_delimeter,
const char_type* const period_open_range_end_delimeter = default_period_open_range_end_delimeter,
const char_type* const period_closed_range_end_delimeter = default_period_closed_range_end_delimeter) :
m_range_option(range_option_in),
m_period_separator(period_separator),
m_period_start_delimeter(period_start_delimeter),
m_open_range_end_delimeter(period_open_range_end_delimeter),
m_closed_range_end_delimeter(period_closed_range_end_delimeter)
{}
//! Puts the characters between period elements into stream -- default is /
OutItrT put_period_separator(OutItrT& oitr) const
{
const_itr_type ci = m_period_separator.begin();
while (ci != m_period_separator.end()) {
*oitr = *ci;
ci++;
}
return oitr;
}
//! Puts the period start characters into stream -- default is [
OutItrT put_period_start_delimeter(OutItrT& oitr) const
{
const_itr_type ci = m_period_start_delimeter.begin();
while (ci != m_period_start_delimeter.end()) {
*oitr = *ci;
ci++;
}
return oitr;
}
//! Puts the period end characters into stream as controled by open/closed range setting.
OutItrT put_period_end_delimeter(OutItrT& oitr) const
{
const_itr_type ci, end;
if (m_range_option == AS_OPEN_RANGE) {
ci = m_open_range_end_delimeter.begin();
end = m_open_range_end_delimeter.end();
}
else {
ci = m_closed_range_end_delimeter.begin();
end = m_closed_range_end_delimeter.end();
}
while (ci != end) {
*oitr = *ci;
ci++;
}
return oitr;
}
range_display_options range_option() const
{
return m_range_option;
}
//! Reset the range_option control
void
range_option(range_display_options option) const
{
m_range_option = option;
}
//! Change the delimiter strings
void delimiter_strings(const string_type& separator,
const string_type& start_delim,
const string_type& open_end_delim,
const string_type& closed_end_delim)
{
m_period_separator = separator;
m_period_start_delimeter = start_delim;
m_open_range_end_delimeter = open_end_delim;
m_closed_range_end_delimeter = closed_end_delim;
}
//! Generic code to output a period -- no matter the period type.
/*! This generic code will output any period using a facet to
* to output the 'elements'. For example, in the case of a date_period
* the elements will be instances of a date which will be formatted
* according the to setup in the passed facet parameter.
*
* The steps for formatting a period are always the same:
* - put the start delimiter
* - put start element
* - put the separator
* - put either last or end element depending on range settings
* - put end delimeter depending on range settings
*
* Thus for a typical date period the result might look like this:
*@code
*
* [March 01, 2004/June 07, 2004] <-- closed range
* [March 01, 2004/June 08, 2004) <-- open range
*
*@endcode
*/
template<class period_type, class facet_type>
OutItrT put_period(OutItrT next,
std::ios_base& a_ios,
char_type a_fill,
const period_type& p,
const facet_type& facet) const {
put_period_start_delimeter(next);
next = facet.put(next, a_ios, a_fill, p.begin());
put_period_separator(next);
if (m_range_option == AS_CLOSED_RANGE) {
facet.put(next, a_ios, a_fill, p.last());
}
else {
facet.put(next, a_ios, a_fill, p.end());
}
put_period_end_delimeter(next);
return next;
}
private:
range_display_options m_range_option;
string_type m_period_separator;
string_type m_period_start_delimeter;
string_type m_open_range_end_delimeter;
string_type m_closed_range_end_delimeter;
};
template <class CharT, class OutItrT>
const typename period_formatter<CharT, OutItrT>::char_type
period_formatter<CharT, OutItrT>::default_period_separator[2] = {'/'};
template <class CharT, class OutItrT>
const typename period_formatter<CharT, OutItrT>::char_type
period_formatter<CharT, OutItrT>::default_period_start_delimeter[2] = {'['};
template <class CharT, class OutItrT>
const typename period_formatter<CharT, OutItrT>::char_type
period_formatter<CharT, OutItrT>::default_period_open_range_end_delimeter[2] = {')'};
template <class CharT, class OutItrT>
const typename period_formatter<CharT, OutItrT>::char_type
period_formatter<CharT, OutItrT>::default_period_closed_range_end_delimeter[2] = {']'};
} } //namespace boost::date_time
#endif

View File

@@ -0,0 +1,197 @@
#ifndef DATETIME_PERIOD_PARSER_HPP___
#define DATETIME_PERIOD_PARSER_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 <ios>
#include <string>
#include <vector>
#include <iterator>
#include <boost/throw_exception.hpp>
#include <boost/date_time/special_defs.hpp>
#include <boost/date_time/string_parse_tree.hpp>
#include <boost/date_time/string_convert.hpp>
namespace boost { namespace date_time {
//! Not a facet, but a class used to specify and control period parsing
/*! Provides settings for the following:
* - period_separator -- default '/'
* - period_open_start_delimeter -- default '['
* - period_open_range_end_delimeter -- default ')'
* - period_closed_range_end_delimeter -- default ']'
* - display_as_open_range, display_as_closed_range -- default closed_range
*
* For a typical date_period, the contents of the input stream would be
*@code
* [2004-Jan-04/2004-Feb-01]
*@endcode
* where the date format is controlled by the date facet
*/
template<class date_type, typename CharT>
class period_parser {
public:
typedef std::basic_string<CharT> string_type;
typedef CharT char_type;
//typedef typename std::basic_string<char_type>::const_iterator const_itr_type;
typedef std::istreambuf_iterator<CharT> stream_itr_type;
typedef string_parse_tree<CharT> parse_tree_type;
typedef typename parse_tree_type::parse_match_result_type match_results;
typedef std::vector<std::basic_string<CharT> > collection_type;
static const char_type default_period_separator[2];
static const char_type default_period_start_delimeter[2];
static const char_type default_period_open_range_end_delimeter[2];
static const char_type default_period_closed_range_end_delimeter[2];
enum period_range_option { AS_OPEN_RANGE, AS_CLOSED_RANGE };
//! Constructor that sets up period parser options
period_parser(period_range_option range_opt = AS_CLOSED_RANGE,
const char_type* const period_separator = default_period_separator,
const char_type* const period_start_delimeter = default_period_start_delimeter,
const char_type* const period_open_range_end_delimeter = default_period_open_range_end_delimeter,
const char_type* const period_closed_range_end_delimeter = default_period_closed_range_end_delimeter)
: m_range_option(range_opt)
{
delimiters.push_back(string_type(period_separator));
delimiters.push_back(string_type(period_start_delimeter));
delimiters.push_back(string_type(period_open_range_end_delimeter));
delimiters.push_back(string_type(period_closed_range_end_delimeter));
}
period_range_option range_option() const
{
return m_range_option;
}
void range_option(period_range_option option)
{
m_range_option = option;
}
collection_type delimiter_strings() const
{
return delimiters;
}
void delimiter_strings(const string_type& separator,
const string_type& start_delim,
const string_type& open_end_delim,
const string_type& closed_end_delim)
{
delimiters.clear();
delimiters.push_back(separator);
delimiters.push_back(start_delim);
delimiters.push_back(open_end_delim);
delimiters.push_back(closed_end_delim);
}
//! Generic code to parse a period -- no matter the period type.
/*! This generic code will parse any period using a facet to
* to get the 'elements'. For example, in the case of a date_period
* the elements will be instances of a date which will be parsed
* according the to setup in the passed facet parameter.
*
* The steps for parsing a period are always the same:
* - consume the start delimiter
* - get start element
* - consume the separator
* - get either last or end element depending on range settings
* - consume the end delimeter depending on range settings
*
* Thus for a typical date period the contents of the input stream
* might look like this:
*@code
*
* [March 01, 2004/June 07, 2004] <-- closed range
* [March 01, 2004/June 08, 2004) <-- open range
*
*@endcode
*/
template<class period_type, class duration_type, class facet_type>
period_type get_period(stream_itr_type& sitr,
stream_itr_type& stream_end,
std::ios_base& a_ios,
const period_type& /* p */,
const duration_type& dur_unit,
const facet_type& facet) const
{
// skip leading whitespace
while(std::isspace(*sitr) && sitr != stream_end) { ++sitr; }
typedef typename period_type::point_type point_type;
point_type p1(not_a_date_time), p2(not_a_date_time);
consume_delim(sitr, stream_end, delimiters[START]); // start delim
facet.get(sitr, stream_end, a_ios, p1); // first point
consume_delim(sitr, stream_end, delimiters[SEPARATOR]); // separator
facet.get(sitr, stream_end, a_ios, p2); // second point
// period construction parameters are always open range [begin, end)
if (m_range_option == AS_CLOSED_RANGE) {
consume_delim(sitr, stream_end, delimiters[CLOSED_END]);// end delim
// add 1 duration unit to p2 to make range open
p2 += dur_unit;
}
else {
consume_delim(sitr, stream_end, delimiters[OPEN_END]); // end delim
}
return period_type(p1, p2);
}
private:
collection_type delimiters;
period_range_option m_range_option;
enum delim_ids { SEPARATOR, START, OPEN_END, CLOSED_END };
//! throws ios_base::failure if delimiter and parsed data do not match
void consume_delim(stream_itr_type& sitr,
stream_itr_type& stream_end,
const string_type& delim) const
{
/* string_parse_tree will not parse a string of punctuation characters
* without knowing exactly how many characters to process
* Ex [2000. Will not parse out the '[' string without knowing
* to process only one character. By using length of the delimiter
* string we can safely iterate past it. */
string_type s;
for(unsigned int i = 0; i < delim.length() && sitr != stream_end; ++i) {
s += *sitr;
++sitr;
}
if(s != delim) {
boost::throw_exception(std::ios_base::failure("Parse failed. Expected '"
+ convert_string_type<char_type,char>(delim) + "' but found '" + convert_string_type<char_type,char>(s) + "'"));
}
}
};
template <class date_type, class char_type>
const typename period_parser<date_type, char_type>::char_type
period_parser<date_type, char_type>::default_period_separator[2] = {'/'};
template <class date_type, class char_type>
const typename period_parser<date_type, char_type>::char_type
period_parser<date_type, char_type>::default_period_start_delimeter[2] = {'['};
template <class date_type, class char_type>
const typename period_parser<date_type, char_type>::char_type
period_parser<date_type, char_type>::default_period_open_range_end_delimeter[2] = {')'};
template <class date_type, class char_type>
const typename period_parser<date_type, char_type>::char_type
period_parser<date_type, char_type>::default_period_closed_range_end_delimeter[2] = {']'};
} } //namespace boost::date_time
#endif // DATETIME_PERIOD_PARSER_HPP___

View File

@@ -0,0 +1,100 @@
#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/cstdint.hpp>
#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)
{
return ptime(gregorian::date(1970,1,1)) + seconds(static_cast<long>(t));
}
//! Function that converts a ptime into a time_t
inline
std::time_t to_time_t(ptime pt)
{
return (pt - ptime(gregorian::date(1970,1,1))).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 = static_cast<int>(td.hours());
timetm.tm_min = static_cast<int>(td.minutes());
timetm.tm_sec = static_cast<int>(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 = static_cast<int>(date_time::absolute_value(td.hours()));
timetm.tm_min = static_cast<int>(date_time::absolute_value(td.minutes()));
timetm.tm_sec = static_cast<int>(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::detail::winapi::FILETIME_ 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 BOOST_CXX14_CONSTEXPR
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 BOOST_CXX14_CONSTEXPR
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 BOOST_CXX14_CONSTEXPR
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 BOOST_CXX14_CONSTEXPR
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 BOOST_CXX14_CONSTEXPR
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 BOOST_CXX14_CONSTEXPR
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 BOOST_CXX14_CONSTEXPR
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 BOOST_CXX14_CONSTEXPR
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,39 @@
#ifndef POSIX_TIME_HPP___
#define POSIX_TIME_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$
*/
/*!@file posix_time.hpp Global header file to get all of posix time types
*/
#include "boost/date_time/compiler_config.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
// output functions
#if defined(BOOST_DATE_TIME_INCLUDE_LIMITED_HEADERS)
#include "boost/date_time/posix_time/time_formatters_limited.hpp"
#else
#include "boost/date_time/posix_time/time_formatters.hpp"
#endif // BOOST_DATE_TIME_INCLUDE_LIMITED_HEADERS
// streaming operators
#if defined(USE_DATE_TIME_PRE_1_33_FACET_IO)
#include "boost/date_time/posix_time/posix_time_legacy_io.hpp"
#else
#include "boost/date_time/posix_time/posix_time_io.hpp"
#endif // USE_DATE_TIME_PRE_1_33_FACET_IO
#include "boost/date_time/posix_time/time_parsers.hpp"
#include "boost/date_time/posix_time/conversion.hpp"
#endif

View File

@@ -0,0 +1,165 @@
#ifndef POSIX_TIME_CONFIG_HPP___
#define POSIX_TIME_CONFIG_HPP___
/* Copyright (c) 2002,2003,2005,2020 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 {
#ifdef BOOST_DATE_TIME_POSIX_TIME_STD_CONFIG
// set up conditional test compilations
#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
#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;
#endif
//! Base time duration type
/*! \ingroup time_basics
*/
class BOOST_SYMBOL_VISIBLE 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;
BOOST_CXX14_CONSTEXPR 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)
{}
BOOST_CXX14_CONSTEXPR time_duration() :
date_time::time_duration<time_duration, time_res_traits>(0,0,0)
{}
//! Construct from special_values
BOOST_CXX14_CONSTEXPR 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:
BOOST_CXX14_CONSTEXPR 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;
BOOST_CXX14_CONSTEXPR 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;
BOOST_CXX14_CONSTEXPR bool is_special()const
{
return(is_pos_infinity() || is_neg_infinity() || is_not_a_date_time());
}
BOOST_CXX14_CONSTEXPR bool is_pos_infinity()const
{
return(day.is_pos_infinity() || time_of_day.is_pos_infinity());
}
BOOST_CXX14_CONSTEXPR bool is_neg_infinity()const
{
return(day.is_neg_infinity() || time_of_day.is_neg_infinity());
}
BOOST_CXX14_CONSTEXPR bool is_not_a_date_time()const
{
return(day.is_not_a_date() || time_of_day.is_not_a_date_time());
}
};
class BOOST_SYMBOL_VISIBLE 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,91 @@
#ifndef POSIX_TIME_DURATION_HPP___
#define POSIX_TIME_DURATION_HPP___
/* Copyright (c) 2002,2003, 2020 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/core/enable_if.hpp>
#include <boost/date_time/compiler_config.hpp>
#include <boost/date_time/posix_time/posix_time_config.hpp>
#include <boost/numeric/conversion/cast.hpp>
#include <boost/type_traits/is_integral.hpp>
namespace boost {
namespace posix_time {
//! Allows expression of durations as an hour count
//! The argument must be an integral type
/*! \ingroup time_basics
*/
class BOOST_SYMBOL_VISIBLE hours : public time_duration
{
public:
template <typename T>
BOOST_CXX14_CONSTEXPR explicit hours(T const& h,
typename boost::enable_if<boost::is_integral<T>, void>::type* = BOOST_DATE_TIME_NULLPTR) :
time_duration(numeric_cast<hour_type>(h), 0, 0)
{}
};
//! Allows expression of durations as a minute count
//! The argument must be an integral type
/*! \ingroup time_basics
*/
class BOOST_SYMBOL_VISIBLE minutes : public time_duration
{
public:
template <typename T>
BOOST_CXX14_CONSTEXPR explicit minutes(T const& m,
typename boost::enable_if<boost::is_integral<T>, void>::type* = BOOST_DATE_TIME_NULLPTR) :
time_duration(0, numeric_cast<min_type>(m),0)
{}
};
//! Allows expression of durations as a seconds count
//! The argument must be an integral type
/*! \ingroup time_basics
*/
class BOOST_SYMBOL_VISIBLE seconds : public time_duration
{
public:
template <typename T>
BOOST_CXX14_CONSTEXPR explicit seconds(T const& s,
typename boost::enable_if<boost::is_integral<T>, void>::type* = BOOST_DATE_TIME_NULLPTR) :
time_duration(0,0, numeric_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,236 @@
#ifndef DATE_TIME_POSIX_TIME_IO_HPP__
#define DATE_TIME_POSIX_TIME_IO_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 <locale>
#include <iostream>
#include <iterator> // i/ostreambuf_iterator
#include <boost/io/ios_state.hpp>
#include <boost/date_time/time_facet.hpp>
#include <boost/date_time/period_formatter.hpp>
#include <boost/date_time/posix_time/ptime.hpp>
#include <boost/date_time/posix_time/time_period.hpp>
#include <boost/date_time/posix_time/posix_time_duration.hpp>
#include <boost/date_time/posix_time/conversion.hpp> // to_tm will be needed in the facets
namespace boost {
namespace posix_time {
//! wptime_facet is depricated and will be phased out. use wtime_facet instead
//typedef boost::date_time::time_facet<ptime, wchar_t> wptime_facet;
//! ptime_facet is depricated and will be phased out. use time_facet instead
//typedef boost::date_time::time_facet<ptime, char> ptime_facet;
//! wptime_input_facet is depricated and will be phased out. use wtime_input_facet instead
//typedef boost::date_time::time_input_facet<ptime,wchar_t> wptime_input_facet;
//! ptime_input_facet is depricated and will be phased out. use time_input_facet instead
//typedef boost::date_time::time_input_facet<ptime,char> ptime_input_facet;
typedef boost::date_time::time_facet<ptime, wchar_t> wtime_facet;
typedef boost::date_time::time_facet<ptime, char> time_facet;
typedef boost::date_time::time_input_facet<ptime, wchar_t> wtime_input_facet;
typedef boost::date_time::time_input_facet<ptime, char> time_input_facet;
template <class CharT, class TraitsT>
inline
std::basic_ostream<CharT, TraitsT>&
operator<<(std::basic_ostream<CharT, TraitsT>& os,
const ptime& p) {
boost::io::ios_flags_saver iflags(os);
typedef boost::date_time::time_facet<ptime, CharT> custom_ptime_facet;
std::ostreambuf_iterator<CharT> oitr(os);
if (std::has_facet<custom_ptime_facet>(os.getloc()))
std::use_facet<custom_ptime_facet>(os.getloc()).put(oitr, os, os.fill(), p);
else {
//instantiate a custom facet for dealing with times since the user
//has not put one in the stream so far. This is for efficiency
//since we would always need to reconstruct for every time period
//if the locale did not already exist. Of course this will be overridden
//if the user imbues as some later point.
custom_ptime_facet* f = new custom_ptime_facet();
std::locale l = std::locale(os.getloc(), f);
os.imbue(l);
f->put(oitr, os, os.fill(), p);
}
return os;
}
//! input operator for ptime
template <class CharT, class Traits>
inline
std::basic_istream<CharT, Traits>&
operator>>(std::basic_istream<CharT, Traits>& is, ptime& pt)
{
boost::io::ios_flags_saver iflags(is);
typename std::basic_istream<CharT, Traits>::sentry strm_sentry(is, false);
if (strm_sentry) {
try {
typedef typename date_time::time_input_facet<ptime, CharT> time_input_facet_local;
std::istreambuf_iterator<CharT,Traits> sit(is), str_end;
if(std::has_facet<time_input_facet_local>(is.getloc())) {
std::use_facet<time_input_facet_local>(is.getloc()).get(sit, str_end, is, pt);
}
else {
time_input_facet_local* f = new time_input_facet_local();
std::locale l = std::locale(is.getloc(), f);
is.imbue(l);
f->get(sit, str_end, is, pt);
}
}
catch(...) {
// mask tells us what exceptions are turned on
std::ios_base::iostate exception_mask = is.exceptions();
// if the user wants exceptions on failbit, we'll rethrow our
// date_time exception & set the failbit
if(std::ios_base::failbit & exception_mask) {
try { is.setstate(std::ios_base::failbit); }
catch(std::ios_base::failure&) {} // ignore this one
throw; // rethrow original exception
}
else {
// if the user want's to fail quietly, we simply set the failbit
is.setstate(std::ios_base::failbit);
}
}
}
return is;
}
template <class CharT, class TraitsT>
inline
std::basic_ostream<CharT, TraitsT>&
operator<<(std::basic_ostream<CharT, TraitsT>& os,
const boost::posix_time::time_period& p) {
boost::io::ios_flags_saver iflags(os);
typedef boost::date_time::time_facet<ptime, CharT> custom_ptime_facet;
std::ostreambuf_iterator<CharT> oitr(os);
if (std::has_facet<custom_ptime_facet>(os.getloc())) {
std::use_facet<custom_ptime_facet>(os.getloc()).put(oitr, os, os.fill(), p);
}
else {
//instantiate a custom facet for dealing with periods since the user
//has not put one in the stream so far. This is for efficiency
//since we would always need to reconstruct for every time period
//if the local did not already exist. Of course this will be overridden
//if the user imbues as some later point.
custom_ptime_facet* f = new custom_ptime_facet();
std::locale l = std::locale(os.getloc(), f);
os.imbue(l);
f->put(oitr, os, os.fill(), p);
}
return os;
}
//! input operator for time_period
template <class CharT, class Traits>
inline
std::basic_istream<CharT, Traits>&
operator>>(std::basic_istream<CharT, Traits>& is, time_period& tp)
{
boost::io::ios_flags_saver iflags(is);
typename std::basic_istream<CharT, Traits>::sentry strm_sentry(is, false);
if (strm_sentry) {
try {
typedef typename date_time::time_input_facet<ptime, CharT> time_input_facet_local;
std::istreambuf_iterator<CharT,Traits> sit(is), str_end;
if(std::has_facet<time_input_facet_local>(is.getloc())) {
std::use_facet<time_input_facet_local>(is.getloc()).get(sit, str_end, is, tp);
}
else {
time_input_facet_local* f = new time_input_facet_local();
std::locale l = std::locale(is.getloc(), f);
is.imbue(l);
f->get(sit, str_end, is, tp);
}
}
catch(...) {
std::ios_base::iostate exception_mask = is.exceptions();
if(std::ios_base::failbit & exception_mask) {
try { is.setstate(std::ios_base::failbit); }
catch(std::ios_base::failure&) {}
throw; // rethrow original exception
}
else {
is.setstate(std::ios_base::failbit);
}
}
}
return is;
}
//! ostream operator for posix_time::time_duration
// todo fix to use facet -- place holder for now...
template <class CharT, class Traits>
inline
std::basic_ostream<CharT, Traits>&
operator<<(std::basic_ostream<CharT, Traits>& os, const time_duration& td)
{
boost::io::ios_flags_saver iflags(os);
typedef boost::date_time::time_facet<ptime, CharT> custom_ptime_facet;
std::ostreambuf_iterator<CharT> oitr(os);
if (std::has_facet<custom_ptime_facet>(os.getloc()))
std::use_facet<custom_ptime_facet>(os.getloc()).put(oitr, os, os.fill(), td);
else {
//instantiate a custom facet for dealing with times since the user
//has not put one in the stream so far. This is for efficiency
//since we would always need to reconstruct for every time period
//if the locale did not already exist. Of course this will be overridden
//if the user imbues as some later point.
custom_ptime_facet* f = new custom_ptime_facet();
std::locale l = std::locale(os.getloc(), f);
os.imbue(l);
f->put(oitr, os, os.fill(), td);
}
return os;
}
//! input operator for time_duration
template <class CharT, class Traits>
inline
std::basic_istream<CharT, Traits>&
operator>>(std::basic_istream<CharT, Traits>& is, time_duration& td)
{
boost::io::ios_flags_saver iflags(is);
typename std::basic_istream<CharT, Traits>::sentry strm_sentry(is, false);
if (strm_sentry) {
try {
typedef typename date_time::time_input_facet<ptime, CharT> time_input_facet_local;
std::istreambuf_iterator<CharT,Traits> sit(is), str_end;
if(std::has_facet<time_input_facet_local>(is.getloc())) {
std::use_facet<time_input_facet_local>(is.getloc()).get(sit, str_end, is, td);
}
else {
time_input_facet_local* f = new time_input_facet_local();
std::locale l = std::locale(is.getloc(), f);
is.imbue(l);
f->get(sit, str_end, is, td);
}
}
catch(...) {
std::ios_base::iostate exception_mask = is.exceptions();
if(std::ios_base::failbit & exception_mask) {
try { is.setstate(std::ios_base::failbit); }
catch(std::ios_base::failure&) {}
throw; // rethrow original exception
}
else {
is.setstate(std::ios_base::failbit);
}
}
}
return is;
}
} } // namespaces
#endif // DATE_TIME_POSIX_TIME_IO_HPP__

View File

@@ -0,0 +1,153 @@
#ifndef POSIX_TIME_PRE133_OPERATORS_HPP___
#define POSIX_TIME_PRE133_OPERATORS_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$
*/
/*! @file posix_time_pre133_operators.hpp
* These input and output operators are for use with the
* pre 1.33 version of the date_time libraries io facet code.
* The operators used in version 1.33 and later can be found
* in posix_time_io.hpp */
#include <iostream>
#include <string>
#include <sstream>
#include "boost/date_time/compiler_config.hpp"
#include "boost/date_time/gregorian/gregorian.hpp"
#include "boost/date_time/posix_time/posix_time_duration.hpp"
#include "boost/date_time/posix_time/ptime.hpp"
#include "boost/date_time/posix_time/time_period.hpp"
#include "boost/date_time/time_parsing.hpp"
namespace boost {
namespace posix_time {
//The following code is removed for configurations with poor std::locale support (eg: MSVC6, gcc 2.9x)
#ifndef BOOST_DATE_TIME_NO_LOCALE
#if defined(USE_DATE_TIME_PRE_1_33_FACET_IO)
//! ostream operator for posix_time::time_duration
template <class charT, class traits>
inline
std::basic_ostream<charT, traits>&
operator<<(std::basic_ostream<charT, traits>& os, const time_duration& td)
{
typedef boost::date_time::ostream_time_duration_formatter<time_duration, charT> duration_formatter;
duration_formatter::duration_put(td, os);
return os;
}
//! ostream operator for posix_time::ptime
template <class charT, class traits>
inline
std::basic_ostream<charT, traits>&
operator<<(std::basic_ostream<charT, traits>& os, const ptime& t)
{
typedef boost::date_time::ostream_time_formatter<ptime, charT> time_formatter;
time_formatter::time_put(t, os);
return os;
}
//! ostream operator for posix_time::time_period
template <class charT, class traits>
inline
std::basic_ostream<charT, traits>&
operator<<(std::basic_ostream<charT, traits>& os, const time_period& tp)
{
typedef boost::date_time::ostream_time_period_formatter<time_period, charT> period_formatter;
period_formatter::period_put(tp, os);
return os;
}
#endif // USE_DATE_TIME_PRE_1_33_FACET_IO
/******** input streaming ********/
template<class charT>
inline
std::basic_istream<charT>& operator>>(std::basic_istream<charT>& is, time_duration& td)
{
// need to create a std::string and parse it
std::basic_string<charT> inp_s;
std::stringstream out_ss;
is >> inp_s;
typename std::basic_string<charT>::iterator b = inp_s.begin();
// need to use both iterators because there is no requirement
// for the data held by a std::basic_string<> be terminated with
// any marker (such as '\0').
typename std::basic_string<charT>::iterator e = inp_s.end();
while(b != e){
out_ss << is.narrow(*b, 0);
++b;
}
td = date_time::parse_delimited_time_duration<time_duration>(out_ss.str());
return is;
}
template<class charT>
inline
std::basic_istream<charT>& operator>>(std::basic_istream<charT>& is, ptime& pt)
{
gregorian::date d(not_a_date_time);
time_duration td(0,0,0);
is >> d >> td;
pt = ptime(d, td);
return is;
}
/** operator>> for time_period. time_period must be in
* "[date time_duration/date time_duration]" format. */
template<class charT>
inline
std::basic_istream<charT>& operator>>(std::basic_istream<charT>& is, time_period& tp)
{
gregorian::date d(not_a_date_time);
time_duration td(0,0,0);
ptime beg(d, td);
ptime end(beg);
std::basic_string<charT> s;
// get first date string and remove leading '['
is >> s;
{
std::basic_stringstream<charT> ss;
ss << s.substr(s.find('[')+1);
ss >> d;
}
// get first time_duration & second date string, remove the '/'
// and split into 2 strings
is >> s;
{
std::basic_stringstream<charT> ss;
ss << s.substr(0, s.find('/'));
ss >> td;
}
beg = ptime(d, td);
{
std::basic_stringstream<charT> ss;
ss << s.substr(s.find('/')+1);
ss >> d;
}
// get last time_duration and remove the trailing ']'
is >> s;
{
std::basic_stringstream<charT> ss;
ss << s.substr(0, s.find(']'));
ss >> td;
}
end = ptime(d, td);
tp = time_period(beg,end);
return is;
}
#endif //BOOST_DATE_TIME_NO_LOCALE
} } // namespaces
#endif // POSIX_TIME_PRE133_OPERATORS_HPP___

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,84 @@
#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>
#include <boost/date_time/compiler_config.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 BOOST_SYMBOL_VISIBLE 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
BOOST_CXX14_CONSTEXPR
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)
BOOST_CXX14_CONSTEXPR
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
BOOST_CXX14_CONSTEXPR
ptime(const time_rep_type& rhs):
date_time::base_time<time_type,time_system_type>(rhs)
{}
//! Construct from special value
BOOST_CXX14_CONSTEXPR
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
BOOST_CXX14_CONSTEXPR
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
friend BOOST_CXX14_CONSTEXPR
bool operator==(const ptime& lhs, const ptime& rhs);
};
inline BOOST_CXX14_CONSTEXPR
bool operator==(const ptime& lhs, const ptime& rhs)
{
return ptime::time_system_type::is_equal(lhs.time_,rhs.time_);
}
} }//namespace posix_time
#endif

View File

@@ -0,0 +1,289 @@
#ifndef POSIXTIME_FORMATTERS_HPP___
#define POSIXTIME_FORMATTERS_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/gregorian/gregorian.hpp>
#include <boost/date_time/compiler_config.hpp>
#include <boost/date_time/iso_format.hpp>
#include <boost/date_time/date_format_simple.hpp>
#include <boost/date_time/posix_time/posix_time_types.hpp>
#include <boost/date_time/time_formatting_streams.hpp>
#include <boost/date_time/time_resolution_traits.hpp> // absolute_value
#include <boost/date_time/time_parsing.hpp>
/* NOTE: The "to_*_string" code for older compilers, ones that define
* BOOST_DATE_TIME_INCLUDE_LIMITED_HEADERS, is located in
* formatters_limited.hpp
*/
namespace boost {
namespace posix_time {
// template function called by wrapper functions:
// to_*_string(time_duration) & to_*_wstring(time_duration)
template<class charT>
inline std::basic_string<charT> to_simple_string_type(time_duration td) {
std::basic_ostringstream<charT> ss;
if(td.is_special()) {
/* simply using 'ss << td.get_rep()' won't work on compilers
* that don't support locales. This way does. */
// switch copied from date_names_put.hpp
switch(td.get_rep().as_special())
{
case not_a_date_time:
//ss << "not-a-number";
ss << "not-a-date-time";
break;
case pos_infin:
ss << "+infinity";
break;
case neg_infin:
ss << "-infinity";
break;
default:
ss << "";
}
}
else {
charT fill_char = '0';
if(td.is_negative()) {
ss << '-';
}
ss << std::setw(2) << std::setfill(fill_char)
<< date_time::absolute_value(td.hours()) << ":";
ss << std::setw(2) << std::setfill(fill_char)
<< date_time::absolute_value(td.minutes()) << ":";
ss << std::setw(2) << std::setfill(fill_char)
<< date_time::absolute_value(td.seconds());
//TODO the following is totally non-generic, yelling FIXME
#if (defined(BOOST_MSVC) && (_MSC_VER < 1300))
boost::int64_t frac_sec =
date_time::absolute_value(td.fractional_seconds());
// JDG [7/6/02 VC++ compatibility]
charT buff[32];
_i64toa(frac_sec, buff, 10);
#else
time_duration::fractional_seconds_type frac_sec =
date_time::absolute_value(td.fractional_seconds());
#endif
if (frac_sec != 0) {
ss << "." << std::setw(time_duration::num_fractional_digits())
<< std::setfill(fill_char)
// JDG [7/6/02 VC++ compatibility]
#if (defined(BOOST_MSVC) && (_MSC_VER < 1300))
<< buff;
#else
<< frac_sec;
#endif
}
}// else
return ss.str();
}
//! Time duration to string -hh::mm::ss.fffffff. Example: 10:09:03.0123456
/*!\ingroup time_format
*/
inline std::string to_simple_string(time_duration td) {
return to_simple_string_type<char>(td);
}
// template function called by wrapper functions:
// to_*_string(time_duration) & to_*_wstring(time_duration)
template<class charT>
inline std::basic_string<charT> to_iso_string_type(time_duration td)
{
std::basic_ostringstream<charT> ss;
if(td.is_special()) {
/* simply using 'ss << td.get_rep()' won't work on compilers
* that don't support locales. This way does. */
// switch copied from date_names_put.hpp
switch(td.get_rep().as_special()) {
case not_a_date_time:
//ss << "not-a-number";
ss << "not-a-date-time";
break;
case pos_infin:
ss << "+infinity";
break;
case neg_infin:
ss << "-infinity";
break;
default:
ss << "";
}
}
else {
charT fill_char = '0';
if(td.is_negative()) {
ss << '-';
}
ss << std::setw(2) << std::setfill(fill_char)
<< date_time::absolute_value(td.hours());
ss << std::setw(2) << std::setfill(fill_char)
<< date_time::absolute_value(td.minutes());
ss << std::setw(2) << std::setfill(fill_char)
<< date_time::absolute_value(td.seconds());
//TODO the following is totally non-generic, yelling FIXME
#if (defined(BOOST_MSVC) && (_MSC_VER < 1300))
boost::int64_t frac_sec =
date_time::absolute_value(td.fractional_seconds());
// JDG [7/6/02 VC++ compatibility]
charT buff[32];
_i64toa(frac_sec, buff, 10);
#else
time_duration::fractional_seconds_type frac_sec =
date_time::absolute_value(td.fractional_seconds());
#endif
if (frac_sec != 0) {
ss << "." << std::setw(time_duration::num_fractional_digits())
<< std::setfill(fill_char)
// JDG [7/6/02 VC++ compatibility]
#if (defined(BOOST_MSVC) && (_MSC_VER < 1300))
<< buff;
#else
<< frac_sec;
#endif
}
}// else
return ss.str();
}
//! Time duration in iso format -hhmmss,fffffff Example: 10:09:03,0123456
/*!\ingroup time_format
*/
inline std::string to_iso_string(time_duration td){
return to_iso_string_type<char>(td);
}
//! Time to simple format CCYY-mmm-dd hh:mm:ss.fffffff
/*!\ingroup time_format
*/
template<class charT>
inline std::basic_string<charT> to_simple_string_type(ptime t)
{
// can't use this w/gcc295, no to_simple_string_type<>(td) available
std::basic_string<charT> ts = gregorian::to_simple_string_type<charT>(t.date());// + " ";
if(!t.time_of_day().is_special()) {
charT space = ' ';
return ts + space + to_simple_string_type<charT>(t.time_of_day());
}
else {
return ts;
}
}
inline std::string to_simple_string(ptime t){
return to_simple_string_type<char>(t);
}
// function called by wrapper functions to_*_string(time_period)
// & to_*_wstring(time_period)
template<class charT>
inline std::basic_string<charT> to_simple_string_type(time_period tp)
{
charT beg = '[', mid = '/', end = ']';
std::basic_string<charT> d1(to_simple_string_type<charT>(tp.begin()));
std::basic_string<charT> d2(to_simple_string_type<charT>(tp.last()));
return std::basic_string<charT>(beg + d1 + mid + d2 + end);
}
//! Convert to string of form [YYYY-mmm-DD HH:MM::SS.ffffff/YYYY-mmm-DD HH:MM::SS.fffffff]
/*!\ingroup time_format
*/
inline std::string to_simple_string(time_period tp){
return to_simple_string_type<char>(tp);
}
// function called by wrapper functions to_*_string(time_period)
// & to_*_wstring(time_period)
template<class charT>
inline std::basic_string<charT> to_iso_string_type(ptime t)
{
std::basic_string<charT> ts = gregorian::to_iso_string_type<charT>(t.date());// + "T";
if(!t.time_of_day().is_special()) {
charT sep = 'T';
return ts + sep + to_iso_string_type<charT>(t.time_of_day());
}
else {
return ts;
}
}
//! Convert iso short form YYYYMMDDTHHMMSS where T is the date-time separator
/*!\ingroup time_format
*/
inline std::string to_iso_string(ptime t){
return to_iso_string_type<char>(t);
}
// function called by wrapper functions to_*_string(time_period)
// & to_*_wstring(time_period)
template<class charT>
inline std::basic_string<charT> to_iso_extended_string_type(ptime t)
{
std::basic_string<charT> ts = gregorian::to_iso_extended_string_type<charT>(t.date());// + "T";
if(!t.time_of_day().is_special()) {
charT sep = 'T';
return ts + sep + to_simple_string_type<charT>(t.time_of_day());
}
else {
return ts;
}
}
//! Convert to form YYYY-MM-DDTHH:MM:SS where T is the date-time separator
/*!\ingroup time_format
*/
inline std::string to_iso_extended_string(ptime t){
return to_iso_extended_string_type<char>(t);
}
#if !defined(BOOST_NO_STD_WSTRING)
//! Time duration to wstring -hh::mm::ss.fffffff. Example: 10:09:03.0123456
/*!\ingroup time_format
*/
inline std::wstring to_simple_wstring(time_duration td) {
return to_simple_string_type<wchar_t>(td);
}
//! Time duration in iso format -hhmmss,fffffff Example: 10:09:03,0123456
/*!\ingroup time_format
*/
inline std::wstring to_iso_wstring(time_duration td){
return to_iso_string_type<wchar_t>(td);
}
inline std::wstring to_simple_wstring(ptime t){
return to_simple_string_type<wchar_t>(t);
}
//! Convert to wstring of form [YYYY-mmm-DD HH:MM::SS.ffffff/YYYY-mmm-DD HH:MM::SS.fffffff]
/*!\ingroup time_format
*/
inline std::wstring to_simple_wstring(time_period tp){
return to_simple_string_type<wchar_t>(tp);
}
//! Convert iso short form YYYYMMDDTHHMMSS where T is the date-time separator
/*!\ingroup time_format
*/
inline std::wstring to_iso_wstring(ptime t){
return to_iso_string_type<wchar_t>(t);
}
//! Convert to form YYYY-MM-DDTHH:MM:SS where T is the date-time separator
/*!\ingroup time_format
*/
inline std::wstring to_iso_extended_wstring(ptime t){
return to_iso_extended_string_type<wchar_t>(t);
}
#endif // BOOST_NO_STD_WSTRING
} } //namespace posix_time
#endif

View File

@@ -0,0 +1,212 @@
#ifndef POSIXTIME_FORMATTERS_LIMITED_HPP___
#define POSIXTIME_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.hpp>
#include <boost/date_time/compiler_config.hpp>
#include <boost/date_time/iso_format.hpp>
#include <boost/date_time/date_format_simple.hpp>
#include <boost/date_time/posix_time/posix_time_types.hpp>
#include <boost/date_time/time_formatting_streams.hpp>
#include <boost/date_time/time_resolution_traits.hpp> // absolute_value
namespace boost {
namespace posix_time {
//! Time duration to string -hh::mm::ss.fffffff. Example: 10:09:03.0123456
/*!\ingroup time_format
*/
inline std::string to_simple_string(time_duration td) {
std::ostringstream ss;
if(td.is_special()) {
/* simply using 'ss << td.get_rep()' won't work on compilers
* that don't support locales. This way does. */
// switch copied from date_names_put.hpp
switch(td.get_rep().as_special())
{
case not_a_date_time:
//ss << "not-a-number";
ss << "not-a-date-time";
break;
case pos_infin:
ss << "+infinity";
break;
case neg_infin:
ss << "-infinity";
break;
default:
ss << "";
}
}
else {
if(td.is_negative()) {
ss << '-';
}
ss << std::setw(2) << std::setfill('0')
<< date_time::absolute_value(td.hours()) << ":";
ss << std::setw(2) << std::setfill('0')
<< date_time::absolute_value(td.minutes()) << ":";
ss << std::setw(2) << std::setfill('0')
<< date_time::absolute_value(td.seconds());
//TODO the following is totally non-generic, yelling FIXME
#if (defined(BOOST_MSVC) && (_MSC_VER < 1300))
boost::int64_t frac_sec =
date_time::absolute_value(td.fractional_seconds());
// JDG [7/6/02 VC++ compatibility]
char buff[32];
_i64toa(frac_sec, buff, 10);
#else
time_duration::fractional_seconds_type frac_sec =
date_time::absolute_value(td.fractional_seconds());
#endif
if (frac_sec != 0) {
ss << "." << std::setw(time_duration::num_fractional_digits())
<< std::setfill('0')
// JDG [7/6/02 VC++ compatibility]
#if (defined(BOOST_MSVC) && (_MSC_VER < 1300))
<< buff;
#else
<< frac_sec;
#endif
}
}// else
return ss.str();
}
//! Time duration in iso format -hhmmss,fffffff Example: 10:09:03,0123456
/*!\ingroup time_format
*/
inline
std::string
to_iso_string(time_duration td)
{
std::ostringstream ss;
if(td.is_special()) {
/* simply using 'ss << td.get_rep()' won't work on compilers
* that don't support locales. This way does. */
// switch copied from date_names_put.hpp
switch(td.get_rep().as_special()) {
case not_a_date_time:
//ss << "not-a-number";
ss << "not-a-date-time";
break;
case pos_infin:
ss << "+infinity";
break;
case neg_infin:
ss << "-infinity";
break;
default:
ss << "";
}
}
else {
if(td.is_negative()) {
ss << '-';
}
ss << std::setw(2) << std::setfill('0')
<< date_time::absolute_value(td.hours());
ss << std::setw(2) << std::setfill('0')
<< date_time::absolute_value(td.minutes());
ss << std::setw(2) << std::setfill('0')
<< date_time::absolute_value(td.seconds());
//TODO the following is totally non-generic, yelling FIXME
#if (defined(BOOST_MSVC) && (_MSC_VER < 1300))
boost::int64_t frac_sec =
date_time::absolute_value(td.fractional_seconds());
// JDG [7/6/02 VC++ compatibility]
char buff[32];
_i64toa(frac_sec, buff, 10);
#else
time_duration::fractional_seconds_type frac_sec =
date_time::absolute_value(td.fractional_seconds());
#endif
if (frac_sec != 0) {
ss << "." << std::setw(time_duration::num_fractional_digits())
<< std::setfill('0')
// JDG [7/6/02 VC++ compatibility]
#if (defined(BOOST_MSVC) && (_MSC_VER < 1300))
<< buff;
#else
<< frac_sec;
#endif
}
}// else
return ss.str();
}
//! Time to simple format CCYY-mmm-dd hh:mm:ss.fffffff
/*!\ingroup time_format
*/
inline
std::string
to_simple_string(ptime t)
{
std::string ts = gregorian::to_simple_string(t.date());// + " ";
if(!t.time_of_day().is_special()) {
return ts + " " + to_simple_string(t.time_of_day());
}
else {
return ts;
}
}
//! Convert to string of form [YYYY-mmm-DD HH:MM::SS.ffffff/YYYY-mmm-DD HH:MM::SS.fffffff]
/*!\ingroup time_format
*/
inline
std::string
to_simple_string(time_period tp)
{
std::string d1(to_simple_string(tp.begin()));
std::string d2(to_simple_string(tp.last()));
return std::string("[" + d1 + "/" + d2 +"]");
}
//! Convert iso short form YYYYMMDDTHHMMSS where T is the date-time separator
/*!\ingroup time_format
*/
inline
std::string to_iso_string(ptime t)
{
std::string ts = gregorian::to_iso_string(t.date());// + "T";
if(!t.time_of_day().is_special()) {
return ts + "T" + to_iso_string(t.time_of_day());
}
else {
return ts;
}
}
//! Convert to form YYYY-MM-DDTHH:MM:SS where T is the date-time separator
/*!\ingroup time_format
*/
inline
std::string
to_iso_extended_string(ptime t)
{
std::string ts = gregorian::to_iso_extended_string(t.date());// + "T";
if(!t.time_of_day().is_special()) {
return ts + "T" + to_simple_string(t.time_of_day());
}
else {
return ts;
}
}
} } //namespace posix_time
#endif

View File

@@ -0,0 +1,52 @@
#ifndef POSIXTIME_PARSERS_HPP___
#define POSIXTIME_PARSERS_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/gregorian/gregorian.hpp"
#include "boost/date_time/time_parsing.hpp"
#include "boost/date_time/posix_time/posix_time_types.hpp"
namespace boost {
namespace posix_time {
//! Creates a time_duration object from a delimited string
/*! Expected format for string is "[-]h[h][:mm][:ss][.fff]".
* A negative duration will be created if the first character in
* string is a '-', all other '-' will be treated as delimiters.
* Accepted delimiters are "-:,.". */
inline time_duration duration_from_string(const std::string& s) {
return date_time::parse_delimited_time_duration<time_duration>(s);
}
inline ptime time_from_string(const std::string& s) {
return date_time::parse_delimited_time<ptime>(s, ' ');
}
inline ptime from_iso_string(const std::string& s) {
return date_time::parse_iso_time<ptime>(s, 'T');
}
inline ptime from_iso_extended_string(const std::string& s) {
if (s.size() == 10) { //assume we just have a date which is 10 chars
gregorian::date d = gregorian::from_simple_string(s);
return ptime( d );
}
return date_time::parse_delimited_time<ptime>(s, 'T');
}
} } //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,262 @@
#ifndef POSIX_TIME_SERIALIZE_HPP___
#define POSIX_TIME_SERIALIZE_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 "boost/date_time/posix_time/posix_time.hpp"
#include "boost/date_time/gregorian/greg_serialize.hpp"
#include "boost/core/nvp.hpp"
#include "boost/numeric/conversion/cast.hpp"
#include "boost/type_traits/integral_constant.hpp"
// Define versions for serialization compatibility
// alows the unit tests to make an older version to check compatibility
#ifndef BOOST_DATE_TIME_POSIX_TIME_DURATION_VERSION
#define BOOST_DATE_TIME_POSIX_TIME_DURATION_VERSION 1
#endif
namespace boost {
namespace serialization {
template<typename T>
struct version;
template<>
struct version<boost::posix_time::time_duration>
: integral_constant<int, BOOST_DATE_TIME_POSIX_TIME_DURATION_VERSION>
{
};
// A macro to split serialize functions into save & load functions.
// It is here to avoid dependency on Boost.Serialization just for the
// BOOST_SERIALIZATION_SPLIT_FREE macro
#define BOOST_DATE_TIME_SPLIT_FREE(T) \
template<class Archive> \
inline void serialize(Archive & ar, \
T & t, \
const unsigned int file_version) \
{ \
split_free(ar, t, file_version); \
}
BOOST_DATE_TIME_SPLIT_FREE(boost::posix_time::ptime)
BOOST_DATE_TIME_SPLIT_FREE(boost::posix_time::time_duration)
BOOST_DATE_TIME_SPLIT_FREE(boost::posix_time::time_period)
#undef BOOST_DATE_TIME_SPLIT_FREE
/*** time_duration ***/
//! Function to save posix_time::time_duration objects using serialization lib
/*! time_duration objects are broken down into 4 parts for serialization:
* types are hour_type, min_type, sec_type, and fractional_seconds_type
* as defined in the time_duration class
*/
template<class TimeResTraitsSize, class Archive>
void save_td(Archive& ar, const posix_time::time_duration& td)
{
TimeResTraitsSize h = boost::numeric_cast<TimeResTraitsSize>(td.hours());
TimeResTraitsSize m = boost::numeric_cast<TimeResTraitsSize>(td.minutes());
TimeResTraitsSize s = boost::numeric_cast<TimeResTraitsSize>(td.seconds());
posix_time::time_duration::fractional_seconds_type fs = td.fractional_seconds();
ar & make_nvp("time_duration_hours", h);
ar & make_nvp("time_duration_minutes", m);
ar & make_nvp("time_duration_seconds", s);
ar & make_nvp("time_duration_fractional_seconds", fs);
}
template<class Archive>
void save(Archive & ar,
const posix_time::time_duration& td,
unsigned int version)
{
// serialize a bool so we know how to read this back in later
bool is_special = td.is_special();
ar & make_nvp("is_special", is_special);
if(is_special) {
std::string s = to_simple_string(td);
ar & make_nvp("sv_time_duration", s);
}
else {
// Write support for earlier versions allows for upgrade compatibility testing
// See load comments for version information
if (version == 0) {
save_td<int32_t>(ar, td);
} else {
save_td<int64_t>(ar, td);
}
}
}
//! Function to load posix_time::time_duration objects using serialization lib
/*! time_duration objects are broken down into 4 parts for serialization:
* types are hour_type, min_type, sec_type, and fractional_seconds_type
* as defined in the time_duration class
*/
template<class TimeResTraitsSize, class Archive>
void load_td(Archive& ar, posix_time::time_duration& td)
{
TimeResTraitsSize h(0);
TimeResTraitsSize m(0);
TimeResTraitsSize s(0);
posix_time::time_duration::fractional_seconds_type fs(0);
ar & make_nvp("time_duration_hours", h);
ar & make_nvp("time_duration_minutes", m);
ar & make_nvp("time_duration_seconds", s);
ar & make_nvp("time_duration_fractional_seconds", fs);
td = posix_time::time_duration(h, m, s, fs);
}
template<class Archive>
void load(Archive & ar,
posix_time::time_duration & td,
unsigned int version)
{
bool is_special = false;
ar & make_nvp("is_special", is_special);
if(is_special) {
std::string s;
ar & make_nvp("sv_time_duration", s);
posix_time::special_values sv = gregorian::special_value_from_string(s);
td = posix_time::time_duration(sv);
}
else {
// Version "0" (Boost 1.65.1 or earlier, which used int32_t for day/hour/minute/second and
// therefore suffered from the year 2038 issue.)
// Version "0.5" (Boost 1.66.0 changed to std::time_t but did not increase the version;
// it was missed in the original change, all code reviews, and there were no
// static assertions to protect the code; further std::time_t can be 32-bit
// or 64-bit so it reduced portability. This makes 1.66.0 hard to handle...)
// Version "1" (Boost 1.67.0 or later uses int64_t and is properly versioned)
// If the size of any of these items changes, a new version is needed.
BOOST_STATIC_ASSERT(sizeof(posix_time::time_duration::hour_type) == sizeof(boost::int64_t));
BOOST_STATIC_ASSERT(sizeof(posix_time::time_duration::min_type) == sizeof(boost::int64_t));
BOOST_STATIC_ASSERT(sizeof(posix_time::time_duration::sec_type) == sizeof(boost::int64_t));
BOOST_STATIC_ASSERT(sizeof(posix_time::time_duration::fractional_seconds_type) == sizeof(boost::int64_t));
if (version == 0) {
load_td<int32_t>(ar, td);
} else {
load_td<int64_t>(ar, td);
}
}
}
// no load_construct_data function provided as time_duration provides a
// default constructor
/*** ptime ***/
//! Function to save posix_time::ptime objects using serialization lib
/*! ptime objects are broken down into 2 parts for serialization:
* a date object and a time_duration onject
*/
template<class Archive>
void save(Archive & ar,
const posix_time::ptime& pt,
unsigned int /*version*/)
{
// from_iso_string does not include fractional seconds
// therefore date and time_duration are used
posix_time::ptime::date_type d = pt.date();
ar & make_nvp("ptime_date", d);
if(!pt.is_special()) {
posix_time::ptime::time_duration_type td = pt.time_of_day();
ar & make_nvp("ptime_time_duration", td);
}
}
//! Function to load posix_time::ptime objects using serialization lib
/*! ptime objects are broken down into 2 parts for serialization:
* a date object and a time_duration onject
*/
template<class Archive>
void load(Archive & ar,
posix_time::ptime & pt,
unsigned int /*version*/)
{
// from_iso_string does not include fractional seconds
// therefore date and time_duration are used
posix_time::ptime::date_type d(posix_time::not_a_date_time);
posix_time::ptime::time_duration_type td;
ar & make_nvp("ptime_date", d);
if(!d.is_special()) {
ar & make_nvp("ptime_time_duration", td);
pt = boost::posix_time::ptime(d,td);
}
else {
pt = boost::posix_time::ptime(d.as_special());
}
}
//!override needed b/c no default constructor
template<class Archive>
inline void load_construct_data(Archive & /*ar*/,
posix_time::ptime* pt,
const unsigned int /*file_version*/)
{
// retrieve data from archive required to construct new
// invoke inplace constructor to initialize instance of date
new(pt) boost::posix_time::ptime(boost::posix_time::not_a_date_time);
}
/*** time_period ***/
//! Function to save posix_time::time_period objects using serialization lib
/*! time_period objects are broken down into 2 parts for serialization:
* a begining ptime object and an ending ptime object
*/
template<class Archive>
void save(Archive & ar,
const posix_time::time_period& tp,
unsigned int /*version*/)
{
posix_time::ptime beg(tp.begin().date(), tp.begin().time_of_day());
posix_time::ptime end(tp.end().date(), tp.end().time_of_day());
ar & make_nvp("time_period_begin", beg);
ar & make_nvp("time_period_end", end);
}
//! Function to load posix_time::time_period objects using serialization lib
/*! time_period objects are broken down into 2 parts for serialization:
* a begining ptime object and an ending ptime object
*/
template<class Archive>
void load(Archive & ar,
boost::posix_time::time_period & tp,
unsigned int /*version*/)
{
posix_time::time_duration td(1,0,0);
gregorian::date d(gregorian::not_a_date_time);
posix_time::ptime beg(d,td);
posix_time::ptime end(d,td);
ar & make_nvp("time_period_begin", beg);
ar & make_nvp("time_period_end", end);
tp = boost::posix_time::time_period(beg, end);
}
//!override needed b/c no default constructor
template<class Archive>
inline void load_construct_data(Archive & /*ar*/,
boost::posix_time::time_period* tp,
const unsigned int /*file_version*/)
{
posix_time::time_duration td(1,0,0);
gregorian::date d(gregorian::not_a_date_time);
posix_time::ptime beg(d,td);
posix_time::ptime end(d,td);
new(tp) boost::posix_time::time_period(beg,end);
}
} // namespace serialization
} // namespace boost
#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,97 @@
#ifndef DATETIME_SPECIAL_VALUE_FORMATTER_HPP___
#define DATETIME_SPECIAL_VALUE_FORMATTER_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
* $Date$
*/
#include <vector>
#include <string>
#include <iterator>
#include "boost/date_time/special_defs.hpp"
namespace boost { namespace date_time {
//! Class that provides generic formmatting ostream formatting for special values
/*! This class provides for the formmating of special values to an output stream.
* In particular, it produces strings for the values of negative and positive
* infinity as well as not_a_date_time.
*
* While not a facet, this class is used by the date and time facets for formatting
* special value types.
*
*/
template <class CharT, class OutItrT = std::ostreambuf_iterator<CharT, std::char_traits<CharT> > >
class special_values_formatter
{
public:
typedef std::basic_string<CharT> string_type;
typedef CharT char_type;
typedef std::vector<string_type> collection_type;
static const char_type default_special_value_names[3][17];
//! Construct special values formatter using default strings.
/*! Default strings are not-a-date-time -infinity +infinity
*/
special_values_formatter()
{
std::copy(&default_special_value_names[0],
&default_special_value_names[3],
std::back_inserter(m_special_value_names));
}
//! Construct special values formatter from array of strings
/*! This constructor will take pair of iterators from an array of strings
* that represent the special values and copy them for use in formatting
* special values.
*@code
* const char* const special_value_names[]={"nadt","-inf","+inf" };
*
* special_value_formatter svf(&special_value_names[0], &special_value_names[3]);
*@endcode
*/
special_values_formatter(const char_type* const* begin, const char_type* const* end)
{
std::copy(begin, end, std::back_inserter(m_special_value_names));
}
special_values_formatter(typename collection_type::iterator beg, typename collection_type::iterator end)
{
std::copy(beg, end, std::back_inserter(m_special_value_names));
}
OutItrT put_special(OutItrT next,
const boost::date_time::special_values& value) const
{
unsigned int index = value;
if (index < m_special_value_names.size()) {
std::copy(m_special_value_names[index].begin(),
m_special_value_names[index].end(),
next);
}
return next;
}
protected:
collection_type m_special_value_names;
};
//! Storage for the strings used to indicate special values
/* using c_strings to initialize these worked fine in testing, however,
* a project that compiled its objects separately, then linked in a separate
* step wound up with redefinition errors for the values in this array.
* Initializing individual characters eliminated this problem */
template <class CharT, class OutItrT>
const typename special_values_formatter<CharT, OutItrT>::char_type special_values_formatter<CharT, OutItrT>::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'} };
} } //namespace boost::date_time
#endif

View File

@@ -0,0 +1,163 @@
#ifndef DATE_TIME_SPECIAL_VALUES_PARSER_HPP__
#define DATE_TIME_SPECIAL_VALUES_PARSER_HPP__
/* Copyright (c) 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/string_parse_tree.hpp"
#include "boost/date_time/special_defs.hpp"
#include <string>
#include <vector>
namespace boost { namespace date_time {
//! Class for special_value parsing
/*!
* TODO: add doc-comments for which elements can be changed
* Parses input stream for strings representing special_values.
* Special values parsed are:
* - not_a_date_time
* - neg_infin
* - pod_infin
* - min_date_time
* - max_date_time
*/
template<class date_type, typename charT>
class special_values_parser
{
public:
typedef std::basic_string<charT> string_type;
typedef std::basic_stringstream<charT> stringstream_type;
typedef std::istreambuf_iterator<charT> stream_itr_type;
typedef typename date_type::duration_type duration_type;
typedef string_parse_tree<charT> parse_tree_type;
typedef typename parse_tree_type::parse_match_result_type match_results;
typedef std::vector<std::basic_string<charT> > collection_type;
typedef charT char_type;
static const char_type nadt_string[16];
static const char_type neg_inf_string[10];
static const char_type pos_inf_string[10];
static const char_type min_date_time_string[18];
static const char_type max_date_time_string[18];
//! Creates a special_values_parser with the default set of "sv_strings"
special_values_parser()
{
sv_strings(string_type(nadt_string),
string_type(neg_inf_string),
string_type(pos_inf_string),
string_type(min_date_time_string),
string_type(max_date_time_string));
}
//! Creates a special_values_parser using a user defined set of element strings
special_values_parser(const string_type& nadt_str,
const string_type& neg_inf_str,
const string_type& pos_inf_str,
const string_type& min_dt_str,
const string_type& max_dt_str)
{
sv_strings(nadt_str, neg_inf_str, pos_inf_str, min_dt_str, max_dt_str);
}
special_values_parser(typename collection_type::iterator beg, typename collection_type::iterator end)
{
collection_type phrases;
std::copy(beg, end, std::back_inserter(phrases));
m_sv_strings = parse_tree_type(phrases, static_cast<int>(not_a_date_time));
}
//! Replace special value strings
void sv_strings(const string_type& nadt_str,
const string_type& neg_inf_str,
const string_type& pos_inf_str,
const string_type& min_dt_str,
const string_type& max_dt_str)
{
collection_type phrases;
phrases.push_back(nadt_str);
phrases.push_back(neg_inf_str);
phrases.push_back(pos_inf_str);
phrases.push_back(min_dt_str);
phrases.push_back(max_dt_str);
m_sv_strings = parse_tree_type(phrases, static_cast<int>(not_a_date_time));
}
//! The parser is expensive to create, and not thread-safe so it cannot be static
//! therefore given a string, determine if it is likely to be a special value.
//! A negative response is a definite no, whereas a positive is only likely and
//! match() should be called and return value checked.
//! \param[in] str the string to check
//! \returns false if it is definitely not a special value
static bool likely(const string_type& str)
{
if (!str.empty()) {
switch (str[0]) {
// See string definitions at the end of this class..
case '+':
case '-':
case 'n':
case 'm':
return true;
default:
break;
}
}
return false;
}
//! Given an input iterator, attempt to match it to a known special value
//! \param[in] sitr the start iterator
//! \param[in] str_end the end iterator
//! \param[out] mr the match result:
//! mr.current_match is set to the corresponding special_value or -1
//! \returns whether something matched
bool match(stream_itr_type& sitr,
stream_itr_type& str_end,
match_results& mr) const
{
unsigned int level = 0;
m_sv_strings.match(sitr, str_end, mr, level);
return (mr.current_match != match_results::PARSE_ERROR);
}
private:
parse_tree_type m_sv_strings;
};
template<class date_type, class CharT>
const typename special_values_parser<date_type, CharT>::char_type
special_values_parser<date_type, CharT>::nadt_string[16] =
{'n','o','t','-','a','-','d','a','t','e','-','t','i','m','e'};
template<class date_type, class CharT>
const typename special_values_parser<date_type, CharT>::char_type
special_values_parser<date_type, CharT>::neg_inf_string[10] =
{'-','i','n','f','i','n','i','t','y'};
template<class date_type, class CharT>
const typename special_values_parser<date_type, CharT>::char_type
special_values_parser<date_type, CharT>::pos_inf_string[10] =
{'+','i','n','f','i','n','i','t','y'};
template<class date_type, class CharT>
const typename special_values_parser<date_type, CharT>::char_type
special_values_parser<date_type, CharT>::min_date_time_string[18] =
{'m','i','n','i','m','u','m','-','d','a','t','e','-','t','i','m','e'};
template<class date_type, class CharT>
const typename special_values_parser<date_type, CharT>::char_type
special_values_parser<date_type, CharT>::max_date_time_string[18] =
{'m','a','x','i','m','u','m','-','d','a','t','e','-','t','i','m','e'};
} } //namespace
#endif // DATE_TIME_SPECIAL_VALUES_PARSER_HPP__

View File

@@ -0,0 +1,32 @@
#ifndef _STRING_CONVERT_HPP___
#define _STRING_CONVERT_HPP___
/* Copyright (c) 2005 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/compiler_config.hpp"
#include <string>
namespace boost {
namespace date_time {
//! Converts a string from one value_type to another
/*! Converts a wstring to a string (or a string to wstring). If both template parameters
* are of same type, a copy of the input string is returned. */
template<class InputT, class OutputT>
inline
std::basic_string<OutputT> convert_string_type(const std::basic_string<InputT>& inp_str)
{
typedef std::basic_string<OutputT> output_type;
output_type result;
result.insert(result.begin(), inp_str.begin(), inp_str.end());
return result;
}
}} // namespace boost::date_time
#endif // _STRING_CONVERT_HPP___

View File

@@ -0,0 +1,281 @@
#ifndef BOOST_DATE_TIME_STRING_PARSE_TREE___HPP__
#define BOOST_DATE_TIME_STRING_PARSE_TREE___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 <boost/algorithm/string/case_conv.hpp>
#include <cctype>
#include <map>
#include <string>
#include <vector>
#include <ostream>
#include <iterator>
#include <algorithm>
namespace boost { namespace date_time {
template<typename charT>
struct parse_match_result
{
parse_match_result() :
match_depth(0),
current_match(PARSE_ERROR)
{}
typedef std::basic_string<charT> string_type;
string_type remaining() const
{
if (match_depth == cache.size()) {
return string_type();
}
if (current_match == PARSE_ERROR) {
return cache;
}
//some of the cache was used return the rest
return string_type(cache, match_depth);
}
charT last_char() const
{
return cache[cache.size()-1];
}
//! Returns true if more characters were parsed than was necessary
/*! Should be used in conjunction with last_char()
* to get the remaining character.
*/
bool has_remaining() const
{
return (cache.size() > match_depth);
}
// cache will hold characters that have been read from the stream
string_type cache;
unsigned short match_depth;
short current_match;
enum PARSE_STATE { PARSE_ERROR = -1 };
};
//for debug -- really only char streams...
template<typename charT>
std::basic_ostream<charT>&
operator<<(std::basic_ostream<charT>& os, parse_match_result<charT>& mr)
{
os << "cm: " << mr.current_match
<< " C: '" << mr.cache
<< "' md: " << mr.match_depth
<< " R: " << mr.remaining();
return os;
}
//! Recursive data structure to allow efficient parsing of various strings
/*! This class provides a quick lookup by building what amounts to a
* tree data structure. It also features a match function which can
* can handle nasty input interators by caching values as it recurses
* the tree so that it can backtrack as needed.
*/
template<typename charT>
struct string_parse_tree
{
#if BOOST_WORKAROUND( BOOST_BORLANDC, BOOST_TESTED_AT(0x581) )
typedef std::multimap<charT, string_parse_tree< charT> > ptree_coll;
#else
typedef std::multimap<charT, string_parse_tree > ptree_coll;
#endif
typedef typename ptree_coll::value_type value_type;
typedef typename ptree_coll::iterator iterator;
typedef typename ptree_coll::const_iterator const_iterator;
typedef std::basic_string<charT> string_type;
typedef std::vector<std::basic_string<charT> > collection_type;
typedef parse_match_result<charT> parse_match_result_type;
/*! Parameter "starting_point" designates where the numbering begins.
* A starting_point of zero will start the numbering at zero
* (Sun=0, Mon=1, ...) were a starting_point of one starts the
* numbering at one (Jan=1, Feb=2, ...). The default is zero,
* negative vaules are not allowed */
string_parse_tree(collection_type names, unsigned int starting_point=0) :
m_value(parse_match_result_type::PARSE_ERROR)
{
// iterate thru all the elements and build the tree
unsigned short index = 0;
while (index != names.size() ) {
string_type s = boost::algorithm::to_lower_copy(names[index]);
insert(s, static_cast<unsigned short>(index + starting_point));
index++;
}
//set the last tree node = index+1 indicating a value
index++;
}
string_parse_tree(short value = parse_match_result_type::PARSE_ERROR) :
m_value(value)
{}
ptree_coll m_next_chars;
short m_value;
void insert(const string_type& s, unsigned short value)
{
unsigned int i = 0;
iterator ti;
while(i < s.size()) {
if (i==0) {
if (i == (s.size()-1)) {
ti = m_next_chars.insert(value_type(s[i],
string_parse_tree<charT>(value)));
}
else {
ti = m_next_chars.insert(value_type(s[i],
string_parse_tree<charT>()));
}
}
else {
if (i == (s.size()-1)) {
ti = ti->second.m_next_chars.insert(value_type(s[i],
string_parse_tree<charT>(value)));
}
else {
ti = ti->second.m_next_chars.insert(value_type(s[i],
string_parse_tree<charT>()));
}
}
i++;
}
}
//! Recursive function that finds a matching string in the tree.
/*! Must check match_results::has_remaining() after match() is
* called. This is required so the user can determine if
* stream iterator is already pointing to the expected
* character or not (match() might advance sitr to next char in stream).
*
* A parse_match_result that has been returned from a failed match
* attempt can be sent in to the match function of a different
* string_parse_tree to attempt a match there. Use the iterators
* for the partially consumed stream, the parse_match_result object,
* and '0' for the level parameter. */
short
match(std::istreambuf_iterator<charT>& sitr,
std::istreambuf_iterator<charT>& stream_end,
parse_match_result_type& result,
unsigned int& level) const
{
level++;
charT c;
// if we conditionally advance sitr, we won't have
// to consume the next character past the input
bool adv_itr = true;
if (level > result.cache.size()) {
if (sitr == stream_end) return 0; //bail - input exhausted
c = static_cast<charT>(std::tolower(*sitr));
//result.cache += c;
//sitr++;
}
else {
// if we're looking for characters from the cache,
// we don't want to increment sitr
adv_itr = false;
c = static_cast<charT>(std::tolower(result.cache[level-1]));
}
const_iterator litr = m_next_chars.lower_bound(c);
const_iterator uitr = m_next_chars.upper_bound(c);
while (litr != uitr) { // equal if not found
if(adv_itr) {
sitr++;
result.cache += c;
}
if (litr->second.m_value != -1) { // -1 is default value
if (result.match_depth < level) {
result.current_match = litr->second.m_value;
result.match_depth = static_cast<unsigned short>(level);
}
litr->second.match(sitr, stream_end,
result, level);
level--;
}
else {
litr->second.match(sitr, stream_end,
result, level);
level--;
}
if(level <= result.cache.size()) {
adv_itr = false;
}
litr++;
}
return result.current_match;
}
/*! Must check match_results::has_remaining() after match() is
* called. This is required so the user can determine if
* stream iterator is already pointing to the expected
* character or not (match() might advance sitr to next char in stream).
*/
parse_match_result_type
match(std::istreambuf_iterator<charT>& sitr,
std::istreambuf_iterator<charT>& stream_end) const
{
// lookup to_lower of char in tree.
unsigned int level = 0;
// string_type cache;
parse_match_result_type result;
match(sitr, stream_end, result, level);
return result;
}
void printme(std::ostream& os, int& level)
{
level++;
iterator itr = m_next_chars.begin();
iterator end = m_next_chars.end();
// os << "starting level: " << level << std::endl;
while (itr != end) {
os << "level: " << level
<< " node: " << itr->first
<< " value: " << itr->second.m_value
<< std::endl;
itr->second.printme(os, level);
itr++;
}
level--;
}
void print(std::ostream& os)
{
int level = 0;
printme(os, level);
}
void printmatch(std::ostream& os, charT c)
{
iterator litr = m_next_chars.lower_bound(c);
iterator uitr = m_next_chars.upper_bound(c);
os << "matches for: " << c << std::endl;
while (litr != uitr) {
os << " node: " << litr->first
<< " value: " << litr->second.m_value
<< std::endl;
litr++;
}
}
};
} } //namespace
#endif

View File

@@ -0,0 +1,127 @@
#ifndef DATE_TIME_STRINGS_FROM_FACET__HPP___
#define DATE_TIME_STRINGS_FROM_FACET__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
* $Date$
*/
#include <cstring>
#include <sstream>
#include <string>
#include <vector>
#include <locale>
#include <iterator>
namespace boost { namespace date_time {
//! This function gathers up all the month strings from a std::locale
/*! Using the time_put facet, this function creates a collection of
* all the month strings from a locale. This is handy when building
* custom date parsers or formatters that need to be localized.
*
*@param charT The type of char to use when gathering typically char
* or wchar_t.
*@param locale The locale to use when gathering the strings
*@param short_strings True(default) to gather short strings,
* false for long strings.
*@return A vector of strings containing the strings in order. eg:
* Jan, Feb, Mar, etc.
*/
template<typename charT>
std::vector<std::basic_string<charT> >
gather_month_strings(const std::locale& locale, bool short_strings=true)
{
typedef std::basic_string<charT> string_type;
typedef std::vector<string_type> collection_type;
typedef std::ostreambuf_iterator<charT> ostream_iter_type;
typedef std::basic_ostringstream<charT> stringstream_type;
typedef std::time_put<charT> time_put_facet_type;
charT short_fmt[3] = { '%', 'b' };
charT long_fmt[3] = { '%', 'B' };
collection_type months;
string_type outfmt(short_fmt);
if (!short_strings) {
outfmt = long_fmt;
}
{
//grab the needed strings by using the locale to
//output each month
const charT* p_outfmt = outfmt.c_str(), *p_outfmt_end = p_outfmt + outfmt.size();
tm tm_value;
std::memset(&tm_value, 0, sizeof(tm_value));
for (int m=0; m < 12; m++) {
tm_value.tm_mon = m;
stringstream_type ss;
ostream_iter_type oitr(ss);
std::use_facet<time_put_facet_type>(locale).put(oitr, ss, ss.fill(),
&tm_value,
p_outfmt,
p_outfmt_end);
months.push_back(ss.str());
}
}
return months;
}
//! This function gathers up all the weekday strings from a std::locale
/*! Using the time_put facet, this function creates a collection of
* all the weekday strings from a locale starting with the string for
* 'Sunday'. This is handy when building custom date parsers or
* formatters that need to be localized.
*
*@param charT The type of char to use when gathering typically char
* or wchar_t.
*@param locale The locale to use when gathering the strings
*@param short_strings True(default) to gather short strings,
* false for long strings.
*@return A vector of strings containing the weekdays in order. eg:
* Sun, Mon, Tue, Wed, Thu, Fri, Sat
*/
template<typename charT>
std::vector<std::basic_string<charT> >
gather_weekday_strings(const std::locale& locale, bool short_strings=true)
{
typedef std::basic_string<charT> string_type;
typedef std::vector<string_type> collection_type;
typedef std::ostreambuf_iterator<charT> ostream_iter_type;
typedef std::basic_ostringstream<charT> stringstream_type;
typedef std::time_put<charT> time_put_facet_type;
charT short_fmt[3] = { '%', 'a' };
charT long_fmt[3] = { '%', 'A' };
collection_type weekdays;
string_type outfmt(short_fmt);
if (!short_strings) {
outfmt = long_fmt;
}
{
//grab the needed strings by using the locale to
//output each month / weekday
const charT* p_outfmt = outfmt.c_str(), *p_outfmt_end = p_outfmt + outfmt.size();
tm tm_value;
std::memset(&tm_value, 0, sizeof(tm_value));
for (int i=0; i < 7; i++) {
tm_value.tm_wday = i;
stringstream_type ss;
ostream_iter_type oitr(ss);
std::use_facet<time_put_facet_type>(locale).put(oitr, ss, ss.fill(),
&tm_value,
p_outfmt,
p_outfmt_end);
weekdays.push_back(ss.str());
}
}
return weekdays;
}
} } //namespace
#endif

View File

@@ -0,0 +1,214 @@
#ifndef DATE_TIME_TIME_HPP___
#define DATE_TIME_TIME_HPP___
/* Copyright (c) 2002,2003,2005,2020 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;
BOOST_CXX14_CONSTEXPR
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))
{}
BOOST_CXX14_CONSTEXPR
base_time(special_values sv) :
time_(time_system::get_time_rep(sv))
{}
BOOST_CXX14_CONSTEXPR
base_time(const time_rep_type& rhs) :
time_(rhs)
{}
BOOST_CXX14_CONSTEXPR
date_type date() const
{
return time_system::get_date(time_);
}
BOOST_CXX14_CONSTEXPR
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
BOOST_CXX14_CONSTEXPR
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
BOOST_CXX14_CONSTEXPR
bool is_infinity() const
{
return (is_pos_infinity() || is_neg_infinity());
}
//! check to see if date is greater than all possible dates
BOOST_CXX14_CONSTEXPR
bool is_pos_infinity() const
{
return time_.is_pos_infinity();
}
//! check to see if date is greater than all possible dates
BOOST_CXX14_CONSTEXPR
bool is_neg_infinity() const
{
return time_.is_neg_infinity();
}
//! check to see if time is a special value
BOOST_CXX14_CONSTEXPR
bool is_special() const
{
return(is_not_a_date_time() || is_infinity());
}
//!Equality operator -- others generated by boost::equality_comparable
BOOST_CXX14_CONSTEXPR
bool operator==(const time_type& rhs) const
{
return time_system::is_equal(time_,rhs.time_);
}
//!Equality operator -- others generated by boost::less_than_comparable
BOOST_CXX14_CONSTEXPR
bool operator<(const time_type& rhs) const
{
return time_system::is_less(time_,rhs.time_);
}
//! difference between two times
BOOST_CXX14_CONSTEXPR
time_duration_type operator-(const time_type& rhs) const
{
return time_system::subtract_times(time_, rhs.time_);
}
//! add date durations
BOOST_CXX14_CONSTEXPR
time_type operator+(const date_duration_type& dd) const
{
return time_system::add_days(time_, dd);
}
BOOST_CXX14_CONSTEXPR
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
BOOST_CXX14_CONSTEXPR
time_type operator-(const date_duration_type& dd) const
{
return time_system::subtract_days(time_, dd);
}
BOOST_CXX14_CONSTEXPR
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
BOOST_CXX14_CONSTEXPR
time_type operator+(const time_duration_type& td) const
{
return time_type(time_system::add_time_duration(time_, td));
}
BOOST_CXX14_CONSTEXPR
time_type operator+=(const time_duration_type& td)
{
time_ = time_system::add_time_duration(time_,td);
return time_type(time_);
}
//! subtract time durations
BOOST_CXX14_CONSTEXPR
time_type operator-(const time_duration_type& rhs) const
{
return time_system::subtract_time_duration(time_, rhs);
}
BOOST_CXX14_CONSTEXPR
time_type operator-=(const time_duration_type& td)
{
time_ = time_system::subtract_time_duration(time_, 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,310 @@
#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/core/enable_if.hpp>
#include <boost/cstdint.hpp>
#include <boost/date_time/compiler_config.hpp>
#include <boost/date_time/special_defs.hpp>
#include <boost/date_time/time_defs.hpp>
#include <boost/operators.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_integral.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.
@tparam T The subclass type
@tparam rep_type The time resolution traits for this duration type.
*/
template<class T, typename rep_type>
class BOOST_SYMBOL_VISIBLE 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;
BOOST_CXX14_CONSTEXPR time_duration() : ticks_(0) {}
BOOST_CXX14_CONSTEXPR 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))
{}
//! Construct from special_values
BOOST_CXX14_CONSTEXPR time_duration(special_values sv) : ticks_(impl_type::from_special(sv))
{}
//! Returns smallest representable duration
static BOOST_CXX14_CONSTEXPR duration_type unit()
{
return duration_type(0,0,0,1);
}
//! Return the number of ticks in a second
static BOOST_CXX14_CONSTEXPR tick_type ticks_per_second()
{
return rep_type::res_adjust();
}
//! Provide the resolution of this duration type
static BOOST_CXX14_CONSTEXPR time_resolutions resolution()
{
return rep_type::resolution();
}
//! Returns number of hours in the duration
BOOST_CXX14_CONSTEXPR hour_type hours() const
{
return static_cast<hour_type>(ticks() / (3600*ticks_per_second()));
}
//! Returns normalized number of minutes
BOOST_CXX14_CONSTEXPR min_type minutes() const
{
return static_cast<min_type>((ticks() / (60*ticks_per_second())) % 60);
}
//! Returns normalized number of seconds (0..60)
BOOST_CXX14_CONSTEXPR sec_type seconds() const
{
return static_cast<sec_type>((ticks()/ticks_per_second()) % 60);
}
//! Returns total number of seconds truncating any fractional seconds
BOOST_CXX14_CONSTEXPR sec_type total_seconds() const
{
return static_cast<sec_type>(ticks() / ticks_per_second());
}
//! Returns total number of milliseconds truncating any fractional seconds
BOOST_CXX14_CONSTEXPR 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
BOOST_CXX14_CONSTEXPR 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
BOOST_CXX14_CONSTEXPR 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
BOOST_CXX14_CONSTEXPR fractional_seconds_type fractional_seconds() const
{
return (ticks() % ticks_per_second());
}
//! Returns number of possible digits in fractional seconds
static BOOST_CXX14_CONSTEXPR unsigned short num_fractional_digits()
{
return rep_type::num_fractional_digits();
}
BOOST_CXX14_CONSTEXPR duration_type invert_sign() const
{
return duration_type(ticks_ * (-1));
}
BOOST_CXX14_CONSTEXPR duration_type abs() const
{
if ( is_negative() )
{
return invert_sign();
}
return duration_type(ticks_);
}
BOOST_CONSTEXPR bool is_negative() const
{
return ticks_ < 0;
}
BOOST_CONSTEXPR bool is_zero() const
{
return ticks_ == 0;
}
BOOST_CONSTEXPR bool is_positive() const
{
return ticks_ > 0;
}
BOOST_CONSTEXPR bool operator<(const time_duration& rhs) const
{
return ticks_ < rhs.ticks_;
}
BOOST_CONSTEXPR bool operator==(const time_duration& rhs) const
{
return ticks_ == rhs.ticks_;
}
//! unary- Allows for time_duration td = -td1
BOOST_CONSTEXPR duration_type operator-()const
{
return duration_type(ticks_ * (-1));
}
BOOST_CONSTEXPR duration_type operator-(const duration_type& d) const
{
return duration_type(ticks_ - d.ticks_);
}
BOOST_CONSTEXPR duration_type operator+(const duration_type& d) const
{
return duration_type(ticks_ + d.ticks_);
}
BOOST_CONSTEXPR duration_type operator/(int divisor) const
{
return duration_type(ticks_ / divisor);
}
BOOST_CXX14_CONSTEXPR duration_type operator-=(const duration_type& d)
{
ticks_ = ticks_ - d.ticks_;
return duration_type(ticks_);
}
BOOST_CXX14_CONSTEXPR duration_type operator+=(const duration_type& d)
{
ticks_ = ticks_ + d.ticks_;
return duration_type(ticks_);
}
//! Division operations on a duration with an integer.
BOOST_CXX14_CONSTEXPR duration_type operator/=(int divisor)
{
ticks_ = ticks_ / divisor;
return duration_type(ticks_);
}
//! Multiplication operations an a duration with an integer
BOOST_CXX14_CONSTEXPR duration_type operator*(int rhs) const
{
return duration_type(ticks_ * rhs);
}
BOOST_CXX14_CONSTEXPR duration_type operator*=(int divisor)
{
ticks_ = ticks_ * divisor;
return duration_type(ticks_);
}
BOOST_CXX14_CONSTEXPR tick_type ticks() const
{
return traits_type::as_number(ticks_);
}
//! Is ticks_ a special value?
BOOST_CXX14_CONSTEXPR bool is_special()const
{
if(traits_type::is_adapted())
{
return ticks_.is_special();
}
else{
return false;
}
}
//! Is duration pos-infinity
BOOST_CXX14_CONSTEXPR bool is_pos_infinity()const
{
if(traits_type::is_adapted())
{
return ticks_.is_pos_infinity();
}
else{
return false;
}
}
//! Is duration neg-infinity
BOOST_CXX14_CONSTEXPR bool is_neg_infinity()const
{
if(traits_type::is_adapted())
{
return ticks_.is_neg_infinity();
}
else{
return false;
}
}
//! Is duration not-a-date-time
BOOST_CXX14_CONSTEXPR bool is_not_a_date_time()const
{
if(traits_type::is_adapted())
{
return ticks_.is_nan();
}
else{
return false;
}
}
//! Used for special_values output
BOOST_CONSTEXPR impl_type get_rep()const
{
return ticks_;
}
protected:
BOOST_CXX14_CONSTEXPR 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 resolution adjustment
*/
template<class base_duration, boost::int64_t frac_of_second>
class BOOST_SYMBOL_VISIBLE 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:
// The argument (ss) must be an integral type
template <typename T>
BOOST_CXX14_CONSTEXPR explicit subsecond_duration(T const& ss,
typename boost::enable_if<boost::is_integral<T>,
void>::type* = BOOST_DATE_TIME_NULLPTR) :
base_duration(impl_type(traits_type::ticks_per_second >= frac_of_second ? ss * adjustment_ratio : ss / adjustment_ratio))
{
}
};
} } //namespace date_time
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,122 @@
#ifndef DATE_TIME_TIME_FORMATTING_STREAMS_HPP___
#define DATE_TIME_TIME_FORMATTING_STREAMS_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>
#ifndef BOOST_DATE_TIME_NO_LOCALE
#include <locale>
#include <iomanip>
#include <iostream>
#include <boost/date_time/date_formatting_locales.hpp>
#include <boost/date_time/time_resolution_traits.hpp>
namespace boost {
namespace date_time {
//! Put a time type into a stream using appropriate facets
template<class time_duration_type,
class charT = char>
class ostream_time_duration_formatter
{
public:
typedef std::basic_ostream<charT> ostream_type;
typedef typename time_duration_type::fractional_seconds_type fractional_seconds_type;
//! Put time into an ostream
static void duration_put(const time_duration_type& td,
ostream_type& os)
{
if(td.is_special()) {
os << td.get_rep();
}
else {
charT fill_char = '0';
if(td.is_negative()) {
os << '-';
}
os << std::setw(2) << std::setfill(fill_char)
<< absolute_value(td.hours()) << ":";
os << std::setw(2) << std::setfill(fill_char)
<< absolute_value(td.minutes()) << ":";
os << std::setw(2) << std::setfill(fill_char)
<< absolute_value(td.seconds());
fractional_seconds_type frac_sec =
absolute_value(td.fractional_seconds());
if (frac_sec != 0) {
os << "."
<< std::setw(time_duration_type::num_fractional_digits())
<< std::setfill(fill_char)
<< frac_sec;
}
} // else
} // duration_put
}; //class ostream_time_duration_formatter
//! Put a time type into a stream using appropriate facets
template<class time_type,
class charT = char>
class ostream_time_formatter
{
public:
typedef std::basic_ostream<charT> ostream_type;
typedef typename time_type::date_type date_type;
typedef typename time_type::time_duration_type time_duration_type;
typedef ostream_time_duration_formatter<time_duration_type, charT> duration_formatter;
//! Put time into an ostream
static void time_put(const time_type& t,
ostream_type& os)
{
date_type d = t.date();
os << d;
if(!d.is_infinity() && !d.is_not_a_date())
{
os << " "; //TODO: fix the separator here.
duration_formatter::duration_put(t.time_of_day(), os);
}
} // time_to_ostream
}; //class ostream_time_formatter
//! Put a time period into a stream using appropriate facets
template<class time_period_type,
class charT = char>
class ostream_time_period_formatter
{
public:
typedef std::basic_ostream<charT> ostream_type;
typedef typename time_period_type::point_type time_type;
typedef ostream_time_formatter<time_type, charT> time_formatter;
//! Put time into an ostream
static void period_put(const time_period_type& tp,
ostream_type& os)
{
os << '['; //TODO: facet or manipulator for periods?
time_formatter::time_put(tp.begin(), os);
os << '/'; //TODO: facet or manipulator for periods?
time_formatter::time_put(tp.last(), os);
os << ']';
} // period_put
}; //class ostream_time_period_formatter
} } //namespace date_time
#endif //BOOST_DATE_TIME_NO_LOCALE
#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;
}
const time_type& operator*() const {return current_;}
const time_type* operator->() const {return &current_;}
bool operator< (const time_type& t) const {return current_ < t;}
bool operator<= (const time_type& t) const {return current_ <= t;}
bool operator!= (const time_type& t) const {return current_ != t;}
bool operator== (const time_type& t) const {return current_ == t;}
bool operator> (const time_type& t) const {return current_ > t;}
bool operator>= (const time_type& t) const {return current_ >= t;}
private:
time_type current_;
time_duration_type offset_;
};
} }//namespace date_time
#endif

View File

@@ -0,0 +1,339 @@
#ifndef _DATE_TIME_TIME_PARSING_HPP___
#define _DATE_TIME_TIME_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 "boost/tokenizer.hpp"
#include "boost/lexical_cast.hpp"
#include "boost/date_time/date_parsing.hpp"
#include "boost/date_time/special_values_parser.hpp"
#include "boost/cstdint.hpp"
#include <iostream>
namespace boost {
namespace date_time {
//! computes exponential math like 2^8 => 256, only works with positive integers
//Not general purpose, but needed b/c std::pow is not available
//everywhere. Hasn't been tested with negatives and zeros
template<class int_type>
inline
int_type power(int_type base, int_type exponent)
{
int_type result = 1;
for(int i = 0; i < exponent; ++i){
result *= base;
}
return result;
}
//! Creates a time_duration object from a delimited string
/*! Expected format for string is "[-]h[h][:mm][:ss][.fff]".
* If the number of fractional digits provided is greater than the
* precision of the time duration type then the extra digits are
* truncated.
*
* A negative duration will be created if the first character in
* string is a '-', all other '-' will be treated as delimiters.
* Accepted delimiters are "-:,.".
*/
template<class time_duration, class char_type>
inline
time_duration
str_from_delimited_time_duration(const std::basic_string<char_type>& s)
{
unsigned short min=0, sec =0;
int hour =0;
bool is_neg = (s.at(0) == '-');
boost::int64_t fs=0;
int pos = 0;
typedef typename std::basic_string<char_type>::traits_type traits_type;
typedef boost::char_separator<char_type, traits_type> char_separator_type;
typedef boost::tokenizer<char_separator_type,
typename std::basic_string<char_type>::const_iterator,
std::basic_string<char_type> > tokenizer;
typedef typename boost::tokenizer<char_separator_type,
typename std::basic_string<char_type>::const_iterator,
typename std::basic_string<char_type> >::iterator tokenizer_iterator;
char_type sep_chars[5] = {'-',':',',','.'};
char_separator_type sep(sep_chars);
tokenizer tok(s,sep);
for(tokenizer_iterator beg=tok.begin(); beg!=tok.end();++beg){
switch(pos) {
case 0: {
hour = boost::lexical_cast<int>(*beg);
break;
}
case 1: {
min = boost::lexical_cast<unsigned short>(*beg);
break;
}
case 2: {
sec = boost::lexical_cast<unsigned short>(*beg);
break;
}
case 3: {
int digits = static_cast<int>(beg->length());
//Works around a bug in MSVC 6 library that does not support
//operator>> thus meaning lexical_cast will fail to compile.
#if (defined(BOOST_MSVC) && (_MSC_VER < 1300))
// msvc wouldn't compile 'time_duration::num_fractional_digits()'
// (required template argument list) as a workaround a temp
// time_duration object was used
time_duration td(hour,min,sec,fs);
int precision = td.num_fractional_digits();
// _atoi64 is an MS specific function
if(digits >= precision) {
// drop excess digits
fs = _atoi64(beg->substr(0, precision).c_str());
}
else {
fs = _atoi64(beg->c_str());
}
#else
int precision = time_duration::num_fractional_digits();
if(digits >= precision) {
// drop excess digits
fs = boost::lexical_cast<boost::int64_t>(beg->substr(0, precision));
}
else {
fs = boost::lexical_cast<boost::int64_t>(*beg);
}
#endif
if(digits < precision){
// trailing zeros get dropped from the string,
// "1:01:01.1" would yield .000001 instead of .100000
// the power() compensates for the missing decimal places
fs *= power(10, precision - digits);
}
break;
}
default: break;
}//switch
pos++;
}
if(is_neg) {
return -time_duration(hour, min, sec, fs);
}
else {
return time_duration(hour, min, sec, fs);
}
}
//! Creates a time_duration object from a delimited string
/*! Expected format for string is "[-]h[h][:mm][:ss][.fff]".
* If the number of fractional digits provided is greater than the
* precision of the time duration type then the extra digits are
* truncated.
*
* A negative duration will be created if the first character in
* string is a '-', all other '-' will be treated as delimiters.
* Accepted delimiters are "-:,.".
*/
template<class time_duration>
inline
time_duration
parse_delimited_time_duration(const std::string& s)
{
return str_from_delimited_time_duration<time_duration,char>(s);
}
//! Utility function to split appart string
inline
bool
split(const std::string& s,
char sep,
std::string& first,
std::string& second)
{
std::string::size_type sep_pos = s.find(sep);
first = s.substr(0,sep_pos);
if (sep_pos!=std::string::npos)
second = s.substr(sep_pos+1);
return true;
}
template<class time_type>
inline
time_type
parse_delimited_time(const std::string& s, char sep)
{
typedef typename time_type::time_duration_type time_duration;
typedef typename time_type::date_type date_type;
//split date/time on a unique delimiter char such as ' ' or 'T'
std::string date_string, tod_string;
split(s, sep, date_string, tod_string);
//call parse_date with first string
date_type d = parse_date<date_type>(date_string);
//call parse_time_duration with remaining string
time_duration td = parse_delimited_time_duration<time_duration>(tod_string);
//construct a time
return time_type(d, td);
}
//! Parse time duration part of an iso time of form: [-]hhmmss[.fff...] (eg: 120259.123 is 12 hours, 2 min, 59 seconds, 123000 microseconds)
template<class time_duration>
inline
time_duration
parse_undelimited_time_duration(const std::string& s)
{
int precision = 0;
{
// msvc wouldn't compile 'time_duration::num_fractional_digits()'
// (required template argument list) as a workaround, a temp
// time_duration object was used
time_duration tmp(0,0,0,1);
precision = tmp.num_fractional_digits();
}
// 'precision+1' is so we grab all digits, plus the decimal
int offsets[] = {2,2,2, precision+1};
int pos = 0, sign = 0;
int hours = 0;
short min=0, sec=0;
boost::int64_t fs=0;
// increment one position if the string was "signed"
if(s.at(sign) == '-')
{
++sign;
}
// stlport choked when passing s.substr() to tokenizer
// using a new string fixed the error
std::string remain = s.substr(sign);
/* We do not want the offset_separator to wrap the offsets, we
* will never want to process more than:
* 2 char, 2 char, 2 char, frac_sec length.
* We *do* want the offset_separator to give us a partial for the
* last characters if there were not enough provided in the input string. */
bool wrap_off = false;
bool ret_part = true;
boost::offset_separator osf(offsets, offsets+4, wrap_off, ret_part);
typedef boost::tokenizer<boost::offset_separator,
std::basic_string<char>::const_iterator,
std::basic_string<char> > tokenizer;
typedef boost::tokenizer<boost::offset_separator,
std::basic_string<char>::const_iterator,
std::basic_string<char> >::iterator tokenizer_iterator;
tokenizer tok(remain, osf);
for(tokenizer_iterator ti=tok.begin(); ti!=tok.end();++ti){
switch(pos) {
case 0:
{
hours = boost::lexical_cast<int>(*ti);
break;
}
case 1:
{
min = boost::lexical_cast<short>(*ti);
break;
}
case 2:
{
sec = boost::lexical_cast<short>(*ti);
break;
}
case 3:
{
std::string char_digits(ti->substr(1)); // digits w/no decimal
int digits = static_cast<int>(char_digits.length());
//Works around a bug in MSVC 6 library that does not support
//operator>> thus meaning lexical_cast will fail to compile.
#if (defined(BOOST_MSVC) && (_MSC_VER <= 1200)) // 1200 == VC++ 6.0
// _atoi64 is an MS specific function
if(digits >= precision) {
// drop excess digits
fs = _atoi64(char_digits.substr(0, precision).c_str());
}
else if(digits == 0) {
fs = 0; // just in case _atoi64 doesn't like an empty string
}
else {
fs = _atoi64(char_digits.c_str());
}
#else
if(digits >= precision) {
// drop excess digits
fs = boost::lexical_cast<boost::int64_t>(char_digits.substr(0, precision));
}
else if(digits == 0) {
fs = 0; // lexical_cast doesn't like empty strings
}
else {
fs = boost::lexical_cast<boost::int64_t>(char_digits);
}
#endif
if(digits < precision){
// trailing zeros get dropped from the string,
// "1:01:01.1" would yield .000001 instead of .100000
// the power() compensates for the missing decimal places
fs *= power(10, precision - digits);
}
break;
}
default: break;
}
pos++;
}
if(sign) {
return -time_duration(hours, min, sec, fs);
}
else {
return time_duration(hours, min, sec, fs);
}
}
//! Parse time string of form YYYYMMDDThhmmss where T is delimeter between date and time
template<class time_type>
inline
time_type
parse_iso_time(const std::string& s, char sep)
{
typedef typename time_type::time_duration_type time_duration;
typedef typename time_type::date_type date_type;
typedef special_values_parser<date_type, std::string::value_type> svp_type;
// given to_iso_string can produce a special value string
// then from_iso_string should be able to read a special value string
// the special_values_parser is expensive to set up and not thread-safe
// so it cannot be static, so we need to be careful about when we use it
if (svp_type::likely(s)) {
typedef typename svp_type::stringstream_type ss_type;
typedef typename svp_type::stream_itr_type itr_type;
typedef typename svp_type::match_results mr_type;
svp_type p; // expensive
mr_type mr;
ss_type ss(s);
itr_type itr(ss);
itr_type end;
if (p.match(itr, end, mr)) {
return time_type(static_cast<special_values>(mr.current_match));
}
}
//split date/time on a unique delimiter char such as ' ' or 'T'
std::string date_string, tod_string;
split(s, sep, date_string, tod_string);
//call parse_date with first string
date_type d = parse_undelimited_date<date_type>(date_string);
//call parse_time_duration with remaining string
time_duration td = parse_undelimited_time_duration<time_duration>(tod_string);
//construct a time
return time_type(d, td);
}
} }//namespace date_time
#endif

View File

@@ -0,0 +1,167 @@
#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 <ctime>
#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 BOOST_CXX14_CONSTEXPR 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 BOOST_CXX14_CONSTEXPR int_type as_number(impl_type i){ return i;}
//! Used to determine if implemented type is int_adapter or int
static BOOST_CXX14_CONSTEXPR 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 BOOST_CXX14_CONSTEXPR int_type as_number(impl_type i){ return i.as_number();}
//! Used to determine if implemented type is int_adapter or int
static BOOST_CXX14_CONSTEXPR 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 BOOST_CXX14_CONSTEXPR int_type as_number(impl_type i){ return i;}
//! Used to determine if implemented type is int_adapter or int
static BOOST_CXX14_CONSTEXPR 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 BOOST_CXX14_CONSTEXPR int_type as_number(impl_type i){ return i.as_number();}
//! Used to determine if implemented type is int_adapter or int
static BOOST_CXX14_CONSTEXPR bool is_adapted() { return true;}
};
//
// Note about var_type, which is used to define the variable that
// stores hours, minutes, and seconds values:
//
// In Boost 1.65.1 and earlier var_type was boost::int32_t which suffers
// the year 2038 problem. Binary serialization of posix_time uses
// 32-bit values, and uses serialization version 0.
//
// In Boost 1.66.0 the var_type changed to std::time_t, however
// binary serialization was not properly versioned, so on platforms
// where std::time_t is 32-bits, it remains compatible, however on
// platforms where std::time_t is 64-bits, binary serialization ingest
// will be incompatible with previous versions. Furthermore, binary
// serialized output from 1.66.0 will not be compatible with future
// versions. Yes, it's a mess. Static assertions were not present
// in the serialization code to protect against this possibility.
//
// In Boost 1.67.0 the var_type was changed to boost::int64_t,
// ensuring the output size is 64 bits, and the serialization version
// was bumped. Static assertions were added as well, protecting
// future changes in this area.
//
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::int64_t > // see note above
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 BOOST_CXX14_CONSTEXPR fractional_seconds_type as_number(impl_type i)
{
return frac_sec_type::as_number(i);
}
static BOOST_CXX14_CONSTEXPR 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 BOOST_CXX14_CONSTEXPR time_resolutions resolution()
{
return res;
}
static BOOST_CXX14_CONSTEXPR unsigned short num_fractional_digits()
{
return frac_digits;
}
static BOOST_CXX14_CONSTEXPR fractional_seconds_type res_adjust()
{
return resolution_adjust;
}
//! Any negative argument results in a negative tick_count
static BOOST_CXX14_CONSTEXPR 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 static_cast<tick_type>(((((fractional_seconds_type(hours)*3600)
+ (fractional_seconds_type(minutes)*60)
+ seconds)*res_adjust()) + fs) * -1);
}
return static_cast<tick_type>((((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,269 @@
#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/compiler_config.hpp>
#include <boost/date_time/time_defs.hpp>
#include <boost/date_time/special_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;
BOOST_CXX14_CONSTEXPR
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();
}
}
BOOST_CXX14_CONSTEXPR
explicit counted_time_rep(int_type count) :
time_count_(count)
{}
BOOST_CXX14_CONSTEXPR
explicit counted_time_rep(impl_type count) :
time_count_(count)
{}
BOOST_CXX14_CONSTEXPR
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
BOOST_CXX14_CONSTEXPR
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());
}
BOOST_CXX14_CONSTEXPR int_type time_count() const
{
return resolution_traits::as_number(time_count_);
}
BOOST_CXX14_CONSTEXPR int_type tod() const
{
return resolution_traits::as_number(time_count_) % frac_sec_per_day();
}
static BOOST_CXX14_CONSTEXPR 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;
}
BOOST_CXX14_CONSTEXPR bool is_pos_infinity()const
{
return impl_type::is_pos_inf(time_count_.as_number());
}
BOOST_CXX14_CONSTEXPR bool is_neg_infinity()const
{
return impl_type::is_neg_inf(time_count_.as_number());
}
BOOST_CXX14_CONSTEXPR bool is_not_a_date_time()const
{
return impl_type::is_not_a_number(time_count_.as_number());
}
BOOST_CXX14_CONSTEXPR bool is_special()const
{
return time_count_.is_special();
}
BOOST_CXX14_CONSTEXPR 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 BOOST_CXX14_CONSTEXPR void unused_var(const T&) {}
static BOOST_CXX14_CONSTEXPR
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 BOOST_CXX14_CONSTEXPR 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 BOOST_CXX14_CONSTEXPR date_type
get_date(const time_rep_type& val)
{
return val.date();
}
static BOOST_CXX14_CONSTEXPR
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 BOOST_CXX14_CONSTEXPR bool is_equal(const time_rep_type& lhs, const time_rep_type& rhs)
{
return (lhs.time_count() == rhs.time_count());
}
static BOOST_CXX14_CONSTEXPR
bool is_less(const time_rep_type& lhs, const time_rep_type& rhs)
{
return (lhs.time_count() < rhs.time_count());
}
static BOOST_CXX14_CONSTEXPR
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 BOOST_CXX14_CONSTEXPR
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 BOOST_CXX14_CONSTEXPR
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 BOOST_CXX14_CONSTEXPR
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 BOOST_CXX14_CONSTEXPR
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,226 @@
#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/cstdint.hpp>
#include <boost/date_time/compiler_config.hpp>
#include <boost/date_time/time_defs.hpp>
#include <boost/date_time/special_defs.hpp>
#include <boost/date_time/wrapping_int.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( BOOST_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
BOOST_CXX14_CONSTEXPR
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
BOOST_CXX14_CONSTEXPR
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 BOOST_CONSTEXPR date_type get_date(const time_rep_type& val)
{
return date_type(val.day);
}
static BOOST_CONSTEXPR 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 BOOST_CONSTEXPR
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 BOOST_CXX14_CONSTEXPR
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 BOOST_CXX14_CONSTEXPR
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 BOOST_CXX14_CONSTEXPR
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 BOOST_CXX14_CONSTEXPR
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 BOOST_CXX14_CONSTEXPR
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 BOOST_CXX14_CONSTEXPR
time_duration_type subtract_times(const time_rep_type& lhs,
const time_rep_type& rhs)
{
date_duration_type dd = lhs.day - rhs.day;
if (BOOST_LIKELY(!dd.is_special())) {
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;
} else {
time_duration_type td(dd.as_special());
time_duration_type td2 = lhs.time_of_day - rhs.time_of_day;
return td+td2;
}
}
};
} } //namespace date_time
#endif

Some files were not shown because too many files have changed in this diff Show More