c++carduinoarduino-esp8266time-t

Char to time_t conversion always returns Wed Dec 31 23:59:59 1969


I am working on some code for my ESP8266 in Arduino. I want to send a timestamp to another ESP via UDP.

In the setup(){ I initialize the time using

configTime(3 * 3600, 0, "pool.ntp.org", "time.nist.gov"); 

and in the loop(){

time_t timestamp = time(nullptr);

to get the time. I then send it to another ESP

Udp.write(ctime(&timestamp));

Where I need to make a time_t again to compare it to the actual time.

But for testing purposes, I send time as a char through terminal in UDP using echo -n "Fri Feb 28 14:44:11 2020" >/dev/udp/192.168.43.248/4210 from my MacBook Pro (MacOS Mojave).

The Serial Monitor shows the in- and output is the following:

UDP packet contents: Fri Feb 28 14:44:11 2020
Wed Dec 31 23:59:59 1969

My Code is:

time_t convertStringToTime_t(char timestamp []) {
  time_t result = time(NULL);
  const char *timestampString = timestamp;
  int weekDay, month, dd, hh, mm, ss, yyyy = 0;
  struct tm timestampFromString = {0};

  //input     Fri Feb 28 16:40:11 2020
  //output    Wed Dec 31 23:59:59 1969 TODO always same output?!

  sscanf(timestampString, "%s %s %d %d:%d:%d %d", &weekDay, &month, &dd, &hh, &mm, &ss, &yyyy);

  timestampFromString.tm_year = yyyy - 1900; //years since 1900
  timestampFromString.tm_mon = month - 1;
  timestampFromString.tm_wday = weekDay;
  timestampFromString.tm_mday = dd;
  timestampFromString.tm_hour = hh;
  timestampFromString.tm_min = mm;
  timestampFromString.tm_sec = ss;
  timestampFromString.tm_isdst = -1;

  result = mktime(&timestampFromString);
  // mktime   Convert tm structure to time_t
  return result;
}

I saw this thread but it doesn't help me at all :/ I also tried using sscanf but no difference. I think I do something wrong in scanf?

solved: Thanks to @thomachan I realized I tried to put the Month + Day chars into int's (I could solve that by converting the chars to ints).

But I listened to @Maxim Egorushkin and used the simpler approach using the time_t value:

char *buffer;
time_t i = strtoul(incomingPacket, &buffer, 10);

Solution

  • If you don't require human-readable time, you can send the value of time_t - the number of seconds since Unix epoch.

    date +%s > /dev/udp/192.168.43.248/4210
    

    The receiver can parse it from string to time_t with std::strtoul.