私はArduino YUNでOpenWRTを使用しており、ミリ秒(DD / MM / YYYY h:min:sec:ms)単位の正確な日付を取得するためにタイムサーバーを介して時間を取得しようとしています。
残念ながら、ナノ秒ではなくdate +%N
ナノ秒だけが返されます%N
。+%N
OpenWRTの日付は含まれていないと聞きました。
それでは、私が望む日付(ミリ秒を含む)を取得する方法はありますか?
答え1
OpenWRTではdate
そうですbusybox
。制限がありますが、厳密に言えば、それらの1つではありません。根本的な問題はlibc(uClibc)です。この GNU strftime 拡張はサポートされていません。。 (glibcも同様ですが、これについては後で詳しく説明します。)
基本的にはあるはずlua
ですが役に立たない基本以外のモジュールもあります。
hwclock
RTC(ハードウェアクロック)を比較/設定する必要がありますgettimeofday()
が、1秒未満の解像度を出力しません(RTCにアクセスするのが遅すぎて便利ではない可能性があります)。さらに、OpenWRTは古代のrdate
1秒単位の解像度のみを提供します。
から直接正確なタイムスタンプを得るための直接的な方法はないようです/proc
。最も有用なタイムスタンプは、/proc/timer_list
ナノ秒単位の稼働時間(ライン3)です(解像度はプラットフォームによって異なります)。
ビジボックスがsetで構築されている場合は、CONFIG_BUSYBOX_CONFIG_ADJTIMEX
それを使用してカーネルクロックを読み取ることができるはずですadjtimex
(ビジボックスバージョンは両方標準adjtimexのさまざまなパラメータとさまざまな出力。
一般バージョン、adjtimex -p
出力の最後の行:
raw time: 1416419719s 146628us = 1416419719.146628
Busyboxバージョン、adjtimex
(いいえ-p
!)、最後の3行:
[...]
time.tv_sec: 1416420386
time.tv_usec: 732653
return value: 0 (clock synchronized)
Goldilocksは、OpenWRTクロスビルド設定があると仮定するのに最適なソリューションです(強くお勧めします!)。あなたのcoreutils 日付coreutilsがglibcを認識しても、まったくglibcではないため、ソリューションは機能します。これには独自の独立した実装(glibcから派生)が付属しており、これを使用して基本レイヤをstrftime
ラップ(通過)してさまざまな拡張をサポートします(そうでない場合はuClibcバージョンに置き換えられます)。strftime_case()
strftime
glibc(現在2.23まで)がそれをサポートしていない場合でも、%N
正式なglibcバージョンから派生したcoreutilsはいくつかの異なる変更を追加します。バリアントとパッチのバージョンがたくさんあります(bashとgawkのバージョンを含む)。strftime()
%N
%:z
strftime()
答え2
Cコンパイラがあり、他のものが見つからない場合に報告されます。
> millitime && sleep 1 && millitime
14/11/2014 9:39:49:364
14/11/2014 9:39:50:368
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <sys/time.h>
#include <time.h>
int main (void) {
struct timeval now;
struct tm *parsed;
if (gettimeofday(&now, NULL) == -1) {
fprintf (
stderr,
"gettimeofday() failed: %s\n",
strerror(errno)
);
return 1;
}
parsed = localtime((const time_t*)&now.tv_sec);
if (!parsed) {
fprintf (
stderr,
"localtime() failed: %s\n",
strerror(errno)
);
return 1;
}
printf (
"%d/%d/%d %d:%02d:%02d:%03d\n",
parsed->tm_mday,
parsed->tm_mon + 1,
parsed->tm_year + 1900,
parsed->tm_hour,
parsed->tm_min,
parsed->tm_sec,
now.tv_usec / 1000
);
return 0;
}
gccでコンパイルするだけですgcc whatever.c -o millitime
。 (異常な)エラーが発生した場合は、これをstderrに報告してステータス1で終了します。それ以外の場合はstdoutに報告し、0で終了します。
ミリ秒丸めるマイクロ秒単位で始まります。
答え3
実際、!という別のパッケージがありますcoreutils-date
。わからない!すべての標準機能が含まれています!
答え4
#include <stdio.h>
#include <time.h>
void main (void){
long ms;
time_t s;
struct timespec spec;
clock_gettime(CLOCK_REALTIME, &spec);
s = spec.tv_sec;
ms = (spec.tv_nsec / 1.0e6);
printf("%d%03d\n", s, ms);
return 0;
}
Cでは、coreutils-dateと同様に機能しますdate +%s%3N
。 OpenWrt-SDKを使用してOpenWrtルータにコンパイルします。