Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

boost::posix_time::time_duration fractional part

24 views
Skip to first unread message

Christopher Pisz

unread,
May 12, 2015, 3:19:04 PM5/12/15
to
http://www.boost.org/doc/libs/1_58_0/doc/html/date_time/posix_time.html#date_time.posix_time.ptime_class

In the section about time_duration, the doc states:

time_duration(hours,
minutes,
seconds,
fractional_seconds)

Where fractional seconds are units and are effected by the resolution
the application is compiled with. Ok, fair enough.

It then goes on to say, "Another way to handle this is to utilize the
ticks_per_second() method of time_duration to write code that is
portable no matter how the library is compiled. The general equation for
calculating a resolution independent count is as follows:

count*(time_duration_ticks_per_second / count_ticks_per_second)"

and gives and example:

"int number_of_tenths = 5;
//create a resolution independent count -- divide by 10 since there are
//10 tenths in a second.
int count = number_of_tenths*(time_duration::ticks_per_second()/10);
time_duration td(1,2,3,count); //01:02:03.5 //no matter the resolution
settings"

Well, that just doesn't work!
If the ticks per second for the input value are greater than the ticks
per second for the configured time_duration resolution, count will be 0.


Here is the function I am trying to make. I use a Windows function for
the time zone. Ignore that part if need be, it isn't important in the
context of the question. I also use my own exception classes. I cannot
figure out what to do with the fractional part.


//--------------------------------------------------------------------------------------------------
boost::posix_time::ptime DBDatetimeStringToLocalPtime(const std::string
& value)
{
// Expected input formats:
// "YYYY-MM-DD hh:mm:ss.nnnnnnn"
// "YYYY-MM-DDThh:mm:ss.nnnnnnn"
// "YYYY-MM-DD hh:mm:ss.nnnnnnnZ"
// "YYYY-MM-DDThh:mm:ss.nnnnnnnZ"
// "YYYY-MM-DDThh:mm:ss.nnnnnnn +06:00"
// "YYYY-MM-DDThh:mm:ss.nnnnnnn+06:00"
// "YYYY-MM-DD hh:mm:ss.nnnnnnn -06:00"
// "YYYY-MM-DD hh:mm:ss.nnnnnnn-06:00"
const std::string datePart = value.substr(0, 10);
const std::string otherPart = value.substr(11, std::string::npos);

std::string::size_type index = otherPart.find('+');
if( index == std::string::npos )
{
index = otherPart.find('-');

if( index == std::string::npos )
{
index = otherPart.find('Z');
}
}

const std::string timePart = otherPart.substr(0, index);
std::string timeZonePart;

if( index != std::string::npos )
{
timeZonePart = otherPart.substr(index, std::string::npos);
}

// Date
std::istringstream
converter(Shared::ReplaceAllOccurrences(datePart, "-", " "));
unsigned year;
unsigned month;
unsigned day;

if( (converter >> year).fail() ||
(converter >> month).fail() ||
(converter >> day).fail() )
{
std::ostringstream msg;
msg << "Could not convert string: \"" << value << "\" to ptime.";
throw Shared::Exception(__FILE__, __LINE__, msg.str());
}

boost::gregorian::date date(year, month, day);

// Time

converter.str(Shared::ReplaceAllOccurrences(Shared::ReplaceAllOccurrences(timePart,
":", " "), ".", " "));
converter.clear();

unsigned hour;
unsigned minute;
unsigned second;
unsigned fractional = 0;

if( (converter >> hour).fail() ||
(converter >> minute).fail() ||
(converter >> second).fail() )
{
std::ostringstream msg;
msg << "Could not convert string: \"" << value << "\" to ptime.";
throw Shared::Exception(__FILE__, __LINE__, msg.str());
}

index = timePart.find('.');
if( index != std::string::npos )
{
std::string fractionalPart = timePart.substr(index + 1,
std::string::npos);

if( (converter >> fractional).fail() )
{
std::ostringstream msg;
msg << "Could not convert string: \"" << value << "\" to
ptime.";
throw Shared::Exception(__FILE__, __LINE__, msg.str());
}

// Round to maximum supported resolution
const long long inputTicksPerSecond = std::pow<long
long>(10, fractionalPart.size());
const long long supportedTicksPerSecond =
boost::posix_time::time_duration::ticks_per_second();

if( supportedTicksPerSecond > inputTicksPerSecond)
{
fractional = fractional * (supportedTicksPerSecond /
inputTicksPerSecond);
}
else
{

}
}

boost::posix_time::time_duration time(hour, minute, second,
fractional);
boost::posix_time::ptime datetime(date, time);

// Time Zone
if( !timeZonePart.empty() )
{
if( timeZonePart[0] == 'Z' )
{
TIME_ZONE_INFORMATION timeZoneInformation;
GetTimeZoneInformation(&timeZoneInformation);

long offsetHours = timeZoneInformation.Bias / 60;
long offsetMinutes = timeZoneInformation.Bias % 60;

boost::posix_time::time_duration offset(offsetHours,
offsetMinutes, 0);
datetime = datetime - offset;
}
}

return datetime;
}



Any suggestions?




--
I have chosen to troll filter/ignore all subthreads containing the
words: "Rick C. Hodgins", "Flibble", and "Islam"
So, I won't be able to see or respond to any such messages
---

Christopher Pisz

unread,
May 13, 2015, 11:17:12 AM5/13/15
to
On 5/12/2015 2:18 PM, Christopher Pisz wrote:
> http://www.boost.org/doc/libs/1_58_0/doc/html/date_time/posix_time.html#date_time.posix_time.ptime_class
SNIP
Derp. Types and truncation.

I really do wish standard C++ had better date time support. This doesn't
feel good half in boost and still relying on Windows API calls for timezone.
0 new messages