PROGRAMING
PR

[bash]日付に月の足し算引き算する時は要注意

ycsg113XYZ
記事内に商品プロモーションを含む場合があります
スポンサーリンク

はじめに

今、3月31日なんですが、Shellで1ヶ月後(4月)の末日の日付を算出しようとしたら5月の1日になってしまってあれれれ?
なもんで調べました。

検証してみた

普通に日付に1ヶ月足す場合、こうします。
以下は3月2日に1ヶ月足す例。4月2日が戻ってきます。

$ date '+%Y%m%d' -d "20180302 1 months"
20180402

次に3月31日に1ヶ月足すとどうなるでしょう?

$ date '+%Y%m%d' -d "20180331 1 months"
20180501

あれれ?5月1日が戻ってきました。
んー、おそらく4月31日となって有り得ない日付なので5月1日になっちゃうのでしょうけど、戻して欲しい値はコレジャナイですよね。
月の引き算でも同様の事象かと思います。

ちなみに一般的なDBにも月の足し算をする関数ありますよね。
REDSHIFTで同じように3月末の日付に1ヶ月足してみると

sql=> select add_months('2018-03-31',1);
add_months
---------------------
2018-04-30 00:00:00
(1 行)

となって4月30日の値が返ってきます。これが本来欲しい値ですよね。

というわけでShellで月を足し引きする場合は要注意!

どうすれば?

システム日付の次の月の月初日と月末日を求める、なんて時はまずシステム日付の月の月初日(1日)の日付に対して足し引きするのが良いかと。

具体的に書けって?

ですよねー。

#!/bin/bash

a=$(date +%Y-%m-%d)   # 現在の日付を取得
b=$(date -d "$a +1 month" +%Y-%m-%d)   # 変数aに1ヶ月足した日付を取得

# 変数aが月末日かどうかを判定する
if [[ $(date -d "$a +1 month" +%m) != $(date -d "$b -1 day" +%m) ]]; then
    b=$(date -d "$a +2 month -1 day" +%Y-%m-%d)   # 変数aが月末日の場合、2ヶ月足して1日引く
fi

echo $b   # 結果を出力する

上記のスクリプトでは、まず現在の日付を取得して、その日付に1ヶ月足した日付を変数bに代入します。そして、変数aが月末日かどうかを判定し、月末日の場合は変数aに2ヶ月足して1日引いた日付を変数bに代入します。

このスクリプトを実行すると、変数aに1ヶ月足した日付が表示されます。ただし、変数aが月末日の場合は2ヶ月足して1日引いた日付が表示されます。

スポンサーリンク
ABOUT ME
ひろし
ひろし
都内在中のなんちゃってSE。ギリギリPG。の私が管理者のひろしです。 日々夜遅くまで仕事に追われています。 今日は早く帰りたい・・・
スポンサーリンク
記事URLをコピーしました