add: Duration::Parse to format a duration

This commit is contained in:
Haibo 2018-10-29 13:36:09 +08:00 committed by Nomango
parent 02e418d0e2
commit fe70a520b1
2 changed files with 99 additions and 4 deletions

View File

@ -342,6 +342,8 @@ namespace easy2d
// 5 Ãë: Duration::Second * 5
// 1.5 Сʱ: Duration::Hour * 1.5
// 3 Сʱ 45 ·Ö 15 Ãë: Duration::Hour * 3 + Duration::Minute * 45 + Duration::Second * 15
// 时间段转化为秒: float s = duration.Seconds();
// 时间段格式化: Duration d = Duration::Parse(L"1h35m"); // 1小时35分钟
//
class Duration
{
@ -358,18 +360,24 @@ namespace easy2d
int milliseconds
);
// 获取毫秒数
// 转化为毫秒
int Milliseconds() const;
// 获取秒数
// 转化为秒
float Seconds() const;
// 获取分钟数
// 转化为分钟
float Minutes() const;
// 获取小时数
// 转化为小时
float Hours() const;
// 时间段格式化
// 时间段字符串允许是有符号的浮点数, 并且带有时间单位后缀
// 例如: "300ms", "-1.5h", "2h45m"
// 允许的时间单位有 "ms", "s", "m", "h"
static Duration Parse(const std::wstring& str);
bool operator== (const Duration &) const;
bool operator!= (const Duration &) const;
bool operator> (const Duration &) const;
@ -379,6 +387,7 @@ namespace easy2d
Duration operator + (Duration const &) const;
Duration operator - (Duration const &) const;
Duration operator - () const;
Duration operator * (int) const;
Duration operator * (float) const;
Duration operator * (double) const;

View File

@ -19,6 +19,7 @@
// THE SOFTWARE.
#include "..\e2dutil.h"
#include <regex>
const easy2d::Duration easy2d::Duration::Millisecond = easy2d::Duration(1);
@ -62,6 +63,85 @@ float easy2d::Duration::Hours() const
return static_cast<float>(hour) + static_cast<float>(ms) / (60 * 60 * 1000.f);
}
easy2d::Duration easy2d::Duration::Parse(const std::wstring & str)
{
typedef std::map<std::wstring, Duration> UnitMap;
static const auto regex = std::wregex(L"[-+]?([0-9]*(\\.[0-9]*)?[a-z]+)+");
static const auto unit_map = UnitMap{{L"ms", Millisecond}, {L"s", Second}, {L"m", Minute}, {L"h", Hour}};
size_t len = str.length();
size_t pos = 0;
bool negative = false;
Duration d;
if (!std::regex_match(str, regex))
{
E2D_WARNING("Duration::Parse: invalid duration");
return std::move(Duration{});
}
if (str.empty() || str == L"0") { return std::move(Duration{}); }
// ·ûºÅλ
if (str[0] == L'-' || str[0] == L'+')
{
negative = (str[0] == L'-');
pos++;
}
while (pos < len)
{
// ÊýÖµ
size_t i = pos;
for (; i < len; ++i)
{
wchar_t ch = str[i];
if (!(ch == L'.' || L'0' <= ch && ch <= L'9'))
{
break;
}
}
std::wstring num_str = str.substr(pos, i - pos);
pos = i;
if (num_str.empty() || num_str == L".")
{
E2D_WARNING("Duration::Parse: invalid duration");
return std::move(Duration{});
}
// µ¥Î»
for (; i < len; ++i)
{
wchar_t ch = str[i];
if (ch == L'.' || L'0' <= ch && ch <= L'9')
{
break;
}
}
std::wstring unit_str = str.substr(pos, i - pos);
pos = i;
if (unit_map.find(unit_str) == unit_map.end())
{
E2D_WARNING("Duration::Parse: invalid duration");
return std::move(Duration{});
}
double num = std::stod(num_str);
Duration unit = unit_map.at(unit_str);
d += unit * num;
}
if (negative)
{
d.milliseconds_ = -d.milliseconds_;
}
return std::move(d);
}
bool easy2d::Duration::operator==(const Duration & other) const
{
return milliseconds_ == other.milliseconds_;
@ -104,6 +184,12 @@ easy2d::Duration easy2d::Duration::operator-(Duration const & other) const
return std::move(d);
}
easy2d::Duration easy2d::Duration::operator-() const
{
Duration d(-milliseconds_);
return std::move(d);
}
easy2d::Duration easy2d::Duration::operator*(int value) const
{
Duration d(milliseconds_ * value);