はじめに
以前に【MySQL】うるう年を判定するストアドファンクションという記事を書きましたが、この記事ではWikipediaに載っている計算式でうるう年であるかを判定しました。
その後、@Papageno さんの IS_LEAP_YEAR 閏年チェックという記事を見て、「2月の末日が29日であるか?」という別の方法でうるう年であるかを判定する方法があることに気が付きました。
今回は @Papageno さんの実装とは少し違う方法で、計算式を使わず簡単にうるう年を求めるストアドファンクションを作ってみました。
使用した環境
- Oracle社が提供しているOracle Live SQLでOracle19cを利用しました。
作成したコード
- @Papageno さんと同様に「2月29日が存在すればうるう年」という考え方ですが、「指定した西暦年における2月の末日が2月29日であるか?」という実装にしたため、エラー処理を使わずに実装できました。
- うるう年以外は2月29日は存在しないため、2月29日が存在しないことを前提とした実装にしました。
is_leap_year.sql
-- 引数の西暦年(YYYY)がうるう年であるかを判定するストアドファンクション
-- うるう年であれば1、そうでなければ0を返す。
CREATE OR REPLACE FUNCTION is_leap_year(year IN NUMBER) RETURN NUMBER
-- 宣言部
IS
yyyymmdd VARCHAR2(50);
last_day VARCHAR2(50);
-- 処理部
BEGIN
-- 引数で指定した西暦年の2月の末日を求める。
yyyymmdd := TO_CHAR(year) || '-02-01';
SELECT TO_CHAR( LAST_DAY(TO_DATE(yyyymmdd,'YYYY-MM-DD')) , 'DD')
INTO last_day
FROM DUAL;
-- 2月の末日が29日であればうるう年、そうでなければうるう年以外と判定する。
IF (last_day = '29') THEN
RETURN 1;
ELSE
RETURN 0;
END IF;
END;
実行用SQL
-- 宣言部
DECLARE
year NUMBER;
ret NUMBER;
BEGIN
FOR year IN 2000..2021 LOOP
SELECT
is_leap_year(year)
INTO
ret
FROM
dual;
IF (ret = 1) THEN
DBMS_OUTPUT.PUT_LINE(year || '年はうるう年です。');
ELSE
DBMS_OUTPUT.PUT_LINE(year || '年はうるう年ではありません。');
END IF;
END LOOP;
END;
実行結果
2000年はうるう年です。
2001年はうるう年ではありません。
2002年はうるう年ではありません。
2003年はうるう年ではありません。
2004年はうるう年です。
2005年はうるう年ではありません。
2006年はうるう年ではありません。
2007年はうるう年ではありません。
2008年はうるう年です。
2009年はうるう年ではありません。
2010年はうるう年ではありません。
2011年はうるう年ではありません。
2012年はうるう年です。
2013年はうるう年ではありません。
2014年はうるう年ではありません。
2015年はうるう年ではありません。
2016年はうるう年です。
2017年はうるう年ではありません。
2018年はうるう年ではありません。
2019年はうるう年ではありません。
2020年はうるう年です。
2021年はうるう年ではありません。