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
|
|
|
|
|
|
2020-05-01 18:49:36 +08:00
|
|
|
|
#ifndef NOMINMAX
|
|
|
|
|
#define NOMINMAX
|
|
|
|
|
#endif
|
|
|
|
|
|
2019-12-15 01:25:00 +08:00
|
|
|
|
#include <cstdint>
|
2019-12-16 02:09:43 +08:00
|
|
|
|
#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>
|
2019-12-22 03:02:35 +08:00
|
|
|
|
* 1、总时长范围:TimeDetla(-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]
|
2019-12-22 03:02:35 +08:00
|
|
|
|
* @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
|
|
|
|
*/
|
2020-05-01 18:49:36 +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
|
|
|
|
|
2019-12-16 02:09:43 +08:00
|
|
|
|
/** 通过 boost::posix_time::time_duration 构造 */
|
2019-12-15 01:25:00 +08:00
|
|
|
|
explicit TimeDelta(bt::time_duration td);
|
|
|
|
|
|
2019-12-16 02:09:43 +08:00
|
|
|
|
/** 赋值构造函数 */
|
|
|
|
|
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
|
|
|
|
|
2019-12-16 02:09:43 +08:00
|
|
|
|
/** 获取规范化后的小时数 [0, 23] */
|
2019-12-18 02:04:54 +08:00
|
|
|
|
int64_t hours() const;
|
2019-12-15 01:25:00 +08:00
|
|
|
|
|
2019-12-16 02:09:43 +08:00
|
|
|
|
/** 获取规范化后的分钟数 [0, 59] */
|
2019-12-18 02:04:54 +08:00
|
|
|
|
int64_t minutes() const;
|
2019-12-15 01:25:00 +08:00
|
|
|
|
|
2019-12-16 02:09:43 +08:00
|
|
|
|
/** 获取规范化后的秒数 [0, 59] */
|
2019-12-18 02:04:54 +08:00
|
|
|
|
int64_t seconds() const;
|
2019-12-15 01:25:00 +08:00
|
|
|
|
|
2019-12-16 02:09:43 +08:00
|
|
|
|
/** 获取规范化后的毫秒数 [0, 999] */
|
2019-12-18 02:04:54 +08:00
|
|
|
|
int64_t milliseconds() const;
|
2019-12-15 01:25:00 +08:00
|
|
|
|
|
2019-12-16 02:09:43 +08:00
|
|
|
|
/** 获取规范化后的微秒数 [0, 999] */
|
2019-12-18 02:04:54 +08:00
|
|
|
|
int64_t microseconds() const;
|
2019-12-15 01:25:00 +08:00
|
|
|
|
|
2019-12-16 02:09:43 +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-16 02:09:43 +08:00
|
|
|
|
/** 是否为负时长 */
|
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()));
|
|
|
|
|
}
|
|
|
|
|
|
2019-12-16 02:09:43 +08:00
|
|
|
|
/** 转换为 boost::posix_time::time_duration */
|
2019-12-15 01:25:00 +08:00
|
|
|
|
bt::time_duration time_duration() const {
|
|
|
|
|
return m_duration;
|
|
|
|
|
}
|
|
|
|
|
|
2019-12-16 02:09:43 +08:00
|
|
|
|
/** 转换为字符串,格式:-1 days hh:mm:ss.000000) */
|
|
|
|
|
std::string str() const {
|
2019-12-22 03:02:35 +08:00
|
|
|
|
return fmt::format("{} days, {:>02d}:{:>02d}:{:<2.6f}", days(), hours(), minutes(),
|
|
|
|
|
seconds() + double(milliseconds() * 1000 + microseconds()) * 0.000001);
|
2019-12-16 02:09:43 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** 转换为字符串,格式为:TimeDelta(days,hours,mins,secs,millisecs,microsecs) */
|
|
|
|
|
std::string repr() const {
|
2020-05-01 18:49:36 +08:00
|
|
|
|
return fmt::format("TimeDelta({}, {}, {}, {}, {}, {})", days(), hours(), minutes(),
|
|
|
|
|
seconds(), milliseconds(), microseconds());
|
2019-12-16 02:09:43 +08:00
|
|
|
|
}
|
|
|
|
|
|
2019-12-23 02:18:04 +08:00
|
|
|
|
/////////////////////////////////////////////////////////////////
|
2019-12-16 02:09:43 +08:00
|
|
|
|
//
|
2019-12-24 02:15:37 +08:00
|
|
|
|
// 运算符重载,TimeDelta 相关运算
|
2019-12-16 02:09:43 +08:00
|
|
|
|
//
|
2019-12-23 02:18:04 +08:00
|
|
|
|
/////////////////////////////////////////////////////////////////
|
2019-12-16 02:09:43 +08:00
|
|
|
|
|
2019-12-23 02:18:04 +08:00
|
|
|
|
/** 两个时长相加 */
|
2019-12-24 02:15:37 +08:00
|
|
|
|
TimeDelta operator+(TimeDelta td) const {
|
|
|
|
|
return TimeDelta(td.m_duration + m_duration);
|
|
|
|
|
}
|
2019-12-16 02:09:43 +08:00
|
|
|
|
|
2019-12-23 02:18:04 +08:00
|
|
|
|
/** 两个时长相减 */
|
2019-12-24 02:15:37 +08:00
|
|
|
|
TimeDelta operator-(TimeDelta td) const {
|
|
|
|
|
return TimeDelta(m_duration - td.m_duration);
|
|
|
|
|
}
|
2019-12-23 02:18:04 +08:00
|
|
|
|
|
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
|
|
|
|
/** 时长乘以系数,结果四舍五入 */
|
2019-12-23 02:18:04 +08:00
|
|
|
|
TimeDelta operator*(double p) const;
|
|
|
|
|
|
2019-12-26 01:12:40 +08:00
|
|
|
|
/**
|
|
|
|
|
* 时长除以系数,结果四舍五入。如果除零,将抛出 hku::exception。
|
|
|
|
|
* 如果不希望四舍五入,请使用 floorDiv
|
|
|
|
|
*/
|
2019-12-23 02:18:04 +08:00
|
|
|
|
TimeDelta operator/(double p) const;
|
|
|
|
|
|
2019-12-24 02:15:37 +08:00
|
|
|
|
/** 两个时长相除,求两者比例。如果除以零时长,将抛出 hku::exception。 */
|
2019-12-23 02:18:04 +08:00
|
|
|
|
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。 */
|
2019-12-23 02:18:04 +08:00
|
|
|
|
TimeDelta operator%(TimeDelta td) const;
|
2019-12-16 02:09:43 +08:00
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|
2019-12-16 02:09:43 +08:00
|
|
|
|
bool operator<=(TimeDelta td) const {
|
|
|
|
|
return m_duration <= td.m_duration;
|
|
|
|
|
}
|
|
|
|
|
|
2019-12-23 02:18:04 +08:00
|
|
|
|
/////////////////////////////////////////////////////////////////
|
2019-12-16 02:09:43 +08:00
|
|
|
|
//
|
|
|
|
|
// 静态成员函数
|
|
|
|
|
//
|
2019-12-23 02:18:04 +08:00
|
|
|
|
/////////////////////////////////////////////////////////////////
|
2019-12-16 02:09:43 +08:00
|
|
|
|
|
|
|
|
|
/** 获取能够表达的最小值 TimeDelta(-99999999) */
|
2019-12-15 01:25:00 +08:00
|
|
|
|
static TimeDelta min() {
|
|
|
|
|
return TimeDelta(-99999999);
|
|
|
|
|
}
|
|
|
|
|
|
2019-12-16 02:09:43 +08:00
|
|
|
|
/** 获取能够表达的最大值 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;
|
|
|
|
|
}
|
|
|
|
|
|
2019-12-16 02:09:43 +08:00
|
|
|
|
/** 获取表达精度 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;
|
|
|
|
|
|
2019-12-16 02:09:43 +08:00
|
|
|
|
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-16 02:09:43 +08:00
|
|
|
|
};
|
|
|
|
|
|
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) {
|
2019-12-22 03:02:35 +08:00
|
|
|
|
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-16 02:09:43 +08:00
|
|
|
|
|
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-16 02:09:43 +08:00
|
|
|
|
|
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-16 02:09:43 +08:00
|
|
|
|
|
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-16 02:09:43 +08:00
|
|
|
|
|
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 */
|