
Ich verwende OpenWRT auf dem Arduino YUN und versuche, das genaue Datum in Millisekunden (TT/MM/JJJJ h:min:sek:ms) zu erhalten, indem ich die Uhrzeit von einem Zeitserver abrufe.
Leider date +%N
gibt es nur zurück %N
, aber nicht die Nanosekunden. Ich habe gehört, +%N
dass das Datum nicht im OpenWRT-Datum enthalten ist.
Gibt es also eine Möglichkeit, das Datum (einschließlich Millisekunden) so zu erhalten, wie ich es möchte?
Antwort1
Auf OpenWRT date
gibt es busybox
, das Einschränkungen hat, aber das ist nicht unbedingt eine davon. Das zugrunde liegende Problem ist, dass die libc (uClibc)unterstützt diese GNU strftime-Erweiterung nicht. (Allerdings gilt dies auch für glibc, mehr dazu weiter unten.)
Das sollte lua
standardmäßig der Fall sein, aber daswird nicht helfenohne einige andere nicht standardmäßige Module.
hwclock
fordert gettimeofday()
zum Vergleichen/Einstellen der RTC (Hardware-Uhr), gibt aber keine Auflösung von unter einer Sekunde aus (der Zugriff auf RTCs kann so langsam sein, dass er ohnehin nicht nützlich sein könnte). Abgesehen davon bietet OpenWRT nur das alte rdate
, das nur eine Auflösung von ganzen Sekunden hat.
Es scheint keine einfache Möglichkeit zu geben, direkt von einen genauen Zeitstempel zu erhalten /proc
. Der nützlichste Zeitstempel befindet sich in /proc/timer_list
(3. Zeile), was die Betriebszeit in Nanosekunden angibt (die Auflösung hängt von der Plattform ab).
Wenn Ihre Busybox mit set erstellt wurde CONFIG_BUSYBOX_CONFIG_ADJTIMEX
, sollten Sie in der Lage sein, adjtimex
die Kernel-Uhr zu lesen (beachten Sie jedoch, dass die Busybox-Versionbeideandere Argumente und andere Ausgabe als der Standard-Adjtimex.
Normalversion, adjtimex -p
letzte Ausgabezeile:
raw time: 1416419719s 146628us = 1416419719.146628
Busybox-Version adjtimex
(ohne -p
!), letzte 3 Zeilen:
[...]
time.tv_sec: 1416420386
time.tv_usec: 732653
return value: 0 (clock synchronized)
Goldilocks ist eine gute Lösung, vorausgesetzt, Sie haben Ihr OpenWRT Cross Build Setup (dringend empfohlen!). Ihrcoreutils-datumLösung funktioniert, weil coreutils zwar glibc-fähig ist, aber nicht ausschließlich glibc ist. Es verfügt über eine eigene eigenständige Implementierung von (abgeleitet von glibc) und verwendet diese, um das zugrunde liegende Element (über ) strftime
zu verpacken, um verschiedene Erweiterungen zu unterstützen (und greift andernfalls auf die uClibc-Version zurück).strftime_case()
strftime
Sogar glibc (bis zur aktuellen Version 2.23) unterstützt nicht , die von der kanonischen glibc-Version abgeleiteten %N
Coreutils fügen und und einige andere Änderungen hinzu. Variationen und gepatchte Versionen von gibt es in Hülle und Fülle (einschließlich Versionen in Bash und Gawk).strftime()
%N
%:z
strftime()
Antwort2
Wenn Sie einen C-Compiler darauf haben und nichts anderes finden können, wird dies beispielsweise melden
> 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;
}
Kompilieren Sie es einfach mit gcc gcc whatever.c -o millitime
. Wenn ein Fehler auftritt (was sehr seltsam wäre), wird er an stderr gemeldet und mit dem Status 1 beendet. Andernfalls wird er an stdout gemeldet und mit 0 beendet.
Die Millisekunden sindabgerundetvon Mikrosekunden.
Antwort3
Tatsächlich gibt es auch ein Paket namens coreutils-date
! Davon wusste ich nichts! Dort sind alle Standardfunktionen enthalten!
Antwort4
#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;
}
Dies ist in der Sprache C und funktioniert wie coreutils-date date +%s%3N
. Es wird mit OpenWrt-SDK in den OpenWrt-Router kompiliert.