Преобразование в Unix Timestamp и обратно

Как лучше преобразовать дату, часы, минуты, секунды в метку времени Unix в миллисекундах в Arduino? Мне нужно это преобразование, так как я использую RTC (дата, часы, минуты, секунды и т. д.) и передаю временную метку Unix через BLE

Я нашел несколько фрагментов кода в Интернете, но еще не проверял их подробно.

  byte second = epoch%60; epoch /= 60;
  byte minute = epoch%60; epoch /= 60;
  byte hour   = epoch%24; epoch /= 24;

  unsigned int years = epoch/(365*4+1)*4; epoch %= 365*4+1;
  unsigned int year;
  for (year=3; year>0; year--)
  {
      if (epoch >= days[year][0])
          break;
  }

  unsigned int month;
  for (month=11; month>0; month--)
  {
      if (epoch >= days[year][month])
          break;
  }

  year  = years+year;
  month = month+1;
  unsigned int day   = epoch - days[year][month]+1;

  unsigned int weekday  = (dayOfMonth += month < 3 ? year-- : year - 2, 23*month/9 + dayOfMonth + 4 + year/4- year/100 + year/400)%7;

И чтобы преобразовать временную метку Unix:

unsigned long epoch = (((year/4*(365*4+1)+days[year%4][month]+dayOfMonth)*24+hour)*60+minute)*60+second;

Есть ли в Arduino какая-либо библиотека, реализующая это? Я бы предпочел надежность размеру программы.

, 👍10


4 ответа


7

Я думаю, что двумя наиболее часто используемыми библиотеками являются Adafruit RTClib и pjrc.com TimeLib. У них обоих есть функции для преобразования эпохи, и они оба надежны. Но у обоих отсутствует часовой пояс и летнее время. Я думаю, вы находите библиотеку pjrc.com TimeLib чуть более подходящей для обработки времени эпохи (которое представляет собой 32-разрядное беззнаковое длинное значение, определяемое как 'time_t').

,

+1 для TimeLib. Я использую его все время для временных меток unix., @Majenko


2

Существует стандартный способ выполнения этих преобразований в C, который с помощью функций, определенных в <time.h>. Этот API является стандартным, вы можете проверить это на своем компьютере. Последние версии avr-libc поддерживают это: см. time.h в avr-libc. Эти функции могут обрабатывать местное время, если вы предоставляете функцию, реализующую правила перехода на летнее время: см. set_dst(). Приведены примеры для правил США и ЕС.

,

Круто, я не знал, что «time.h» с часовым поясом, а также DST были включены в Arduino. Спасибо. К сожалению, подключать чип RTC к этой системе времени не очень приятно. Каждую секунду следует вызывать system_tick(). Пока я просто остаюсь с pjrc.com TimeLib., @Jot

@Jot Это не совсем правильно. Вы можете использовать RTC для установки внутренних часов Arduino, а затем вызывать внутренние часы для получения необходимой информации о времени ... RTC в этом случае - это просто часы с батарейным питанием, которые ИНОГДА используются ... один раз при перезагрузке и, возможно, каждую неделю или две для коррекции дрейфа., @Michael Sims


-6

Любой хотя бы приличный компилятор c должен иметь набор связанных со временем типов и подпрограмм для решения этой проблемы. Обратитесь к руководству по компилятору за более подробной информацией.

Кстати, вопреки общепринятому мнению, вам не нужен и т. д., чтобы отслеживать время. Подойдет любой хороший старый таймер плюс ваш код.

,

Большинство плат Arduino работают от керамического резонатора и, таким образом, плохо подходят для любого вида хронометража. Таким образом, потребность в RTC. «Хороший старый таймер» может выполнять свою работу только в том случае, если у вас есть Arduino с кварцевой тактовой частотой., @Edgar Bonet

Кстати, «Проконсультируйтесь с руководством по компилятору» на самом деле не является ответом., @Edgar Bonet


1

Вот пример преобразования секунд (время Unix) в Date & Время с использованием TimeLib.h:

#include <TimeLib.h>

unsigned long offset_days = 3;    // 3 дня
unsigned long t_unix_date1, t_unix_date2;

void setup() {
  Serial.begin(115200);
  t_unix_date1 = 1564398600;
  Serial.print("t_unix_date1: ");
  Serial.println(t_unix_date1);
  offset_days = offset_days * 86400;    // преобразовать количество дней в секунды
  t_unix_date2 = 1564398600 + offset_days;
  Serial.print("t_unix_date2: ");
  Serial.println(t_unix_date2);
  printf("Date1: %4d-%02d-%02d %02d:%02d:%02d\n", year(t_unix_date1), month(t_unix_date1), day(t_unix_date1), hour(t_unix_date1), minute(t_unix_date1), second(t_unix_date1));
  printf("Date2: %4d-%02d-%02d %02d:%02d:%02d\n", year(t_unix_date2), month(t_unix_date2), day(t_unix_date2), hour(t_unix_date2), minute(t_unix_date2), second(t_unix_date2));
}

void loop() {



}
,