解析时间戳
最近在学习用esp-idf给ESP32写代码。打算写一个NTP授时功能的时候发现要自己解析时间戳。在网上搜了一下,发现大佬们都是按照每四年一闰年的方法来判断是否是闰年。但是这个方法并不准确。
四年一闰,百年不闰,四百年再闰。例如:2000年是闰年,2100年则是平年。——摘自百度百科
考虑到这个问题,所以自己重新写了一个算法(就是不知道有没有大佬也写个这个算法hhh),通过循环来判断是否为闰年。虽然在速度上稍微慢一点但至少会更严谨一些。
#include
#include
#include
#include
const long DAY_SEC = 86400;//一天中的秒数#define my_timezone 8
#define start_year 2021
#define isLeap false
#define start_day 5
const long TO2021_SEC = 1609459200;//1970-1-1到2021-1-1的秒数int nor_month[] = {31,28,31,30,31,30,31,31,30,31,30,31};
int leap_month[] = {31,29,31,30,31,30,31,31,30,31,30,31};struct {int year;int month;int date;int hour;int min;int sec;int day;bool isLeapYear;
}my_time;void getTime(unsigned long timestamp);
bool isLeapYear(int year);int main() {while(1){unsigned long timestamp = time(NULL);//scanf("%ul",×tamp);printf("时间戳是:%u\n",timestamp);getTime(timestamp);printf("%d-%d-%d %02d:%02d:%02d %d %d \n",my_time.year,my_time.month,my_time.date,my_time.hour,my_time.min,my_time.sec,my_time.isLeapYear,my_time.day);Sleep(1000);}
}bool isLeapYear(int year)
{if(year%400 == 0)return true;else if(year%4 == 0 && year%100 !=0)return true;return false;
}void getTime(unsigned long timestamp)
{timestamp += my_timezone * 3600;//时区偏移timestamp -= TO2021_SEC;//预处理//时分秒my_time.sec = timestamp % 60;//算出没凑够一分钟的秒数my_time.min = timestamp % 3600 / 60;//算出没凑够一小时的秒数再除以一分钟的秒数my_time.hour = timestamp % DAY_SEC / 3600;//算出没凑够一天的秒数再除以一小时的秒数//my_time.year = start_year;my_time.isLeapYear = isLeap;my_time.month = 1;//一开始是1月//long nDays = timestamp / DAY_SEC ;int tem = nDays % 7;//没凑够一周的天数my_time.day = start_day + tem;//当时是星期五if(my_time.day > 7)my_time.day -= 7;//while(nDays > 365)//经过多少年就减去对应的天数{my_time.year++;if(isLeapYear(my_time.year)){nDays -= 366;my_time.isLeapYear = true;}else{nDays -= 365;my_time.isLeapYear = false;}}int *month;//根据闰年选择是有29的还是普通月份if(my_time.isLeapYear){month = leap_month;}else{month = nor_month;}for(int i = 0;i < 12; i++){if(nDays > month[i])//如果剩余的天数比该月份的上限天数要大{my_time.month++;//说明至少月份是下一个月的nDays -= month[i];}else//否则就是该月份的{break;}}my_time.date = nDays + 1;//剩余的天数就是经过多少天,一开始是1要加上
}
为了减少循环的次数我直接从2021-1-1开始计算,所以直接减去了从1970-1-1到2021-1-1的秒数。所以说循环次可能也不会很多,如果感觉年份靠后了的话也可以改一开始的几个定义,把时间往后推。
代码在Clion上运行过是没有问题的,但就是不知道有没有特定的时间点会出错。如果代码有BUG 的话欢迎各位大佬指出。如果觉得我代码不规范的也可以吐槽一下我不听
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!