mirror of
https://gitee.com/fasiondog/hikyuu.git
synced 2024-12-03 04:17:58 +08:00
175 lines
5.8 KiB
C++
175 lines
5.8 KiB
C++
/*
|
|
* TimeDelta.h
|
|
*
|
|
* Copyright(C) 2019, hikyuu.org
|
|
*
|
|
* Created on: 2019-12-12
|
|
* Author: fasiondog
|
|
*/
|
|
|
|
#include <cstdint>
|
|
#include "TimeDelta.h"
|
|
#include "../Log.h"
|
|
#include "../utilities/util.h"
|
|
|
|
namespace hku {
|
|
|
|
TimeDelta::TimeDelta(int64_t days, int64_t hours, int64_t minutes, int64_t seconds,
|
|
int64_t milliseconds, int64_t microseconds) {
|
|
// 各参数添加限制,防止出现总和溢出的情况
|
|
HKU_CHECK(days <= 99999999 && days >= -99999999, "Out of range! Input days: {}", days);
|
|
HKU_CHECK(hours >= -100000 && hours <= 100000, "Out of range! Input hours: {}", hours);
|
|
HKU_CHECK(minutes >= -100000 && minutes <= 100000, "Out of range! Input minutes: {}", minutes);
|
|
HKU_CHECK(seconds >= -8639900 && seconds <= 8639900, "Out of range! Input seconds: {}",
|
|
seconds);
|
|
HKU_CHECK(milliseconds >= -86399000000 && milliseconds <= 86399000000,
|
|
"Out of range! Input milliseconds: {}", milliseconds);
|
|
HKU_CHECK(microseconds >= -86399000000 && microseconds <= 86399000000,
|
|
"Out of range! Input microseconds: {}", microseconds);
|
|
int64_t total =
|
|
((((days * 24 + hours) * 60 + minutes) * 60 + seconds) * 1000 + milliseconds) * 1000 +
|
|
microseconds;
|
|
HKU_CHECK(total >= m_min_micro_seconds && total <= m_max_micro_seconds, "Out of total range!");
|
|
m_duration = bt::time_duration(0, 0, 0, total);
|
|
}
|
|
|
|
TimeDelta::TimeDelta(bt::time_duration td) {
|
|
int64_t total = td.total_microseconds();
|
|
HKU_CHECK(total >= m_min_micro_seconds && total <= m_max_micro_seconds, "Out of total range!");
|
|
m_duration = td;
|
|
}
|
|
|
|
TimeDelta TimeDelta::fromTicks(int64_t ticks) {
|
|
HKU_CHECK(ticks >= m_min_micro_seconds && ticks <= m_max_micro_seconds, "Out of total range!");
|
|
return TimeDelta(bt::time_duration(0, 0, 0, ticks));
|
|
}
|
|
|
|
int64_t TimeDelta::days() const {
|
|
if (isNegative()) {
|
|
if (ticks() % m_one_day_ticks == 0) {
|
|
return ticks() / m_one_day_ticks;
|
|
} else {
|
|
return ticks() / m_one_day_ticks - 1;
|
|
}
|
|
}
|
|
return std::abs(m_duration.hours() / 24);
|
|
}
|
|
|
|
int64_t TimeDelta::hours() const {
|
|
if (isNegative()) {
|
|
if (ticks() % m_one_day_ticks == 0) {
|
|
return 0;
|
|
} else {
|
|
int64_t pos_ticks =
|
|
std::abs((ticks() / m_one_day_ticks - 1) * m_one_day_ticks) + ticks();
|
|
return bt::time_duration(0, 0, 0, pos_ticks).hours();
|
|
}
|
|
}
|
|
return std::abs(m_duration.hours()) % 24;
|
|
}
|
|
|
|
int64_t TimeDelta::minutes() const {
|
|
if (isNegative()) {
|
|
if (ticks() % m_one_day_ticks == 0) {
|
|
return 0;
|
|
} else {
|
|
int64_t pos_ticks =
|
|
std::abs((ticks() / m_one_day_ticks - 1) * m_one_day_ticks) + ticks();
|
|
return bt::time_duration(0, 0, 0, pos_ticks).minutes();
|
|
}
|
|
}
|
|
return std::abs(m_duration.minutes());
|
|
}
|
|
|
|
int64_t TimeDelta::seconds() const {
|
|
if (isNegative()) {
|
|
if (ticks() % m_one_day_ticks == 0) {
|
|
return 0;
|
|
} else {
|
|
int64_t pos_ticks =
|
|
std::abs((ticks() / m_one_day_ticks - 1) * m_one_day_ticks) + ticks();
|
|
return bt::time_duration(0, 0, 0, pos_ticks).seconds();
|
|
}
|
|
}
|
|
return std::abs(m_duration.seconds());
|
|
}
|
|
|
|
int64_t TimeDelta::milliseconds() const {
|
|
if (isNegative()) {
|
|
if (ticks() % m_one_day_ticks == 0) {
|
|
return 0;
|
|
} else {
|
|
int64_t pos_ticks =
|
|
std::abs((ticks() / m_one_day_ticks - 1) * m_one_day_ticks) + ticks();
|
|
int64_t milli = pos_ticks % 1000000;
|
|
return milli == 0 ? 0 : (milli - microseconds()) / 1000;
|
|
}
|
|
}
|
|
return (std::abs(ticks()) % 1000000 - microseconds()) / 1000;
|
|
}
|
|
|
|
int64_t TimeDelta::microseconds() const {
|
|
if (isNegative()) {
|
|
if (ticks() % m_one_day_ticks == 0) {
|
|
return 0;
|
|
} else {
|
|
int64_t micro = ticks() % 1000;
|
|
return micro == 0 ? micro : 1000 + micro;
|
|
}
|
|
}
|
|
return std::abs(ticks() % 1000);
|
|
}
|
|
|
|
TimeDelta HKU_API Hours(int64_t hours) {
|
|
HKU_CHECK(hours >= TimeDelta::minTicks() / 3600000000LL &&
|
|
hours <= TimeDelta::maxTicks() / 3600000000LL,
|
|
"Out of total range!");
|
|
return TimeDelta::fromTicks(hours * 3600000000LL);
|
|
}
|
|
|
|
TimeDelta HKU_API Minutes(int64_t mins) {
|
|
HKU_CHECK(
|
|
mins >= TimeDelta::minTicks() / 60000000LL && mins <= TimeDelta::maxTicks() / 60000000LL,
|
|
"Out of total range!");
|
|
return TimeDelta::fromTicks(mins * 60000000LL);
|
|
}
|
|
|
|
TimeDelta HKU_API Seconds(int64_t secs) {
|
|
HKU_CHECK(
|
|
secs >= TimeDelta::minTicks() / 1000000LL && secs <= TimeDelta::maxTicks() / 1000000LL,
|
|
"Out of total range!");
|
|
return TimeDelta::fromTicks(secs * 1000000LL);
|
|
}
|
|
|
|
TimeDelta HKU_API Milliseconds(int64_t milliseconds) {
|
|
HKU_CHECK(milliseconds >= TimeDelta::minTicks() / 1000LL &&
|
|
milliseconds <= TimeDelta::maxTicks() / 1000LL,
|
|
"Out of total range!");
|
|
return TimeDelta::fromTicks(milliseconds * 1000LL);
|
|
}
|
|
|
|
TimeDelta TimeDelta::operator*(double p) const {
|
|
return TimeDelta::fromTicks(static_cast<int64_t>(roundEx(double(ticks()) * p, 0)));
|
|
}
|
|
|
|
TimeDelta TimeDelta::operator/(double p) const {
|
|
HKU_CHECK(p != 0, "Attempt to divide by 0!");
|
|
return TimeDelta::fromTicks(static_cast<int64_t>(roundEx(double(ticks()) / p, 0)));
|
|
}
|
|
|
|
TimeDelta TimeDelta::floorDiv(double p) const {
|
|
HKU_CHECK(p != 0, "Attempt to divide by 0!");
|
|
return TimeDelta::fromTicks(static_cast<int64_t>(double(ticks()) / p));
|
|
}
|
|
|
|
double TimeDelta::operator/(TimeDelta td) const {
|
|
HKU_CHECK(td.ticks() != 0, "Attemp to divide by zero TimeDelta!");
|
|
return double(ticks()) / double(td.ticks());
|
|
}
|
|
|
|
TimeDelta TimeDelta::operator%(TimeDelta td) const {
|
|
HKU_CHECK(td.ticks() != 0, "Attemp to divide(mod) by zero TimeDelta!");
|
|
return TimeDelta::fromTicks(ticks() % td.ticks());
|
|
}
|
|
|
|
} /* namespace hku */ |