Jak sprawdzić, które lata są latami przestępnymi?


Odpowiedzi:


39

Możesz użyć datekodu wyjścia do sprawdzenia roku przestępnego, opierając się na datezachowaniu generowania kodu wyjścia innego niż 0 dla niepoprawnej daty, oczywiście nie ma 29 lutego w roku innym niż przestępny:

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

jako funkcja:

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

Stosowanie:

$ isleap 2019
is not leap

$ isleap 2020
is leap

Jeśli chodzi o twoje pytanie:

Jak mogę dowiedzieć się, które lata przestępne między 2014 a 2020 rokiem znajdują się w terminalu Linux?

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

dlaczego to nie działa w terminalu Mac
Lee

Mam nadzieję, że nie poprosiłeś o rozwiązanie dla Maca na ask ubuntu ... Zobacz to dla komendy date systemu osx .
pLumo,

9

Tylko wariant odpowiedzi @ 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 ustawia datę na 29 lutego i drukuje rok, ignorując wszelkie występujące błędy.


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

@DigitalTrauma: bardzo fajne!

7

Tutaj, w przypadku przepełnienia stosu, anubhava zapewniło eleganckie rozwiązanie :

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

Zapisz powyższe w plikach tekstowych o nazwie isleap.

Nie zapomnij ustawić uprawnienia do wykonywania:

chmod +x isleap

Sprawdź to:

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

To jest poprawna odpowiedź. Inne, które zależą od arbitralnej implementacji datepolecenia, to hacki.
DocSalvager,

3

Jeśli nie chcesz polegać na niektórych przypadkowych „tajemnych” właściwościach lat przestępnych (takich jak ich podzielność, liczba dni w roku lub istnienie określonego dnia), powinieneś użyć języka programowania z odpowiednią biblioteką kalendarza funkcjonować. Polecam 1, 2 Python :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

Stosowanie:

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

Lub jako jedna linijka (bez odpowiedniej obsługi błędów):

$ 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 Jestem pewien, że istnieje proste równoważne rozwiązanie Perla.

2calendar Moduł Pythona korzysta z proleptycznego kalendarza gregoriańskiego , tzn. Rozszerza kalendarz G. na czas nieokreślony w przeszłość i przyszłość. Nie bierze pod uwagę, że kalendarz G. wszedł w życie dopiero w 1582 roku, ani że niektóre lokalizacje nadal używają innych kalendarzy z różnymi regułami dotyczącymi roku przestępnego. Jeśli potrzebujesz wsparcia dla innych kalendarzy, np. Kalendarza juliańskiego, zalecamy zainstalowanie odpowiedniego modułu rozszerzenia Python i korzystanie z niego.


Od 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). Ten sam fct. jak używany w askubuntu.com/a/1081237/790920
abu_bua

@abu_bua: Tak, ale nie wynalezienie koła oznacza, że ​​nie popełnisz tych samych błędów (nawet literówek), co jego oryginalny wynalazca. Zakłada się, że ufasz pracy tego wynalazcy. Podstawowe moduły Pythona są ogólnie dobrze utrzymane.
David Foerster,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.