通过sntp同步系统时间

article/2025/8/21 23:14:01

通过sntp同步系统时间

小型物联网设备,很少有接口提供给用户进行数据交互,那么我们设备的系统时间只能够通过获取网络时间后,再更新到本地。那么,就少不了使用sntp协议。
ntp协议:NTP(Network Time Protocol)网络时间协议基于UDP,用于网络时间同步的协议,使网络中的计算机时钟同步到UTC(通用协调时,可以理解为0时区的时间,领先东八区8个小时),再配合各个时区的偏移调整就能实现精准同步对时功能。
sntp协议:简单网络时间协议(Simple Network Time Protocol),由 NTP 改编而来,主要用来同步因特网中的计算机时钟。在 RFC2030 中定义。主要运用于小型的设备,占用内存小。

注意:NTP时间戳从1900年开始记秒数,而UNIX时间戳从1970年开始记秒数

一.常用时间函数介绍

首先介绍time.h中的常用api;

1.time();

函数原型:time_t time(time_t *t)
介绍:C 库函数 time_t time(time_t *seconds) 返回自纪元 Epoch(1970-01-01 00:00:00 UTC)起经过的时间,以秒为单位。如果 seconds 不为空,则返回值也存储在变量 seconds 中。
返回值:1970-01-01 00:00:00 起至今经过的时间,单位秒

2.ctime()

函数原型:char *ctime(const time_t *timer)
介绍:C 库函数 char *ctime(const time_t *timer) 返回一个表示当地时间的字符串,当地时间是基于参数 timer。
返回的字符串格式如下: Www(星期) Mmm (月)dd(日) hh:mm:ss(时分秒) yyyy(年)
返回值:是基于参数 timer计算,1970-01-01 00:00:00 经过timer时间后的时间字符串

3.localtime()

函数原型:struct tm *localtime(const time_t *timer)
介绍:C 库函数 struct tm *localtime(const time_t *timer) 使用 timer 的值来填充 tm 结构。timer 的值被分解为 tm 结构,并用本地时区表示。
返回值:填充tm结构体,表示1970-01-01 00:00:00 经过timer时间后的时间结构体
注意:年份输出需要+1900,月份输出需要+1才能得到准确的utc时间
tm结构体:

struct tm {int tm_sec;         /* 秒,范围从 0 到 59                */int tm_min;         /* 分,范围从 0 到 59                */int tm_hour;        /* 小时,范围从 0 到 23                */int tm_mday;        /* 一月中的第几天,范围从 1 到 31                    */int tm_mon;         /* 月份,范围从 0 到 11                */int tm_year;        /* 自 1900 起的年数                */  int tm_wday;        /* 一周中的第几天,范围从 0 到 6                */int tm_yday;        /* 一年中的第几天,范围从 0 到 365                    */int tm_isdst;       /* 夏令时                        */    
};

4.mktime()

函数原型:time_t mktime(struct tm * timeptr)
介绍:C库函数time_t mktime(struct tm * timeptr)把timeptr所指向的结构转换为一个依据本地时区的time_t值。
参数:tm结构体,同上。
返回值:将参数timeptr所指的tm结构数据转换成从公元1970年1月1日0时0分0秒算起至今的UTC时间所经过的秒数。

二.功能实现

下面分析某项目将网络时间更新到本地的流程,平台可能存在差异,实现流程大致相同的。
源码分析
创建一个sntp客户端,目的从网络中获取时间,更新。

