概要
SQLite にはデータ型として日付型がないため、日付の計算は少し特殊な書き方をする必要がある。
この記事では「年」単位の計算についてまとめる。
実行例
環境
- Windows 10
- sqlite Command-Line Shell ver 3.51.3
単純な日付型の加減算では計算出来ない
date()や
datetime()の加減算では計算出来ず、以下のような結果になってしまう。
どうやら最初の「年」の箇所だけを数値として取り出して計算しているらしいが、正直モヤっとする。
sqlite> select date('2026-05-01') - date('2026-03-01');
0
sqlite> select date('2025-01-31') - date('2022-12-31');
3
sqlite> select date('2026-05-01') - 1;
2025
年を加算/減算する
上記の式で納得できるのであれば、それでOK。
ただ、コードの保守性や引継ぎを考えると 「ここは年の計算をしている」ことがコードからわかることがベスト。
年単位の加算/減算をする場合はdate()や
datetime()の引数にNNN yearsを追加する。
例えば1年後を計算したければ+1 yearsを追加する。
sqlite> select date('2026-04-01', '+1 years');
2027-04-01
sqlite> select date('2026-04-01', '-1 years');
2025-04-01
sqlite> select datetime('2026-04-01 09:00:00', '+1 years');
2027-04-01 09:00:00
sqlite> select datetime('2026-04-01 09:00:00', '-1 years');
2025-04-01 09:00:00
例えばこのようなテーブルの各行の1年後、1年前を計算するには以下のようなSQLになる。
| user_name | expiration_date |
|---|---|
| hoge1 | 2026-04-15 |
| hoge2 | 2026-12-31 |
| hoge3 | 2024-02-29 |
select
user_name
, expiration_date
, date(expiration_date, '+1 years') as next_year
, date(expiration_date, '-1 years') as prev_year
from
user_table
;
| user_name | expiration_date | next_year | prev_year |
|---|---|---|---|
| hoge1 | 2026-04-15 | 2027-04-15 | 2025-04-15 |
| hoge2 | 2026-12-31 | 2027-12-31 | 2025-12-31 |
| hoge3 | 2024-02-29 | 2023-03-01 | 2025-03-01 |
2つの日付間の年数を計算する
大きく分けて2パターン。
1つ目は、strftime()関数を使って年の部分だけを取り出して計算する方法。
2つ目は、julianday()関数を使って日数に変換してから年数に変換する方法。
1つ目の方法は、単純に年の部分だけを取り出して計算する方法。
例えば以下のようなSQLになる。
sqlite> select strftime('%Y', '2026-05-01') - strftime('%Y', '2025-11-01') as span_year;
1
ただし、この方法は単純に年の部分だけを取り出して計算するため、月や日が考慮されない。
例えば上記のSQLでは、2026年5月1日と2025年11月1日の年数の差は1年と計算されるが、実際には6ヶ月の差しかない。
2つ目の方法は、日付を日数に変換してから年数に変換する方法。
例えば以下のようなSQLになる。
sqlite> select (julianday('2026-05-01') - julianday('2026-03-01')) / 365.25;
0.167008898015058
この方法では、日付を日数に変換してから年数に変換するため、月や日が考慮される。
例えば上記のSQLでは、2026年5月1日と2026年3月1日の年数の差は0.16年と計算される。
(厳密にうるう年を計算しようと思うと大変なのでここでは0.25日を使う。)
必要に応じて小数点以下を切り捨てるなどの処理を行うと良い。
sqlite> select cast((julianday('2026-05-01') - julianday('2026-03-01')) / 365.25 as int);
0
sqlite> select cast((julianday('2026-05-31') - julianday('2025-04-30')) / 365.25 as int);
1
参考URL
-
SQLite Query Language: Date And Time Functions(英語)
公式の日時型に関するドキュメント
https://www.sqlite.org/lang_datefunc.html -
SQLite備忘録:日時の処理のまとめ
https://sfnovicenotes.blogspot.com/2022/01/sqlite3_02064292495.html -
SQLite備忘録: SQLite 3 で日付型の加減算を行う
https://sfnovicenotes.blogspot.com/2021/12/sqlite3_18.html -
SQLite備忘録: SQLite 3 で二つの日付間の日数を計算する
https://sfnovicenotes.blogspot.com/2023/01/sqlite3.html