- Получение разницы между датами bash
- Как сравнить две даты в оболочке?
- Как рассчитать разницу во времени в bash-скрипт?
- 18 ответов:
- секунд
- целочисленное значение прошедших секунд:
- преобразовать такое целое число в полезный формат
- дата GNU.
- математика внутри дня.
- Busybox дата
- 7.3. Операции сравнения
- 12.3. Команды для работы с датой и временем
Получение разницы между датами bash
Проблема по мотивам архивного сообщения Получение разницы между датами
Необходимо получить разницу в количестве месяцев между двумя датами вида dd/mm/yyyy
SDIFF=$((`date -d «$current_date» ‘+%s’` — `date -d «$before_date» ‘+%s’`))
Собственно проблема что date никак не воспринимает формат dd/mm/yyyy и ругается «date: неверная дата «31/12/2015»» Аналогичная ошибка у меня и в примере, которое приведено в том архивном сообщении, которое якобы работало в далеком 2007 году.
Система РедХат 6
В man date есть пример с датой в том формате, в котором оно понимает: «2004-02-29 16:21:42».
И приведенный пример считает разницу в секундах, а не в месяцах.
А в месяцах можно считать двояко. Можно в секундах, затем делить на 30 дней:
Переводить в Epoch, разность делить до нужной точности.
А зачем вообще все эти date и прочие сложности? Количество месяцев в любом году же, вроде бы, постоянно, не?
Необходимо получить разницу в количестве месяцев между двумя датами вида dd/mm/yyyy
А скорость получения важна? 🙂
Или я задачу не понял? Судя по тому, как тут все ее серьезно обсуждают, это весьма возможно.
bash -c «python -c \„import datetime;. \“»
Глобальная задача проверять срок действия сертификата эцп, хранимого на токене 🙂 срок когда начал действовать сертификат вытянул в виде дата/время из поля Not valid before: Зная, что срок действия сертификата эцп по российскому законодательству 1 год и 3 месяца, или 15 месяцев говоря другими словами, просто проверяю
Если (текущая дата — дата сертификата из токена > 14 месяцев) то слать емыл админу что в сервере hostname срок действия сертификата, через месяц закончится. иначе Если (текущая дата — дата сертификата из токена > 15 месяцев) то слать емыл админу что в сервере hostname срок действия сертификата уж кончился.
Скрипт засовывается в крон, и раз в день исполняется. Цель всего, заблаговременно понять что сертификат скоро кончится и нужно его перевыпустить.
Собственно весь код «скрипта» готов, только последняя часть расчета разницы в датах всё застопорило. Предполагал что «date -d» можно передать дату/время в нужном мне формате (dd/mm/yyyy), а оказывается оно понимает только один определенный вид указанный в man. Решение задачи будет приведение даты в тот вид который надо команде date, точность расчета +/- день роли особой не играет.
Источник
Как сравнить две даты в оболочке?
Как можно сравнить две даты в оболочке?
Вот пример того, как я хотел бы использовать это, хотя это не работает как есть:
Как мне достичь желаемого результата?
Правильный ответ все еще отсутствует:
Обратите внимание, что для этого требуется дата GNU. Эквивалентный date синтаксис для BSD date (подобный найденному в OSX по умолчанию) date -j -f «%F» 2014-08-19 +»%s»
Вам не хватает формата даты для сравнения:
Вам тоже не хватает циклических структур, как вы планируете получать больше дат?
Можно использовать стандартное сравнение строк для сравнения хронологического порядка [строк в формате год, месяц, день].
К счастью, когда [строки, которые используют формат YYYY-MM-DD] сортируются * в алфавитном порядке, они также сортируются * в хронологическом порядке.
(* — отсортировано или сравнено)
Ничего особенного в этом деле не нужно. ура!
Это проблема не циклических структур, а типов данных.
Эти даты ( todate и cond ) являются строками, а не числами, поэтому вы не можете использовать оператор «-ge» для test . (Помните, что обозначение в квадратных скобках эквивалентно команде test .)
Что вы можете сделать, это использовать другую запись для ваших дат, чтобы они были целыми числами. Например:
выдаст целое число, например 20130715, 15 июля 2013 г. Затем вы сможете сравнить свои даты с «-ge» и эквивалентными операторами.
Обновление: если указаны ваши даты (например, вы читаете их из файла в формате 2013-07-13), то вы можете легко предварительно обработать их с помощью tr.
Оператор -ge работает только с целыми числами, которых нет у ваших дат.
Если ваш скрипт представляет собой скрипт bash или ksh или zsh, вы можете использовать вместо этого оператор. Этот оператор недоступен в тире или других оболочках, которые не выходят за рамки стандарта POSIX.
В любой оболочке вы можете преобразовать строки в числа, соблюдая порядок дат, просто удалив тире.
Кроме того, вы можете перейти на традиционные и использовать expr утилиту.
Поскольку запуск подпроцессов в цикле может быть медленным, вы можете предпочесть выполнить преобразование, используя конструкции обработки строки оболочки.
Конечно, если вы можете получить даты без дефисов, вы сможете их сравнить -ge .
Источник
Как рассчитать разницу во времени в bash-скрипт?
я печатаю время начала и окончания с помощью date +»%T» , что приводит к чему-то вроде:
как я могу рассчитать и распечатать разницу между этими двумя?
Я хотел бы сделать что-то вроде:
18 ответов:
Bash имеет удобный SECONDS встроенная переменная, которая отслеживает количество секунд, прошедших с момента запуска оболочки. Эта переменная сохраняет свои свойства при назначении, и значение, возвращаемое после назначения, является числом секунд с момента назначения плюс назначенное значение.
таким образом, вы можете просто установить SECONDS до 0 перед началом события timed, просто прочитайте SECONDS после события, и сделать арифметику времени до отображающий.
как это решение не зависит от date +%s (который является расширением GNU), он переносится на все системы, поддерживаемые Bash.
секунд
для измерения прошедшего времени (в секундах) нам нужно:
- целое число, представляющее число секунд, прошедших и
- способ преобразования такого целого числа в полезный формат.
целочисленное значение прошедших секунд:
есть два внутренних способа bash найти целое значение для количества прошедших секунд:
Баш переменная секунды (если секунды не заданы, она теряет свое специальное свойство).
установка значения секунд в 0:
сохранение значения переменной SECONDS в начале:
Bash printf option %(datefmt)T :
преобразовать такое целое число в полезный формат
Баш внутренний printf может сделать это напрямую:
но это не удастся для длительностей более 24 часов, так как мы на самом деле печатаем время настенных часов, а не продолжительность:
для любителей деталей, от bash-hackers.org:
%(FORMAT)T выводит строку даты и времени, полученную в результате использования формата как строка формата для strftime(3) . Этот связанный аргумент количество секунд с момента эпохи, или -1 (текущее время) или -2 (оболочки время запуска.) Если соответствующий аргумент не указан, то текущий время используется по умолчанию.
так что вы можете просто позвонить textifyDuration $elpasedseconds здесь textifyDuration еще одна реализация печати продолжительности:
дата GNU.
чтобы получить формируемое время, мы должны использовать внешний инструмент (GNU date) несколькими способами получить до почти год длины и в том числе наносекунды.
математика внутри дня.
нет необходимости во внешней арифметике, сделайте все это в один шаг внутри date :
Да, есть 0 ноль в командной строке. Это необходимо.
это предполагает, что вы могли бы изменить date +»%T» команда a date +»%s» команда таким образом, значения будут сохранены (напечатаны) в секундах.
обратите внимание, что команда ограничена к:
- положительные значения $StartDate и $FinalDate секунд.
- значение $FinalDate больше (позже), чем $StartDate .
- разница во времени менее 24 часов.
- вы принимаете выходной формат с часами, минутами и секундами. Очень легко изменить.
- допустимо использовать-U UTC раз. Чтобы избежать» DST » и коррекции местного времени.
если вы должны использовать элемент 10:33:56 строка, ну, просто преобразовать его в секундах,
кроме того, слово секунды может быть сокращено как sec:
обратите внимание, что преобразование времени секунд (как представлено выше) относительно начала «этого» дня (сегодня).
концепция может быть расширена до наносекунд, например:
если требуется рассчитать более длительные (до 364 дней) временные разницы, мы должны использовать начало (некоторого) года в качестве ссылки и значение формата %j (номер дня в году):
к сожалению, в этом случае нужно вручную вычесть 1 один из числа дней. Команда date отображает первый день года как 1. Не так уж и сложно .
Busybox дата
инструмент, используемый в небольших устройствах (очень маленький исполняемый файл для установки): Busybox.
либо сделать ссылку на busybox называется дата:
используйте его тогда, называя это date (поместите его в каталог, включенный в путь).
или псевдоним например:
Busybox дата имеет хороший вариант: — D, чтобы получить формат времени ввода. Это открывает много форматов, которые будут использоваться в качестве времени. Используя опцию-D, мы можем конвертировать время 10:33: 56 напрямую:
и как вы можете видеть из вывода команды выше, день считается «сегодня». Чтобы получить время, начиная с эпохи:
Busybox дата может даже получить время (в формате выше) без — Д:
и выходной формат может быть даже секунд с начала эпохи.
для обоих раз, и немного Баш математика (busybox не может сделать математику, пока):
очень просто, возьмите количество секунд в начале, а затем взять количество секунд в конце, и распечатать разницу в минутах:секунд.
вы также можете использовать gawk . mawk 1.3.4 также strftime и mktime но более старые версии mawk и nawk нет.
Или вот еще один способ сделать это с GNU date :
Я хотел бы предложить другой способ, чтобы не вспоминать . Это может быть полезно в случае, если вы уже собрали метки времени в дата:
мы можем даже обрабатывать миллисекунды таким же образом.
sed заменяет a : с формулой для преобразования в 1/60. Тогда расчет времени, который производится по bc
по состоянию на дату (GNU coreutils) 7.4 теперь вы можете использовать-d для выполнения арифметики:
единицы измерения, которые вы можете использовать, — это дни, годы, месяцы, часы, минуты и секунды:
следуя ответу Даниэля Камила Козара, чтобы показать часы / минуты / секунды:
таким образом, полный сценарий будет:
Источник
7.3. Операции сравнения
сравнение целых чисел
if [ «$a» -eq «$b» ]
if [ «$a» -ne «$b» ]
if [ «$a» -gt «$b» ]
больше или равно
if [ «$a» -ge «$b» ]
if [ «$a» -lt «$b» ]
меньше или равно
if [ «$a» -le «$b» ]
меньше или равно (внутри двойных круглых скобок)
больше (внутри двойных круглых скобок)
больше или равно (внутри двойных круглых скобок)
сравнение строк
if [ «$a» = «$b» ]
if [ «$a» == «$b» ]
if [ «$a» != «$b» ]
Этот оператор используется при поиске по шаблону внутри [[ . ]].
меньше, в смысле величины ASCII-кодов
if [[ «$a» if [ «$a» \ » необходимо экранировать внутри [ ].
больше, в смысле величины ASCII-кодов
if [[ «$a» > «$b» ]]
if [ «$a» \> «$b» ]
Обратите внимание! Символ «>» необходимо экранировать внутри [ ].
См. Пример 25-6 относительно применения этого оператора сравнения.
строка «пустая» , т.е. имеет нулевую длину
строка не «пустая» .