posts - 210, comments - 61, trackbacks - 0, articles - 0
   :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

#include <chrono>
#include <sstream>
#include <iomanip>

using namespace std;

constexpr int64_t SEC = 1000000;
constexpr int64_t MIN = SEC * 60;
constexpr int64_t HOUR = MIN * 60;
constexpr int64_t DAY = HOUR * 24;

// 返回当前时间作为 格林威治(GMT)时间 距离 GMT时间 1970-1-1 00:00:00 的微秒数
int64_t get_time_us()
{
    chrono::system_clock clock;
    return chrono::duration_cast<chrono::microseconds>(
        clock.now().time_since_epoch()).count();
}

// 返回当前时间作为 本地(北京)时间 距离 GMT时间 1970-1-1 00:00:00 的微秒数,等于get_gmtime_us加8小时
int64_t get_localtime_us()
{
    return get_time_us() + HOUR * 8;
}

// 格林威治时间的微秒数格式化成本地时间字符串
string gmtime2localstr(int64_t time_us, const string& fmt="%Y-%m-%d %H:%M:%S")
{
    stringstream ss;
    time_t t = time_us / SEC;
    auto tm = std::localtime(&t);
    ss << std::put_time(tm, fmt.c_str());
    return ss.str();
}

// 本地时间字符串解析成格林威治时间的微秒数
int64_t localstr2gmtime(const std::string& s, const std::string& fmt="%Y-%m-%d %H:%M:%S")
{
    stringstream ss;
    ss << s;
    struct tm tm;
    ss >> std::get_time(&tm, fmt.c_str());
    return (int64_t)mktime(&tm) * SEC;
}

// 字符串转微秒数,不考虑时区
std::string time2str(int64_t time_us, const std::string& fmt="%Y-%m-%d %H:%M:%S")
{
    stringstream ss;
    time_t t = time_us / SEC;
    auto tm = std::gmtime(&t);
    ss << std::put_time(tm, fmt.c_str());
    return ss.str();
}

// 微秒数转字符串,不考虑时区
int64_t str2time(const std::string& s, const std::string& fmt="%Y-%m-%d %H:%M:%S")
{
    stringstream ss;
    ss << s;
    struct tm tm;
    ss >> std::get_time(&tm, fmt.c_str());
    return (int64_t)mktime(&tm) * SEC + HOUR * 8; // 这里 + 8 HOURs是因为mktime内部考虑了时区,我期望有一个gmmktime函数,但是标准库似乎并没有
}
其实对于time_t或者说从格林尼治1970年1月1日0时的毫秒数来说,并不需要区分时区,全球都是同一个毫秒数只是在对应到有时间表示时才需要区分时区,
这里之所有引入get_localtime_us是为了方便时间计算,例如计算当前时间的下一个8点40的微秒数,如果任意天00:00对齐到 % DAY == 0这样会比较好算。
auto _08_40 = (HOUR * 8 + MIN * 40);
auto next_08_40 = ((time_us - _08_40) / DAY + 1) * DAY + _08_40;
只有注册用户登录后才能发表评论。