如何在 Oracle 中檢測給定年份是否為閏年?
問題
您需要確定任何給定年份是否為閏年。
解決方案
解決此問題的方法有很多。這些方法包括計算以確定該年份是否存在 2 月 29 日,或 3 月 1 日是該年份的第 61 天還是第 62 天。
示例
SELECT to_number(to_char(sysdate,'YYYY')) Year, CASE WHEN MOD(to_number(to_char(sysdate,'YYYY')),400) = 0 then 'Yes' WHEN MOD(to_number(to_char(sysdate,'YYYY')),100) = 0 then 'No' WHEN MOD(to_number(to_char(sysdate,'YYYY')),4) = 0 then 'Yes' ELSE 'No' END AS "Leap Year?" FROM dual;
輸出
2020 Yes
顯然 2020 年是不值得紀念的一年,它是一個閏年。讓我們在非閏年上嘗試一下,例如 2019 年。
示例
SELECT '2019' Year, CASE WHEN MOD(2019,400) = 0 then 'Yes' WHEN MOD(2019,100) = 0 then 'No' WHEN MOD(2019,4) = 0 then 'Yes' ELSE 'No' END AS "Leap Year?" FROM dual;
輸出
2019 No
該解決方案基於從年份數字推匯出的閏年的標準定義。標準演算法指出,如果年份可以被四整除,則它是閏年。但是,如果年份也可以被 100 整除,則此規則將覆蓋可被四整除的規則,並且該年份不是閏年。最後,如果年份也可以被 400 整除,則此規則將覆蓋所有其他規則,並且該年份是閏年。
上述步驟序列在我們的 SQL 中使用 CASE 語句執行。
我們使用 CASE 語句來驅動閏年檢測的主體。我們在 case 語句中反向應用閏年演算法,以利用 CASE 語句的行為。一旦找到匹配規則,CASE 語句就會中斷。這意味著我們希望首先評估最重要的規則,即覆蓋所有其他規則的規則,年份是否可以被 400 整除?如果結果為假,我們希望評估下一個最嚴格的規則——被 100 整除——依此類推。
我們使用 MOD 函式執行模除法。首先,如果年份模 400 沒有餘數,我們知道它可以被 400 整除,因此它是閏年。對於這種情況,我們返回字串“閏年”,並且 CASE 語句結束。如果我們的年份模 400 有餘數,我們知道它不是閏年,然後繼續對年份模 100 進行除法。如果沒有餘數,我們知道年份可以被 100 整除,因此不是閏年。我們知道這一點,因為如果年份也可以被 400 整除,我們不會評估 CASE 表示式的這一部分,因為 CASE 語句已經終止了。
類似地,如果兩個模除法都有餘數,我們將繼續執行第三個模除法,該除法找到年份除以四的餘數。同樣,如果沒有餘數,我們知道前兩個規則沒有匹配,因此年份是閏年。
此時,我們的 CASE 語句已用盡,我們知道該年份與任何查詢閏年的顯式規則都不匹配。