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