整理
This commit is contained in:
164
include/boost/date_time/adjust_functors.hpp
Normal file
164
include/boost/date_time/adjust_functors.hpp
Normal 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
|
||||
|
||||
72
include/boost/date_time/c_local_time_adjustor.hpp
Normal file
72
include/boost/date_time/c_local_time_adjustor.hpp
Normal 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
|
||||
128
include/boost/date_time/c_time.hpp
Normal file
128
include/boost/date_time/c_time.hpp
Normal 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___
|
||||
137
include/boost/date_time/compiler_config.hpp
Normal file
137
include/boost/date_time/compiler_config.hpp
Normal 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
|
||||
129
include/boost/date_time/constrained_value.hpp
Normal file
129
include/boost/date_time/constrained_value.hpp
Normal 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
|
||||
209
include/boost/date_time/date.hpp
Normal file
209
include/boost/date_time/date.hpp
Normal 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 8601 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
|
||||
77
include/boost/date_time/date_clock_device.hpp
Normal file
77
include/boost/date_time/date_clock_device.hpp
Normal 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
|
||||
26
include/boost/date_time/date_defs.hpp
Normal file
26
include/boost/date_time/date_defs.hpp
Normal 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
|
||||
146
include/boost/date_time/date_duration.hpp
Normal file
146
include/boost/date_time/date_duration.hpp
Normal 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
|
||||
|
||||
265
include/boost/date_time/date_duration_types.hpp
Normal file
265
include/boost/date_time/date_duration_types.hpp
Normal 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___
|
||||
766
include/boost/date_time/date_facet.hpp
Normal file
766
include/boost/date_time/date_facet.hpp
Normal 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
|
||||
159
include/boost/date_time/date_format_simple.hpp
Normal file
159
include/boost/date_time/date_format_simple.hpp
Normal 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
|
||||
137
include/boost/date_time/date_formatting.hpp
Normal file
137
include/boost/date_time/date_formatting.hpp
Normal 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
|
||||
|
||||
121
include/boost/date_time/date_formatting_limited.hpp
Normal file
121
include/boost/date_time/date_formatting_limited.hpp
Normal 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
|
||||
|
||||
234
include/boost/date_time/date_formatting_locales.hpp
Normal file
234
include/boost/date_time/date_formatting_locales.hpp
Normal 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
|
||||
|
||||
265
include/boost/date_time/date_generator_formatter.hpp
Normal file
265
include/boost/date_time/date_generator_formatter.hpp
Normal 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___
|
||||
330
include/boost/date_time/date_generator_parser.hpp
Normal file
330
include/boost/date_time/date_generator_parser.hpp
Normal 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__
|
||||
|
||||
514
include/boost/date_time/date_generators.hpp
Normal file
514
include/boost/date_time/date_generators.hpp
Normal 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
|
||||
101
include/boost/date_time/date_iterator.hpp
Normal file
101
include/boost/date_time/date_iterator.hpp
Normal 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 ¤t_;}
|
||||
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
|
||||
321
include/boost/date_time/date_names_put.hpp
Normal file
321
include/boost/date_time/date_names_put.hpp
Normal 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
|
||||
342
include/boost/date_time/date_parsing.hpp
Normal file
342
include/boost/date_time/date_parsing.hpp
Normal 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
|
||||
|
||||
391
include/boost/date_time/dst_rules.hpp
Normal file
391
include/boost/date_time/dst_rules.hpp
Normal 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
|
||||
75
include/boost/date_time/dst_transition_generators.hpp
Normal file
75
include/boost/date_time/dst_transition_generators.hpp
Normal 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
|
||||
84
include/boost/date_time/filetime_functions.hpp
Normal file
84
include/boost/date_time/filetime_functions.hpp
Normal 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__
|
||||
42
include/boost/date_time/find_match.hpp
Normal file
42
include/boost/date_time/find_match.hpp
Normal 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
|
||||
724
include/boost/date_time/format_date_parser.hpp
Normal file
724
include/boost/date_time/format_date_parser.hpp
Normal 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
|
||||
|
||||
|
||||
|
||||
68
include/boost/date_time/gregorian/conversion.hpp
Normal file
68
include/boost/date_time/gregorian/conversion.hpp
Normal 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
|
||||
162
include/boost/date_time/gregorian/formatters.hpp
Normal file
162
include/boost/date_time/gregorian/formatters.hpp
Normal 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 8601 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 8601 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 8601 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
|
||||
|
||||
81
include/boost/date_time/gregorian/formatters_limited.hpp
Normal file
81
include/boost/date_time/gregorian/formatters_limited.hpp
Normal 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 8601 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 8601 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 8601 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
|
||||
|
||||
49
include/boost/date_time/gregorian/greg_calendar.hpp
Normal file
49
include/boost/date_time/gregorian/greg_calendar.hpp
Normal 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
|
||||
|
||||
144
include/boost/date_time/gregorian/greg_date.hpp
Normal file
144
include/boost/date_time/gregorian/greg_date.hpp
Normal file
@@ -0,0 +1,144 @@
|
||||
#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>(from_special_adjusted(sv))
|
||||
{}
|
||||
//!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:
|
||||
|
||||
BOOST_CXX14_CONSTEXPR date_rep_type from_special_adjusted(special_values sv)
|
||||
{
|
||||
switch (sv)
|
||||
{
|
||||
case min_date_time: return gregorian_calendar::day_number(ymd_type(1400, 1, 1));
|
||||
case max_date_time: return gregorian_calendar::day_number(ymd_type(9999, 12, 31));
|
||||
default: return date_rep_type::from_special(sv);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
inline BOOST_CXX14_CONSTEXPR
|
||||
bool operator==(const date& lhs, const date& rhs)
|
||||
{
|
||||
return lhs.days_ == rhs.days_;
|
||||
}
|
||||
|
||||
|
||||
} } //namespace gregorian
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
58
include/boost/date_time/gregorian/greg_day.hpp
Normal file
58
include/boost/date_time/gregorian/greg_day.hpp
Normal 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
|
||||
39
include/boost/date_time/gregorian/greg_day_of_year.hpp
Normal file
39
include/boost/date_time/gregorian/greg_day_of_year.hpp
Normal 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
|
||||
147
include/boost/date_time/gregorian/greg_duration.hpp
Normal file
147
include/boost/date_time/gregorian/greg_duration.hpp
Normal 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
|
||||
44
include/boost/date_time/gregorian/greg_duration_types.hpp
Normal file
44
include/boost/date_time/gregorian/greg_duration_types.hpp
Normal 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___
|
||||
374
include/boost/date_time/gregorian/greg_facet.hpp
Normal file
374
include/boost/date_time/gregorian/greg_facet.hpp
Normal 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
|
||||
|
||||
133
include/boost/date_time/gregorian/greg_month.hpp
Normal file
133
include/boost/date_time/gregorian/greg_month.hpp
Normal 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
|
||||
524
include/boost/date_time/gregorian/greg_serialize.hpp
Normal file
524
include/boost/date_time/gregorian/greg_serialize.hpp
Normal 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
|
||||
100
include/boost/date_time/gregorian/greg_weekday.hpp
Normal file
100
include/boost/date_time/gregorian/greg_weekday.hpp
Normal 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
|
||||
52
include/boost/date_time/gregorian/greg_year.hpp
Normal file
52
include/boost/date_time/gregorian/greg_year.hpp
Normal 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
|
||||
33
include/boost/date_time/gregorian/greg_ymd.hpp
Normal file
33
include/boost/date_time/gregorian/greg_ymd.hpp
Normal 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
|
||||
|
||||
38
include/boost/date_time/gregorian/gregorian.hpp
Normal file
38
include/boost/date_time/gregorian/gregorian.hpp
Normal 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
|
||||
784
include/boost/date_time/gregorian/gregorian_io.hpp
Normal file
784
include/boost/date_time/gregorian/gregorian_io.hpp
Normal 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__
|
||||
109
include/boost/date_time/gregorian/gregorian_types.hpp
Normal file
109
include/boost/date_time/gregorian/gregorian_types.hpp
Normal 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
|
||||
110
include/boost/date_time/gregorian/parsers.hpp
Normal file
110
include/boost/date_time/gregorian/parsers.hpp
Normal 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 8601 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 8601 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
|
||||
69
include/boost/date_time/gregorian_calendar.hpp
Normal file
69
include/boost/date_time/gregorian_calendar.hpp
Normal 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
|
||||
|
||||
|
||||
224
include/boost/date_time/gregorian_calendar.ipp
Normal file
224
include/boost/date_time/gregorian_calendar.ipp
Normal 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 8601 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
|
||||
516
include/boost/date_time/int_adapter.hpp
Normal file
516
include/boost/date_time/int_adapter.hpp
Normal 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
|
||||
303
include/boost/date_time/iso_format.hpp
Normal file
303
include/boost/date_time/iso_format.hpp
Normal 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 8601 formatting spec
|
||||
template<class charT>
|
||||
class iso_format_base {
|
||||
public:
|
||||
//! Describe month format -- its an integer in ISO 8601 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 8601 char for a year -- used in durations
|
||||
static charT year_sep_char()
|
||||
{
|
||||
return 'Y';
|
||||
}
|
||||
//! ISO 8601 char for a month
|
||||
static charT month_sep_char()
|
||||
{
|
||||
return '-';
|
||||
}
|
||||
//! ISO 8601 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 8601 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 8601 formatting spec
|
||||
template<>
|
||||
class iso_format_base<wchar_t> {
|
||||
public:
|
||||
//! Describe month format -- its an integer in ISO 8601 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 8601 char for a year -- used in durations
|
||||
static wchar_t year_sep_char()
|
||||
{
|
||||
return 'Y';
|
||||
}
|
||||
//! ISO 8601 char for a month
|
||||
static wchar_t month_sep_char()
|
||||
{
|
||||
return '-';
|
||||
}
|
||||
//! ISO 8601 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 8601 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 8601 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
|
||||
34
include/boost/date_time/local_time/conversion.hpp
Normal file
34
include/boost/date_time/local_time/conversion.hpp
Normal 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__
|
||||
168
include/boost/date_time/local_time/custom_time_zone.hpp
Normal file
168
include/boost/date_time/local_time/custom_time_zone.hpp
Normal 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
|
||||
115
include/boost/date_time/local_time/date_duration_operators.hpp
Normal file
115
include/boost/date_time/local_time/date_duration_operators.hpp
Normal 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___
|
||||
@@ -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
|
||||
529
include/boost/date_time/local_time/local_date_time.hpp
Normal file
529
include/boost/date_time/local_time/local_date_time.hpp
Normal 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 8601 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 8601 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
|
||||
24
include/boost/date_time/local_time/local_time.hpp
Normal file
24
include/boost/date_time/local_time/local_time.hpp
Normal 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
|
||||
187
include/boost/date_time/local_time/local_time_io.hpp
Normal file
187
include/boost/date_time/local_time/local_time_io.hpp
Normal 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__
|
||||
52
include/boost/date_time/local_time/local_time_types.hpp
Normal file
52
include/boost/date_time/local_time/local_time_types.hpp
Normal 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__
|
||||
475
include/boost/date_time/local_time/posix_time_zone.hpp
Normal file
475
include/boost/date_time/local_time/posix_time_zone.hpp
Normal 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__
|
||||
32
include/boost/date_time/local_time/tz_database.hpp
Normal file
32
include/boost/date_time/local_time/tz_database.hpp
Normal 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__
|
||||
|
||||
218
include/boost/date_time/local_time_adjustor.hpp
Normal file
218
include/boost/date_time/local_time_adjustor.hpp
Normal 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
|
||||
193
include/boost/date_time/local_timezone_defs.hpp
Normal file
193
include/boost/date_time/local_timezone_defs.hpp
Normal 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
|
||||
33
include/boost/date_time/locale_config.hpp
Normal file
33
include/boost/date_time/locale_config.hpp
Normal 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
|
||||
|
||||
158
include/boost/date_time/microsec_time_clock.hpp
Normal file
158
include/boost/date_time/microsec_time_clock.hpp
Normal 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
|
||||
|
||||
29
include/boost/date_time/parse_format_base.hpp
Normal file
29
include/boost/date_time/parse_format_base.hpp
Normal 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
|
||||
375
include/boost/date_time/period.hpp
Normal file
375
include/boost/date_time/period.hpp
Normal 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
|
||||
200
include/boost/date_time/period_formatter.hpp
Normal file
200
include/boost/date_time/period_formatter.hpp
Normal 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
|
||||
197
include/boost/date_time/period_parser.hpp
Normal file
197
include/boost/date_time/period_parser.hpp
Normal 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___
|
||||
100
include/boost/date_time/posix_time/conversion.hpp
Normal file
100
include/boost/date_time/posix_time/conversion.hpp
Normal 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(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
|
||||
|
||||
114
include/boost/date_time/posix_time/date_duration_operators.hpp
Normal file
114
include/boost/date_time/posix_time/date_duration_operators.hpp
Normal 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___
|
||||
39
include/boost/date_time/posix_time/posix_time.hpp
Normal file
39
include/boost/date_time/posix_time/posix_time.hpp
Normal 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
|
||||
|
||||
165
include/boost/date_time/posix_time/posix_time_config.hpp
Normal file
165
include/boost/date_time/posix_time/posix_time_config.hpp
Normal 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
|
||||
|
||||
|
||||
91
include/boost/date_time/posix_time/posix_time_duration.hpp
Normal file
91
include/boost/date_time/posix_time/posix_time_duration.hpp
Normal 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
|
||||
|
||||
236
include/boost/date_time/posix_time/posix_time_io.hpp
Normal file
236
include/boost/date_time/posix_time/posix_time_io.hpp
Normal 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 wants 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__
|
||||
153
include/boost/date_time/posix_time/posix_time_legacy_io.hpp
Normal file
153
include/boost/date_time/posix_time/posix_time_legacy_io.hpp
Normal 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___
|
||||
68
include/boost/date_time/posix_time/posix_time_system.hpp
Normal file
68
include/boost/date_time/posix_time/posix_time_system.hpp
Normal 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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
55
include/boost/date_time/posix_time/posix_time_types.hpp
Normal file
55
include/boost/date_time/posix_time/posix_time_types.hpp
Normal 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
|
||||
|
||||
84
include/boost/date_time/posix_time/ptime.hpp
Normal file
84
include/boost/date_time/posix_time/ptime.hpp
Normal 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
|
||||
|
||||
289
include/boost/date_time/posix_time/time_formatters.hpp
Normal file
289
include/boost/date_time/posix_time/time_formatters.hpp
Normal 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 8601 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 8601 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 8601 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 8601 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
|
||||
|
||||
212
include/boost/date_time/posix_time/time_formatters_limited.hpp
Normal file
212
include/boost/date_time/posix_time/time_formatters_limited.hpp
Normal 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 8601 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 8601 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
|
||||
|
||||
52
include/boost/date_time/posix_time/time_parsers.hpp
Normal file
52
include/boost/date_time/posix_time/time_parsers.hpp
Normal 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
|
||||
|
||||
29
include/boost/date_time/posix_time/time_period.hpp
Normal file
29
include/boost/date_time/posix_time/time_period.hpp
Normal 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
|
||||
|
||||
262
include/boost/date_time/posix_time/time_serialize.hpp
Normal file
262
include/boost/date_time/posix_time/time_serialize.hpp
Normal 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
|
||||
25
include/boost/date_time/special_defs.hpp
Normal file
25
include/boost/date_time/special_defs.hpp
Normal 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
|
||||
|
||||
97
include/boost/date_time/special_values_formatter.hpp
Normal file
97
include/boost/date_time/special_values_formatter.hpp
Normal 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
|
||||
163
include/boost/date_time/special_values_parser.hpp
Normal file
163
include/boost/date_time/special_values_parser.hpp
Normal 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 should_call_match(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__
|
||||
|
||||
32
include/boost/date_time/string_convert.hpp
Normal file
32
include/boost/date_time/string_convert.hpp
Normal 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___
|
||||
281
include/boost/date_time/string_parse_tree.hpp
Normal file
281
include/boost/date_time/string_parse_tree.hpp
Normal 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
|
||||
127
include/boost/date_time/strings_from_facet.hpp
Normal file
127
include/boost/date_time/strings_from_facet.hpp
Normal 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
|
||||
214
include/boost/date_time/time.hpp
Normal file
214
include/boost/date_time/time.hpp
Normal 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
|
||||
|
||||
83
include/boost/date_time/time_clock.hpp
Normal file
83
include/boost/date_time/time_clock.hpp
Normal 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
|
||||
43
include/boost/date_time/time_defs.hpp
Normal file
43
include/boost/date_time/time_defs.hpp
Normal 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
|
||||
310
include/boost/date_time/time_duration.hpp
Normal file
310
include/boost/date_time/time_duration.hpp
Normal 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
|
||||
|
||||
1370
include/boost/date_time/time_facet.hpp
Normal file
1370
include/boost/date_time/time_facet.hpp
Normal file
File diff suppressed because it is too large
Load Diff
122
include/boost/date_time/time_formatting_streams.hpp
Normal file
122
include/boost/date_time/time_formatting_streams.hpp
Normal 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
|
||||
52
include/boost/date_time/time_iterator.hpp
Normal file
52
include/boost/date_time/time_iterator.hpp
Normal 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 ¤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;}
|
||||
bool operator>= (const time_type& t) const {return current_ >= t;}
|
||||
|
||||
private:
|
||||
time_type current_;
|
||||
time_duration_type offset_;
|
||||
};
|
||||
|
||||
|
||||
|
||||
} }//namespace date_time
|
||||
|
||||
|
||||
#endif
|
||||
339
include/boost/date_time/time_parsing.hpp
Normal file
339
include/boost/date_time/time_parsing.hpp
Normal 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 8601 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::should_call_match(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
|
||||
167
include/boost/date_time/time_resolution_traits.hpp
Normal file
167
include/boost/date_time/time_resolution_traits.hpp
Normal 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
|
||||
269
include/boost/date_time/time_system_counted.hpp
Normal file
269
include/boost/date_time/time_system_counted.hpp
Normal 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
|
||||
|
||||
226
include/boost/date_time/time_system_split.hpp
Normal file
226
include/boost/date_time/time_system_split.hpp
Normal 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
|
||||
100
include/boost/date_time/time_zone_base.hpp
Normal file
100
include/boost/date_time/time_zone_base.hpp
Normal file
@@ -0,0 +1,100 @@
|
||||
#ifndef _DATE_TIME_TIME_ZONE_BASE__
|
||||
#define _DATE_TIME_TIME_ZONE_BASE__
|
||||
|
||||
/* 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 <boost/date_time/compiler_config.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace date_time {
|
||||
|
||||
|
||||
|
||||
//! Interface class for dynamic time zones.
|
||||
/*! This class represents the base interface for all timezone
|
||||
* representations. Subclasses may provide different systems
|
||||
* for identifying a particular zone. For example some may
|
||||
* provide a geographical based zone construction while others
|
||||
* may specify the offset from GMT. Another possible implementation
|
||||
* would be to convert from POSIX timezone strings. Regardless of
|
||||
* the construction technique, this is the interface that these
|
||||
* time zone types must provide.
|
||||
*
|
||||
* Note that this class is intended to be used as a shared
|
||||
* resource (hence the derivation from boost::counted_base.
|
||||
*/
|
||||
template<typename time_type, typename CharT>
|
||||
class BOOST_SYMBOL_VISIBLE time_zone_base {
|
||||
public:
|
||||
typedef CharT char_type;
|
||||
typedef std::basic_string<CharT> string_type;
|
||||
typedef std::basic_ostringstream<CharT> stringstream_type;
|
||||
typedef typename time_type::date_type::year_type year_type;
|
||||
typedef typename time_type::time_duration_type time_duration_type;
|
||||
|
||||
time_zone_base() {}
|
||||
virtual ~time_zone_base() {}
|
||||
//!String for the timezone when in daylight savings (eg: EDT)
|
||||
virtual string_type dst_zone_abbrev() const=0;
|
||||
//!String for the zone when not in daylight savings (eg: EST)
|
||||
virtual string_type std_zone_abbrev() const=0;
|
||||
//!String for the timezone when in daylight savings (eg: Eastern Daylight Time)
|
||||
virtual string_type dst_zone_name() const=0;
|
||||
//!String for the zone when not in daylight savings (eg: Eastern Standard Time)
|
||||
virtual string_type std_zone_name() const=0;
|
||||
//! True if zone uses daylight savings adjustments otherwise false
|
||||
virtual bool has_dst() const=0;
|
||||
//! Local time that DST starts -- undefined if has_dst is false
|
||||
virtual time_type dst_local_start_time(year_type y) const=0;
|
||||
//! Local time that DST ends -- undefined if has_dst is false
|
||||
virtual time_type dst_local_end_time(year_type y) const=0;
|
||||
//! Base offset from UTC for zone (eg: -07:30:00)
|
||||
virtual time_duration_type base_utc_offset() const=0;
|
||||
//! Adjustment forward or back made while DST is in effect
|
||||
virtual time_duration_type dst_offset() const=0;
|
||||
//! Returns a POSIX time_zone string for this object
|
||||
virtual string_type to_posix_string() const =0;
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
|
||||
//! Structure which holds the time offsets associated with daylight savings time
|
||||
/*!
|
||||
*@tparam time_duration_type A type used to represent the offset
|
||||
*/
|
||||
template<class time_duration_type>
|
||||
class dst_adjustment_offsets
|
||||
{
|
||||
public:
|
||||
dst_adjustment_offsets(const time_duration_type& dst_adjust,
|
||||
const time_duration_type& dst_start_offset,
|
||||
const time_duration_type& dst_end_offset) :
|
||||
dst_adjust_(dst_adjust),
|
||||
dst_start_offset_(dst_start_offset),
|
||||
dst_end_offset_(dst_end_offset)
|
||||
{}
|
||||
|
||||
//! Amount DST adjusts the clock eg: plus one hour
|
||||
time_duration_type dst_adjust_;
|
||||
//! Time past midnight on start transition day that dst starts
|
||||
time_duration_type dst_start_offset_;
|
||||
//! Time past midnight on end transition day that dst ends
|
||||
time_duration_type dst_end_offset_;
|
||||
};
|
||||
|
||||
|
||||
} } //namespace date_time
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user