關於不同地區夏令時處理的問題

剛第一家實習,就到了要說離開的時候了 !
實習期間,做了個小項目,有個夏令時區間判定定的小算法問題,也不是太難,不過也算自己處理的一個小難題了,下面是一些相關的代碼。
傳參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的算法,有點小得意,嘻嘻嘻,以後再說

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章