【原创出品§转载请注明出处】
出处: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 ", 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