在我的 PC 中,RTC 无法工作,因此我想使用curl
命令从服务器获取日期和时间,或者是否有可能在不使用 PC 中的 RTC 的情况下获取日期和时间。日期和时间所需的格式是DDMMYYYYHHMMSS
。
答案1
首先,curl
发出 http(s) 请求。假设您有一个在计算机上监听的 Web 服务器,那么您有 2 个选项:
创建一个脚本(php/asp/node),为您提供日期和时间作为对请求的响应。
从服务器响应头中获取时间。
curl -v https://google.com/
这会给你一些类似这样的内容
... < Date: Wed, 02 Mar 2016 18:39:13 GMT ...
有了这个结果,您可以解析并转换为您想要的格式。
dateFromServer=$(curl -v --silent https://google.com/ 2>&1 \ | grep Date | sed -e 's/< Date: //'); date +"%d%m%Y%H%M%S" -d "$dateFromServer"
您必须注意格林威治标准时间 (GMT) 与当地时间之间的差异,并根据您的需要进行调整。
更新2018-11-26:
正如@SopalajodeArrierez 所说,当证书未更新或时间偏离正确值时,无法运行此功能,因此--insecure
curl 命令需要选项。
dateFromServer=$(curl -v --insecure --silent https://google.com/ 2>&1 \
| grep Date | sed -e 's/< Date: //'); date +"%d%m%Y%H%M%S" -d "$dateFromServer"
答案2
如果必须从远程服务器获取时间,请使用 NTP 服务器。
例如:
$ ntpq -c 'rv 0 clock' localhost
clock=da8b6fe7.ae195287 Thu, Mar 10 2016 9:30:39.680
该clock
值是十六进制的 NTP 时间戳(纪元为 01/01/1900)。您可以对其进行一些处理以获取 Unix 时间戳,然后可以使用它date
:
$ ntpq -c raw -c 'rv 0 clock' localhost
Output set to raw
clock=0xda8b775d.ee94c630
$ ntpq -c raw -c 'rv 0 clock' localhost | gawk -F '[ =.]' --non-decimal-data 'NR==2{printf "@%d.%d\n", $2 - 2209075200, "0x"$3}'
@1457497973.4177870717
$ ntpq -c raw -c 'rv 0 clock' localhost | gawk -F '[=.]' --non-decimal-data 'NR==2{printf "@%d.%d\n", $2 - 2209075200, "0x"$3}' | xargs date +'%d%m%Y%H%M%S' -d
09032016100323
在我的例子中,我有一个本地运行的 NTP 守护进程,我可以对其进行查询,因此使用了localhost
。你也可以使用众多公共 NTP 服务器之一,例如ntp.ubuntu.com
。
该awk
命令读取行,将其拆分为=
和.
,因此三个字段分别为clock
、时间戳的整数部分和小数部分。然后,它减去 2209075200(Unix 和 NTP 纪元之间的秒差,从这篇文章) 从整数部分分离出来并以十进制形式打印两个部分。
答案3
从 HTTP 响应标头中获取日期。清除杂乱信息。设置日期。
$ date -s `curl -I 'https://google.com/' 2>/dev/null | grep -i '^date:' | sed 's/^[Dd]ate: //g'`
希望能帮助到你。
答案4
以下是我的做法。我保留了一个 switch 语句,用于将服务器返回的三个字符月份表示转换为月份的数字值。只要安装了 curl、echo、cut、date 和 bash,这应该可以在许多标准 Unix 环境中工作。
#!/bin/bash
# Automatically Updates System Time According to the NIST Atomic Clock in a Linux Environment
nistTime=$(curl -I --insecure 'https://nist.time.gov/' | grep "Date")
echo $nistTime
dateString=$(echo $nistTime | cut -d' ' -f2-7)
dayString=$(echo $nistTime | cut -d' ' -f2-2)
dateValue=$(echo $nistTime | cut -d' ' -f3-3)
monthValue=$(echo $nistTime | cut -d' ' -f4-4)
yearValue=$(echo $nistTime | cut -d' ' -f5-5)
timeValue=$(echo $nistTime | cut -d' ' -f6-6)
timeZoneValue=$(echo $nistTime | cut -d' ' -f7-7)
#echo $dateString
case $monthValue in
"Jan")
monthValue="01"
;;
"Feb")
monthValue="02"
;;
"Mar")
monthValue="03"
;;
"Apr")
monthValue="04"
;;
"May")
monthValue="05"
;;
"Jun")
monthValue="06"
;;
"Jul")
monthValue="07"
;;
"Aug")
monthValue="08"
;;
"Sep")
monthValue="09"
;;
"Oct")
monthValue="10"
;;
"Nov")
monthValue="11"
;;
"Dec")
monthValue="12"
;;
*)
continue
esac
date --utc --set "$yearValue-$monthValue-$dateValue $timeValue"