
私は Arduino YUN で OpenWRT を使用しており、タイムサーバーで時間を取得して、正確な日付をミリ秒単位 (DD/MM/YYYY h:min:sec:ms) で取得しようとしています。
残念ながら、ナノ秒date +%N
は返されません。OpenWRTの日付には含まれていないと聞きました。%N
+%N
それで、私が望む日付(ミリ秒を含む)を取得する方法はあるのでしょうか?
答え1
OpenWRTでは、制限がありdate
ますbusybox
が、これは厳密にはその1つではありません。根本的な問題は、libc(uClibc)このGNU strftime拡張をサポートしていません(glibc も同様ですが、これについては後述します。)
lua
デフォルトでそうするべきですが、役に立たない他のデフォルト以外のモジュールなし。
hwclock
RTC (ハードウェア クロック) の比較/設定を呼び出しますgettimeofday()
が、1 秒未満の解像度は出力されません (RTC へのアクセスは十分に遅いため、いずれにしても役に立たない可能性があります)。それ以外では、OpenWRT はrdate
、1 秒単位の解像度しかない古い のみを提供します。
から直接正確なタイムスタンプを取得する簡単な方法はないようですが/proc
、最も有用なタイムスタンプは/proc/timer_list
(3 行目) にあり、これはナノ秒単位の稼働時間です (解像度はプラットフォームによって異なります)。
もしbusyboxがset付きでビルドされていたら、カーネルクロックを読むためにCONFIG_BUSYBOX_CONFIG_ADJTIMEX
使用できるはずです(ただしbusyboxのバージョンには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 専用ではないためです。coreutils には独自のスタンドアロン実装 (glibc から派生) が付属しており、それを使用して ( を介して) 基盤strftime
をラップし、さまざまな拡張機能をサポートします (それ以外の場合は uClibc バージョンにフォールバックします)。strftime_case()
strftime
glibc (現在の 2.23 まで) でも はサポートされていませんが、標準の glibc バージョンから派生した%N
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 ルーターにコンパイルされます。