C++ 毫秒转日期 以及 日期转时间的类

简述

由于C标准库<ctime>(或者<time.h>)中,只支持1970年之后的日期。因此我自制了一个可以将日期转化为从公元1年1月1日0点0分0秒开始所经历的毫秒数,或者反过来将毫秒数转化为对应日期。

如有错漏,还望指摘。

类定义

class time_struct 
{
public:
    time_struct() = default;
    time_struct(long long ms, int base_year = 1);
    long long ms_past_since(int base_year = 1) const;
    std::string print() const;
    bool is_leap_year() const;
    bool check_validity() const;

private:
    long long ms_past_since_1() const;
    void set_time_by_ms(long long ms);

public:
    short int year       = 1;
    short int month      = 1;
    short int day        = 1;
    short int hour       = 0;
    short int minute     = 0;
    short int second     = 0;
    short int milisecond = 0;
};

毫秒数转日期

void time_struct::set_time_by_ms(long long ms)
{
    if (ms < 0)
        return;

    // milisecond
    milisecond = ms % 1000;
    ms /= 1000;
    // second
    second = ms % 60;
    ms /= 60;
    // minute
    minute = ms % 60;
    ms /= 60;
    // hour
    hour = ms % 24;
    ms /= 24;
    // How many 400 years are there
    year = (int)(ms / 146097) * 400;
    ms %= 146097;
    // How many 100 years are there
    // Since the last 100 years in a 400 years period
    // 
    int num100years = ms / 36524;
    if (num100years == 4)
    {
        --num100years;
        ms -= 36524 * 3;
    }
    else
    {
        ms %= 36524;
    }
    year += num100years * 100;

    year += (int)(ms / 1461) * 4;
    ms %= 1461;

    int num1years = ms / 365;
    if (num1years == 4)
    {
        --num1years;
        ms -= 365 * 3;
    }
    else
    {
        ms %= 365;
    }
    year += num1years + 1;

    if (ms < 31)
    {
        month = 1;
        day = ms + 1;
    }
    else
    {
        if (is_leap_year())
        {
            ms = ms - 31 + 2;
            month = (int)(ms * 12 / 367);
            day = ms - month * 367 / 12;
            day -= month ? 0 : 1;
        }
        else
        {
            ms = ms - 31 + 3;
            month = (int)(ms * 12 / 367);
            day = ms - month * 367 / 12;
            day -= month ? 0 : 2;
        }
        month += 2;
    }
}

以任意年为基准的毫秒数转日期

time_struct::time_struct(long long ms, int base_year)
{
    time_struct base;
    base.year = base_year;
    set_time_by_ms(ms + base.ms_past_since_1());
}

日期转毫秒数

long long time_struct::ms_past_since_1() const
{
    if (!check_validity())
    {
        // TODO: log
        // We assume LLONG_MIN is the error code
        return LLONG_MIN;
    }
    int temp_month = month - 2;
    int temp_year = year;
    if (0 >= temp_month) {    /* 1..12 -> 11,12,1..10 */
        temp_month += 12;      /* Puts Feb last since it has leap day */
        temp_year -= 1;
    }

    long long days = (long long)(temp_year / 4 - temp_year / 100 + temp_year / 400 + 367 * temp_month / 12 + day)
        + temp_year * 365 - 337;

    return ((((
        (long long)(temp_year / 4 - temp_year / 100 + temp_year / 400 + 367 * temp_month / 12 + day)
        + temp_year * 365 - 337
        ) * 24 + hour        /* now have hours */
        ) * 60 + minute      /* now have minutes */
        ) * 60 + second      /* now have seconds */
        ) * 1000 + milisecond; /* millisecond */
}

日期转以任意年为基准的毫秒数

long long time_struct::ms_past_since(int base_year) const
{
    time_struct base;
    base.year = base_year;
    return this->ms_past_since_1() - base.ms_past_since_1();
}

检测是否是闰年

bool time_struct::is_leap_year() const
{
    return ((year % 4) || (!(year % 100) && (year % 400))) ? false : true;
}

检测日期有效性

bool time_struct::check_validity() const
{
    if (year < 1)
        return false;
    if (day < 1)
        return false;
    switch (month)
    {
    case 1:
    case 3:
    case 5:
    case 7:
    case 8:
    case 10:
    case 12:
        if (day > 31)
            return false;
        else
            break;
    case 4:
    case 6:
    case 9:
    case 11:
        if (day > 30)
            return false;
        else
            break;
    case 2:
        if (day > (is_leap_year() ? 29 : 28))
            return false;
        else
            break;
    default:
        return false;
    }
    if (hour < 0 || hour > 23)
        return false;
    if (minute < 0 || minute > 59)
        return false;
    if (second < 0 || second > 59)
        return false;
    if (milisecond < 0 || milisecond > 999)
        return false;

    return true;
}

打印日期

string time_struct::print() const
{
    char buff[28];
    sprintf_s(
        buff,
        "%04d-%02d-%02d %02d:%02d:%02d:%03d",
        year,
        month,
        day,
        hour,
        minute,
        second,
        milisecond
    );
    return buff;
}
  • 6
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值