刚第一家实习,就到了要说离开的时候了 !
实习期间,做了个小项目,有个夏令时区间判定定的小算法问题,也不是太难,不过也算自己处理的一个小难题了,下面是一些相关的代码。
传参RTC的日期时间结构体,以及夏令时结构体:
void apply_dst(RTC_TimeTypeDef *pTime, RTC_DateTypeDef *pDate, Dst_t dst)
{
int8_t hours = pTime->Hours;
int8_t year = pDate->Year;
int8_t month = pDate->Month;
int8_t day = pDate->Date;
int8_t weekday_firstday_startmonth = get_days((int)(year)+2000, (int)dst.monthstart, 1) % DAYS_PER_WEEK;
if(weekday_firstday_startmonth==0)
weekday_firstday_startmonth=7;
int8_t weekday_firstday_stopmonth = get_days((int)(year)+2000, (int) dst.monthstop, 1) % DAYS_PER_WEEK;
if(weekday_firstday_stopmonth==0)
weekday_firstday_stopmonth=7;
int days_of_thisyear = days_of_year((int)(year)+2000,(int)month,(int)day);
int dststartdays_of_thisyear;
int dststopdays_of_thisyear;
if(dst.weekday_numstart==5)
{
dststartdays_of_thisyear=days_of_year((int)(year)+2000,(int)dst.monthstart,(((int)dst.weekdaystart-weekday_firstday_startmonth)+7*4+1));
} else{dststartdays_of_thisyear=days_of_year((int)(year)+2000,(int)dst.monthstart,(((int)dst.weekdaystart-weekday_firstday_startmonth)+7*((int)dst.weekday_numstart-1)+1));}
if(dst.weekday_numstop==5)
{
dststopdays_of_thisyear= days_of_year((int)(year)+2000,(int)dst.monthstop,(((int)dst.weekdaystop-weekday_firstday_stopmonth)+7*4+1));
} else{ dststopdays_of_thisyear=days_of_year((int)(year)+2000,(int)dst.monthstop,(((int)dst.weekdaystop-weekday_firstday_stopmonth)+7*((int)dst.weekday_numstop-1)+1));}
printf("start_m:%d stop_m:%d now:%d start:%d stop:%d\r\n",weekday_firstday_startmonth,weekday_firstday_stopmonth,days_of_thisyear,dststartdays_of_thisyear,dststopdays_of_thisyear);
if(dststartdays_of_thisyear<=days_of_thisyear && days_of_thisyear<dststopdays_of_thisyear)
{
hours+=1;
printf("DST_1 rtc_hours+1\r\n");
} else{
printf("DST_0\r\n");
}
if (hours < 0) {
day -= 1;
hours += 24;
if (day == 0) {
if (--month == 0) {
month += 12;
year -= 1;
}
day = get_days_in_month(month, year);
}
} else if (hours >= 24) {
day += 1;
hours -= 24;
if (day > get_days_in_month(month, year)) {
day = 1;
if (++month > 12) {
month -= 12;
year += 1;
}
}
}
pTime->Hours = hours;
pDate->Year = year;
pDate->Month = month;
pDate->Date = day;
}
上面有用到一个关于日历算法的小函数,我也是网上查到的,有点懒得想,哈哈哈
int get_days(int year, int month, int day)
{
int days = days_of_year(year, month, day);
int temp = year-1;
return temp * 365 + temp / 4 - temp / 100 + temp / 400 + days;
}
//
int days_of_month(int year, int month)
{
const int month_days[MONTHS] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
if(2 == month && is_leap_year(year))
return 29;
else
return month_days[month-1];
}
int days_of_year(int year, int month, int day)
{
int i;
int days = 0;
for(i = 1; i < month; i++)
{
days += days_of_month(year, i);
}
return days + day;
}
//
//
static const uint8_t days_in_month[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
static uint8_t get_days_in_month(uint8_t month, uint8_t year) {
if (month == 2 && (year % 4 == 0))
return 29;
else
return days_in_month[month - 1];
}
//
为了方便理解,我把RTC结构体跟DST结构体也列举一下,dst是我自己建的,里面的逻辑是几月份第几个周几的几点开始 到 几月份第几个周几的几点结束,因为这个结口的数据源相对可靠,所以也就没做数据排错处理,其实就是懒,哈哈哈
typedef struct Dst
{
uint8_t monthstart;
uint8_t weekday_numstart;
uint8_t weekdaystart;
uint8_t hoursstart;
uint8_t monthstop;
uint8_t weekday_numstop;
uint8_t weekdaystop;
uint8_t hoursstop;
}Dst_t;
/**
* @brief RTC Time structure definition
*/
typedef struct
{
uint8_t Hours;
uint8_t Minutes;
uint8_t Seconds;
uint8_t TimeFormat;
uint32_t SubSeconds;
uint32_t SecondFraction;
uint32_t DayLightSaving;
uint32_t StoreOperation;
} RTC_TimeTypeDef;
/**
* @brief RTC Date structure definition
*/
typedef struct
{
uint8_t WeekDay;
uint8_t Month;
uint8_t Date;
uint8_t Year;
} RTC_DateTypeDef;
//rtc结构体是去了注释的hal库函数哦
还有个实现每日Schedule的算法,有点小得意,嘻嘻嘻,以后再说