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语言实现时间戳转日期的算法(推荐)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持毛票票。