static void sntp_client(void)
{/** Set this to 1 to allow config of SNTP server(s) by DNS name */
#if (!SNTP_SERVER_DNS)struct ip4_addr test_addr;
#endifhal_rtc_time_t r_time = {6,6,6,1,1,6,0};hal_rtc_status_t ret = HAL_RTC_STATUS_OK;//Set RTC to a incorrect time.//设置默认系统时间ret = hal_rtc_set_time(&r_time);// LOG_I(sntp_client_main, "[%d]cur_time[%d:%d:%d]", ret, r_time.rtc_hour, r_time.rtc_min, r_time.rtc_sec);// 设置sntp服务器ip地址或者DNS(目的地址),从什么服务器获取时间/** Set this to 1 to allow config of SNTP server(s) by DNS name */
#if SNTP_SERVER_DNSsntp_setservername(0, "1.cn.pool.ntp.org");sntp_setservername(1, "1.hk.pool.ntp.org");
#elseIP4_ADDR(&test_addr, 213, 161, 194, 93);sntp_setserver(0, (const ip_addr_t *)(&test_addr));IP4_ADDR(&test_addr, 129, 6, 15, 29);sntp_setserver(1, (const ip_addr_t *)(&test_addr));
#endif//初始化设置sntp_init();// LOG_I(sntp_client_main, "SNTP init done");
}
/*** Initialize this module.* Send out request instantly or after SNTP_STARTUP_DELAY(_FUNC).*/
void
sntp_init(void)
{
#ifdef SNTP_SERVER_ADDRESS
#if SNTP_SERVER_DNSsntp_setservername(0, SNTP_SERVER_ADDRESS);
#else
#error SNTP_SERVER_ADDRESS string not supported SNTP_SERVER_DNS==0
#endif
#endif /* SNTP_SERVER_ADDRESS */if (sntp_pcb == NULL) {SNTP_RESET_RETRY_TIMEOUT();//创建udp,用于接收udp包,时间数据sntp_pcb = udp_new();LWIP_ASSERT("Failed to allocate udp pcb for sntp client", sntp_pcb != NULL);if (sntp_pcb != NULL) {//有数据,处理接收数据,同步到本地,由sntp_recv处理。udp_recv(sntp_pcb, sntp_recv, NULL);
#if SNTP_STARTUP_DELAYsys_timeout((u32_t)SNTP_STARTUP_DELAY_FUNC, sntp_request, NULL);
#elsesntp_request(NULL);
#endif}}
}

上述程序执行成功,再次获取本地时间,本地时间就会被更新。

uint32_t get_rtc_stamp_time(char * cur_time)
{hal_rtc_time_t r_time;hal_rtc_status_t ret = HAL_RTC_STATUS_OK;time_t timep = 0;    struct tm p;struct tm *tp;//获取本地时间,是utc时间ret = hal_rtc_get_time(&r_time);if (ret == HAL_RTC_STATUS_OK){// printf("cur_time[%d,%d,%d,%d]\r\n", r_time.rtc_year, r_time.rtc_mon, r_time.rtc_day, r_time.rtc_week);// printf("[%d]cur_time[%d:%d:%d]\r\n", ret, r_time.rtc_hour, r_time.rtc_min, r_time.rtc_sec);#if 1p.tm_year = r_time.rtc_year + 2000 - 1900;//DATA%100 + 2000 -1900;p.tm_mon = r_time.rtc_mon-1;//(DATA/100) %100 -1;p.tm_mday = r_time.rtc_day;//DATA/10000;p.tm_hour= r_time.rtc_hour;//(UTCTime / 10000);p.tm_min= r_time.rtc_min;//(UTCTime / 100)%100;p.tm_sec= r_time.rtc_sec;//UTCTime % 100;//从utc时间转换成东八区时间timep=mktime(&p);timep = timep+28800;tp = localtime(&timep);  //0时区与东八区相差8个小时//printf("%d %d %d %d %d %d\n",(tp->tm_year+1900), (tp->tm_mon+1), tp->tm_mday,tp->tm_hour, tp->tm_min, tp->tm_sec);sprintf(cur_time,"%02d-%02d-%02d %02d:%02d:%02d",(tp->tm_year+1900), (tp->tm_mon+1), tp->tm_mday,tp->tm_hour, tp->tm_min, tp->tm_sec);//下图logprintf("%02d-%02d-%02d %02d:%02d:%02d",(tp->tm_year+1900), (tp->tm_mon+1), tp->tm_mday,tp->tm_hour, tp->tm_min, tp->tm_sec);#endif//sprintf(cur_time,"%d-%02d-%02d %d %02d:%02d:%02d",r_time.rtc_year, r_time.rtc_mon, r_time.rtc_day, r_time.rtc_week,r_time.rtc_hour, r_time.rtc_min, r_time.rtc_sec);}else{printf("get_rtc_stamp_time fail\r\n");}return timep;
}

