Как получить дату и время с помощью команды curl?

Вопрос или проблема

На моем ПК RTC не работает, поэтому я хочу получить дату и время с сервера, используя команду curl, или если есть какие-либо возможности получить дату и время без RTC на ПК. Требуемый формат для даты и времени — DDMMYYYYHHMMSS.

Сначала, curl осуществляет http(s) запросы. Предполагая, что у вас есть веб-сервер, который слушает на машине, у вас есть 2 варианта:

  1. Создайте скрипт (php/asp/node), который возвращает дату и время в ответе на запрос.

  2. Получите время из заголовков ответа сервера:

    curl -v https://google.com/
    

    Это вернет вам, среди прочего, строку, подобную этой:

    ...
    < Date: Wed, 02 Mar 2016 18:39:13 GMT
    ...
    
  3. С этим результатом вы можете разобрать и преобразовать его в формат, который вам нужен.

    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 для получения даты и времени — эффективное решение в сценариях, где доступ к ресурсу времени ограничен или отсутствует. Такой подход позволяет не только компенсировать неисправности аппаратного уровня, но и интегрировать изменения в различные системные процессы и приложения.

Оцените материал
Добавить комментарий

Капча загружается...