저는 Arduino YUN에서 OpenWRT를 사용하고 있으며 밀리초(DD/MM/YYYY h:min:sec:ms) 단위의 정확한 날짜를 얻기 위해 시간 서버를 통해 시간을 얻으려고 합니다.
불행하게도 나노초가 아닌 date +%N
나노초만 반환됩니다 %N
. +%N
OpenWRT 날짜는 포함되지 않는다고 들었습니다 .
그렇다면 내가 원하는 날짜(밀리초 포함)를 얻을 수 있는 방법이 있나요?
답변1
OpenWRT에서는 date
그렇습니다 busybox
. 제한 사항이 있지만 엄밀히 말하면 그 중 하나는 아닙니다. 근본 문제는 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 라우터로 컴파일합니다.