user48730: Why do I get wrong result when using time.h library when using AVR boards, such Nano/Uno/Pro Micro (while when using TimeLib.h).
OUTPUT (for given Epoch ):
TimeLib: 2022-04-02 16:11:20
time.h: 0152-03-01 16:11:20
CODE:
#define CASE 1

#if CASE == 1
#include <time.h>
#elif CASE == 2
#include <TimeLib.h>
#endif

time_t bootTime = 1648915880;

void setup()
{
  // put your setup code here, to run once:
  Serial.begin(115200);
  Serial.println("\nStart!");
  delay(1000);

  char clk2[40];

#if CASE == 1
  struct tm *tm = localtime(&bootTime);
  sprintf(clk2, "%04d-%02d-%02d %02d:%02d:%02d", tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec);
  
#elif CASE == 2
  sprintf(clk2, "%04d-%02d-%02d %02d:%02d:%02d", year(bootTime), month(bootTime), day(bootTime), hour(bootTime), minute(bootTime), second(bootTime));
#endif
  Serial.println(clk2);
}

void loop()
{
  // put your main code here, to run repeatedly:
}


user4143: You are assuming the avr-libc "epoch" is the same as the UNIX "epoch". It isn't. According to the manual:

Though not specified in the standard, it is often expected that time_t is a signed integer representing an offset in seconds from Midnight Jan 1 1970... i.e. 'Unix time'. This implementation uses an unsigned 32 bit integer offset from Midnight Jan 1 2000. The use of this 'epoch' helps to simplify the conversion functions, while the 32 bit value allows time to be properly represented until Tue Feb 7 06:28:15 2136 UTC. The macros UNIX_OFFSET and NTP_OFFSET are defined to assist in converting to and from Unix and NTP time stamps.

So you need to subtract the UNIX_OFFSET from your time value before passing it to any avr-libc functions.
Also you should initialize the time system with set_zone() and similar functions.

48730: <p>Why do I get wrong result when using <code>time.h</code> library when using AVR boards, such Nano/Uno/Pro Micro (while when using <code>TimeLib.h</code>).</p>
<p>OUTPUT (for given Epoch ):</p>
<p><code>TimeLib</code>: 2022-04-02 16:11:20</p>
<p><code>time.h</code>: 0152-03-01 16:11:20</p>
<p>CODE:</p>
<pre><code>#define CASE 1

#if CASE == 1
#include &lt;time.h&gt;
#elif CASE == 2
#include &lt;TimeLib.h&gt;
#endif

time_t bootTime = 1648915880;

void setup()
{
  // put your setup code here, to run once:
  Serial.begin(115200);
  Serial.println(&quot;\nStart!&quot;);
  delay(1000);

  char clk2[40];

#if CASE == 1
  struct tm *tm = localtime(&amp;bootTime);
  sprintf(clk2, &quot;%04d-%02d-%02d %02d:%02d:%02d&quot;, tm-&gt;tm_year, tm-&gt;tm_mon, tm-&gt;tm_mday, tm-&gt;tm_hour, tm-&gt;tm_min, tm-&gt;tm_sec);
  
#elif CASE == 2
  sprintf(clk2, &quot;%04d-%02d-%02d %02d:%02d:%02d&quot;, year(bootTime), month(bootTime), day(bootTime), hour(bootTime), minute(bootTime), second(bootTime));
#endif
  Serial.println(clk2);
}

void loop()
{
  // put your main code here, to run repeatedly:
}
</code></pre>
 4143: <p>You are assuming the avr-libc &quot;epoch&quot; is the same as the UNIX &quot;epoch&quot;. It isn't. According to <a href="https://www.nongnu.org/avr-libc/user-manual/group__avr__time.html#gaa9336f97d394e8e02d97b9ff4fb0aca2" rel="nofollow noreferrer">the manual</a>:</p>
<blockquote>
<p>Though not specified in the standard, it is often expected that time_t is a signed integer representing an offset in seconds from Midnight Jan 1 1970... i.e. 'Unix time'. <strong>This implementation uses an unsigned 32 bit integer offset from Midnight Jan 1 2000.</strong> The use of this 'epoch' helps to simplify the conversion functions, while the 32 bit value allows time to be properly represented until Tue Feb 7 06:28:15 2136 UTC. The macros UNIX_OFFSET and NTP_OFFSET are defined to assist in converting to and from Unix and NTP time stamps.</p>
</blockquote>
<p>So you need to subtract the <code>UNIX_OFFSET</code> from your time value before passing it to any avr-libc functions.</p>
<p>Also you should initialize the time system with <code>set_zone()</code> and similar functions.</p>
