Date

Arduino YUN 上 OpenWRT 上的日期(以毫秒為單位)

  • June 5, 2019

我在 Arduino YUN 上使用 OpenWRT,我試圖通過時間伺服器獲取時間以獲取以毫秒為單位的確切日期 (DD/MM/YYYY h:min:sec:ms)。

不幸的是,date +%N只是返回%N,但不是納秒。聽說+%NOpenWRT中不包含日期。

那麼有什麼方法可以獲取我想要的日期(包括毫秒)嗎?

在 OpenWRT 上,dateisbusybox有限制,但這並不是其中之一。根本問題是 libc (uClibc)不支持這個 GNU strftime extension。(儘管 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 是一個很好的解決方案,假設您有 OpenWRT 交叉建構設置(強烈推薦!)。您的coreutils-date解決方案之所以有效,是因為雖然 coreutils 支持 glibc,但它不僅限於 glibc。它帶有自己的獨立實現strftime(源自 glibc),並使用它來包裝(通過strftime_case())底層strftime以支持各種擴展(否則回退到 uClibc 版本)。

甚至 glibc(直到目前的 2.23)都不支持%Nstrftime()從規範 glibc 版本派生的 coreutils 添加了%N%:z其他一些更改。變體和修補版本strftime()比比皆是(包括 bash 和 gawk 中的版本)。

如果你有一個 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。

毫秒從微秒向下舍入。

引用自:https://unix.stackexchange.com/questions/167968