• 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;
    }

  • 相关阅读:
    怎么实现在微信公众号点外卖的功能
    史上最全前端八股文来了
    小程序如何搭建在服务器上
    架构的未来——End
    css 对号 叉号
    基于XML的自动装配
    MySQL数据类型:字符串类型详解
    两个有助于理解Common Lisp宏的例子
    Android Navigation 过渡动画
    qlib熟练使用后如何进阶?tests和examples
  • 原文地址:https://blog.csdn.net/zhaodongdong2012/article/details/134540242