Вопрос или проблема
На моем ПК RTC не работает, поэтому я хочу получить дату и время с сервера, используя команду curl
, или если есть какие-либо возможности получить дату и время без RTC на ПК. Требуемый формат для даты и времени — DDMMYYYYHHMMSS
.
Сначала, curl
осуществляет http(s) запросы. Предполагая, что у вас есть веб-сервер, который слушает на машине, у вас есть 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"
Если вам нужно получить время с удаленного сервера, используйте 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, как указано в этой публикации на Stack Overflow) из целой части и выводит обе части в десятичном формате.
Получите дату из заголовка HTTP ответа. Удалите лишнее. Установите дату.
$ date -s `curl -I 'https://google.com/' 2>/dev/null | grep -i '^date:' | sed 's/^[Dd]ate: //g'`
Надеюсь, это поможет.
// по какой-то причине ntpdate
или htpdate
не работают
просто делюсь скриптом (для bash)
для установки системной даты и времени с помощью curl (HTTP заголовок ответа).
// комбинированные ответы других людей
-
curl -k (для https с неправильным местным временем
-
curl -I (используйте
HEAD
запрос, более эффективно, требуется поддержка сервера -
grep -i (для ответа сервера
date:
илиDate:
.. -
grep ‘^Date:’ (избегайте других заголовков, таких как
XXX-date:
…
// требуется grep -P
поддержка PCRE
// примечание: grep ‘^Date:.*’ может ничего не выводить, потому что \r
трюкачит вывод
#!/bin/bash
url="${1:-goo.gle}"
echo "time before: `date -Is`"
echo
time=`curl -ksI "$url" | grep -iPo '^Date: \K[\S ]*'`
echo "time on net: $time"
echo "time parsed: `date -Is -d "$time"`"
[ -n "$time" ] && {
echo
echo "time apply: `date -s "$time"`"
echo "time after: `date -Is`"
}
выводы:
$ sudo TZ=GMT-4 ./htpdate.sh bing.com
time before: 2022-10-30T02:10:28+04:00
time on net: Sat, 29 Oct 2022 22:10:28 GMT
time parsed: 2022-10-30T02:10:28+04:00
time apply: Sun Oct 30 02:10:28 GMT 2022
time after: 2022-10-30T02:10:28+04:00
TZ=.. для передачи часового пояса для отображения (только в этом скрипте)
arg1 для передачи URL (по умолчанию goo.gle)
Вот как я это делаю.
Я сохраняю оператор switch
для перевода из трехбуквенного представления месяца, возвращаемого сервером, в цифровое значение месяца. Это должно работать на многих стандартных Unix окружениях, при условии установки curl
, echo
, cut
, date
, и bash
.
#!/bin/bash
# Автоматически обновляет системное время в соответствии с атомными часами NIST в Linux окружении
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"
используйте временную метку в HTTP заголовках ответа.
date -d "$(curl -sI baidu.com| grep -i '^date:'|cut -d' ' -f2-)"
date -d "$(curl -sI baidu.com| grep -i '^date:'|cut -d' ' -f2-)" | xargs -I {} date --date="{}" "+%Y-%m-%d %H:%M:%S"
# ниже команда для установки новой даты
date -s "$(date -d "$(curl -sI baidu.com| grep -i '^date:'|cut -d' ' -f2-)" | xargs -I {} date --date="{}" "+%Y-%m-%d %H:%M:%S")"
На Windows это (получить дату и время, используя curl) будет:
CURL -s -I "https://google.com/" | FINDSTR "date:"
ответ, что-то вроде: date: Sat, 03 Jun 2023 15:44:25 GMT
ПРИМЕЧАНИЕ: “что-то вроде”, потому что время имеет свойство быстро меняться 😉
или, если вы хотите только дату:
FOR /f "usebackq tokens=3,4,5" %f in (`CURL -s -I "https://google.com/" ^| FINDSTR "date:"`) DO ECHO %f %g %h
вывод: 03 Jun 2023
Это на самом деле не отвечает на ваш вопрос о дате и времени, но определенно будет полезно многим людям:
$ curl -Is https://some.web.site/a-file-of-interest.tgz | grep last-modified | cut -d":" -f2-
с результатом, который выглядит так:
Wed, 29 Jan 2025 16:15:35 GMT
Эта команда curl получает время последнего изменения, чтобы вы загрузили нужный файл только один раз, а затем загрузили в будущем, если файл физически изменился на диске. Вы знаете, что файл изменен, если изменилось временное метка.
.
Ответ или решение
Чтобы получить дату и время с сервера с использованием команды curl
, в случае, если на вашем ПК не работает реальное время (RTC), необходимо придерживаться определенной последовательности действий. Выбор метода будет зависеть от ваших предпочтений, требуемого уровня точности и возможности установки дополнительных инструментов на вашем устройстве. Рассмотрим несколько подходов к решению этой задачи.
Теория
В контексте получения даты и времени с удаленного сервера возможно использование стандартных HTTP-заголовков, которые предоставляет сервер при обработке запроса. Один из таких заголовков — это Date
, который содержит текущие дату и время на сервере в формате, близком к стандарту GMT. Кроме того, существует возможность получения времени с помощью сервера времени NTP (Network Time Protocol), который предоставляет более точные данные. Однако первичный подход может быть сведен к использованию сервиса HTTP, что делает его более универсальным.
Пример
Вы можете использовать команду curl
для отправки HTTP-запроса на сервер и получения заголовка с информацией о дате. Один из вариантов команды выглядит следующим образом:
dateFromServer=$(curl -v --silent https://google.com/ 2>&1 | grep Date | sed -e 's/< Date: //')
Эта команда делает следующее:
- Использует
curl
для отправки запроса на сервер (например, google.com). - Извлекает и обрабатывает информацию из заголовка, содержащую текущее время на сервере.
После этого можно преобразовать полученную дату в формат DDMMYYYYHHMMSS
, используя утилиту date
:
date +"%d%m%Y%H%M%S" -d "$dateFromServer"
Для более надежной работы команды curl
, особенно в случае отсутствия актуальных сертификатов на ПК, вы можете использовать флаг --insecure
, чтобы отключить проверку SSL-сертификатов:
dateFromServer=$(curl -v --insecure --silent https://google.com/ 2>&1 | grep Date | sed -e 's/< Date: //')
Применение
Предположим, на вашем устройстве не установлены обновленные сертификаты безопасности, что может препятствовать успешному выполнению команды curl
из-за несоответствия времени сервера. В этом случае использование --insecure
позволяет обойти проблему. Вы также должны учитывать, что время в заголовке предоставляется в формате GMT. Если вам необходимо локальное время, потребуется корректировка с учетом часового пояса вашего местоположения.
При необходимости вы можете воспользоваться утилитами, такими как ntpq
, для синхронизации времени с использованием NTP-серверов. Однако этот метод требует более сложной настройки и окружения.
Альтернативные подхваты
Для пользователей систем, где команда ntpdate
недоступна, или где выполнение команд через NTP-протокол невозможно, предлагается создать скрипт, который выполнит аналогичные действия, используя curl
и другие утилиты Linux. Вот пример на bash:
#!/bin/bash
url="${1:-goo.gle}"
echo "Время до: `date -Is`"
time=`curl -ksI "$url" | grep -iPo '^Date: \K[\S ]*'`
echo "Время на сервере: $time"
echo "Время после парсинга: `date -Is -d "$time"`"
[ -n "$time" ] && {
echo "Время установлено: `date -s "$time"`"
echo "Время после: `date -Is`"
}
Данный скрипт позволяет быстро установить системное время в соответствии с данными, полученными с удаленного сервера, минимизируя задержки и уменьшая вероятность ошибки.
Подводя итоги, использование команды curl
для получения даты и времени — эффективное решение в сценариях, где доступ к ресурсу времени ограничен или отсутствует. Такой подход позволяет не только компенсировать неисправности аппаратного уровня, но и интегрировать изменения в различные системные процессы и приложения.