dateコマンドで前月をYYYYMM形式で取得する(※ーdオプション禁止)


仕事でSolarisサーバーからシステム日付の前月と前々月の年月を
YYYYMM
形式で取得する処理のシェルスクリプトを書くことになりました。
この時に、一筋縄ではいかないことがありました。

 

その時にどうやって対処したかを記載します。

 

 

 

一番簡単な方法

 

普通、日付の1か月前の計算はこのようにして行います。

 

# 1カ月前

 

$ date -d ‘1 month ago’

 

 

 

このように-dオプション又は-dateオプションを使います。

 

ところが、同じUnix系なのにSolarisでは使えません。

 

(参照:http://www.fujitsu.com/jp/products/computing/servers/unix/sparc/technical/command-reference/sys2/07.html) 

 

 

Solarisdateコマンドで過去や未来の日付を出すには

 

sh-utils若しくはshutilsというパッケージをインストールすればいいらしいです。

(参照:https://blogs.yahoo.co.jp/bobuton/26034312.html)

 

そこで、これを本番環境でインストールしてもいいかお客様に尋ねたところ
「他の重要な処理に影響が出たら困るので、避けてほしい」

 

との回答が……。

 

ということで、-dオプションを使わずに日付計算をすることになりました。

 

 

 

最初は、タイムゾーンを設定することで取得できると調べたときにわかり、考えたのが

 

LASTMONTH=`JST+15 date “+%Y%m”`

(1日前の年月日時刻を取得し、YYYYMM形式で表示)

 

(参照:http://shellscript.sunone.me/date.html#gnu-date-が使用できない場合-1) 

 

でした。

 

 

この処理が「毎月1日に行われる」ことを利用した策ですが

 

実行日を変更するとき、わざわざこの“+15”を変えないといけません。

 

これではいつの日にか、ユーザー様にご迷惑をお掛けすることになりますね。

 

しかも、これは最大でも1週間程度までしか遡れなかったので

 

中旬以降に実施することに変更になってしまえば、たちまち使えなくなってしまいます。

 

別の手段を探すことになりました。

 

 

 

そして、日付を整数として計算するという方法を見つけました。
(参照:http://shellscript.sunone.me/date.html#先月の月を取得する)

 

 

まずは、システム日付を年月だけの形式(YYYYMM)で取得します。

 

SYSDATE=`date “+%Y%m”`

 

 

1カ月前なら、この変数SYSDATEを整数扱いにして1を引けばいいので

 

LASTMONTH=`expr ${SYSDATE} -1`

 

 

 

しかし、これではある罠にはまってしまうことに気付きました。

 

例えば、この処理が2018年1月に行われたとき、どうなるでしょうか。

 

LASTMONTH=201801-1=201800

 

と、20180月となってしまいます。

 

 

これでは具合が悪いので

 

1月にこの処理が行われた時とそうじゃない時とで条件分岐を与え

 

別の処理を施す必要が出てきました。

 

 

 

最初に思いついたのは

 

この変数LASTMONTHを月だけに分け

 

LASTMONTH_M=${LASTMONTH:4:2}(これで変数から部分的に文字列を取得する)

 

 

 

このLASTMONTH_M”00”になるときは

 

LASTMONTH=LASTMONTH-88

 

をするということでした。

 

 

 

実際、20181月にこの処理を実行したとすると

 

LASTMONTH=201801-1=201800

 

LASTMONTH_M=00

 

LASTMONTH=201800-88=201712

 

となります。

 

 

 

ただ、これでいいかどうか、相談してみたところ

 

月計算で88を使うなんて直感的ではない、分かりにくいと指摘を受けました。

 

それとともに、年と月で分けて計算したほうがいいのではないか?とアドバイスをもらいました。

 

 

 

その後、次のように変更しました。

 

LASTMONTH=`expr ${SYSDATE} -1`

 

LASTMONTH_Y=`${LASTMONTH:0:4}`

 

LASTMONTH_M=`${LASTMONTH:4:2}`

 

 

 

if [${LASTMONTH_M} -eq “00”]; then

 

LASTMONTH_Y=`expr ${LASTMONTH_Y} -1`

 

LASTMONTH=”${LASTMONTH_Y}12”

 

fi

 

 

 

取得した前月を年と月に分け

 

前月が“00”になったとき

 

年だけ1引いて

 

その年の後ろに“12”を付け足すという考えです。

 

 

 

実際に20181月に実行されたとして計算してみると

 

LASTMONTH=`expr ${SYSDATE} -1` =201801-1=201800

 

LASTMONTH_Y=`${LASTMONTH:0:4}` =2018

 

LASTMONTH_M=`${LASTMONTH:4:2}` =00

 

 

 

if [${LASTMONTH_M} -eq “00”]; then

 

LASTMONTH_Y=`expr ${LASTMONTH_Y} -1` =2018-1=2017

 

LASTMONTH=”${LASTMONTH_Y}12” =201712

 

fi

 

 

 

このように前月を取得することができます。