Come posso verificare quali anni sono gli anni bisestili?


Risposte:


39

Puoi utilizzare dateil codice di uscita per verificare un anno bisestile, basandoti sul datecomportamento di generare un codice di uscita diverso da 0 per una data non valida, ovviamente non c'è il 29 febbraio in un anno non bisestile:

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

come una funzione:

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

Per quanto riguarda la tua domanda:

Come posso sapere quali sono gli anni bisestili tra il 2014 e il 2020 in un terminale Linux?

echo "Leap years between 2014 and 2020:";
for y in {2014..2020}; do
    date -d $y-02-29 &>/dev/null && echo $y;
done

perché questo non funziona nel terminale mac
lee

Spero che tu non abbia chiesto una soluzione per Mac su Chiedi a Ubuntu ... Vedi questo per osx date command .
pLumo,

9

Solo una variante della risposta di @ 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 imposta la data al 29 febbraio e stampa l'anno, ignorando gli errori che si verificano.


3
O addiritturaseq -f "%g-02-29" 2014 2020 | date -f- +"%Y" 2>/dev/null
Digital Trauma,

@DigitalTrauma: molto bello!

7

Qui su Stack Overflow, un'elegante soluzione è stata fornita da anubhava :

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

Salvare quanto sopra in un file di testo denominato isleap.

Non dimenticare di impostare il permesso di esecuzione:

chmod +x isleap

Provalo:

$ ./isleap 1900
not a leap
$ ./isleap 2000
leap year

Questa è la risposta corretta Gli altri che dipendono da un'implementazione arbitraria nel datecomando sono hack.
DocSalvager,

3

Se non si desidera fare affidamento su alcune proprietà "arcane" accidentali degli anni bisestili (come la loro divisibilità, il numero di giorni in un anno o l'esistenza di un giorno specifico) è necessario utilizzare un linguaggio di programmazione con una libreria di calendari appropriata funzione. Consiglio Python's 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

O come one-liner (senza una corretta gestione degli errori):

$ 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 Sono sicuro che esiste una soluzione Perl equivalente semplice.

2 Il calendarmodulo di Python utilizza il proletico calendario gregoriano , ovvero estende il calendario G. indefinitamente nel passato e nel futuro. Non tiene conto del fatto che il calendario G. è entrato in vigore solo nel 1582 o che alcune versioni locali continuano a utilizzare altri calendari con regole diverse per l'anno bisestile. Se hai bisogno di supporto per altri calendari, ad esempio il calendario giuliano, ti consiglio di installare e utilizzare un modulo di estensione Python appropriato.


Da 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). Stesso fatto. come usato in askubuntu.com/a/1081237/790920
abu_bua

@abu_bua: Sì, ma non reinventare la ruota significa che non commetterai gli stessi errori (anche errori di battitura) del suo inventore originale. Questo presuppone che tu abbia fiducia nel lavoro di quell'inventore. I moduli core di Python sono generalmente ben mantenuti.
David Foerster,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.