【原創出品§轉載請注明出處】
出處:http://www.cnblogs.com/libra13179/p/5796082.html
文件下載地址:http://files.cnblogs.com/files/libra13179/sw_wall_clock.zip
/** *@brief: monthLength *@details: Get month length. *@param[in] uint8_t lpyr 1 for leap year, 0 if not. *@param[in] uint8_t month 0 - 11 (january - December). *@retval: number of days in specified month. */ uint8_t monthLength( uint8_t lpyr, uint8_t month) { #if 1 uint8_t days = 31; if ( month == 1 ) //February { days = ( 28 + lpyr ); //2月天數為28 + (是否閏年) } else { if ( month > 6 ) // aug-dec //大於6月的30天的月份為9、11月,此時對應的mon為8、10,--之后變為7、9 { month--; } if ( month & 1 ) //判斷是否為4 6 9 11 { days = 30; } } return ( days ); #else const uint8_t month_days[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; if( lpyr ) { goto leap_year_February_days; } return month_days[ month-1 ]; leap_year_February_days: return 29; #endif }
解析:上面的代碼的對照一下下面的表格
備注其實可以用上面的那個復雜,直接使用空間換時間的方法。
const uint8_t month_days[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; if( lpyr ) { goto leap_year_February_days; } return month_days[ month-1 ]; leap_year_February_days: return 29;
下面的代碼就不細說了。
/** *@brief: ConvertToUTCTime *@details: Converts UTCTime to UTCTime_struct *@param[out] UTCTime_struct *p_utc_time pointer to breakdown struct *@param[in] UTCTime_t secTime_param number of seconds since 0 hour, 0 minutes, 0 seconds, on the 1st of January 2000 UTC *@retval: None */ void ConvertToUTCTime( UTCTime_struct *p_utc_time, UTCTime_t secTime_param) { uint32_t day = secTime_param% DAY_LENGTH; uint16_t numDays = secTime_param/ DAY_LENGTH; /* calculate the time less than a day - hours, minutes, seconds */ p_utc_time->seconds = day % 60UL; p_utc_time->minutes = (day % 3600UL) / 60UL; p_utc_time->hour = day / 3600UL; /* Fill in the calendar - day, month, year */ p_utc_time->year = UTC_BASE_YEAR; while ( numDays >= YearLength( p_utc_time->year ) ) { numDays -= YearLength( p_utc_time->year ); p_utc_time->year++; } p_utc_time->month = 0; while ( numDays >= monthLength( IsLeapYear( p_utc_time->year ), p_utc_time->month )) { numDays -= monthLength( IsLeapYear( p_utc_time->year ), p_utc_time->month ); p_utc_time->month++; } p_utc_time->day = numDays; }
/** *@brief: get_wall_clock_time *@details: general purpose wall-clock timing routine. *@retval: UTCTime_struct */ UTCTime_struct * get_wall_clock_time(void) { ConvertToUTCTime(&Global_Time,SecondCountRTC); Global_Time.month += 1; //calibration Global_Time.day += 1; //calibration #ifdef RTT_LOG_ENABLED logi(" %d-%d-%d %d:%2d:%2d \r\n", Global_Time.year, Global_Time.month, Global_Time.day, Global_Time.hour, Global_Time.minutes, Global_Time.seconds); #endif //RTT_LOG_ENABLED return &Global_Time; } /**@brief Function for handling the WallClockID request timer time-out. * * @details This function will be called each time the WallClockID request timer expires. * * @param[in] p_context Pointer used for passing some arbitrary information (context) from the * app_start_timer() call to the time-out handler. */ static void update_wall_clock_handler(void * p_context) { (void)p_context; /* Here we should use RTC attributes */ SecondCountRTC++; get_wall_clock_time(); } /** *@brief: wall_clock_init *@details: wall clock initialization *@retval: */ void wall_clock_init(void) { uint32_t err_code; /* set a default value */ Global_Time.year = UTC_BASE_YEAR; Global_Time.month = 0; Global_Time.day = 0; Global_Time.hour = 0; Global_Time.minutes = 0; Global_Time.seconds = 0; /* Init ticks from RTC */ SecondCountRTC = 0; err_code = app_timer_create(&WallClockID, APP_TIMER_MODE_REPEATED, update_wall_clock_handler); APP_ERROR_CHECK(err_code); err_code = app_timer_start(WallClockID, ONE_SECOND_INTERVAL, NULL); APP_ERROR_CHECK(err_code); }
問題來了。
1、請問代碼中static UTCTime_t SecondCountRTC能保存多少年?
保存UTC時間對應的秒數變量:UTCTime_t類型即uint32,能保存的年數為2^32/86400/365=136年左右,如果UTC以2000年為起點,則最長可以設置的時間為2136年。
2、請問如果修改起點的年需要修改那些宏定義
#define UTC_BASE_YEAR 2000 //< UTC started at 00:00:00 January 1, 2000
#define UTC_ORIGIN_DAY_OF_WEEK (Saturday) //<2000-01-01 is Saturday