1

Can anyone provide a sample code that would convert a human readable date like 2019-10-27 22:10:35 to a unix timestamp like 1572214235?

I found many topics about it, but they eider refer to out of date libraries, or they seem to address more complex time functions, I find it hard to extract this functionality from them.

1

If you have a fixed format you can use strtok() to slice the string into individual segments, then convert those segments to integers. They can then be used with TimeLib.h with the setTime() function. You can then query TimeLib for the unix timestamp with now().

Edit: using PaulStoffregen's TimeLib, this code sets current time and returns current unix timestamp.

#include <TimeLib.h>

void setup() {
  Serial.begin(9600);

  // hour, min, sec, day, month, year
  setTime(22, 30, 11, 29, 3, 2019);

  // 1553898611
  Serial.println(now());
}
void loop() {}

Edit 2: And to convert any given date to a unix timestamp (without setting current time):

#include "TimeLib.h"

tmElements_t my_time;  // time elements structure
time_t unix_timestamp; // a timestamp

void setup() {
  Serial.begin(9600);

  // convert a date and time into unix time, offset 1970
  my_time.Second = 0;
  my_time.Hour = 23;
  my_time.Minute = 0;
  my_time.Day = 25;
  my_time.Month = 3 - 1;      // months start from 0, so deduct 1
  my_time.Year = 2017 - 1970; // years since 1970, so deduct 1970

  unix_timestamp =  makeTime(my_time);
  Serial.println(unix_timestamp);
}

void loop() {}
  • I already have them into separate values like year, month, etc, I just have no clue on how the code should look when using the time library. I am new to Arduino. – adrianTNT Oct 28 at 14:17
  • Pass the values to setTime() - I forget the order, but I think it's setTime(hours, minutes, seconds, year, month, day) - though check the documentation or source to be sure. Then you get the time since the unix epoch with now(). – Majenko Oct 28 at 14:19
  • Thanks, I was able to do that and added a full sample code in your answer, I still need a way to convert any given date (not just current time). – adrianTNT Oct 28 at 15:11
  • I hope you don't mind, I altered a code once more so I am able to select your answer as the correct one :D – adrianTNT Oct 28 at 20:53
2

After parsing the time into numbers, you can use the standard C time library time.h. More specifically, use the mktime function to convert a struct tm into a time_t, and use difftime to get the seconds since the start of the Unix expoch:

#include <time.h>

void loop() {
    struct tm ltm = {0};
    ltm.tm_year = 2019 - 1900;
    ltm.tm_mon  = 11 - 1;
    ltm.tm_mday = 5;

    double epoch_seconds = difftime(mktime(&ltm), (time_t)0);
    Serial.print("Remember, remember, ");
    Serial.print(epoch_seconds);
}

Note that in struct tm, the year starts at 1900 and the month starts at 0.

  • So I replace 2019 with my year and I leave/append the ` -1900` part, same for month, then where do I specify the hour, minute and second ? – adrianTNT Oct 27 at 16:40
  • @adrianTNT Yes, you can use tm_hour, tm_min and tm_sec to specify hours, minutes and seconds, respectively. The available fields of struct tm are linked in the reference. Cf. en.cppreference.com/w/c/chrono/tm – Heinrich supports Monica Oct 27 at 20:58
  • I tried the code, seems close but I get a timestamp like 626227200.00 which (without .00) is around 1989, I am lost. – adrianTNT Oct 28 at 14:13
  • Serial.print might have some trouble printing double-precision floats. Does it work when you change it to Serial.print((float)epoch_seconds, 0);? This should also cut off the '.00' decimal places at the end. – Heinrich supports Monica Oct 28 at 14:32
  • Do I have to set current time first ? If I just set year to 0 and no month or day, it prints a timestamp since 2006-02-07 (1139293696). In another answer I was able to set current time and print current timestamp, but converting any date with mktime would be nice. – adrianTNT Oct 28 at 15:26

Not the answer you're looking for? Browse other questions tagged or ask your own question.