GCP Composerでbotoファイルを使用してGCSからS3にファイルをコピーする方法
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日引いた日付が表示されます。