user78174: With ESP8266, I noticed that for the first 1 or 2 loops, localtime returns Unix epoch (1970 date) until it has finished getting the actual time from NTP, after which point I see the real date. Sometimes it can take 10 seconds or so before NTP is available, depending on what time server I use and how frequently I make requests to it (most time servers have request throttling, it seems).
Right now, I'm checking whether the date is valid by testing if the year is 70 but this seems weird and hacky. Is there a better way? For instance, is there a function that returns true if the NTP update has been successful or -1 if not?
All of the examples of localtime that I have found so far don't seem to check if the date is valid, and if I run their code, it almost always prints the 1970 Unix epoch date on the first loop.
#define TIME_SERVER_1 "time.google.com"
#define TIME_SERVER_2 "time.nist.gov"
#define TIME_SERVER_3 "pool.ntp.org"
#define TIMEZONE TZ_Europe_London

void setup() {

// ..

  configTime(TIMEZONE, TIME_SERVER_1, TIME_SERVER_2, TIME_SERVER_3);

// ..

}

void loop() { 

// ..

      time_t now;
      time(&now);
      struct tm* timeinfo = localtime(&now);

      // TODO: maybe there's a better way to check unknown time?
      if (timeinfo->tm_year == 70) {
        TRACE_LN(F("ntp not yet available"));
      } else {
        epoch = mktime(timeinfo);
      }

//..

}


user7508: If time() doesn't return -1 as expected when it doesn't know, then I
have nothing cleaner (less “hacky”) to suggest. That being said,
converting the scalar time to a broken-down representation is a
relatively expensive operation. I suggest avoiding it and just comparing
the returned time to an arbitrary threshold:
// May we consider this valid as the "current" time?
// If it is too far in the past, it is centainly not valid.
static bool is_time_valid(time_t t) {
    const time_t old_past = 1577836800;  // 2020-01-01T00:00:00Z
    return t >= old_past;
}


user31043: You can define a call back function which is triggered when SNTP updates the system time. There is an example of it on the GitHub esp8266/Arduino project with a short description in the comments. The call back function is registered by the example function call settimeofday_cb(time_is_set) where time_is_set() is a user defined funtion.
I have an application (a timeswitch) which maintains an indicator to show how 'fresh' the current time status is. If it is stale, the time source reverts to an RTC until a new time can be fetched. It uses this callback mechanism for that purpose.

78174: <p>With ESP8266, I noticed that for the first 1 or 2 loops, <code>localtime</code> returns Unix epoch (1970 date) until it has finished getting the actual time from NTP, after which point I see the real date. Sometimes it can take 10 seconds or so before NTP is available, depending on what time server I use and how frequently I make requests to it (most time servers have request throttling, it seems).</p>
<p>Right now, I'm checking whether the date is valid by testing if the year is <code>70</code> but this seems weird and hacky. Is there a better way? For instance, is there a function that returns <code>true</code> if the NTP update has been successful or <code>-1</code> if not?</p>
<p>All of the examples of <code>localtime</code> that I have found so far don't seem to check if the date is valid, and if I run their code, it almost always prints the 1970 Unix epoch date on the first loop.</p>
<pre><code>#define TIME_SERVER_1 &quot;time.google.com&quot;
#define TIME_SERVER_2 &quot;time.nist.gov&quot;
#define TIME_SERVER_3 &quot;pool.ntp.org&quot;
#define TIMEZONE TZ_Europe_London

void setup() {

// ..

  configTime(TIMEZONE, TIME_SERVER_1, TIME_SERVER_2, TIME_SERVER_3);

// ..

}

void loop() { 

// ..

      time_t now;
      time(&amp;now);
      struct tm* timeinfo = localtime(&amp;now);

      // TODO: maybe there's a better way to check unknown time?
      if (timeinfo-&gt;tm_year == 70) {
        TRACE_LN(F(&quot;ntp not yet available&quot;));
      } else {
        epoch = mktime(timeinfo);
      }

//..

}
</code></pre>
 7508: <p>If <code>time()</code> doesn't return <code>-1</code> as expected when it doesn't know, then I
have nothing cleaner (less “hacky”) to suggest. That being said,
converting the scalar time to a broken-down representation is a
relatively expensive operation. I suggest avoiding it and just comparing
the returned time to an arbitrary threshold:</p>
<pre class="lang-cpp prettyprint-override"><code>// May we consider this valid as the &quot;current&quot; time?
// If it is too far in the past, it is centainly not valid.
static bool is_time_valid(time_t t) {
    const time_t old_past = 1577836800;  // 2020-01-01T00:00:00Z
    return t &gt;= old_past;
}
</code></pre>
 31043: <p>You can define a call back function which is triggered when SNTP updates the system time. There is an example of it on the <a href="https://github.com/esp8266/Arduino/blob/da48a52d7a8854363946fe0c05f02ec029c852c5/libraries/esp8266/examples/NTP-TZ-DST/NTP-TZ-DST.ino#L241" rel="nofollow noreferrer">GitHub esp8266/Arduino project</a> with a short description in the comments. The call back function is registered by the example function call <code>settimeofday_cb(time_is_set)</code> where time_is_set() is a user defined funtion.</p>
<p>I have an application (a timeswitch) which maintains an indicator to show how 'fresh' the current time status is. If it is stale, the time source reverts to an RTC until a new time can be fetched. It uses this callback mechanism for that purpose.</p>
