cpp-utilities/chrono/timespan.cpp

124 lines
3.8 KiB
C++
Raw Normal View History

2015-09-06 20:19:09 +02:00
#include "./timespan.h"
2015-04-22 18:36:40 +02:00
2015-09-06 20:19:09 +02:00
#include "../conversion/stringconversion.h"
2015-04-22 18:36:40 +02:00
#include <cmath>
#include <iomanip>
2017-05-01 03:13:11 +02:00
#include <sstream>
2015-04-22 18:36:40 +02:00
#include <vector>
using namespace std;
using namespace ChronoUtilities;
using namespace ConversionUtilities;
/*!
* \class ChronoUtilities::TimeSpan
* \brief Represents a time interval.
* \remarks Time values are measured in 100-nanosecond units called ticks.
*/
/*!
* \brief Parses the given C-style string as TimeSpan.
2015-04-22 18:36:40 +02:00
*/
TimeSpan TimeSpan::fromString(const char *str, char separator)
2015-04-22 18:36:40 +02:00
{
2017-06-25 15:09:16 +02:00
if (!*str) {
return TimeSpan();
}
2015-04-22 18:36:40 +02:00
vector<double> parts;
size_t partsSize = 1;
2017-05-01 03:13:11 +02:00
for (const char *i = str; *i; ++i) {
*i == separator && ++partsSize;
}
parts.reserve(partsSize);
2017-05-01 03:13:11 +02:00
for (const char *i = str;;) {
if (*i == separator) {
parts.emplace_back(stringToNumber<double>(string(str, i)));
str = ++i;
2017-05-01 03:13:11 +02:00
} else if (*i == '\0') {
parts.emplace_back(stringToNumber<double>(string(str, i)));
2015-04-22 18:36:40 +02:00
break;
} else {
++i;
2016-01-27 00:14:20 +01:00
}
2015-04-22 18:36:40 +02:00
}
2017-05-01 03:13:11 +02:00
switch (parts.size()) {
2015-04-22 18:36:40 +02:00
case 1:
return TimeSpan::fromSeconds(parts.front());
case 2:
return TimeSpan::fromMinutes(parts.front()) + TimeSpan::fromSeconds(parts[1]);
case 3:
return TimeSpan::fromHours(parts.front()) + TimeSpan::fromMinutes(parts[1]) + TimeSpan::fromSeconds(parts[2]);
default:
return TimeSpan::fromDays(parts.front()) + TimeSpan::fromHours(parts[1]) + TimeSpan::fromMinutes(parts[2]) + TimeSpan::fromSeconds(parts[3]);
}
}
/*!
2016-01-18 23:41:30 +01:00
* \brief Converts the value of the current TimeSpan object to its equivalent std::string representation
* according the given \a format.
2015-04-22 18:36:40 +02:00
*
* If \a noMilliseconds is true the time interval will be rounded to full seconds.
*/
string TimeSpan::toString(TimeSpanOutputFormat format, bool noMilliseconds) const
{
string result;
toString(result, format, noMilliseconds);
return result;
}
/*!
2016-01-18 23:41:30 +01:00
* \brief Converts the value of the current TimeSpan object to its equivalent std::string representation
* according the given \a format.
2015-04-22 18:36:40 +02:00
*
* If \a noMilliseconds is true the time interval will be rounded to full seconds.
*
* The string representation will be stored in \a result.
*/
void TimeSpan::toString(string &result, TimeSpanOutputFormat format, bool noMilliseconds) const
{
stringstream s(stringstream::in | stringstream::out);
2017-06-25 15:09:16 +02:00
TimeSpan positive(m_ticks);
if (positive.isNegative()) {
s << '-';
positive.m_ticks = -positive.m_ticks;
}
2017-05-01 03:13:11 +02:00
switch (format) {
2015-04-22 18:36:40 +02:00
case TimeSpanOutputFormat::Normal:
2017-06-25 15:09:16 +02:00
s << setfill('0') << setw(2) << floor(positive.totalHours()) << ":" << setw(2) << positive.minutes() << ":" << setw(2) << positive.seconds()
<< " ";
2015-04-22 18:36:40 +02:00
break;
case TimeSpanOutputFormat::WithMeasures:
2017-05-01 03:13:11 +02:00
if (isNull()) {
2015-04-22 18:36:40 +02:00
s << "0 s ";
} else {
2017-06-25 15:09:16 +02:00
if (positive.totalMilliseconds() < 1.0) {
s << setprecision(2) << (m_ticks / 10.0) << " µs ";
} else {
if (const int days = positive.days()) {
s << days << " d ";
}
if (const int hours = positive.hours()) {
s << hours << " h ";
}
if (const int minutes = positive.minutes()) {
s << minutes << " min ";
}
if (const int seconds = positive.seconds()) {
s << seconds << " s ";
}
if (!noMilliseconds) {
if (const int milliseconds = positive.milliseconds()) {
s << milliseconds << " ms ";
}
}
2015-04-22 18:36:40 +02:00
}
}
break;
}
result = s.str().substr(0, static_cast<string::size_type>(s.tellp()) - 1);
}