
Estou usando OpenWRT no Arduino YUN e estou tentando obter a data exata em milissegundos (DD/MM/AAAA h:min:sec:ms) obtendo a hora por um servidor de tempo.
Infelizmente date +%N
apenas retorna %N
, mas não os nanossegundos. Ouvi dizer +%N
que não está incluído na data do OpenWRT.
Então, existe alguma maneira de obter a data (incluindo milissegundos) como eu quero?
Responder1
No OpenWRT, date
é busybox
, que tem limitações, mas esta não é estritamente uma delas. O problema subjacente é que o libc (uClibc)não suporta esta extensão GNU strftime. (Embora a glibc também não, mais sobre isso abaixo.)
Você deveria ter feito isso lua
por padrão, mas issonão vai ajudarsem alguns outros módulos não padrão.
hwclock
exige gettimeofday()
comparação/configuração do RTC (relógio de hardware), mas não produz resolução abaixo de um segundo (o acesso aos RTCs pode ser lento o suficiente para não ser útil de qualquer maneira). Fora isso, o OpenWRT fornece apenas o antigo rdate
, que só tem resolução de segundos inteiros.
Parece não haver uma maneira direta de obter um carimbo de data/hora preciso diretamente do /proc
, o carimbo de data/hora mais útil está na /proc/timer_list
(3ª linha), que é o tempo de atividade em nanossegundos (a resolução dependerá da plataforma).
Se o seu busybox foi construído com CONFIG_BUSYBOX_CONFIG_ADJTIMEX
set, então você poderá usá-lo adjtimex
para ler o relógio do kernel (embora observe que a versão do busybox possuiambosargumentos diferentes e saída diferente para o adjtimex padrão.
Versão normal, adjtimex -p
última linha de saída:
raw time: 1416419719s 146628us = 1416419719.146628
Versão Busybox, adjtimex
(sem -p
!), últimas 3 linhas:
[...]
time.tv_sec: 1416420386
time.tv_usec: 732653
return value: 0 (clock synchronized)
Goldilocks é uma ótima solução, supondo que você tenha sua configuração de construção cruzada OpenWRT (altamente recomendado!). Seudata coreutilsA solução funciona porque, embora o coreutils seja compatível com glibc, não é exclusivamente glibc. Ele vem com sua própria implementação autônoma de strftime
(derivada de glibc) e a usa para encerrar (via strftime_case()
) o subjacente, strftime
de modo a suportar várias extensões (caso contrário, volta para a versão uClibc).
Mesmo que o glibc (até o atual 2.23) não suporte %N
, os coreutils strftime()
derivados da versão canônica do glibc adicionam %N
e %:z
algumas outras alterações. Variações e versões corrigidas são strftime()
abundantes (incluindo versões em bash e gawk).
Responder2
Se você tiver um compilador C instalado e não conseguir encontrar mais nada, isso irá reportar, por exemplo
> 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;
}
Com o gcc, basta compilá-lo gcc whatever.c -o millitime
. Se houver um erro (o que seria muito estranho), ele reporta para stderr e sai com status 1. Caso contrário, reporta para stdout e sai 0.
Os milissegundos sãoarredondado para baixode microssegundos.
Responder3
Na verdade, também existe um pacote chamado coreutils-date
! Não sabia disso! Todas as funcionalidades padrão estão incluídas!
Responder4
#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;
}
Isso na linguagem C e funciona como coreutils-date date +%s%3N
. Ele é compilado para roteador OpenWrt com OpenWrt-SDK.