Как проверить, какие годы являются високосными?

19

Как я могу узнать, какие високосные годы между 2014 и 2020 годами в терминале Linux?

Есть ли способ использовать какой-то код, например, $calчто-нибудь, чтобы показать, какие годы являются високосными между 2014 и 2020 годами?

подветренный
источник

Ответы:

39

Вы можете использовать dateкод выхода для проверки високосного года, полагаясь на dateповедение генерации кода выхода, отличного от 0, для недопустимой даты, очевидно, что 29-го февраля не было високосного года:

date -d $year-02-29 &>/dev/null
echo $?

как функция:

isleap() { date -d $1-02-29 &>/dev/null && echo is leap || echo is not leap; }

Использование:

$ isleap 2019
is not leap

$ isleap 2020
is leap

По поводу вашего вопроса:

Как я могу узнать, какие високосные годы между 2014 и 2020 годами в терминале Linux?

echo "Leap years between 2014 and 2020:";
for y in {2014..2020}; do
    date -d $y-02-29 &>/dev/null && echo $y;
done
pLumo
источник
почему это не работает в Mac терминал
Ли
Я надеюсь, что вы не просили решение для Mac на Ask Ubuntu ... Смотрите это для команды OSX Date .
pLumo
9

Просто вариант ответа @ RoVo ...

for a in {2014..2020}
do 
  date -d $a-02-29 +"%Y" 2>/dev/null
done

date -d $a-02-29 +"%Y" 2> /dev/null устанавливает дату 29 февраля и печатает год, игнорируя любые возникающие ошибки.

wjandrea
источник
3
Или дажеseq -f "%g-02-29" 2014 2020 | date -f- +"%Y" 2>/dev/null
Цифровая травма
@DigitalTrauma: очень круто!
7

Здесь, на Stack Overflow, анубхава предоставила элегантное решение :

#!/bin/bash
(( !($1 % 4) && ( $1 % 100 || !( $1 % 400) ) )) &&
echo "leap year" || echo "not a leap"
exit 0

Сохраните вышесказанное в текстовых файлах с именем isleap.

Не забудьте установить разрешение на выполнение:

chmod +x isleap

Проверь это:

$ ./isleap 1900
not a leap
$ ./isleap 2000
leap year
abu_bua
источник
Это правильный ответ. Другие, которые зависят от произвольной реализации в dateкоманде, являются хаки.
DocSalvager
3

Если вы не хотите полагаться на некоторые случайные «тайные» свойства високосных лет (такие как их делимость, количество дней в году или наличие определенного дня), вам следует использовать язык программирования с соответствующей библиотекой календаря. функция. Я рекомендую Python 1, 2 :calendar.isleap()

#!/usr/bin/python3
import sys
import traceback
import calendar

try:
    year = int(sys.argv[1])
    is_leap = calendar.isleap(year)
except:
    traceback.print_exc()
    sys.exit(2)

print(is_leap)  # Print the year’s leap status
sys.exit(not is_leap)  # Exit program with "success" if leap and "failure" otherwise

Использование:

$ python3 is_leap.py 2000
True
$ python3 is_leap.py 2100
False

Или в виде одной строки (без надлежащей обработки ошибок):

$ python3 -c 'import sys, calendar; print(calendar.isleap(int(sys.argv[1])))' 2000
True
$ python3 -c 'import sys, calendar; sys.exit(not calendar.isleap(int(sys.argv[1])))' 2000
$ echo $?
0

1 Я уверен, что существует простое эквивалентное решение Perl.

2calendar Модуль Python использует пролептический григорианский календарь , то есть он расширяет календарь G. на неопределенное время в прошлое и будущее. При этом не учитывается, что календарь G. вступил в силу только в 1582 году или что некоторые регионы продолжают использовать другие календари с другими правилами високосного года. Если вам нужна поддержка других календарей, например, юлианского календаря, я рекомендую вам установить и использовать соответствующий модуль расширения Python.

Дэвид Фёрстер
источник
Из calendar.py: def isleap(year): """Return True for leap years, False for non-leap years.""" return year % 4 == 0 and (year % 100 != 0 or year % 400 == 0). То же самое как используется в askubuntu.com/a/1081237/790920
abu_bua
@abu_bua: Да, но не изобретать велосипед означает, что вы не будете делать те же ошибки (даже опечатки), как его первоначальный изобретатель. Это предполагает, что вы доверяете работе этого изобретателя. Основные модули Python, как правило, в хорошем состоянии.
Дэвид Фёрстер,