C++时间转换

#include
#include
#include
#include
#include
#include "boost/date_time.hpp"
using namespace std;

namespace {
    std::string StringFormat(const char* format, ...) {
        va_list ap;
        va_start(ap, format);
        // Returns the number of characters in the formatted string using a pointer to a list of arguments.
        size_t size = _vscprintf(format, ap) + 1;
        char* buf = new char[size];
        memset(buf, 0, size);
        vsprintf_s(buf, size, format, ap);
        std::string str_tmp(buf);
        delete[] buf;
        buf = nullptr;
        return str_tmp;
    }
}

// 获取本地时差
int32_t GetLocalDif(const time_t t) {

    int32_t t_dif = 0;  // 单位秒

    //time_t t = time(nullptr);
    tm tm_local = { 0 };
    localtime_s(&tm_local, &t);
    tm tm_gm = { 0 };
    gmtime_s(&tm_gm, &t);
    time_t t_gm = mktime(&tm_gm);
    tm_local.tm_isdst = 0;
    time_t t_local_not_dst = mktime(&tm_local);
    t_dif = int32_t(t_local_not_dst - t_gm);

    return t_dif;
}

string CreateTimeDif(const int32_t t_dif ) {
    int32_t h = abs(t_dif / 3600);
    int32_t m = abs(((t_dif % 3600) / 60));

    char dif_buf[16] = { 0 };
    //snprintf(dif_buf, sizeof(16), "%02d:%02d", h, m); // error
    string str_dif =  StringFormat("%02d:%02d", h, m);

    string str_symbol = t_dif >= 0 ? "+" : "-";
    str_dif = str_symbol + str_dif;

    return str_dif;
}

bool TimetToLocal(string& str_local, int32_t& t_dif, const time_t t) {
    tm tm_local = { 0 };
    localtime_s(&tm_local, &t);
    char time_buf[32] = { 0 };
    strftime(time_buf, sizeof(time_buf), "%Y-%m-%d %H:%M:%S", &tm_local);

    str_local = time_buf;
    t_dif = GetLocalDif(t);
    return true;
}

time_t LocalToTimet(const string& str_local, const int32_t t_dif) {

    tm t_m = { 0 };
    if (sscanf_s(str_local.c_str(), "%d-%d-%d %d:%d:%d",
        &t_m.tm_year,
        &t_m.tm_mon,
        &t_m.tm_mday,
        &t_m.tm_hour,
        &t_m.tm_min,
        &t_m.tm_sec) <= 0) {
        return -1;  // 时间格式不正确
    }

    t_m.tm_year -= 1900;
    t_m.tm_mon -= 1;
    t_m.tm_isdst = 0;

    // 当作系统本地时间进行转换,但是具体的时差需要根据传入的来计算!!!
    time_t t_local = mktime(&t_m);

    time_t t = t_local + GetLocalDif(t_local) - t_dif;

    return t;
}

string  TimetToISO(const time_t t) {

    tm tm_local = { 0 };
    localtime_s(&tm_local, &t);
    char time_buf[32] = { 0 };
    strftime(time_buf, sizeof(time_buf), "%Y-%m-%dT%H:%M:%S", &tm_local);

    string str_local = time_buf;
    int32_t t_dif = GetLocalDif(t);
    string str_dif = CreateTimeDif(t_dif);

    string str_iso = str_local + str_dif;
    return str_iso;
}

