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のライブラリはありますか?プログラムのサイズと信頼性のトレードオフを考えます。

回答:


7

最もよく使用される2つのライブラリは、Adafruit RTClibpjrc.com TimeLibだと思います。どちらもエポックを変換する機能があり、どちらも信頼性があります。しかし、どちらにもタイムゾーンとDaylightSavingTimeがありません。私は、pjrc.comのTimeLibがエポック時間( 'time_t'として定義された32ビットの符号なしlongである)を処理するのに少し適していると思います。


TimeLibの+1。私はいつもそれをUNIXタイムスタンプに使用しています。
マジェンコ

3

Cでこれらの変換を行う標準的な方法があり<time.h>ます。これは、で定義されている関数を使用する方法です。このAPIは標準であり、コンピューターでテストできます。avr-libcの最近のバージョンはこれをサポートしています:avr-libcのtime.hを参照してください。DSTルールを実装する関数を提供すると、これらの関数は現地時間を処理できますset_dst()。を参照してください 。米国とEUの規則の例を示します。


素晴らしい、タイムゾーンを含む 'time.h'とDSTがArduinoに含まれていることを知りませんでした。ありがとう。RTCチップをその時間システムに接続することは悲しいことに残念です。毎秒system_tick()を呼び出す必要があります。とりあえず、pjrc.com TimeLibを使い続けます。
Jot

@Jotそれは完全に正しくはありません。RTCを使用してArduinoの内部クロックを設定し、必要な時間情報を求めて内部クロックを呼び出すことができます。その場合のRTCは、たまに使用されるバッテリーバックアップのクロックです...リブートごとに1回、場合によっては1週間または2週間ドリフト補正用。
Michael Sims

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コンパイラには、これに対処するための時間関連の型とルーチンのセットがあります。詳細については、compikerのマニュアルを参照してください。

ところで、従来の知識とは異なり、時間を追跡するためにetcなどは必要ありません。古き良きタイマーに加えて、コードで十分です。


4
ほとんどのArduinoはセラミック発振子からクロック供給されているため、あらゆる種類の計時には適していません。したがって、RTCの必要性。「古き良きタイマー」が機能するのは、水晶時計のArduinoを持っている場合だけです。
Edgar Bonet

2
ところで、「コンパイカーマニュアルを参照してください」というのは、実際の答えではありません。
Edgar Bonet、2017年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.