diff --git a/include/boost/date_time/posix_time/time_formatters.hpp b/include/boost/date_time/posix_time/time_formatters.hpp index a0b39ef..a7d7446 100644 --- a/include/boost/date_time/posix_time/time_formatters.hpp +++ b/include/boost/date_time/posix_time/time_formatters.hpp @@ -2,7 +2,7 @@ #define POSIXTIME_FORMATTERS_HPP___ /* Copyright (c) 2002 CrystalClear Software, Inc. * Disclaimer & Full Copyright at end of file - * Author: Jeff Garland + * Author: Jeff Garland, Bart Garst */ #include "boost/date_time/gregorian/gregorian.hpp" @@ -15,22 +15,31 @@ namespace boost { namespace posix_time { - //! Time duration to string hh::mm::ss.fffffff. Example: 10:09:03.0123456 + //! 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; - ss << std::setw(2) << std::setfill('0') << td.hours() << ":"; - ss << std::setw(2) << std::setfill('0') << td.minutes() << ":"; - ss << std::setw(2) << std::setfill('0') << td.seconds(); + 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 <= 1200)) // 1200 == VC++ 6.0 - boost::int64_t frac_sec = td.fractional_seconds(); + 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 = td.fractional_seconds(); + 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()) @@ -46,22 +55,31 @@ namespace posix_time { return ss.str(); } - //! Time duration in iso format hhmmss,fffffff Example: 10:09:03,0123456 + //! Time duration in iso format -hhmmss,fffffff Example: 10:09:03,0123456 /*!\ingroup time_format */ inline std::string to_iso_string(time_duration td) { std::ostringstream ss; - ss << std::setw(2) << std::setfill('0') << td.hours(); - ss << std::setw(2) << std::setfill('0') << td.minutes(); - ss << std::setw(2) << std::setfill('0') << td.seconds(); + 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 <= 1200)) // 1200 == VC++ 6.0 - boost::int64_t frac_sec = td.fractional_seconds(); + 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 = td.fractional_seconds(); + 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()) @@ -148,7 +166,7 @@ namespace posix_time { -#endif +#endif //BOOST_DATE_TIME_NO_LOCALE } } //namespace posix_time diff --git a/include/boost/date_time/time_formatting_streams.hpp b/include/boost/date_time/time_formatting_streams.hpp index 5099d8e..0cefb4e 100644 --- a/include/boost/date_time/time_formatting_streams.hpp +++ b/include/boost/date_time/time_formatting_streams.hpp @@ -2,11 +2,12 @@ #define DATE_TIME_TIME_FORMATTING_STREAMS_HPP___ /* Copyright (c) 2002 CrystalClear Software, Inc. * Disclaimer & Full Copyright at end of file - * Author: Jeff Garland + * Author: Jeff Garland, Bart Garst */ #include "boost/date_time/date_formatting_locales.hpp" +#include "boost/date_time/time_resolution_traits.hpp" #ifndef BOOST_DATE_TIME_NO_LOCALE @@ -27,10 +28,17 @@ namespace date_time { static void duration_put(const time_duration_type& td, ostream_type& os) { - os << std::setw(2) << std::setfill('0') << td.hours() << ":"; - os << std::setw(2) << std::setfill('0') << td.minutes() << ":"; - os << std::setw(2) << std::setfill('0') << td.seconds(); - fractional_seconds_type frac_sec = td.fractional_seconds(); + if(td.is_negative()) { + os << '-'; + } + os << std::setw(2) << std::setfill('0') + << absolute_value(td.hours()) << ":"; + os << std::setw(2) << std::setfill('0') + << absolute_value(td.minutes()) << ":"; + os << std::setw(2) << std::setfill('0') + << 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('0') diff --git a/include/boost/date_time/time_parsing.hpp b/include/boost/date_time/time_parsing.hpp index 94980f0..3fa1905 100644 --- a/include/boost/date_time/time_parsing.hpp +++ b/include/boost/date_time/time_parsing.hpp @@ -9,28 +9,33 @@ #include "boost/lexical_cast.hpp" #include "boost/date_time/date_parsing.hpp" #include "boost/cstdint.hpp" - +#include namespace boost { namespace date_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 "-:,.". */ template inline time_duration parse_delimited_time_duration(const std::string& s) { unsigned short min=0, sec =0; - short hour=0; + int hour =0; + bool is_neg = (s.at(0) == '-'); boost::int64_t fs=0; int pos = 0; - char_separator sep(":,."); + char_separator sep("-:,."); tokenizer > tok(s,sep); for(tokenizer >::iterator beg=tok.begin(); beg!=tok.end();++beg){ switch(pos) { case 0: { - hour = boost::lexical_cast(*beg); + hour = boost::lexical_cast(*beg); break; } case 1: { @@ -54,10 +59,15 @@ namespace date_time { }//switch pos++; } - return time_duration(hour, min, sec, fs); + if(is_neg) { + return -time_duration(hour, min, sec, fs); + } + else { + return time_duration(hour, min, sec, fs); + } } - //TODO this could use some error checking! + //! Utility function to split appart string inline bool split(const std::string& s, @@ -71,6 +81,7 @@ namespace date_time { return true; } + template inline time_type @@ -91,28 +102,52 @@ namespace date_time { } - //! Parse time duration part of an iso time of form: hhmmss (eg: 120259 is 12 hours 2 min 59 seconds) + //! Parse time duration part of an iso time of form: [-]hhmmss (eg: 120259 is 12 hours 2 min 59 seconds) template inline time_duration parse_undelimited_time_duration(const std::string& s) { int offsets[] = {2,2,2}; - int pos = 0; - short hours=0, min=0, sec=0; + int pos = 0, sign = 0; + int hours = 0; + short min=0, sec=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); boost::offset_separator osf(offsets, offsets+3); - boost::tokenizer tok(s, osf); + boost::tokenizer tok(remain, osf); for(boost::tokenizer::iterator ti=tok.begin(); ti!=tok.end();++ti){ - short i = boost::lexical_cast(*ti); - // std::cout << i << std::endl; switch(pos) { - case 0: hours = i; break; - case 1: min = i; break; - case 2: sec = i; break; + case 0: + { + hours = boost::lexical_cast(*ti); + break; + } + case 1: + { + min = boost::lexical_cast(*ti); + break; + } + case 2: + { + sec = boost::lexical_cast(*ti); + break; + } }; pos++; - } - return time_duration(hours, min, sec); + } + if(sign) { + return -time_duration(hours, min, sec); + } + else { + return time_duration(hours, min, sec); + } } //! Parse time string of form YYYYMMDDThhmmss where T is delimeter between date and time diff --git a/include/boost/date_time/time_resolution_traits.hpp b/include/boost/date_time/time_resolution_traits.hpp index 3b6b520..756da07 100644 --- a/include/boost/date_time/time_resolution_traits.hpp +++ b/include/boost/date_time/time_resolution_traits.hpp @@ -3,7 +3,7 @@ /* Copyright (c) 2002 CrystalClear Software, Inc. * Disclaimer & Full Copyright at end of file - * Author: Jeff Garland + * Author: Jeff Garland, Bart Garst */ @@ -13,11 +13,20 @@ namespace boost { namespace date_time { - template + //! Simple function to calculate absolute value of a numeric type + template + // JDG [7/6/02 made a template], + // moved here from time_duration.hpp 2003-Sept-4. + inline T absolute_value(T x) + { + return x < 0 ? -x : x; + } + + template class time_resolution_traits { public: typedef frac_sec_type fractional_seconds_type; @@ -43,14 +52,27 @@ namespace date_time { { return resolution_adjust; } + //! Any negative argument results in a negative tick_count static tick_type to_tick_count(hour_type hours, min_type minutes, sec_type seconds, fractional_seconds_type fs) { - return (((fractional_seconds_type(hours)*3600) - + (fractional_seconds_type(minutes)*60) - + seconds)*res_adjust()) + 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 (-1 *(((fractional_seconds_type(hours)*3600) + + (fractional_seconds_type(minutes)*60) + + seconds)*res_adjust()) + fs); + } + else{ + return (((fractional_seconds_type(hours)*3600) + + (fractional_seconds_type(minutes)*60) + + seconds)*res_adjust()) + fs; + } } };