Пример A-8. days-between: Подсчет числа дней между двумя датами
Пример A-8. days-between: Подсчет числа дней между двумя датами
#!/bin/bash
# days-between.sh: Подсчет числа дней между двумя датами.
# Порядок использования: ./days-between.sh [M]M/[D]D/YYYY [M]M/[D]D/YYYY
ARGS=2 # Ожидается два аргумента из командной строки.
E_PARAM_ERR=65 # Ошибка в числе ожидаемых аргументов.
REFYR=1600 # Начальный год.
CENTURY=100
DIY=365
ADJ_DIY=367 # Корректировка на високосный год + 1.
MIY=12
DIM=31
LEAPCYCLE=4
MAXRETVAL=255 # Максимально возможное возвращаемое значение
# для положительных чисел.
diff= # Количество дней между датами.
value= # Абсолютное значение.
day= # день, месяц, год.
month=
year=
Param_Error () # Ошибка в пвраметрах командной строки.
{
echo "Порядок использования: `basename $0` [M]M/[D]D/YYYY [M]M/[D]D/YYYY"
echo " (даты должны быть после 1/3/1600)"
exit $E_PARAM_ERR
}
Parse_Date () # Разбор даты.
{
month=${1%%/**}
dm=${1%/**} # День и месяц.
day=${dm#*/}
let "year = `basename $1`" # Хотя это и не имя файла, но результат тот же.
}
check_date () # Проверка даты.
{
[ "$day" -gt "$DIM" ] || [ "$month" -gt "$MIY" ] || [ "$year" -lt "$REFYR" ] && Param_Error
# Выход из сценария при обнаружении ошибки.
# Используется комбинация "ИЛИ-списка / И-списка".
#
# Упражнение: Реализуйте более строгую проверку даты.
}
strip_leading_zero () # Удалить ведущий ноль
{
val=${1#0} # иначе Bash будет считать числа
return $val # восьмеричными (POSIX.2, sect 2.9.2.1).
}
day_index () # Формула Гаусса:
{ # Количество дней от 3 Янв. 1600 до заданной даты.
day=$1
month=$2
year=$3
let "month = $month - 2"
if [ "$month" -le 0 ]
then
let "month += 12"
let "year -= 1"
fi
let "year -= $REFYR"
let "indexyr = $year / $CENTURY"
let "Days = $DIY*$year + $year/$LEAPCYCLE - $indexyr + $indexyr/$LEAPCYCLE + $ADJ_DIY*$month/$MIY + $day - $DIM"
# Более подробное объяснение алгоритма вы найдете в
# http://home.t-online.de/home/berndt.schwerdtfeger/cal.htm
if [ "$Days" -gt "$MAXRETVAL" ] # Если больше 255,
then # то поменять знак
let "dindex = 0 - $Days" # чтобы функция смогла вернуть полное значение.
else let "dindex = $Days"
fi
return $dindex
}
calculate_difference () # Разница между двумя датами.
{
let "diff = $1 - $2" # Глобальная переменная.
}
abs () # Абсолютное значение
{ # Используется глобальная переменная "value".
if [ "$1" -lt 0 ] # Если число отрицательное
then # то
let "value = 0 - $1" # изменить знак,
else # иначе
let "value = $1" # оставить как есть.
fi
}
if [ $# -ne "$ARGS" ] # Требуется два аргумента командной строки.
then
Param_Error
fi
Parse_Date $1
check_date $day $month $year # Проверка даты.
strip_leading_zero $day # Удалить ведущие нули
day=$? # в номере дня и/или месяца.
strip_leading_zero $month
month=$?
day_index $day $month $year
date1=$?
abs $date1 # Абсолютное значение
date1=$value
Parse_Date $2
check_date $day $month $year
strip_leading_zero $day
day=$?
strip_leading_zero $month
month=$?
day_index $day $month $year
date2=$?
abs $date2 # Абсолютное значение
date2=$value
calculate_difference $date1 $date2
abs $diff # Абсолютное значение
diff=$value
echo $diff
exit 0
# Сравните этот сценарий с реализацией формулы Гаусса на C
# http://buschencrew.hypermart.net/software/datedif
Более 800 000 книг и аудиокниг! 📚
Получи 2 месяца Литрес Подписки в подарок и наслаждайся неограниченным чтением
ПОЛУЧИТЬ ПОДАРОКЧитайте также
Пример: передача текстовых строк между клиентом и сервером
Пример: передача текстовых строк между клиентом и сервером Изменим наш сервер так, чтобы он, по-прежнему принимая текстовую строку от клиента, предполагал, что строка содержит два целых числа, разделенных пробелом, и возвращал сумму этих чисел. Функции main наших клиента и
Пример: передача двоичных структур между клиентом и сервером
Пример: передача двоичных структур между клиентом и сервером Теперь мы изменим код клиента и сервера, чтобы передавать через сокет не текстовые строки, а двоичные значения. Мы увидим, что клиент и сервер работают некорректно, когда они запущены на узлах с различным
(6.14) Как настроить роутинг между двумя подсетями на W2kPro?
(6.14) Как настроить роутинг между двумя подсетями на W2kPro? Это нужно когда на машине с W2k имеется две сетевые карты, одна из которых смотрит в одну подсеть, а другая в другую. Для того что бы компьютеры из разных подсетей могли видеть друг друга, на машине с W2k надо прописать
2.28. Подсчет числа символов в строке
2.28. Подсчет числа символов в строке Метод count подсчитывает число вхождений в строку символов из заданного набора:s1 = "abracadabra"a = s1.count("с") # 1b = s1.count("bdr") # 5Строковый параметр ведет себя как простое регулярное выражение. Если он начинается с символа ^, то берется дополнение к
2.36. Вычисление расстояния Левенштейна между двумя строками
2.36. Вычисление расстояния Левенштейна между двумя строками Расстояние между строками важно знать в индуктивном обучении (искусственный интеллект), криптографии, исследовании структуры белков и других областях.Расстоянием Левенштейна называется минимальное число
7.17. Вычисление разности между двумя моментами времени
7.17. Вычисление разности между двумя моментами времени Можно вычислить интервал между двумя моментами времени. В результате вычитания одного объекта Time из другого получаем число секунд:today = Time.local(2000,11,10)yesterday = Time.local(2000,11,9)cliff = today - yesterday # 86400 секунд.И снова оказывается
5.3. Выполнение вычислений с датами и временем
5.3. Выполнение вычислений с датами и временем ПроблемаТребуется узнать количество времени, прошедшего между двумя точками даты/времени.РешениеЕсли обе временные точки находятся между 1970 и 2038 годами, то используйте тип time_t и функцию difftime, определенную в заголовочном
Поиск различий между двумя файлами
Поиск различий между двумя файлами Рассмотрим следующую задачу. Имеются две версии исходного файла, одна из которых - более поздняя, содержащая ряд изменений. Как выяснить различия между этими двумя файлами? Какие строки были добавлены, а какие удалены? Какие строки
Пример 10-2. Цикл for с двумя параметрами в каждом из элементов списка
Пример 10-2. Цикл for с двумя параметрами в каждом из элементов списка #!/bin/bash# Список планет.# Имя кажой планеты ассоциировано с расстоянием от планеты до Солнца (млн. миль).for planet in "Меркурий 36" "Венера 67" "Земля 93" "Марс 142" "Юпитер 483"do set -- $planet # Разбиение переменной "planet" на
Пример 12-37. Разложение числа на простые множители
Пример 12-37. Разложение числа на простые множители #!/bin/bash# factr.sh: Разложение числа на простые множителиMIN=2 # Не работает с числами меньше 2.E_NOARGS=65E_TOOSMALL=66if [ -z $1 ]then echo "Порядок использования: $0 number" exit $E_NOARGSfiif [ "$1" -lt "$MIN" ]then echo "Исходное число должно быть больше или равно $MIN."
Пример 25-11. Эмуляция массива с двумя измерениями
Пример 25-11. Эмуляция массива с двумя измерениями #!/bin/bash# Эмуляция двумерного массива.# Второе измерение представлено как последовательность строк.Rows=5Columns=5declare -a alpha # char alpha [Rows] [Columns]; # Необязательное объявление массива.load_alpha (){local rc=0local indexfor i in A B C D E F G H I J K L M N O P
Пример 2 - еще через пару дней
Пример 2 - еще через пару дней Через пару дней доска задач может выглядеть примерно так: Как видно, мы закончили историю «Депозит» (т.е. она была зафиксирована в системе контроля версий, протестирована, отрефакторена и т.д.) «Автоматическое обновление» сделано частично,