与Unix时间戳转换


8

在Arduino中以毫秒为单位在日期,小时,分钟,秒之间转换为Unix时间戳的最佳方法是什么?我需要进行此转换,因为我正在使用RTC(日期,小时,分钟,秒等)并通过BLE传递Unix时间戳。

我在网上找到了一些代码片段,但尚未对其进行广泛的测试。

  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中有没有实现此功能的库?我会在程序的大小上权衡可靠性。

Answers:


7

我认为最常用的两个库是Adafruit RTClibpjrc.com TimeLib。它们都具有转换历元的功能,并且都是可靠的。但是两者都缺少时区和DaylightSavingTime。我认为您发现pjrc.com TimeLib稍微更适合处理时代时间(这是一个32位无符号长定义为“ time_t”)。


+1为TimeLib。我一直在使用它作为unix时间戳。
马延科

3

在C中,有一种标准的方法可以通过中定义的函数进行这些转换<time.h>。此API是标准的,您可以在计算机中对其进行测试。在AVR-libc的支持这个最近的版本:看time.h中的AVR-libc中。如果您提供实现DST规则的功能,那么这些功能可以处理当地时间:请参阅 set_dst()。提供了美国和欧盟规则的示例。


太棒了,我不知道Arduino是否包含带时区的'time.h'和DST。谢谢。遗憾的是,将RTC芯片与该时间系统连接是不好的。每秒应调用system_tick()。我现在暂时呆在pjrc.com TimeLib上。

@Jot这并不完全正确。您可以使用RTC设置Arduino的内部时钟,然后调用内部时钟以获取所需的时间信息...在这种情况下,RTC只是偶尔使用的电池供电时钟...每次重新启动一次,可能每周或每两周一次用于漂移校正。
迈克尔·西姆斯

0

这是一个使用TimeLib.h将秒(Unix时间)转换为日期和时间的示例:

#include <TimeLib.h>

unsigned long offset_days = 3;    // 3 days
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;    // convert number of days to seconds
  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() {



}

-6

任何一半不错的c编译器都将具有一组与时间相关的类型和例程来处理此问题。有关更多详细信息,请查阅您的编辑器手册。

顺便说一句,与传统观点相反,您不需要诸如此类的东西就可以跟踪时间。任何好的旧计时器加上您的代码都可以。


4
大多数Arduino都是由陶瓷谐振器提供时钟,因此不适用于任何类型的计时。因此需要RTC。仅当您使用水晶时钟的Arduino时,“优秀的老式计时器”才能完成工作。
埃德加·博内特

2
顺便说一句,“咨询您的作曲者手册”并不是一个真正的答案。
埃德加·博内特
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.