Como verifico quais anos são bissextos?

19

Como posso descobrir quais são os anos bissextos entre 2014 e 2020 em um terminal Linux?

Existe alguma maneira de usar algum código como $cal- algo para mostrar quais anos são anos bissextos entre 2014 e 2020 imediatamente?

lee
fonte

Respostas:

39

Você pode usar dateo código de saída de para verificar um ano bissexto, contando com dateo comportamento de gerar um código de saída diferente de 0 para uma data inválida. Obviamente, não há 29 de fevereiro em um ano sem bissextos:

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

Como uma função:

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

Uso:

$ isleap 2019
is not leap

$ isleap 2020
is leap

Quanto à sua pergunta:

Como posso descobrir quais são os anos bissextos entre 2014 e 2020 em um terminal 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
fonte
porque este não é um trabalho no terminal de mac
lee
Espero que você não tenha solicitado uma solução para mac no ask ubuntu ... Veja isto para o comando osx date .
PLumo # 17/18
9

Apenas uma variante da resposta de @ 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 define a data para 29 de fevereiro e imprime o ano, ignorando quaisquer erros que ocorram.

wjandrea
fonte
3
Ou até mesmoseq -f "%g-02-29" 2014 2020 | date -f- +"%Y" 2>/dev/null
Digital Trauma
@DigitalTrauma: muito legal!
7

Aqui no Stack Overflow, uma solução elegante foi fornecida pelo anubhava :

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

Salve o acima em um arquivo de texto chamado isleap .

Não se esqueça de definir a permissão de execução:

chmod +x isleap

Teste-o:

$ ./isleap 1900
not a leap
$ ./isleap 2000
leap year
abu_bua
fonte
Essa é a resposta correta. Os outros que dependem de uma implementação arbitrária no datecomando são hacks.
DocSalvager
3

Se você não quiser confiar em algumas propriedades "arcanas" incidentais dos anos bissextos (como a divisibilidade, o número de dias em um ano ou a existência de um dia específico), use uma linguagem de programação com uma biblioteca de calendário apropriada função. Eu recomendo o 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

Uso:

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

Ou como uma linha (sem tratamento adequado de erros):

$ 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 Tenho certeza de que existe uma solução Perl equivalente simples.

2 O calendarmódulo Python usa o calendário gregoriano proléptico , ou seja, estende o calendário G. indefinidamente no passado e no futuro. Não leva em conta que o calendário G. entrou em vigor apenas em 1582 ou que alguns locais continuam usando outros calendários com regras diferentes para o ano bissexto. Se você precisar de suporte para outros calendários, por exemplo, o calendário juliano, recomendo que você instale e use um módulo de extensão Python apropriado.

David Foerster
fonte
De 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). Mesmo fct. como usado em askubuntu.com/a/1081237/790920
abu_bua
@abu_bua: Sim, mas não reinventar a roda significa que você não cometerá os mesmos erros (mesmo erros de digitação) que seu inventor original. Isso pressupõe que você confia no trabalho desse inventor. Os módulos principais do Python geralmente são bem mantidos.
David Foerster