SparkTime and Unix epoch time

Silly question. When using the SparkTime library, I find that if I call time.now() and store it in an unsigned long, I get back a value that’s approximately 2208988800 seconds off of Unix epoch time. For example, I just (a few minutes ago) did it and got 3652206481, while the corresponding Unix epoch time was 1443217681.

Any idea what this is all about?

Thanks!

Hi @Butch

NTP time does not use Unix epoch but instead uses an epoch based on Jan 1, 1900. They should differ by the 70 years from 1900 to 1970, including all the leap days.

You can also use the built-in Time object and get Cloud time, as it were.

Here’s a function you can call using Time.year(), Time.month(), etc to get a UNIX time stamp. Courtesy of @BulldogLowell posted from my phone. Sorry for the lack of formatting (ScruffR: done). You can use Time.zone(-5) for say Central time to shift to local time. The -1 on month was needed but I can’t remember why and if I still use it so I encourage you to verify the return is accurate

time_t tmConvert_t(int YYYY, byte MM, byte DD, byte hh, byte mm, byte ss)
{
  struct tm t;
  t.tm_year = YYYY-1900;
  t.tm_mon = MM - 1;
  t.tm_mday = DD;
  t.tm_hour = hh;
  t.tm_min = mm;
  t.tm_sec = ss;
  t.tm_isdst = 0;
  time_t t_of_day = mktime(&t);
  return t_of_day;
}

Example of using the above function.
uint32_t now_time = tmConvert_t(Time.year(), Time.month(), Time.day(), Time.hour(), Time.minute(), Time.second());

And lesson learned. Time.now() doesn’t use the Time.zone(-5) offset but Time.hour() does.

1 Like

I have been using the time function with zone to set it to CST, but it does not handle DST. Any suggestions or built in libraries for determining if in DST?

You can track some of what's happening on this here...

https://github.com/spark/firmware/issues/211

meanwhile you could use a webhook to compare local time to GMT, but you have to know where on earth you are:

or you can simply calculate it, if you know you are in CST, for example:

bool IsDST(int dayOfMonth, int month, int dayOfWeek)  // North American values
{
  if (month < 3 || month > 11)
  {
    return false;
  }
  if (month > 3 && month < 11)
  {
    return true;
  }
  int previousSunday = dayOfMonth - dayOfWeek;
  if (month == 3)
  {
    return previousSunday >= 8;
  }
  return previousSunday <= 0;
}

and in loop()

bool daylightSavings = IsDST(Time.day(), Time.month(), Time.weekday());
Time.zone(daylightSavings? -5 : -6);

Like @BulldogLowell I use a webhook that returns data from WeatherUnderground API and they include a isDST field that I key off of. Can’t say it works perfectly because I have yet to transition but have forced it to non-DST and as soon as my webhook runs it is corrected without issue. I wrote a tutorial on using webhooks and specifically the WeatherUnderground API. That should help if you choose to go that direction.

Because January is month 1 in Particle's Time Library and the tm_mon (month) member of the tm struct in C++ expects zero through 11, January is zero. :wink: