/** * @file time_clock.c * @author Chen Jihang (embedded@eseaoptics.com) * @brief 提供与时间和时钟相关函数 * @version 0.1 * @date 2022-07-18 * * @copyright ESEA (c) 2020 * */ #include "time_clock.h" struct time_clock { volatile uint64_t time_s; volatile uint32_t time_ms; volatile int64_t time_offset_ms; }; static struct time_clock tc={0}; /** * @brief 获取当前时间戳(秒) * * @return uint64_t 当前时间戳(秒) */ uint64_t time_clock_get_time_s(void) { return tc.time_s; } /** * @brief 获取当前时间戳(毫秒) * * @return uint32_t 当前时间戳(毫秒) */ uint32_t time_clock_get_time_ms(void) { return tc.time_ms; } /** * @brief 获取当前时间 * * @param ptime struct time_clock_time 结构指针 * @return struct time_clock_time* ptime */ struct time_clock_time *time_clock_get_time(struct time_clock_time *ptime) { ptime->time_s=tc.time_s; ptime->time_ms=tc.time_ms; if(ptime->time_s!=tc.time_s){ ptime->time_ms=0; ptime->time_s++; } return ptime; } /** * @brief 获取struct time_clock_time 结构存储的时间与当前时间的偏移量(毫秒) * * @param ptime struct time_clock_time 结构指针 * @return int64_t 偏移量(毫秒) */ int64_t time_clock_get_time_offset_ms(struct time_clock_time *ptime) { int64_t time_s; int32_t time_ms; time_s=tc.time_s; time_ms=tc.time_ms; if(time_s!=tc.time_s){ time_s++; time_ms=0; } return ((int64_t)time_s-(int64_t)ptime->time_s)*1000+((int32_t)time_ms-(int32_t)ptime->time_ms); } /** * @brief 获取给定时间与当前时间的偏移量(秒) * * @param time_s 给定时间(秒) * @return int64_t 偏移量(秒) */ int64_t time_clock_get_time_offset_s(uint64_t time_s) { return (int64_t)tc.time_s-(int64_t)time_s; } /** * @brief 设置时间 * * @param time_to_set 当前时间 * @param ptime 基础时间 */ void time_clock_set_time(struct time_clock_time *time_to_set,struct time_clock_time *ptime) { int64_t time_offset_ms; time_offset_ms=time_clock_get_time_offset_ms(time_to_set); time_offset_ms-=time_clock_get_time_offset_ms(ptime); tc.time_offset_ms=time_offset_ms; } /** * @brief 时间戳转日期 * * @param time_s 当前时间戳(秒) * @param date 日期结构 * @param time_zone 时区 * @return struct time_clock_date* date */ struct time_clock_date *time_clock_time_to_date(uint64_t time_s,struct time_clock_date *date,int8_t time_zone) { struct tm *time_tm; time_t time_tmp=time_s+(int64_t)time_zone*60*60; time_tm=gmtime(&time_tmp); date->year=time_tm->tm_year+1900; date->mon=time_tm->tm_mon+1; date->mday=time_tm->tm_mday; date->hour=time_tm->tm_hour; date->min=time_tm->tm_min; date->sec=time_tm->tm_sec; date->wday=time_tm->tm_wday; date->yday=time_tm->tm_yday+1; return date; } /** * @brief 日期转时间戳(秒) * * @param date 日期结构 * @param time_zone 时区 * @return uint64_t 时间戳(秒) */ uint64_t time_clock_date_to_time(struct time_clock_date *date,int8_t time_zone) { struct tm time_tm; time_tm.tm_year=date->year-1900; time_tm.tm_mon=date->mon-1; time_tm.tm_mday=date->mday; time_tm.tm_hour=date->hour; time_tm.tm_min=date->min; time_tm.tm_sec=date->sec; time_tm.tm_wday=date->wday-1; time_tm.tm_yday=date->yday-1; time_tm.tm_isdst=0; return mktime(&time_tm)-(int64_t)time_zone*60*60; } /** * @brief 获取当前时间的字符串形式 * * @param buf 缓冲区 * @param time_zone 时区 * @return uint32_t 字符串长度 */ uint32_t time_clock_get_time_str(char *buf,int8_t time_zone) { int i=0; struct time_clock_date date_tmp; struct time_clock_time time_tmp; time_clock_get_time(&time_tmp); time_clock_time_to_date(time_tmp.time_s,&date_tmp,time_zone); buf[i++]=date_tmp.year/1000+'0'; buf[i++]=(date_tmp.year/100)%10+'0'; buf[i++]=(date_tmp.year/10)%10+'0'; buf[i++]=date_tmp.year%10+'0'; buf[i++]='/'; buf[i++]=date_tmp.mon/10+'0'; buf[i++]=date_tmp.mon%10+'0'; buf[i++]='/'; buf[i++]=date_tmp.mday/10+'0'; buf[i++]=date_tmp.mday%10+'0'; buf[i++]=' '; buf[i++]=date_tmp.hour/10+'0'; buf[i++]=date_tmp.hour%10+'0'; buf[i++]=':'; buf[i++]=date_tmp.min/10+'0'; buf[i++]=date_tmp.min%10+'0'; buf[i++]=':'; buf[i++]=date_tmp.sec/10+'0'; buf[i++]=date_tmp.sec%10+'0'; buf[i++]='.'; buf[i++]=time_tmp.time_ms/100+'0'; buf[i++]=(time_tmp.time_ms/10)%10+'0'; buf[i++]=time_tmp.time_ms%10+'0'; buf[i++]='\0'; return i; } /** * @brief 回调函数 每1ms调用一次 * */ void time_clock_tick_callback(void) { tc.time_ms++; if(tc.time_offset_ms!=0){ tc.time_s-=tc.time_offset_ms/1000; tc.time_s--; tc.time_ms+=1000; tc.time_ms-=tc.time_offset_ms%1000; tc.time_offset_ms=0; } while(tc.time_ms>=1000){ tc.time_s++; tc.time_ms-=1000; } }