Compare commits

...

8 Commits

Author SHA1 Message Date
nobody 834153d13f This commit was manufactured by cvs2svn to create tag
'Version_1_33_1_beta'.

[SVN r31604]
2005-11-08 23:18:41 +00:00
Jeff Garland 392ce9b175 Fix one last unqualified tm struct --> make std::tm
[SVN r31521]
2005-11-01 04:27:29 +00:00
Jeff Garland e87b6b95b5 merge changes for QNX port to branch -- basically a half dozen changes to ensure that 'tm' and 'time_t' are qualified with std::
[SVN r31500]
2005-10-28 13:32:38 +00:00
Jeff Garland 4d6afa2bf1 Add tests for fix to negative duration problem that caused incorrect calculation results
[SVN r31441]
2005-10-24 01:33:50 +00:00
Jeff Garland 1995c94b9a Fix problem where negative durations would create incorrect calculation results.
[SVN r31440]
2005-10-24 01:32:08 +00:00
Markus Schöpflin 17e4d59d53 Merged changes done by Jeff Garland from trunk to RC branch.
[SVN r30843]
2005-09-07 09:15:03 +00:00
Jeff Garland 757b5fb3cf Fix problem with localtime_r and Borland
[SVN r30376]
2005-08-02 13:52:44 +00:00
nobody f91a6391ad This commit was manufactured by cvs2svn to create branch 'RC_1_33_0'.
[SVN r30300]
2005-07-28 18:22:24 +00:00
8 changed files with 206 additions and 119 deletions
+1 -1
View File
@@ -135,7 +135,7 @@ namespace std {
#endif // auto-linking disabled
#if defined(BOOST_HAS_THREADS)
# if defined(_MSC_VER) || defined(__MWERKS__) || defined(__MINGW32__)
# if defined(_MSC_VER) || defined(__MWERKS__) || defined(__MINGW32__) || defined(__BORLANDC__)
//no reentrant posix functions (eg: localtime_r)
# else
# define BOOST_DATE_TIME_HAS_REENTRANT_STD_FUNCTIONS
@@ -7,7 +7,7 @@
* Boost Software License, Version 1.0. (See accompanying
* file LICENSE-1.0 or http://www.boost.org/LICENSE-1.0)
* Author: Jeff Garland, Bart Garst
* $Date:
* $Date$
*/
@@ -20,7 +20,11 @@
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:
/*! 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"
@@ -30,24 +34,22 @@ namespace boost { namespace date_time {
*
* Weekday and Month names and formats are handled via the date_input_facet.
*
* TODO: add doc-comments for which elements can be changed
*/
template<class date_type, typename charT>
class date_generator_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 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::duration_type duration_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 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 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;
@@ -73,56 +75,52 @@ namespace boost { namespace date_time {
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));
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,
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)
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, second, third, fourth, fifth, last, before, after, of);
}
date_generator_parser(const date_generator_parser<date_type,charT>* dgp)
{
this->m_element_strings = dgp.m_element_strings;
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,
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)
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);
phrases.push_back(second);
phrases.push_back(third);
phrases.push_back(fourth);
phrases.push_back(fifth);
phrases.push_back(last);
phrases.push_back(before);
phrases.push_back(after);
phrases.push_back(of);
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
}
@@ -30,7 +30,7 @@ namespace gregorian {
//! Converts a date to a tm struct. Throws out_of_range exception if date is a special value
inline
tm to_tm(const date& d)
std::tm to_tm(const date& d)
{
if(d.is_pos_infinity() || d.is_neg_infinity() || d.is_not_a_date()){
#if defined(USE_DATE_TIME_PRE_1_33_FACET_IO)
@@ -42,7 +42,7 @@ namespace gregorian {
throw std::out_of_range(ss.str());
#endif // USE_DATE_TIME_PRE_1_33_FACET_IO
}
tm datetm;
std::tm datetm;
boost::gregorian::date::ymd_type ymd = d.year_month_day();
datetm.tm_year = ymd.year-1900;
datetm.tm_mon = ymd.month-1;
@@ -56,7 +56,7 @@ namespace gregorian {
//! Converts a tm structure into a date dropping the any time values.
inline
date date_from_tm(const tm& datetm)
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),
@@ -84,7 +84,7 @@ namespace date_time {
static time_type create_time(TZ_FOR_CREATE tz) {
timeval tv;
gettimeofday(&tv, 0); //gettimeofday does not support TZ adjust on Linux.
time_t t = tv.tv_sec;
std::time_t t = tv.tv_sec;
boost::uint32_t fs = tv.tv_usec;
std::tm curr, *curr_ptr = 0;
if (tz == LOCAL) {
@@ -155,7 +155,7 @@ namespace date_time {
boost::uint32_t sub_sec = (filetime % 10000000) / 10; // microseconds
time_t t = static_cast<time_t>(filetime / 10000000); // seconds since epoch
std::time_t t = static_cast<time_t>(filetime / 10000000); // seconds since epoch
std::tm curr, *curr_ptr = 0;
if (tz == LOCAL) {
@@ -30,8 +30,8 @@ namespace posix_time {
//! Convert a time to a tm structure truncating any fractional seconds
inline
tm to_tm(const boost::posix_time::ptime& t) {
tm timetm = boost::gregorian::to_tm(t.date());
std::tm to_tm(const boost::posix_time::ptime& t) {
std::tm timetm = boost::gregorian::to_tm(t.date());
boost::posix_time::time_duration td = t.time_of_day();
timetm.tm_hour = td.hours();
timetm.tm_min = td.minutes();
@@ -41,8 +41,8 @@ namespace posix_time {
}
//! Convert a time_duration to a tm structure truncating any fractional seconds and zeroing fields for date components
inline
tm to_tm(const boost::posix_time::time_duration& td) {
tm timetm;
std::tm to_tm(const boost::posix_time::time_duration& td) {
std::tm timetm;
timetm.tm_year = 0;
timetm.tm_mon = 0;
timetm.tm_mday = 0;
@@ -58,7 +58,7 @@ namespace posix_time {
//! Convert a tm struct to a ptime ignoring is_dst flag
inline
ptime ptime_from_tm(const tm& timetm) {
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));
}
+72 -50
View File
@@ -1,7 +1,7 @@
#ifndef _DATE_TIME_WRAPPING_INT_HPP__
#define _DATE_TIME_WRAPPING_INT_HPP__
/* Copyright (c) 2002,2003 CrystalClear Software, Inc.
/* 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 or http://www.boost.org/LICENSE-1.0)
@@ -13,10 +13,19 @@
namespace boost {
namespace date_time {
//! A wrapping integer used to support time durations
//! A wrapping integer used to support time durations (WARNING: only instantiate with a signed type)
/*! In composite date and time types this type is used to
* wrap at the day boundary.
* Ex:
* A wrapping_int<short, 10> will roll over after nine, and
* roll under below zero. This gives a range of [0,9]
*
* NOTE: it is strongly recommended that wrapping_int2 be used
* instead of wrapping_int as wrapping_int is to be depricated
* at some point soon.
*
* Also Note that warnings will occur if instantiated with an
* unsigned type. Only a signed type should be used!
*/
template<typename int_type_, int_type_ wrap_val>
class wrapping_int {
@@ -29,54 +38,55 @@ public:
//! Explicit converion method
int_type as_int() const {return value_;}
operator int_type() const {return value_;}
//!Add, return number of wraps performed
/*! The sign of the returned value will indicate which direction the
* wraps went. Ex: add a negative number and wrapping under could occur,
* this would be indicated by a negative return value. If wrapping over
* took place, a positive value would be returned */
int_type add(int_type v)
{
//take the mod here and assign it....
int_type remainder = static_cast<int_type>(v % wrap_val);
int_type overflow = static_cast<int_type>(v / wrap_val);
int_type remainder = static_cast<int_type>(v % (wrap_val));
int_type overflow = static_cast<int_type>(v / (wrap_val));
value_ = static_cast<int_type>(value_ + remainder);
if ((value_) >= wrap_val) {
value_ -= wrap_val;
overflow++;
}
return overflow;
return calculate_wrap(overflow);
}
//! Subtract will return '+d' if wrapping under took place ('d' is the number of wraps)
/*! The sign of the returned value will indicate which direction the
* wraps went (positive indicates wrap under, negative indicates wrap over).
* Ex: subtract a negative number and wrapping over could
* occur, this would be indicated by a negative return value. If
* wrapping under took place, a positive value would be returned. */
int_type subtract(int_type v)
{
//take the mod here and assign it....
int_type remainder = v % wrap_val;
int_type underflow = v / wrap_val;
// std::cout << "wi :" << value_ << "|"
// << v << "|"
// << underflow << "|"
// << remainder << "|"
// << wrap_val << std::endl;
if (remainder > value_) {
underflow++;
// value_ = remainder - value_;
value_ = wrap_val - (remainder-value_);
}
else {
value_ -= remainder;
//value_ = wrap_val-(remainder-value_);
// value_ = wrap_val -(value_-remainder);
}
// std::cout << "wi final uf: " << underflow
// << " value: " << value_ << std::endl;
return underflow;
int_type remainder = static_cast<int_type>(v % (wrap_val));
int_type underflow = static_cast<int_type>(-(v / (wrap_val)));
value_ = static_cast<int_type>(value_ - remainder);
return calculate_wrap(underflow) * -1;
}
private:
int_type value_;
int_type calculate_wrap(int_type wrap)
{
if ((value_) >= wrap_val)
{
wrap++;
value_ -= (wrap_val);
}
else if(value_ < 0)
{
wrap--;
value_ += (wrap_val);
}
return wrap;
}
};
//! A wrapping integer used to wrap around at the top
//! A wrapping integer used to wrap around at the top (WARNING: only instantiate with a signed type)
/*! Bad name, quick impl to fix a bug -- fix later!!
* This allows the wrap to restart at a value other than 0.
* Currently this only works if wrap_min == 1
*/
template<typename int_type_, int_type_ wrap_min, int_type_ wrap_max>
class wrapping_int2 {
@@ -99,36 +109,48 @@ public:
//! Explicit converion method
int_type as_int() const {return value_;}
operator int_type() const {return value_;}
//!Add, return number of wraps performed
//!Add, return number of wraps performed
/*! The sign of the returned value will indicate which direction the
* wraps went. Ex: add a negative number and wrapping under could occur,
* this would be indicated by a negative return value. If wrapping over
* took place, a positive value would be returned */
int_type add(int_type v)
{
int_type remainder = static_cast<int_type>(v % (wrap_max - wrap_min + 1));
int_type overflow = static_cast<int_type>(v / (wrap_max - wrap_min + 1));
value_ = static_cast<int_type>(value_ + remainder);
if ((value_) > wrap_max)
{
overflow++;
value_ -= (wrap_max - wrap_min + 1);
}
return overflow;
return calculate_wrap(overflow);
}
//! Subtract will return '-d' if wrapping took place ('d' is the number of wraps)
//! Subtract will return '-d' if wrapping under took place ('d' is the number of wraps)
/*! The sign of the returned value will indicate which direction the
* wraps went. Ex: subtract a negative number and wrapping over could
* occur, this would be indicated by a positive return value. If
* wrapping under took place, a negative value would be returned */
int_type subtract(int_type v)
{
int_type remainder = static_cast<int_type>(v % (wrap_max - wrap_min + 1));
int_type underflow = static_cast<int_type>(-(v / (wrap_max - wrap_min + 1)));
value_ = static_cast<int_type>(value_ - remainder);
if ((value_) < wrap_min)
{
underflow--;
value_ += (wrap_max - wrap_min + 1);
}
return underflow;
return calculate_wrap(underflow);
}
private:
int_type value_;
int_type calculate_wrap(int_type wrap)
{
if ((value_) > wrap_max)
{
wrap++;
value_ -= (wrap_max - wrap_min + 1);
}
else if((value_) < wrap_min)
{
wrap--;
value_ += (wrap_max - wrap_min + 1);
}
return wrap;
}
};
+32 -1
View File
@@ -1,4 +1,4 @@
/* Copyright (c) 2002,2003 CrystalClear Software, Inc.
/* 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 or http://www.boost.org/LICENSE-1.0)
@@ -29,6 +29,37 @@ int main(){
check("months & months subtractable", months(-5) == m2 - m1);
m2 -= m1;
check("months & months subtractable", months(-5) == m2);
{
// adding and subtracting negative values
date d1(2005, Jan, 1);
date d2(2005, Feb, 1);
check("add neg months (year wrap under)",
d1 + months(-1) == date(2004,Dec,1));
check("add neg months (no year wrap under)",
d2 + months(-1) == date(2005,Jan,1));
check("add neg months (year wrap under)",
d2 + months(-2) == date(2004,Dec,1));
check("add neg months (year wrap under)",
d2 + months(-12) == date(2004,Feb,1));
check("add neg months (year wrap under)",
d2 + months(-13) == date(2004,Jan,1));
check("add neg months (year wrap under)",
d2 + months(-14) == date(2003,Dec,1));
date d3(2005, Dec, 1);
date d4(2005, Nov, 1);
check("subtract neg months (year wrap over)",
d3 - months(-1) == date(2006,Jan,1));
check("subtract neg months (no year wrap over)",
d4 - months(-1) == date(2005,Dec,1));
check("subtract neg months (year wrap over)",
d4 - months(-2) == date(2006,Jan,1));
check("subtract neg months (year wrap over)",
d4 - months(-12) == date(2006,Nov,1));
check("subtract neg months (year wrap over)",
d4 - months(-13) == date(2006,Dec,1));
check("subtract neg months (year wrap over)",
d4 - months(-14) == date(2007,Jan,1));
}
{
months m1(5), m2(3), m3(10);
check("months & int multipliable", months(15) == m1 * 3);
+41 -5
View File
@@ -1,8 +1,8 @@
/* Copyright (c) 2002,2003 CrystalClear Software, Inc.
/* 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 or http://www.boost.org/LICENSE-1.0)
* Author: Jeff Garland
* Author: Jeff Garland, Bart Garst
*/
#include "boost/date_time/wrapping_int.hpp"
@@ -20,7 +20,7 @@ main()
{
using namespace boost::date_time;
wrapping_int<unsigned int, 3600> wi(3599);
wrapping_int<int, 3600> wi(3599);
check("construction/conversion", wi == 3599);
check("add with wrap", wi.add(1) == 1);
check("added value ok", wi == 0);
@@ -40,7 +40,7 @@ main()
check("subtract again", (wi.subtract(1) == 0) && (wi == 1));
std::cout << wi << std::endl;
wrapping_int<unsigned short, 60> wi2(0);
wrapping_int<short, 60> wi2(0);
check("add with wrap - return", wi2.add(121) == 2);
check("add with wrap - value", wi2 == 1);
@@ -48,6 +48,14 @@ main()
check("signed int - add return", wi3.add(5) == 0);
check("signed int - value", wi3 == 0);
{ // subtracting negative values
wrapping_int<short, 10> wi3(5);
check("subtract negative value to cause wrap",
(wi3.subtract(-8) == -1 && wi3 == 3));
check("reset", wi3.add(2) == 0 && wi3 ==5);
check("add negative value to cause wrap",
(wi3.add(-8) == -1 && wi3 == 7));
}
wrapping_int2<short, 1, 5> wi4(1);
check("construct", wi4 == 1);
@@ -75,6 +83,34 @@ main()
check("sub under the wrap value X 2", wi6.subtract(11) == -2 && wi6 == 5);
//std::cout << wi6 << std::endl;
// adding & subtracting negative values
wrapping_int2<short, 1, 12> wi7(6);
wrapping_int2<short, -5, 5> wi8(0);
check("add negative value", (wi7.add(-2) == 0 && wi7 == 4));
check("add negative value", (wi8.add(-2) == 0 && wi8 == -2));
check("add negative value to cause single wrap",
(wi7.add(-6) == -1 && wi7 == 10));
check("add negative value to cause single wrap",
(wi8.add(-5) == -1 && wi8 == 4));
check("add negative value to cause multiple wrap",
(wi7.add(-22) == -2 && wi7 == 12));
check("add negative value to cause multiple wrap",
(wi8.add(-22) == -2 && wi8 == 4));
// reset values to mid range
wi7.subtract(6);
check("reset", wi7 == 6);
wi8.subtract(4);
check("reset", wi8 == 0);
check("subtract negative value", (wi7.subtract(-2) == 0 && wi7 == 8));
check("subtract negative value", (wi8.subtract(-2) == 0 && wi8 == 2));
check("subtract negative value to cause single wrap",
(wi7.subtract(-6) == 1 && wi7 == 2));
check("subtract negative value to cause single wrap",
(wi8.subtract(-5) == 1 && wi8 == -4));
check("subtract negative value to cause multiple wrap",
(wi7.subtract(-23) == 2 && wi7 == 1));
check("subtract negative value to cause multiple wrap",
(wi8.subtract(-22) == 2 && wi8 == -4));
// #ifdef BOOST_HAS_LONG_LONG
// wrapping_int<boost::int64_t, 86400*100000LL> wi4(0);
@@ -91,7 +127,7 @@ main()
// // check("construction/conversion", wi4 == 0);
// #endif
// wrapping_int<unsigned int, 60> wi(121);
// wrapping_int<int, 60> wi(121);
// check("construction/conversion", wi == 121);
// check("add with wrap", wi.add(1) == 1);