Дата в миллисекундах на OpenWRT на Arduino YUN

Дата в миллисекундах на OpenWRT на Arduino YUN

Я использую OpenWRT на Arduino YUN и пытаюсь получить точную дату в миллисекундах (ДД/ММ/ГГГГ ч:мин:сек:мс), получая время от сервера времени.

К сожалению, date +%Nвозвращает только %N, но не наносекунды. Я слышал, +%Nчто не включено в дату OpenWRT.

Так есть ли способ получить нужную мне дату (включая миллисекунды)?

решение1

На OpenWRT dateесть busybox, который имеет ограничения, но это не совсем одно из них. Основная проблема в том, что libc (uClibc)не поддерживает это расширение GNU strftime. (Хотя glibc тоже этого не делает, подробнее об этом ниже.)

luaПо умолчанию у вас должно быть так, но этоне поможетбез некоторых других нестандартных модулей.

hwclockтребует gettimeofday()сравнения/установки RTC (аппаратных часов), но не выводит субсекундное разрешение (доступ к RTC может быть достаточно медленным, так что это может быть бесполезно в любом случае). Кроме этого OpenWRT предоставляет только древний rdate, который имеет только целосекундное разрешение.

Похоже, не существует простого способа получить точную временную метку непосредственно из /proc, самая полезная временная метка находится в /proc/timer_list(3-я строка), которая представляет собой время безотказной работы в наносекундах (разрешение будет зависеть от платформы).

Если ваш busybox был собран с помощью CONFIG_BUSYBOX_CONFIG_ADJTIMEXset, то вы должны иметь возможность использовать его adjtimexдля чтения часов ядра (хотя обратите внимание, что версия busybox имеетобадругие аргументы и другой вывод для стандартного 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's — это прекрасное решение, если у вас есть настройка кросс-сборки OpenWRT (настоятельно рекомендуется!).coreutils-датарешение работает, потому что, хотя coreutils и поддерживает glibc, он не является исключительно glibc. Он поставляется со своей собственной автономной реализацией strftime(выведенной из glibc) и использует ее для обертывания (через strftime_case()) базового strftime, чтобы поддерживать различные расширения (и в противном случае возвращается к версии uClibc).

Даже glibc (до текущей версии 2.23) не поддерживает %N, coreutils, strftime()полученные из канонической версии glibc, добавляют %Nи %:zи несколько других изменений. Вариации и пропатченные версии strftime()изобилуют (включая версии в bash и gawk).

решение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 с OpenWrt-SDK.

Связанный контент