C语言实现时间戳转日期的算法(推荐)
1、算法
时间是有周期规律的,4年一个周期(平年、平年、平年、闰年)共计1461天。Windows上C库函数time(NULL)返回的是从1970年1月1日以来的毫秒数,我们最后算出来的年数一定要加上这个基数1970。总的天数除以1461就可以知道经历了多少个周期;总的天数对1461取余数就可以知道剩余的不足一个周期的天数,对这个余数进行判断也就可以得到月份和日了。
当然了,C语言库函数:localtime就可以获得一个时间戳对应的具体日期了,这里主要说的是实现的一种算法。
2、C语言代码实现
intnTime=time(NULL);//得到当前系统时间
intnDays=nTime/DAYMS+1;//time函数获取的是从1970年以来的毫秒数,因此需要先得到天数
intnYear4=nDays/FOURYEARS;//得到从1970年以来的周期(4年)的次数
intnRemain=nDays%FOURYEARS;//得到不足一个周期的天数
intnDesYear=1970+nYear4*4;
intnDesMonth=0,nDesDay=0;
boolbLeapYear=false;
if(nRemain<365)//一个周期内,第一年
{//平年
}
elseif(nRemain<(365+365))//一个周期内,第二年
{//平年
nDesYear+=1;
nRemain-=365;
}
elseif(nRemain<(365+365+365))//一个周期内,第三年
{//平年
nDesYear+=2;
nRemain-=(365+365);
}
else//一个周期内,第四年,这一年是闰年
{//润年
nDesYear+=3;
nRemain-=(365+365+365);
bLeapYear=true;
}
GetMonthAndDay(nRemain,nDesMonth,nDesDay,bLeapYear);
计算月份和日期的函数:
staticconstintMON1[12]={31,28,31,30,31,30,31,31,30,31,30,31}; //平年
staticconstintMON2[12]={31,29,31,30,31,30,31,31,30,31,30,31}; //闰年
staticconstintFOURYEARS=(366+365+365+365); //每个四年的总天数
staticconstintDAYMS=24*3600; //每天的毫秒数
voidGetMonthAndDay(intnDays,int&nMonth,int&nDay,boolIsLeapYear)
{
int*pMonths=IsLeapYear?MON2:MON1;
//循环减去12个月中每个月的天数,直到剩余天数小于等于0,就找到了对应的月份
for(inti=0;i<12;++i)
{
intnTemp=nDays-pMonths[i];
if(nTemp<=0)
{
nMonth=i+1;
if(nTemp==0)//表示刚好是这个月的最后一天,那么天数就是这个月的总天数了
nDay=pMonths[i];
else
nDay=nDays;
break;
}
nDays=nTemp;
}
}
3、附上C语言库函数的实现
<prename="code"class="cpp">/***
*errno_t_gmtime32_s(ptm,timp)-convert*timptoastructure(UTC)
*
*Purpose:
*Convertsthecalendartimevalue,in32bitinternalformat,to
*broken-downtime(tmstructure)withthecorrespondingUTCtime.
*
*Entry:
*consttime_t*timp-pointertotime_tvaluetoconvert
*
*Exit:
*errno_t=0success
*tmmembersfilled-in
*errno_t=nonzero
*tmmembersinitializedto-1ifptm!=NULL
*
*Exceptions:
*
*******************************************************************************/
errno_t__cdecl_gmtime32_s(
structtm*ptm,
const__time32_t*timp
)
{
__time32_tcaltim;/*=*timp;*//*calendartimetoconvert*/
intislpyr=0;/*is-current-year-a-leap-yearflag*/
REG1inttmptim;
REG3int*mdays;/*pointertodaysorlpdays*/
structtm*ptb=ptm;
_VALIDATE_RETURN_ERRCODE((ptm!=NULL),EINVAL)
memset(ptm,0xff,sizeof(structtm));
_VALIDATE_RETURN_ERRCODE((timp!=NULL),EINVAL)
caltim=*timp;
_VALIDATE_RETURN_ERRCODE_NOEXC((caltim>=_MIN_LOCAL_TIME),EINVAL)
/*
*Determineyearssince1970.First,identifythefour-yearinterval
*sincethismakeshandlingleap-yearseasy(notethat2000ISa
*leapyearand2100isout-of-range).
*/
tmptim=(int)(caltim/_FOUR_YEAR_SEC);
caltim-=((__time32_t)tmptim*_FOUR_YEAR_SEC);
/*
*Determinewhichyearoftheinterval
*/
tmptim=(tmptim*4)+70;/*1970,1974,1978,...,etc.*/
if(caltim>=_YEAR_SEC){
tmptim++;/*1971,1975,1979,...,etc.*/
caltim-=_YEAR_SEC;
if(caltim>=_YEAR_SEC){
tmptim++;/*1972,1976,1980,...,etc.*/
caltim-=_YEAR_SEC;
/*
*Note,ittakes366days-worthofsecondstogetpastaleap
*year.
*/
if(caltim>=(_YEAR_SEC+_DAY_SEC)){
tmptim++;/*1973,1977,1981,...,etc.*/
caltim-=(_YEAR_SEC+_DAY_SEC);
}
else{
/*
*Inaleapyearafterall,settheflag.
*/
islpyr++;
}
}
}
/*
*tmptimnowholdsthevaluefortm_year.caltimnowholdsthe
*numberofelapsedsecondssincethebeginningofthatyear.
*/
ptb->tm_year=tmptim;
/*
*DeterminedayssinceJanuary1(0-365).Thisisthetm_ydayvalue.
*Leavecaltimwithnumberofelapsedsecondsinthatday.
*/
ptb->tm_yday=(int)(caltim/_DAY_SEC);
caltim-=(__time32_t)(ptb->tm_yday)*_DAY_SEC;
/*
*DeterminemonthssinceJanuary(0-11)anddayofmonth(1-31)
*/
if(islpyr)
mdays=_lpdays;
else
mdays=_days;
for(tmptim=1;mdays[tmptim]<ptb->tm_yday;tmptim++);
ptb->tm_mon=--tmptim;
ptb->tm_mday=ptb->tm_yday-mdays[tmptim];
/*
*DeterminedayssinceSunday(0-6)
*/
ptb->tm_wday=((int)(*timp/_DAY_SEC)+_BASE_DOW)%7;
/*
*Determinehourssincemidnight(0-23),minutesafterthehour
*(0-59),andsecondsaftertheminute(0-59).
*/
ptb->tm_hour=(int)(caltim/3600);
caltim-=(__time32_t)ptb->tm_hour*3600L;
ptb->tm_min=(int)(caltim/60);
ptb->tm_sec=(int)(caltim-(ptb->tm_min)*60);
ptb->tm_isdst=0;
return0;
}
以上这篇C语言实现时间戳转日期的算法(推荐)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持毛票票。