本文主要是介绍32位旧内核2038溢出time记录,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
项目中有使用arm32的机器 现在内核动不了 有个使用时间范围显示是2023-2123
int在32bit下的 2038危机诞生了。
下面在svn找到代码 优化了一下 供大家学习哈,废话不多说直接上家伙:
需要的函数自己抄
#pragma once
#include <stdio.h>
#include <time.h>
#include <chrono>
#include <iostream>
#include <ctime>
#include <fstream>
#include <sstream>
#include <iomanip>
#include <random>//类型定义
using time64 = long long;//解决32bit系统mktime的溢出问题
time64 mkTime64(struct tm* mk)
{using TIME_DEF = enum{SEC = 1,MIN = SEC * 60,HOUR = MIN * 60,DAY = HOUR * 24,YEAR = DAY * 365,};time64 time_difference = 8 * HOUR;static time64 mon_yday[2][12] ={{0,31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334},{0,31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335},};auto leap = [](int year)->int{if ((year % 400 == 0) || (year % 4 == 0 && year % 100 != 0))return 1;return 0;};auto get_day = [](time64 year)->time64{year = year - 1;time64 leap_year_num = year / 4 - year / 100 + year / 400;time64 tol_day = year * 365 + leap_year_num;return tol_day;};auto mymktime = [&](int year, int mon, int day, int hour, int min, int sec)->time64{time64 tol_day = 0;mon -= 1;//year += 1900;tol_day = get_day(year) - get_day(1970) + mon_yday[leap(year)][mon] + day - 1;time64 ret = tol_day * TIME_DEF::DAY + hour * TIME_DEF::HOUR + min * TIME_DEF::MIN + sec * TIME_DEF::SEC - time_difference;return ret;};if (!mk)return -1;if (!(mk->tm_sec >= 0 && mk->tm_sec <= 59))return -1;if (!(mk->tm_min >= 0 && mk->tm_min <= 59))return -1;if (!(mk->tm_hour >= 0 && mk->tm_hour <= 23))return -1;if (!(mk->tm_mday >= 1 && mk->tm_hour <= 31))return -1;if (!(mk->tm_mon >= 0 && mk->tm_mon <= 11))return -1;if (!(mk->tm_year >= 70))return -1;return mymktime(mk->tm_year, mk->tm_mon, mk->tm_mday, mk->tm_hour, mk->tm_min, mk->tm_sec);
}//解决32bit系统localtime的溢出问题
struct tm* localTime64(const time64* timer)
{static struct tm tmz;
#define CHCK_IS_LEAP_YEAR(y) (((y % 4 == 0) && (y % 100 != 0)) || (y % 400 == 0))int startYear = 1970;time64 iTimep = *timer;iTimep += 8 * 3600;tmz.tm_sec = iTimep % 60;tmz.tm_min = ((iTimep - tmz.tm_sec) / 60) % 60;tmz.tm_hour = (((iTimep - tmz.tm_sec) / 60 - tmz.tm_min) / 60) % 24;int _alldays = (((iTimep - tmz.tm_sec) / 60 - tmz.tm_min) / 60 - tmz.tm_hour) / 24;tmz.tm_wday = _alldays % 6 + 1;tmz.tm_isdst = 0;tmz.tm_year = _alldays / 365 + startYear;int _ndays = 0;for (int i = startYear; i < tmz.tm_year; i++){if (CHCK_IS_LEAP_YEAR(i))_ndays += 366;else_ndays += 365;}int k, leap;int yearday = _alldays - _ndays;tmz.tm_yday = yearday;int _months_days[2][13] ={{0,31,28,31,30,31,30,31,31,30,31,30,31},{0,31,29,31,30,31,30,31,31,30,31,30,31}};if (CHCK_IS_LEAP_YEAR(tmz.tm_year))leap = 1;elseleap = 0;for (k = 1; yearday > _months_days[leap][k]; k++)yearday -= _months_days[leap][k];tmz.tm_mon = k;tmz.tm_mday = yearday + 1;return &tmz;
}//时间戳->"yyyy-mm-dd HH:MM:SS"
std::string TimeToStr(time_t timer)
{std::stringstream ss;auto tm = std::localtime(&timer);ss << std::put_time(tm, "%Y-%m-%d %H:%M:%S");return ss.str();
}//"yyyy-mm-dd HH:MM:SS"->时间戳
time_t StrToTime(std::string str)
{std::stringstream ss;ss << str;struct tm mytime;ss >> std::get_time(&mytime, "%Y-%m-%d %H:%M:%S");return (time_t)mktime(&mytime);
}//时间戳->时间字符串
std::string myTimeToStr(time64 timer)
{struct tm* pt = localTime64(&timer);char stTime[20] = { 0 };snprintf(stTime, sizeof(stTime), "%d-%02d-%02d %02d:%02d:%02d", pt->tm_year,pt->tm_mon, pt->tm_mday, pt->tm_hour, pt->tm_min, pt->tm_sec);return stTime;
}//时间字符串->时间戳
time64 myStrToTime(std::string str)
{struct tm mytm;sscanf(str.c_str(), "%d-%d-%d %d:%d:%d", &mytm.tm_year, &mytm.tm_mon, &mytm.tm_mday,&mytm.tm_hour, &mytm.tm_min, &mytm.tm_sec);mytm.tm_isdst = 0;return mkTime64(&mytm);
}int main(int argc, char** argv)
{std::cout << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" << std::endl;std::string timerstr = "2180-10-10 12:12:12";auto timestamp = StrToTime(timerstr);auto timestr = TimeToStr(timestamp);std::cout << "timestr = " << timerstr << std::endl;//系统方法std::cout << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" << std::endl;std::cout << "StrToTime = " << timestamp << std::endl;std::cout << "TimeToStr = " << timestr << std::endl;std::cout << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" << std::endl;//自己实现方法auto mytimestamp = myStrToTime(timerstr);auto mytimestr = myTimeToStr(mytimestamp);std::cout << "myStrToTime = " << mytimestamp << std::endl;std::cout << "myTimeToStr = " << mytimestr << std::endl;std::cout << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" << std::endl;scanf("\n");return 0;
}
g++ time.cpp -std=c++20 -o cpp.exe
这篇关于32位旧内核2038溢出time记录的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!