Akward date parsing

Hi,

I'm trying to parse Home assistant API results and I've got a weird behaviour.

#include <HTTPClient.h>
#include <ArduinoJson.h>
#include <TimeLib.h>

#include "arduino_secrets.h"
#include "common.h"
#include "weather-forecast.h"

OneWeekWeatherForecast WeatherForecastService::get() {
  OneWeekWeatherForecast oneWeekWeatherForecast;
  HTTPClient http;
  TimeElements tm;
  int parsedYear, parsedMonth, parsedDay;
  char* tmp;
  String homeAssistantWeatherURL;
  homeAssistantWeatherURL += F("http://");
  homeAssistantWeatherURL += SECRET_HOME_ASSISTANT_HOST;
  homeAssistantWeatherURL += F("/api/states/weather.talence");
  http.begin(homeAssistantWeatherURL);

  String bearer;
  bearer += F("Bearer ");
  bearer += SECRET_HOME_ASSISTANT_TOKEN;
  http.addHeader("Authorization", bearer);

  String message;
  message += F("Récupération de la météo");
  message += F(" (GET ");
  message += homeAssistantWeatherURL;
  message += F(")");
  Serial.println(message);

  int httpCode;
  int retry = 0;

  do {
    httpCode = http.GET();
    retry++;
    Serial.println("...");
  } while (httpCode <= 0 && retry < HTTP_RETRY);

  if (httpCode > 0) {
    Serial.println("OK");
    Serial.println("");

    String response = http.getString();
    http.end();
    DynamicJsonDocument doc(8192);
    DeserializationError error = deserializeJson(doc, response);
    if (error) {
      Serial.print(F("deserializeJson() failed: "));
      Serial.println(error.c_str());
      return oneWeekWeatherForecast;
    }

    for (int dayIndex = 0; dayIndex < 7; dayIndex++) {
      // https://arduino.stackexchange.com/questions/55248/how-to-parse-20180810t143000z-to-time-t

/*
Sample result :
{
                "datetime": "2023-07-09T02:00:00+02:00",
                "condition": "sunny",
                "temperature": 29.8,
                "templow": 19.6,
                "precipitation": 3.6
            }
*/
      const char* datetime = doc["attributes"]["forecast"][dayIndex]["datetime"];

      sscanf(datetime, "%d-%d-%dT", &parsedYear, &parsedMonth, &parsedDay);

      tm.Year = CalendarYrToTm(parsedYear);
      tm.Month = parsedMonth;
      tm.Day = parsedDay;
      time_t parsedDatetime = makeTime(tm);

      String condition = doc["attributes"]["forecast"][dayIndex]["condition"];

      String message;
      // Datetime
      message += datetime;
      message += F(" - ");

      // Parsed raw
      message += String(parsedDay);
      message += F("/");
      message += String(parsedMonth);
      message += F("/");
      message += String(parsedYear);
      message += F(" - ");

      // Parsed - 1970
      message += String(parsedDay);
      message += F("/");
      message += String(parsedMonth);
      message += F("/");
      message += String(CalendarYrToTm(parsedYear));
      message += F(" - ");

      // Read again
      message += String(day(parsedDatetime));
      message += F("/");
      message += String(month(parsedDatetime));
      message += F("/");
      message += String(year(parsedDatetime));
      Serial.println(message);

  /*
The problem :
2023-07-09T02:00:00+02:00 - 9/7/2023 - 9/7/53 - 15/7/2023
2023-07-10T02:00:00+02:00 - 10/7/2023 - 10/7/53 - 16/7/2023
2023-07-11T02:00:00+02:00 - 11/7/2023 - 11/7/53 - 17/7/2023
2023-07-12T02:00:00+02:00 - 12/7/2023 - 12/7/53 - 18/7/2023
2023-07-13T02:00:00+02:00 - 13/7/2023 - 13/7/53 - 19/7/2023
2023-07-14T02:00:00+02:00 - 14/7/2023 - 14/7/53 - 20/7/2023
2023-07-15T02:00:00+02:00 - 15/7/2023 - 15/7/53 - 21/7/2023
*/

      oneWeekWeatherForecast.days[dayIndex] = {
        parsedDatetime,
        condition,
        doc["attributes"]["forecast"][dayIndex]["temperature"],
        doc["attributes"]["forecast"][dayIndex]["templow"],
        doc["attributes"]["forecast"][dayIndex]["precipitation"]
      };
    }

    return oneWeekWeatherForecast;

  } else {
    String error;
    error += F("KO -> code erreur = ");
    error += String(httpCode);
    Serial.println(error);
    Serial.println("");
    return oneWeekWeatherForecast;
  }
}

I've got a different day when I read again the time_t. Do you have any clue about what my problem can be ?

Thank you

what string are you parsing and what are your results?

Input :

"datetime": "2023-07-09T02:00:00+02:00"

Output :

2023-07-09T02:00:00+02:00 - 9/7/2023 - 9/7/53 - 15/7/2023

You posted this link:
https://arduino.stackexchange.com/questions/55248/how-to-parse-20180810t143000z-to-time-t

There were some solutions there. Did you follow them? What happened?

is it the parsing part or the part used to construct the 3 strings?

is it this part of the code producing the "15" instead of a "9"?

Yep, I've tried. It was the same problem :\

I've not understand your first question.
For the second one,

      // Read again
      message += String(day(parsedDatetime));
      message += F("/");

Yes, that is the code producing the "15" instead of a "9".

it looks like the parsedDay was extracted correctly because it printed correctly in the first 2 cases

and it is used to construct parsedDatetime

which is then disassembled in

so is there a problem in

or

Yes probably but I'm searching since 2 days and I can't find out what is happening...

there have been so many ways to deal with time that i'm not familiar with the approach you're using.

but since you have the day in tm.Day why are you using day() to extract it? guessing you're exploring

have you tried printing tm.Day to make sure it's set correctly?

After two days, I've found out. As soon as I set

  tm.Second = 0;
  tm.Hour = 12;
  tm.Minute = 0;

It works ... I don't know why but it works ...

may be better to make sure it's fully initialized

  TimeElements tm = {};

will initialize every element of tm to zero

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.