Время 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 с теми же результатами.
Спасибо за любой вклад или предложения.
@Lifesigns, 👍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
Библиотека времени Stoffregen (с time_t t = ms/1000;
). В целом
случаев, когда я получаю одинаковое время.
- ESP8266: ошибка: 'getLocalTime' was not declared in this scope
- Как разобрать 20180810T143000Z в time_t
- Как найти разницу между двумя timestamp
- Установить time() на ESP8266
- ESP8266 ISO 8601 string to tm struct
- Каков идеальный способ проверить, готово ли время на ESP8266 через NTP?
- Не удалось изменить NtpClient для использования статического IP-адреса
- Безопасный при опрокидывании NTP дизайн с ESP8266 (Curiosity)
1. Не смешивайте time.h с TimeLib.h: они оба определяют свою собственную версию
time_t
. 2. Эта программа слишком длинная для вопроса здесь. Вы должны разбить свою проблему на маленькие части и решать их по одной. Во-первых,Serial.println(CurrentUpdatedMS)
, чтобы узнать, заключается ли проблема в десериализации JSON или в интерпретации числа как времени. Затем напишите [минимальный воспроизводимый пример](https://stackoverflow.com/help/minimal-reproducible-example), посвященный _только_ этой проблеме. См. мой ответ как пример того, как может выглядеть «минимальный воспроизводимый пример»., @Edgar Bonet