/**
* str_iso:2023.11.20T08:00:00+08:00
*/
time_t ISOToTimet(const string& str_iso) {
    string local;
    int32_t t_dif = 0;

    size_t pos_symbol = str_iso.find_last_of("+-");
    if (string::npos == pos_symbol) {
        time_t t_local = time(nullptr);
        t_dif = GetLocalDif(t_local);
        local = str_iso;
    }
    else
    {
        local = str_iso.substr(0, pos_symbol);

        size_t pos_colon = str_iso.find(":", pos_symbol);
        if (string::npos == pos_colon)
        {
            time_t t_local = time(nullptr);
            t_dif = GetLocalDif(t_local);
        }
        else
        {
            string str_symbol = str_iso.substr(pos_symbol, 1);
            string str_h = str_iso.substr(pos_symbol + 1, pos_colon - (pos_symbol + 1));
            string str_m = str_iso.substr(pos_colon + 1);

            t_dif = atoi(str_h.c_str()) * 60 * 60 + atoi(str_m.c_str()) * 60;
            if ("-" == str_symbol) {
                t_dif *= -1;
            }
        }
    }

    tm t_m = { 0 };
    if (sscanf_s(local.c_str(), "%d-%d-%dT%d:%d:%d",
        &t_m.tm_year,
        &t_m.tm_mon,
        &t_m.tm_mday,
        &t_m.tm_hour,
        &t_m.tm_min,
        &t_m.tm_sec) <= 0){
        return -1;  // 时间格式不正确
    }

    t_m.tm_year -= 1900;
    t_m.tm_mon -= 1;
    t_m.tm_isdst = 0;

    time_t t = 0;
    // Converts a UTC time represented by a struct tm to a UTC time represented by a time_t type.
    t = _mkgmtime(&t_m);

    t = t - t_dif;

    return t;
}

// 加一天、减一天、加一个月、减一个月、加一年、减一年
// 按天循环、按月循环、按年循环
string AddDays(const string& date, const int32_t days) {
    string str_date_ret = date;

    try
    {
        boost::gregorian::date b_date1 = boost::gregorian::from_string(date);
        if (b_date1.is_not_a_date())
        {
            return str_date_ret;
        }

        b_date1 += boost::gregorian::days(days);

        str_date_ret = StringFormat("%04d-%02d-%02d", 
            (uint32_t)b_date1.year(), (uint32_t)b_date1.month(), (uint32_t)b_date1.day());
    }
    catch (const std::exception&)
    {
        // error
        return str_date_ret;
    }

    return str_date_ret;
}

string AddMonths(const string& date, const int32_t months) {
    string str_date_ret = date;

    try
    {
        boost::gregorian::date b_date1 = boost::gregorian::from_string(date);
        if (b_date1.is_not_a_date())
        {
            return str_date_ret;
        }

        b_date1 += boost::gregorian::months(months);

        str_date_ret = StringFormat("%04d-%02d-%02d",
            (uint32_t)b_date1.year(), (uint32_t)b_date1.month(), (uint32_t)b_date1.day());
    }
    catch (const std::exception&)
    {
        // error
        return str_date_ret;
    }

    return str_date_ret;
}

string AddYears(const string& date, const int32_t years) {
    string str_date_ret = date;

    try
    {
        boost::gregorian::date b_date1 = boost::gregorian::from_string(date);
        if (b_date1.is_not_a_date())
        {
            return str_date_ret;
        }

        b_date1 += boost::gregorian::years(years);

        str_date_ret = StringFormat("%04d-%02d-%02d",
            (uint32_t)b_date1.year(), (uint32_t)b_date1.month(), (uint32_t)b_date1.day());
    }
    catch (const std::exception&)
    {
        // error
        return str_date_ret;
    }

    return str_date_ret;
}

int32_t CalcDays(const string& date1, const string& date2) {
    int32_t days = 0;

    do
    {
        try
        {
            boost::gregorian::date b_date1 = boost::gregorian::from_string(date1);
            boost::gregorian::date b_date2 = boost::gregorian::from_string(date2);
            if (b_date1.is_not_a_date()
                || b_date2.is_not_a_date())
            {
                break;
            }

            boost::gregorian::days b_days = b_date2 - b_date1;
            days = int32_t(b_days.days());
        }
        catch (const std::exception&)
        {
            // error
            break;
        }
    } while (false);


    return days;
}

int32_t CalcHours(const string& time1, const string& time2) {
    int32_t hours = 0;

    do
    {
        try
        {
            boost::posix_time::ptime b_time1 = boost::posix_time::time_from_string(time1);
            boost::posix_time::ptime b_time2 = boost::posix_time::time_from_string(time2);
            if (b_time1.is_not_a_date_time()
                || b_time2.is_not_a_date_time())
            {
                break;
            }

            auto t_d = b_time2 - b_time1;
            hours = int32_t(t_d.hours());
        }
        catch (const std::exception&)
        {
            // error
            break;
        }
    } while (false);

    return hours;
}

