Время UNIX в мс в человеческую дату и время

Несколько дней мучался с чем-то.

Загрузка данных с веб-сайта в формате JSON, включая обновленную дату и время в миллисекундах. Это дата EPOCH, и я могу получить правильное значение, используя один из сайтов онлайн-конвертера, epochconvertor.com

Тем не менее, когда я пытаюсь разобрать его в своем скетче, он не настраивает правильную дату.

JSON «currentupdatedms»: 1588312648603

Конвертер отображается как: 1 мая 2020 г. 05:57:28.603

Мой скетч показывает: 1 мая 2020 г. 02:33:00

Это в формате JSON, и я не могу использовать тип Long, поскольку он состоит из 13 цифр. Пробовал Long Long, и он принимает значение, но когда я позже делю на 1000, чтобы получить секунды, число полностью меняется, когда я пытаюсь распечатать его на серийный номер или на OLED.

Планируется использовать библиотеку Timeh для отображения даты и времени в формате человека.

Любые мысли приветствуются.

Вот мой код, и я пробовал разные методы:

#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <ArduinoJson.h>
#include <TimeLib.h>
#include <time.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128 // Ширина OLED-дисплея в пикселях
#define SCREEN_HEIGHT 64 // Высота OLED-дисплея в пикселях

// Объявление для дисплея SSD1306, подключенного к I2C (контакты SDA, SCL)
#define OLED_RESET     4 // Номер вывода сброса (или -1, если используется общий вывод сброса Arduino)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

#define ARDUINOJSON_JSON_LONG_LONG 1 //Не нужен???
#define   ONE_HOUR   3600
const size_t capacity = JSON_OBJECT_SIZE(8) + 140;
DynamicJsonDocument doc(capacity);

/*Notes
   Need to look at conversion of Update and Changed times as they are not showing correctly
   Move the conversion of time datetime in ms to a seperate function
   Move the get request and JSON section to seperate function
*/

const char* ssid = "SSID";
const char* password = "PWD";

void setup () {

  Serial.begin(4800);

  Wire.begin(2, 0);           // устанавливаем контакты I2C (SDA = GPIO2, SCL = GPIO0), тактовая частота по умолчанию 100 кГц

  // SSD1306_SWITCHCAPVCC = генерировать внутреннее напряжение дисплея от 3,3 В
  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println(F("SSD1306 allocation failed"));
    for (;;); // Не продолжать, цикл навсегда
  }

  display.clearDisplay();
  display.setTextColor(SSD1306_WHITE);

  WiFi.begin(ssid, password);

  display.setCursor(0, 0);
  display.println(F("Connecting to Wifi..."));
  display.display();

  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.println("Connecting to Wifi...");
  }

  display.setCursor(0, 10);
  display.println(F("Wifi Connected..."));
  display.display();
}

