在运用中经常会使用到数值转换为时间和周几和数值转换为日期日期的情况,刚好在学习STM32的RTC(实时时钟)中用到了,就花了点时间自己摸索了下,胡乱写了个C语言代码(万恶的C-Free5.0有时候会发神经,提示一些错误),只是能用,可能没有进过优化,不够精炼,但是很好理解这倒是真的!!!!!废话不多说,上代码!!!
1、数值转换为时间和周几
<span style="font-size:14px;">#include <stdio.h>
#define u32 unsigned long
#define u16 unsigned int
#define u8 unsigned char
u8 mon_day[2][12] ={{31,28,31,30,31,30,31,31,30,31,30,31},{31,29,31,30,31,30,31,31,30,31,30,31}};
u8 Judeg_year(u16 year)
{
if(((year%4==0)&&(year%100!=0))||(year%400)==0) return 0;//闰年
else return 1;//平年
}
int main()
{
u32 sec;
u32 yearcount;
u32 daycount;
u32 year=0;
u16 i,runy=0,mounth=0,day=0,hour=0,minutes=0,second=0;
u8 temp=0,temp1=0,week,x;
scanf("%ld",&sec);
printf("sec=%ld\n",sec);
daycount = sec/86400;//总共的天数
yearcount= daycount/365;//总共的年数
year = 1970+yearcount;
runy=((year-1)/4-(year-1)/100+(year-1)/400)-((1970-1)/4-(1970-1)/100+(1970-1)/400);//计算从1970开始到过了多少个闰年
// for(i=0;i<yearcount;i++)//判断此间闰年数
// {
// if(!Judeg_year(1970+i))
// runy++;
// }
daycount=(daycount%365)-runy;//减去此间闰年多出来的n个一天
//(注意此处闰年的个数不能超过365次,算是一个小BUG,
//但是我们要的是1970-2099之间的时间所以说也是满足条件的)
while(daycount>28)
{
if(!Judeg_year(1970+yearcount))//当前年是否是闰年
{
if(daycount>=mon_day[1][temp1]) //闰年计算
daycount-=mon_day[1][temp1];
else break;
}
else
{
if(daycount>=mon_day[0][temp1]) //平年计算
daycount-=mon_day[0][temp1];
else break;
}
temp1++;//月数加1
}
mounth=temp1+1;//月
day = daycount+1;//日
hour=(sec%86400)/3600;//时
minutes=((sec%86400)%3600)/60;//分
second=((sec%86400)%3600)%60;//秒
printf("data:%ld-%d-%d\ntime:%d:%d:%d\n",year,mounth,day,hour,minutes,second);
if(year>1970&&year<2099)
{
if(mounth<3)//把1月2月转成上一年的13月14月
{
mounth+=12;
--year;
}
week=(day+1+2*mounth+3*(mounth+1)/5+year+(year>>2)-year/100+year/400)%7;//基姆拉尔森星期计算公式
//http://blog.csdn.net/qq_33114231/article/details/52352668资料
}
switch (week){
case 0:printf("Sunday\n"); break;
case 1:printf("Monday\n"); break;
case 2:printf("Tuesday\n"); break;
case 3:printf("Wednesday\n");break;
case 4:printf("Thursday\n"); break;
case 5:printf("Friday\n"); break;
case 6:printf("Saturday\n"); break;
default:printf("error\n"); break;
}
return 0;
}</span>
程序计算年月日的思路:①把输入的数值转换成天数,daycount = sec/86400;②把天数转换成年yearcount= daycount/365;③计算从1970-1970+x年之间的闰年数runy,④daycount=daycount%365-runy,⑤判断在平年或闰年的情况下剩余的天数daycount可以计算到几月,⑥剩下的就是第几天了,后面的时分秒就很好计算了,关于星期的计算请参考上面的基姆拉尔森公式!!!
2、时间和转换为数值
#include <stdio.h>
#define u8 unsigned char
#define u16 unsigned int
#define u32 unsigned long
u8 mon_day[2][12] ={{31,28,31,30,31,30,31,31,30,31,30,31},{31,29,31,30,31,30,31,31,30,31,30,31}};
u8 Judeg_year(u16 year)
{
if(((year%4==0)&&(year%100!=0))||(year%400)==0) return 0;//闰年
else return 1;//平年
}
u32 Get_second(u16 year,u8 mon,u8 day,u8 hour,u8 min,u8 sec)
{
u32 countsec=0;
u16 i;
u8 j;
if(Judeg_year(year))
printf("%ld this is ping year\n",year);
else
printf("%ld this is run year\n",year);
if(year>1970&&year<2099)//有效年份判断
{
for(i=1970;i<year;i++)
{
if(Judeg_year(i)) countsec += 31536000;//平年的秒数累加
else countsec += 31622400;//闰年
}
mon-=1;
if(Judeg_year(year)) //平年
{
for(j=0;j<mon;j++)
countsec += (mon_day[0][j]*86400);//平年时累加各个月的秒数
}
else //闰年
{
for(j=0;j<mon;j++)
countsec += (mon_day[1][j]*86400);
}
day-=1;
countsec += day*86400;//天数秒数累加
countsec += hour*3600;//小时秒数累加
countsec += min*60; //分钟秒数累加
countsec += sec; //秒数累加
return countsec;
}
return 0;
}
int main(int argc, char *argv[])
{
u8 sec=0,min=0,hour=0;
u8 day=0,mon=0;
u32 year=0;
scanf("%ld%d%d%d%d%d",&year,&mon,&day,&hour,&min,&sec);
printf("year=%ld,mon=%d,day=%d,hour=%d,min=%d,sec=%d\n",year,mon,day,hour,min,sec);
printf("countsec= %ld\n",Get_second(year,mon,day,hour,min,sec));//1970到设置时间的秒数
return 0;
}
以上程序稍作修改就可以用在别的地方!!!