Bagaimana cara memeriksa tahun mana yang merupakan tahun kabisat?

19

Bagaimana saya bisa mengetahui tahun kabisat antara tahun 2014 dan 2020 di terminal Linux?

Apakah ada cara menggunakan beberapa kode seperti $cal- apa saja untuk menunjukkan tahun mana yang melompat tahun antara 2014 dan 2020 secara langsung?

lee
sumber

Jawaban:

39

Anda dapat menggunakan datekode keluar untuk memeriksa tahun kabisat, dengan mengandalkan dateperilaku menghasilkan kode keluar non 0 untuk tanggal yang tidak valid, jelas tidak ada tanggal 29 Februari di tahun bukan kabisat:

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

sebagai fungsi:

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

Pemakaian:

$ isleap 2019
is not leap

$ isleap 2020
is leap

Mengenai pertanyaan Anda:

Bagaimana saya bisa mengetahui tahun kabisat antara tahun 2014 dan 2020 di 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
sumber
mengapa ini tidak berfungsi di terminal mac
lee
Saya harap Anda tidak meminta solusi untuk mac di ask ubuntu ... Lihat ini untuk perintah osx date .
pLumo
9

Hanya varian dari jawaban @ 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 menetapkan tanggal ke 29 Februari dan mencetak tahun, mengabaikan segala kesalahan yang terjadi.

wjandrea
sumber
3
Atau bahkanseq -f "%g-02-29" 2014 2020 | date -f- +"%Y" 2>/dev/null
Digital Trauma
@DigitalTrauma: sangat keren!
7

Di sini, di Stack Overflow, solusi elegan disediakan oleh anubhava :

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

Simpan di atas dalam file teks bernama isleap.

Jangan lupa untuk mengatur izin eksekusi:

chmod +x isleap

Menguji:

$ ./isleap 1900
not a leap
$ ./isleap 2000
leap year
abu_bua
sumber
Ini jawaban yang benar. Yang lain yang bergantung pada implementasi sewenang-wenang dalam dateperintah ini adalah peretasan.
DocSalvager
3

Jika Anda tidak ingin bergantung pada beberapa properti "misterius" insidental dari tahun kabisat (seperti keterbagiannya, jumlah hari dalam setahun, atau keberadaan hari tertentu), Anda harus menggunakan bahasa pemrograman dengan perpustakaan kalender yang sesuai fungsi. Saya merekomendasikan 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

Pemakaian:

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

Atau sebagai one-liner (tanpa penanganan kesalahan yang tepat):

$ 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 Saya yakin ada solusi Perl setara sederhana.

2calendar Modul Python menggunakan kalender Gregorian yang proleptik , yaitu memperluas kalender G. tanpa batas ke masa lalu dan masa depan. Tidak memperhitungkan bahwa G. kalender hanya berlaku pada 1582 atau bahwa beberapa lokal terus menggunakan kalender lain dengan aturan tahun kabisat yang berbeda. Jika Anda memerlukan dukungan untuk kalender lain, misalnya kalender Julian, saya sarankan Anda menginstal dan menggunakan modul ekstensi Python yang sesuai.

David Foerster
sumber
Dari 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). Fct yang sama seperti yang digunakan di askubuntu.com/a/1081237/790920
abu_bua
@abu_bua: Ya, tetapi tidak menemukan kembali roda berarti Anda tidak akan membuat kesalahan yang sama (bahkan kesalahan ketik) seperti penemu aslinya. Itu dengan asumsi bahwa Anda percaya pada karya penemu itu. Modul inti Python umumnya dipelihara dengan baik.
David Foerster