void loop() {

  if (WiFi.status() == WL_CONNECTED) { //Проверяем статус соединения WiFi

    display.setCursor(0, 20);
    display.println(F("Requesting Data..."));
    display.display();
    delay(2000); // Пауза на 2 секунды

    HTTPClient http;  //Объявить объект класса HTTPClient

    http.begin("http://corona.tuply.co.za/DataHandler.ashx?w=s&uq=8f1fp8p5jdxi84481"); // Указываем место назначения запроса
    int httpCode = http.GET();                                                                  //Отправить запрос

    if (httpCode > 0) { // Проверяем возвращаемый код

      String payload = http.getString();   //Получить полезную нагрузку ответа на запрос
      Serial.println(payload);                     // Печатаем полезную нагрузку ответа

      deserializeJson(doc, payload);

      int TotalCases = doc["TotalCases"];
      int TotalCasesToday = doc["TotalCasesToday"];
      int TotalDeaths = doc["TotalDeaths"];
      int TotalDeathsToday = doc["TotalDeathsToday"];
      int TotalRecovered = doc["TotalRecovered"];
      int TotalTerritories = doc["TotalTerritories"];
      long long CurrentUpdatedMS = doc["CurrentUpdatedMS"];
      long long CurrentChangedMS = doc["CurrentChangedMS"];

      // задержка (10000);

      time_t CurrentUpdateMS_t = (CurrentUpdatedMS/1000) + ONE_HOUR; //Добавлено ONE_HOUR по BST

      char buffUpdateMS[32];
      sprintf(buffUpdateMS, "%02d/%02d/%02d %02d:%02d:%02d", day(CurrentUpdateMS_t), month(CurrentUpdateMS_t), year(CurrentUpdateMS_t), hour(CurrentUpdateMS_t), minute(CurrentUpdateMS_t), second(CurrentUpdateMS_t));
      Serial.print("U:");
      Serial.println(buffUpdateMS);
      Serial.print("ctime: ");
      Serial.println(ctime(&CurrentUpdateMS_t));

      time_t CurrentChangedMS_t = CurrentChangedMS/1000 + ONE_HOUR; //Добавлено ONE_HOUR по BST

      char buffChangedMS[32];
      sprintf(buffChangedMS, "%02d/%02d/%02d %02d:%02d:%02d", day(CurrentChangedMS_t), month(CurrentChangedMS_t), year(CurrentChangedMS_t), hour(CurrentChangedMS_t), minute(CurrentChangedMS_t), second(CurrentChangedMS_t));
      Serial.print("C:");
      Serial.println(buffChangedMS);
      Serial.print("ctime: ");
      Serial.println(ctime(&CurrentChangedMS_t));

      display.clearDisplay();

      display.setCursor(0, 0);
      display.print(F("T Cases: "));
      display.println(TotalCases);

      Serial.print("Total Cases: ");
      Serial.println(TotalCases);

      Serial.print("Total Cases Today: ");
      Serial.println(TotalCasesToday);

      display.setCursor(0, 10);
      display.print(F("T Deaths: "));
      display.println(TotalDeaths);

      Serial.print("Total Deaths: ");
      Serial.println(TotalDeaths);

      Serial.print("Total Deaths Today: ");
      Serial.println(TotalDeathsToday);

      display.setCursor(0, 20);
      display.print(F("T Recov: "));
      display.println(TotalRecovered);

      Serial.print("Total Recovered: ");
      Serial.println(TotalRecovered);

      Serial.print("Total Territories: ");
      Serial.println(TotalTerritories);

      display.setCursor(0, 30);
      display.print(F("U T: "));
      display.println(buffUpdateMS);

      display.setCursor(0, 40);
      display.print(F("C T: "));
      display.println(buffChangedMS);

      display.display();

    }

    http.end();   //Закрыть соединение

  }

  delay(60000);    //Отправлять запрос каждые 60 секунд

}

Если я запущу это сейчас, я получу эту строку JSON:

{"TotalCases":4036128,"TotalCasesToday":26837,"TotalDeaths":276825,"TotalDeathsToday":849,"TotalRecovered":1400460,"TotalTerritories":214,"CurrentUpdatedMS":1589027095790,"CurrentChangedMS": 1589026765665

CurrentUpdateMS = 1589027095790, то есть суббота, 09 мая 2020 г., 13:24:55, при условии, что может быть разница в час с BST.

Вместо этого я получаю:

Сб, 9 мая, 13:23:32 2020

Также кажется, что он остается прежним после обновления, которое я установил на 60 секунд.

Я попробовал библиотеку Time.h с теми же результатами.

Спасибо за любой вклад или предложения.

, 👍1

Обсуждение

1. Не смешивайте time.h с TimeLib.h: они оба определяют свою собственную версию time_t. 2. Эта программа слишком длинная для вопроса здесь. Вы должны разбить свою проблему на маленькие части и решать их по одной. Во-первых, Serial.println(CurrentUpdatedMS), чтобы узнать, заключается ли проблема в десериализации JSON или в интерпретации числа как времени. Затем напишите [минимальный воспроизводимый пример](https://stackoverflow.com/help/minimal-reproducible-example), посвященный _только_ этой проблеме. См. мой ответ как пример того, как может выглядеть «минимальный воспроизводимый пример»., @Edgar Bonet


1 ответ


1

Трудно понять, что не так с вашим кодом... потому что вы не показывая это в вопросе! Вот базовый тест, который я провел на своем Uno:

#include <time.h>

const uint64_t ms = 1588312648603;

void setup() {
    time_t t = ms/1000 - UNIX_OFFSET;
    Serial.begin(9600);
    Serial.println(ctime(&t));
}

void loop(){}

Вывод:

Fri May 01 05:57:28 2020

Обратите внимание, что это <time.h> исходит из avr-libc. Он использует эпоху отличается от эпохи Unix, поэтому исправление UNIX_OFFSET.

ОБНОВЛЕНО: я попытался заменить <time.h> avr-libc на Adafruit RTClib (объявление DateTime t(ms/1000);) и Paul Библиотека времени Stoffregentime_t t = ms/1000;). В целом случаев, когда я получаю одинаковое время.

,