various fixes for time_duration negative handling

[SVN r19954]
This commit is contained in:
Jeff Garland
2003-09-08 05:32:30 +00:00
parent 6893422d7e
commit fe9be81269
4 changed files with 129 additions and 46 deletions

View File

@@ -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

View File

@@ -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')

View File

@@ -9,28 +9,33 @@
#include "boost/lexical_cast.hpp"
#include "boost/date_time/date_parsing.hpp"
#include "boost/cstdint.hpp"
#include <iostream>
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<class time_duration>
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<char> sep(":,.");
char_separator<char> sep("-:,.");
tokenizer<char_separator<char> > tok(s,sep);
for(tokenizer<char_separator<char> >::iterator beg=tok.begin(); beg!=tok.end();++beg){
switch(pos) {
case 0: {
hour = boost::lexical_cast<short>(*beg);
hour = boost::lexical_cast<int>(*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<class time_type>
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<class time_duration>
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<boost::offset_separator> tok(s, osf);
boost::tokenizer<boost::offset_separator> tok(remain, osf);
for(boost::tokenizer<boost::offset_separator>::iterator ti=tok.begin(); ti!=tok.end();++ti){
short i = boost::lexical_cast<int>(*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<int>(*ti);
break;
}
case 1:
{
min = boost::lexical_cast<int>(*ti);
break;
}
case 2:
{
sec = boost::lexical_cast<int>(*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

View File

@@ -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<typename frac_sec_type,
time_resolutions res,
frac_sec_type resolution_adjust,
unsigned short frac_digits,
typename v_type = boost::int32_t >
//! Simple function to calculate absolute value of a numeric type
template <typename T>
// JDG [7/6/02 made a template],
// moved here from time_duration.hpp 2003-Sept-4.
inline T absolute_value(T x)
{
return x < 0 ? -x : x;
}
template<typename frac_sec_type,
time_resolutions res,
frac_sec_type resolution_adjust,
unsigned short frac_digits,
typename v_type = boost::int32_t >
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;
}
}
};