hikyuu2/hikyuu_cpp/hikyuu/datetime/TimeDelta.h

312 lines
8.4 KiB
C++
Raw Normal View History

2019-12-15 01:25:00 +08:00
/*
* TimeDelta.h
*
* Copyright(C) 2019, hikyuu.org
*
* Created on: 2019-12-12
* Author: fasiondog
*/
#pragma once
#ifndef HIKYUU_DATETIME_TIMEDELTA_H
#define HIKYUU_DATETIME_TIMEDELTA_H
#ifndef NOMINMAX
#define NOMINMAX
#endif
2019-12-15 01:25:00 +08:00
#include <cstdint>
#include <fmt/format.h>
2019-12-15 01:25:00 +08:00
#include <boost/date_time/posix_time/posix_time.hpp>
#ifndef HKU_API
#define HKU_API
#endif
namespace hku {
namespace bt = boost::posix_time;
namespace bd = boost::gregorian;
/**
2019-12-17 02:31:44 +08:00
*
2019-12-15 01:25:00 +08:00
* @ingroup DataType
*/
class HKU_API TimeDelta {
public:
/**
*
2019-12-17 02:31:44 +08:00
* @note
* <pre>
* 1TimeDetla(-99999999) - TimeDelta(99999999, 23, 59, 59, 999, 999)
2019-12-17 02:31:44 +08:00
* 2 boost::posix_time::time_duration time_duration
* TimeDelta ticks数之和
2019-12-18 02:04:54 +08:00
* 3 days() hours() ... python
* datetime.timedelta
2019-12-17 02:31:44 +08:00
* </pre>
2019-12-15 01:25:00 +08:00
* @param days [-99999999, 99999999]
* @param hours [-100000, 100000]
* @param minutes [-100000, 100000]
* @param seconds [-8639900, 8639900])
* @param milliseconds [-86399000000, 86399000000])
* @param microseconds [-86399000000, 86399000000])
2019-12-15 01:25:00 +08:00
*/
explicit TimeDelta(int64_t days = 0, int64_t hours = 0, int64_t minutes = 0,
int64_t seconds = 0, int64_t milliseconds = 0, int64_t microseconds = 0);
2019-12-15 01:25:00 +08:00
/** 通过 boost::posix_time::time_duration 构造 */
2019-12-15 01:25:00 +08:00
explicit TimeDelta(bt::time_duration td);
/** 赋值构造函数 */
TimeDelta(const TimeDelta&) = default;
/** 赋值拷贝函数 */
TimeDelta& operator=(const TimeDelta& other) {
if (this != &other) {
m_duration = other.m_duration;
}
return *this;
}
/** 获取规范化后的天数 */
2019-12-18 02:04:54 +08:00
int64_t days() const;
2019-12-15 01:25:00 +08:00
/** 获取规范化后的小时数 [0, 23] */
2019-12-18 02:04:54 +08:00
int64_t hours() const;
2019-12-15 01:25:00 +08:00
/** 获取规范化后的分钟数 [0, 59] */
2019-12-18 02:04:54 +08:00
int64_t minutes() const;
2019-12-15 01:25:00 +08:00
/** 获取规范化后的秒数 [0, 59] */
2019-12-18 02:04:54 +08:00
int64_t seconds() const;
2019-12-15 01:25:00 +08:00
/** 获取规范化后的毫秒数 [0, 999] */
2019-12-18 02:04:54 +08:00
int64_t milliseconds() const;
2019-12-15 01:25:00 +08:00
/** 获取规范化后的微秒数 [0, 999] */
2019-12-18 02:04:54 +08:00
int64_t microseconds() const;
2019-12-15 01:25:00 +08:00
/** 获取 tick 数,即转换为微秒后的总微秒数 */
2019-12-15 01:25:00 +08:00
int64_t ticks() const {
return m_duration.ticks();
}
2019-12-26 01:12:40 +08:00
/** 返回带小数的总天数 */
double total_days() const {
return double(ticks()) / 86400000000.0;
}
/** 返回带小数的总小时数 */
double total_hours() const {
return double(ticks()) / 3600000000.0;
}
/** 返回带小数的总分钟数 */
double total_minutes() const {
return double(ticks()) / 60000000.0;
}
/** 返回带小数的总秒数 */
double total_seconds() const {
return double(ticks()) / 1000000.0;
}
/** 返回带小数的总毫秒数 */
double total_milliseconds() const {
return double(ticks()) / 1000.0;
}
/** 是否为负时长 */
2019-12-15 01:25:00 +08:00
bool isNegative() const {
return m_duration.is_negative();
}
2019-12-25 02:45:24 +08:00
/** 求绝对值 */
TimeDelta abs() const {
return TimeDelta::fromTicks(std::abs(ticks()));
}
/** 转换为 boost::posix_time::time_duration */
2019-12-15 01:25:00 +08:00
bt::time_duration time_duration() const {
return m_duration;
}
/** 转换为字符串,格式:-1 days hh:mm:ss.000000) */
std::string str() const {
return fmt::format("{} days, {:>02d}:{:>02d}:{:<2.6f}", days(), hours(), minutes(),
seconds() + double(milliseconds() * 1000 + microseconds()) * 0.000001);
}
/** 转换为字符串格式为TimeDelta(days,hours,mins,secs,millisecs,microsecs) */
std::string repr() const {
return fmt::format("TimeDelta({}, {}, {}, {}, {}, {})", days(), hours(), minutes(),
seconds(), milliseconds(), microseconds());
}
/////////////////////////////////////////////////////////////////
//
2019-12-24 02:15:37 +08:00
// 运算符重载TimeDelta 相关运算
//
/////////////////////////////////////////////////////////////////
/** 两个时长相加 */
2019-12-24 02:15:37 +08:00
TimeDelta operator+(TimeDelta td) const {
return TimeDelta(td.m_duration + m_duration);
}
/** 两个时长相减 */
2019-12-24 02:15:37 +08:00
TimeDelta operator-(TimeDelta td) const {
return TimeDelta(m_duration - td.m_duration);
}
2019-12-25 02:45:24 +08:00
/** + 号,返回相同值 */
TimeDelta operator+() const {
return *this;
}
/** - 号, 求负值,相当于 TimeDelta(0) 减自身 */
TimeDelta operator-() const {
return TimeDelta::fromTicks(-ticks());
}
2019-12-24 02:15:37 +08:00
/** 时长乘以系数,结果四舍五入 */
TimeDelta operator*(double p) const;
2019-12-26 01:12:40 +08:00
/**
* hku::exception
* 使 floorDiv
*/
TimeDelta operator/(double p) const;
2019-12-24 02:15:37 +08:00
/** 两个时长相除,求两者比例。如果除以零时长,将抛出 hku::exception。 */
double operator/(TimeDelta td) const;
2019-12-26 01:12:40 +08:00
/** 地板除,小数点后直接截断 */
TimeDelta floorDiv(double p) const;
2019-12-24 02:15:37 +08:00
/** 两个时长相除求余。如果除以零时长,将抛出 hku::exception。 */
TimeDelta operator%(TimeDelta td) const;
bool operator==(TimeDelta td) const {
return m_duration == td.m_duration;
}
bool operator!=(TimeDelta td) const {
return m_duration != td.m_duration;
}
bool operator>(TimeDelta td) const {
return m_duration > td.m_duration;
}
bool operator<(TimeDelta td) const {
return m_duration < td.m_duration;
}
bool operator>=(TimeDelta td) const {
return m_duration >= td.m_duration;
}
2019-12-15 01:25:00 +08:00
bool operator<=(TimeDelta td) const {
return m_duration <= td.m_duration;
}
/////////////////////////////////////////////////////////////////
//
// 静态成员函数
//
/////////////////////////////////////////////////////////////////
/** 获取能够表达的最小值 TimeDelta(-99999999) */
2019-12-15 01:25:00 +08:00
static TimeDelta min() {
return TimeDelta(-99999999);
}
/** 获取能够表达的最大值 TimeDelta(99999999, 23, 59, 59, 999, 999) */
2019-12-15 01:25:00 +08:00
static TimeDelta max() {
return TimeDelta(99999999, 23, 59, 59, 999, 999);
}
2019-12-21 03:01:33 +08:00
/** 支持的最大 tick 数 */
static int64_t maxTicks() {
return m_max_micro_seconds;
}
/** 支持的最小 tick 数 */
static int64_t minTicks() {
return m_min_micro_seconds;
}
/** 获取表达精度 1 微秒, TimeDelta(0, 0, 0, 0, 0, 1) */
2019-12-15 01:25:00 +08:00
static TimeDelta resolution() {
return TimeDelta(0, 0, 0, 0, 0, 1);
}
2019-12-21 03:01:33 +08:00
/** 从 ticks 创建 */
static TimeDelta fromTicks(int64_t ticks);
2019-12-15 01:25:00 +08:00
private:
bt::time_duration m_duration;
static constexpr const int64_t m_max_micro_seconds = 100000000LL * 24 * 60 * 60 * 1000000 - 1;
static constexpr const int64_t m_min_micro_seconds = -99999999LL * 24 * 60 * 60 * 1000000;
2019-12-17 02:31:44 +08:00
static constexpr const int64_t m_one_day_ticks = 24 * 60 * 60 * 1000000LL;
};
2019-12-17 02:31:44 +08:00
std::ostream& operator<<(std::ostream& out, TimeDelta td);
inline std::ostream& operator<<(std::ostream& out, TimeDelta td) {
out << td.str();
2019-12-17 02:31:44 +08:00
return out;
}
2019-12-19 02:32:06 +08:00
/**
* TimeDelta
* @param days [-99999999, 99999999]
* @ingroup DataType
*/
TimeDelta Days(int64_t days);
inline TimeDelta Days(int64_t days) {
return TimeDelta(days);
}
2019-12-19 02:32:06 +08:00
/**
* TimeDelta
* @param hours
* @ingroup DataType
*/
2019-12-21 03:01:33 +08:00
TimeDelta HKU_API Hours(int64_t hours);
2019-12-19 02:32:06 +08:00
/**
* TimeDelta
* @param mins
* @ingroup DataType
*/
2019-12-21 03:01:33 +08:00
TimeDelta HKU_API Minutes(int64_t mins);
2019-12-19 02:32:06 +08:00
/**
* TimeDelta
* @param secs
* @ingroup DataType
*/
2019-12-21 03:01:33 +08:00
TimeDelta HKU_API Seconds(int64_t secs);
2019-12-19 02:32:06 +08:00
/**
* TimeDelta
2019-12-21 03:01:33 +08:00
* @param milliseconds
2019-12-19 02:32:06 +08:00
* @ingroup DataType
*/
2019-12-21 03:01:33 +08:00
TimeDelta HKU_API Milliseconds(int64_t milliseconds);
2019-12-15 01:25:00 +08:00
2019-12-19 02:32:06 +08:00
/**
* TimeDelta
* @param microsecs
* @ingroup DataType
*/
TimeDelta Microseconds(int64_t microsecs);
inline TimeDelta Microseconds(int64_t microsecs) {
2019-12-21 03:01:33 +08:00
return TimeDelta::fromTicks(microsecs);
2019-12-19 02:32:06 +08:00
}
2019-12-15 01:25:00 +08:00
} /* namespace hku */
#endif /* HIKYUU_DATETIME_TIMEDELTA_H */