int64_t CalcSeconds(const string& time1, const string& time2) {
    int64_t seconds = 0;

    do
    {
        try
        {
            boost::posix_time::ptime b_time1 = boost::posix_time::time_from_string(time1);
            boost::posix_time::ptime b_time2 = boost::posix_time::time_from_string(time2);
            if (b_time1.is_not_a_date_time()
                || b_time2.is_not_a_date_time())
            {
                break;
            }

            auto t_d = b_time2 - b_time1;
            seconds = int64_t(t_d.total_seconds());
        }
        catch (const std::exception&)
        {
            // error
            break;
        }
    } while (false);

    return seconds;
}

void GeMonths(list& month_list, const string& date1, const string& date2) {
    int32_t days = 0;

    do
    {
        try
        {
            boost::gregorian::date b_date1 = boost::gregorian::from_string(date1);
            boost::gregorian::date b_date2 = boost::gregorian::from_string(date2);
            if (b_date1.is_not_a_date()
                || b_date2.is_not_a_date())
            {
                break;
            }

            boost::gregorian::month_iterator iter_date(b_date1);
            while (iter_date <= b_date2)
            {
                string str_date = StringFormat("%04d-%02d-%02d",
                    (uint32_t)iter_date->year(), (uint32_t)iter_date->month(), (uint32_t)0);
                month_list.push_back(str_date);
                ++iter_date;
            }
        }
        catch (const std::exception&)
        {
            // error
            break;
        }
    } while (false);

    return;
}

void GetDays(list& day_list, const string& date1, const string& date2){
    int32_t days = 0;

    do
    {
        try
        {
            boost::gregorian::date b_date1 = boost::gregorian::from_string(date1);
            boost::gregorian::date b_date2 = boost::gregorian::from_string(date2);
            if (b_date1.is_not_a_date()
                || b_date2.is_not_a_date())
            {
                break;
            }

            boost::gregorian::day_iterator iter_date(b_date1);
            while (iter_date <= b_date2)
            {
                string str_date = StringFormat("%04d-%02d-%02d",
                    (uint32_t)iter_date->year(), (uint32_t)iter_date->month(), (uint32_t)iter_date->day());
                day_list.push_back(str_date);
                ++iter_date;
            }
        }
        catch (const std::exception&)
        {
            // error
            break;
        }
    } while (false);

    return;
}

void GetHours(list& hour_list, const string& time1, const string& time2) {
    int32_t days = 0;

    do
    {
        try
        {
            boost::posix_time::ptime b_time1 = boost::posix_time::time_from_string(time1);
            boost::posix_time::ptime b_time2 = boost::posix_time::time_from_string(time2);
            if (b_time1.is_not_a_date_time()
                || b_time2.is_not_a_date_time())
            {
                break;
            }

            boost::posix_time::ptime b_time_tmp = b_time1;
            while (b_time_tmp <= b_time2)
            {
                string str_time = StringFormat("%04d-%02d-%02d %02d:%02d:%02d",
                    (uint32_t)b_time_tmp.date().year(), (uint32_t)b_time_tmp.date().month(), (uint32_t)b_time_tmp.date().day(),
                    (uint32_t)b_time_tmp.time_of_day().hours(), 0, 0);
                hour_list.push_back(str_time);
                b_time_tmp += boost::posix_time::hours(1);
            }
        }
        catch (const std::exception&)
        {
            // error
            break;
        }
    } while (false);

    return;
}

int main()
{
    time_t t = time(nullptr);

    int32_t t_dif = GetLocalDif(t);
    string str_dif = CreateTimeDif(t_dif);

    string str_local;
    int32_t t_dif2 = 0;
    TimetToLocal(str_local, t_dif2, t);

    time_t t2 = LocalToTimet(str_local, t_dif2);

    string str_iso = TimetToISO(t);
    time_t t3 = ISOToTimet(str_iso);

    string str_local_date = str_local.substr(0, str_local.find(" "));
    string str_local_date2 = "2023-12-19";
    string str_local_add_days = AddDays(str_local, 1);
    string str_local_add_months = AddMonths(str_local, 1);
    string str_local_add_years = AddYears(str_local, 1);

    string str_local2 = "2023-12-19 08:00:00";
    int32_t days = CalcDays(str_local_date, str_local_date2);
    int32_t hours = CalcHours(str_local, str_local2);
    int64_t seconds = CalcSeconds(str_local, str_local2);
    return 0;
}

你可能感兴趣的:(C++,c++)