if (esp_netif_sntp_sync_wait(pdMS_TO_TICKS(10000)) != ESP_OK) {
printf("Failed to update system time within 10s timeout");
要配置多个 NTP 服务器(或使用更高级的设置,例如 DHCP 提供的 NTP 服务器),请参考 esp_netif 文档 SNTP API 中的详细说明。
lwIP SNTP 库可在下列任一同步模式下工作:
SNTP_SYNC_MODE_IMMED
(默认):使用 settimeofday()
,收到 SNTP 服务器响应后立即更新系统时间。
SNTP_SYNC_MODE_SMOOTH
:使用函数 adjtime()
逐渐减少时间误差以平滑更新时间。如果 SNTP 响应时间和系统时间之差超过 35 分钟,请立即使用 settimeofday()
更新系统时间。
如要选择 SNTP_SYNC_MODE_SMOOTH
模式,请将 SNTP 配置结构体中的 esp_sntp_config::smooth
设置为 true
,否则将默认使用 SNTP_SYNC_MODE_IMMED
模式。
设置时间同步时的回调函数,请使用配置结构体中的 esp_sntp_config::sync_cb
字段。
添加此初始化代码后,应用程序将定期同步时间。时间同步周期由 CONFIG_LWIP_SNTP_UPDATE_DELAY 设置(默认为一小时)。如需修改,请在项目配置中设置 CONFIG_LWIP_SNTP_UPDATE_DELAY。
如需查看示例代码,请前往 protocols/sntp 目录。该目录下的示例展示了如何基于 lwIP SNTP 库实现时间同步。
也可以直接使用 lwIP API,但请务必注意线程安全。线程安全的 API 如下:
sntp_set_time_sync_notification_cb()
用于设置通知时间同步过程的回调函数。
sntp_get_sync_status()
和 sntp_set_sync_status()
用于获取/设置时间同步状态。
sntp_set_sync_mode()
用于设置同步模式。
esp_sntp_setoperatingmode()
用于设置首选操作模式。ESP_SNTP_OPMODE_POLL
和 esp_sntp_init()
可初始化 SNTP 模块。
esp_sntp_setservername()
用于配置特定 SNTP 服务器。
要设置本地时区,请使用以下 POSIX 函数:
调用 setenv()
,将 TZ
环境变量根据设备位置设置为正确的值。时间字符串的格式与 GNU libc 文档 中描述的相同(但实现方式不同)。
调用 tzset()
,为新的时区更新 C 库的运行数据。
完成上述步骤后,请调用标准 C 库函数 localtime()
。该函数将返回排除时区偏差和夏令时干扰后的准确本地时间。
2036 年和 2038 年溢出问题
SNTP/NTP 2036 年溢出问题
SNTP/NTP 时间戳为 64 位无符号定点数,其中前 32 位表示整数部分,后 32 位表示小数部分。该 64 位无符号定点数代表从 1900 年 1 月 1 日 00:00 起经过的秒数,因此 SNTP/NTP 时间将在 2036 年溢出。
为了解决这一问题,可以使用整数部分的 MSB(惯例为位 0)来表示 1968 年到 2104 年之间的时间范围(查看 RFC2030 了解更多信息),这一惯例将使得 SNTP/NTP 时间戳的生命周期延长。该惯例会在 lwIP 库的 SNTP 模块中实现,因此 ESP-IDF 中 SNTP 相关功能在 2104 年之前能够经受住时间的考验。
Unix 时间 2038 年溢出问题
Unix 时间(类型 time_t
)此前为有符号的 32 位整数,因此将于 2038 年溢出(即 Y2K38 问题)。为了解决 Y2K38 问题,ESP-IDF 从 v5.0 版本起开始使用有符号的 64 位整数来表示 time_t
,从而将 time_t
溢出推迟 2920 亿年。
API 参考
Header File
components/lwip/include/apps/esp_sntp.h
This header file can be included with:
#include "esp_sntp.h"
This header file is a part of the API provided by the lwip
component. To declare that your component depends on lwip
, add the following to your CMakeLists.txt:
REQUIRES lwip
PRIV_REQUIRES lwip
void sntp_sync_time(struct timeval *tv)
This function updates the system time.
This is a weak-linked function. It is possible to replace all SNTP update functionality by placing a sntp_sync_time() function in the app firmware source. If the default implementation is used, calling sntp_set_sync_mode() allows the time synchronization mode to be changed to instant or smooth. If a callback function is registered via sntp_set_time_sync_notification_cb(), it will be called following time synchronization.
tv – Time received from SNTP server.
void sntp_set_sync_mode(sntp_sync_mode_t sync_mode)
Set the sync mode.
Modes allowed: SNTP_SYNC_MODE_IMMED and SNTP_SYNC_MODE_SMOOTH.
sync_mode – Sync mode.
sntp_sync_status_t sntp_get_sync_status(void)
Get status of time sync.
After the update is completed, the status will be returned as SNTP_SYNC_STATUS_COMPLETED. After that, the status will be reset to SNTP_SYNC_STATUS_RESET. If the update operation is not completed yet, the status will be SNTP_SYNC_STATUS_RESET. If a smooth mode was chosen and the synchronization is still continuing (adjtime works), then it will be SNTP_SYNC_STATUS_IN_PROGRESS.
SNTP_SYNC_STATUS_RESET: Reset status. SNTP_SYNC_STATUS_COMPLETED: Time is synchronized. SNTP_SYNC_STATUS_IN_PROGRESS: Smooth time sync in progress.
void sntp_set_time_sync_notification_cb(sntp_sync_time_cb_t callback)
Set a callback function for time synchronization notification.
callback – a callback function
void sntp_set_sync_interval(uint32_t interval_ms)
Set the sync interval of SNTP operation.
Note: SNTPv4 RFC 4330 enforces a minimum sync interval of 15 seconds. This sync interval will be used in the next attempt update time throught SNTP. To apply the new sync interval call the sntp_restart() function, otherwise, it will be applied after the last interval expired.
interval_ms – The sync interval in ms. It cannot be lower than 15 seconds, otherwise 15 seconds will be set.
void esp_sntp_setoperatingmode(esp_sntp_operatingmode_t operating_mode)
Sets SNTP operating mode. The mode has to be set before init.
operating_mode – Desired operating mode
void esp_sntp_setserver(u8_t idx, const ip_addr_t *addr)
Sets SNTP server address.
idx – Index of the server
addr – IP address of the server
typedef void (*sntp_sync_time_cb_t)(struct timeval *tv)
SNTP callback function for notifying about time sync event.
Param tv
Time received from SNTP server.