测试log如下图所示
在这里插入图片描述


http://chatgpt.dhexx.cn/article/A8dvAqwA.shtml

相关文章

2012系统sntp服务器,如何设置SNTP服务器,实现同步PLC时钟

在过程/生产自动化系统构架和运行时,有时需要实现对时间的精确控制,即系统中所有子系统(包括设备等)的时间必须保持同步。 作为自动化系统组成部分的 以Windows 7操作系统为例,将PC机配置为SNTP服务器端的操作步骤: [注意]操作前前…

ESP32学习笔记(41)——SNTP接口使用

一、SNTP简介 简单网络时间协议(Simple Network Time Protocol),由 NTP 改编而来,主要用来同步因特网中的计算机时钟。 SNTP 协议是用来同步本地的时间到 unix 时间戳。通常嵌入式设备上电,连接 AP(access point)&…

物联网专题27:SNTP

什么是SNTP(Simple Network Time Protocol)?简单时钟控制协议,主要用来同步因特网中的计算机时钟。 SNTP,使用的默认端口号是 UDP123。 ESP8266中,SNTP相关的API: 1 设置SNTP服务器&#xff08…

ESP8266-----SNTP获取网络时间

目录 前言 user_init IP定时的回调函数 初始化SNTP SNTP定时回调函数 前言 介绍了8266如何获取网络时间 user_init 首先将8266设置为sta模式 void ICACHE_FLASH_ATTR user_init(void) {uart_init(115200,115200); // 初始化串口波特率os_delay_us(10000); // 等待串口…

微软 sntp服务器地址,电脑sntp服务器地址

电脑sntp服务器地址 内容精选 换一换 当创建文件系统后,您需要使用云服务器来挂载该文件系统,以实现多个云服务器共享使用文件系统的目的。本章节以Windows 2012版本操作系统为例进行NFS文件系统挂载,其他版本请参考以下主要步骤根据实际界面…

ESP32 SNTP设置

SNTP,Simple Network Time Protocol(简单网络时间协议),用来同步时钟。 百度百科:[SNTP](https://baike.baidu.com/item/sntp/4749147?fraladdin) SNTP协议采用客户端/服务器的工作方式,可以采用单播&…

sntp服务器位置,sntp的服务器地址

sntp的服务器地址 内容精选 换一换 介绍常见的安全组配置示例。如下示例中,出方向默认全通,仅介绍入方向规则配置方法。不同安全组内的云耀云服务器内网互通仅允许特定 IP 地址远程连接云耀云服务器SSH远程连接Linux云耀云服务器RDP远程连接Windows云服务器公网ping云耀云服务…

sntp 校时问题

1、背景 由于项目中的数据对时间比较敏感,目前常常出现校时问题,导致时间偏差,出现曲线数据丢失和曲线数据重复等问题。 因此对sntp源码进行深入分析。 要了解SNTP,首先需要了解NTP协议。SNTP是NTP的子集,简化了NTP…

ESP8266_SNTP(Simple Network Time Protocol)

1、SNTP 简单网络时间协议 SNTP协议采用客户端/服务器的工作方式,以UDP方式通信,SNTP服务器通过接收GPS信号或自带的原子钟作为系统的时间基准。 网络中存在很多台SNTP服务器,客户端会选择几台SNTP服务器使用。如果一台SNTP服务器在工作过程…

WIFI学习六(SNTP)

简介 SNPT(Simple Network Time Protocal简单网络时间协议)用于跨广域网或局域网时间同步的协议,具有较高的精确度(几十毫秒)。SNTP是NTP协议的简化版 SNTP的工作方式 SNTP协议采用客户端/服务器的工作方式&#xff0…

SNTP简介

要了解SNTP,首先需要了解NTP协议。SNTP是NTP的子集,简化了NTP的许多算法和步骤,得到了效率,但时间的精度不如NTP,可是对于民用时间来说足够了,大概最多差距几秒的样子。 NTP(Network Time Proto…

SNTP原理讲解 客户端 C语言实现

1.定义 SNTP(Simple Network Time Protocal简单网络时间协议),用于跨广域网或局域网同步时间的协议,具有较高的精确度(几十毫秒) 这里给出SNTP的详细定义和解释,以及基于C语言的SNTP客户端实现代码:SNTP c…

使用SNTP协议获取时间

要了解SNTP,首先需要了解NTP协议。SNTP是NTP的子集,简化了NTP的许多算法和步骤,得到了效率,但时间的精度不如NTP,可是对于民用时间来说足够了,大概最多差距几秒的样子。 NTP(Network Time Protocol,网络时间协议)是由RFC 1305定义的时间同步协议,用来在分布式时间服…

sntp协议简介

SNTP(Simple Network Time Protocal简单网络时间协议),用于跨广域网或局域网同步时间的协议,具有较高的精确度(几十毫秒)。SNTP是NTP协议的简化版,两者分别在RFC1305和RFC2030介绍。 SNTP工作方式 SNTP采用客户端/服务…

关于马尔可夫过程的一些学习笔记

①马尔可夫性质:已知“现在”的情况下,“未来”与“过去”彼此独立(N1仅与N有关,与N以前的所有都无关) ②马尔可夫过程:具有马尔可夫性质的随机过程 ③马尔可夫链:马尔可夫过程的原始模型&…

来聊聊马尔可夫过程

相信你对马尔科夫这个词一定不陌生,因为在人工智能机器学习领域,这个词是避不开的,如马尔可夫链(Markov chain),马尔科夫随机场(Markov random field),马尔可夫过程(Markov process),隐马尔可夫…

【算法学习】马尔可夫过程及经典例题讲解(含代码实现)

公众号关注 52DATA ,获得更多数据分析知识,感谢支持—> 文章目录 马尔可夫过程1. 马尔可夫性2. 马尔可夫链2.1 转移概率矩阵(随机矩阵)2.2 状态概率2.3 平稳分布 3.一个很经典的例题帮助理解马尔科夫预测方法1.求状态转移概率2.运用状态概…

数学基础(8)-- 马尔可夫链与马尔可夫过程

目录 1. 简介 1.1 定义 1.2 变种 2. 瞬态演变 3. 马尔科夫链性质 3.1 可还原性 3.2 周期性 3.3 重现性 4. 有限状态空间 1. 简介 马尔可夫链(英语:Markov chain),又称离散时间马可夫链(discrete-time Markov…

部分可观测马尔可夫过程POMDP

POMDP与MDP的一句话区别:POMDP的state具有不确定性,由七元数组定义,多了观测空间、观测函数、初始置信(belief),根据观测概率矩阵求出最可能是的状态 利用值迭代法解决POMDP问题 MDP POMDP 状态→动作 信…

马尔可夫 java_马尔可夫过程(以马尔科夫链Markov为例)

马尔可夫过程(以马尔科夫链Markov为例) 马尔可夫过程 马尔可夫过程的大概意思就是未来只与现在有关,与过去无关。 简单理解就是渣男只在乎下一刻会不会爱你只取决于这一时刻对你的新鲜感,而与你之前对这段感情的付出毫无关系。 设有一个随机过程X(t)&…