{IDF_TARGET_EXT_CRYSTAL_PIN:default="Not updated", esp32="32K_XP and 32K_XN", esp32s2="XTAL_32K_P and XTAL_32K_N", esp32s3="XTAL_32K_P and XTAL_32K_N", esp32c3="XTAL_32K_P and XTAL_32K_N"}
{IDF_TARGET_NAME} uses two hardware timers for the purpose of keeping system time. System time can be kept by using either one or both of the hardware timers depending on the application's purpose and accuracy requirements for system time. The two hardware timers are:
-**RTC timer**: This timer allows time keeping in various sleep modes, and can also persist time keeping across any resets (with the exception of power-on resets which reset the RTC timer). The frequency deviation depends on the `RTC Timer Clock Sources`_ and affects the accuracy only in sleep modes, in which case the time will be measured at 6.6667 μs resolution.
-**High-resolution timer**: This timer is not available in sleep modes and will not persist over a reset, but has greater accuracy. The timer uses the APB_CLK clock source (typically 80 MHz), which has a frequency deviation of less than ±10 ppm. Time will be measured at 1 μs resolution.
It is recommended that users stick to the default option as it provides the highest accuracy. However, users can also select a different setting via the :ref:`CONFIG_NEWLIB_TIME_SYSCALL` configuration option.
-``Internal {IDF_TARGET_RTC_CLK_FRE} RC oscillator`` (default): Features the lowest Deep-sleep current consumption and no dependence on any external components. However, the frequency stability of this clock source is affected by temperature fluctuations, so time may drift in both Deep-sleep and Light-sleep modes.
:not esp32c2:- ``External 32 kHz crystal``: Requires a 32 kHz crystal to be connected to the {IDF_TARGET_EXT_CRYSTAL_PIN} pins. This source provides a better frequency stability at the expense of a slightly higher (by 1 μA) Deep-sleep current consumption.
-``External 32 kHz oscillator at {IDF_TARGET_EXT_OSC_PIN} pin``: Allows using 32 kHz clock generated by an external circuit. The external clock signal must be connected to the {IDF_TARGET_EXT_OSC_PIN} pin. The amplitude should be less than 1.2 V for sine wave signal and less than 1 V for square wave signal. Common mode voltage should be in the range of 0.1 < Vcm < 0.5xVamp, where Vamp stands for signal amplitude. In this case, the {IDF_TARGET_EXT_OSC_PIN} pin cannot be used as a GPIO pin.
-``Internal {IDF_TARGET_INT_OSC_FRE} oscillator, divided by 256 ({IDF_TARGET_INT_OSC_FRE_DIVIDED})``: Provides better frequency stability than the ``Internal {IDF_TARGET_RTC_CLK_FRE} RC oscillator`` at the expense of a higher (by 5 μA) Deep-sleep current consumption. It also does not require external components.
The choice depends on your requirements for system time accuracy and power consumption in sleep modes. To modify the RTC clock source, set :ref:`CONFIG_RTC_CLK_SRC` in project configuration.
To get the current time, use the POSIX function ``gettimeofday()``. Additionally, you can use the following standard C library functions to obtain time and manipulate it:
To set the current time, you can use the POSIX functions ``settimeofday()`` and ``adjtime()``. They are used internally in the lwIP SNTP library to set current time when a response from the NTP server is received. These functions can also be used separately from the lwIP SNTP library.
The function to use inside the lwIP SNTP library depends on the sync mode for system time. Use the function :cpp:func:`sntp_set_sync_mode` to set one of the following sync modes:
-:cpp:enumerator:`SNTP_SYNC_MODE_IMMED` (default): Updates system time immediately upon receiving a response from the SNTP server after using ``settimeofday()``.
-:cpp:enumerator:`SNTP_SYNC_MODE_SMOOTH`: Updates time smoothly by gradually reducing time error using the function ``adjtime()``. If the difference between the SNTP response time and system time is more than 35 minutes, update system time immediately by using ``settimeofday()``.
An application with this initialization code will periodically synchronize the time. The time synchronization period is determined by :ref:`CONFIG_LWIP_SNTP_UPDATE_DELAY` (the default value is one hour). To modify the variable, set :ref:`CONFIG_LWIP_SNTP_UPDATE_DELAY` in project configuration.
A code example that demonstrates the implementation of time synchronization based on the lwIP SNTP library is provided in the :example:`protocols/sntp` directory.
1. Call ``setenv()`` to set the ``TZ`` environment variable to the correct value based on the device location. The format of the time string is the same as described in the `GNU libc documentation <https://www.gnu.org/software/libc/manual/html_node/TZ-Variable.html>`_ (although the implementation is different).
2. Call ``tzset()`` to update C library runtime data for the new timezone.
Once these steps are completed, call the standard C library function ``localtime()``, and it will return the correct local time taking into account the timezone offset and daylight saving time.
Currently, this requires building the cross-compiler toolchain from scratch. See the instructions for building the toolchain in :doc:`/get-started/linux-macos-setup`. To enable 64-bit ``time_t`` support in the toolchain, you need to remove the ``--enable-newlib-long-time_t`` option from the ``crosstool-NG/samples/xtensa-esp32-elf/crosstool.config`` file before building the toolchain.
If you need to make the program compatible with both 32-bit and 64-bit ``time_t``, you may use the following methods:
- In C or C++ source files, ``_USE_LONG_TIME_T`` preprocessor macro will be defined if 32-bit ``time_t`` is used. You need to include ``<sys/types.h>`` to make this macro available.
- In CMake files, ``TIME_T_SIZE`` IDF build property will be set to the size of ``time_t`` in bytes. You may call ``idf_build_get_property(var TIME_T_SIZE)`` to get the value of this property into a CMake variable ``var``. See :ref:`ESP-IDF CMake Build System API <cmake_buildsystem_api>` for more information about ``idf_build_get_property``.