dateコマンドで来月1日を取得する方法

# はじめに
来月1日を取得する処理で単純なようで、バグが発生したので、その際に調べたことをメモする。

# 誤った方法
## コマンド
```shell-session
date '+%Y%m01' -d "1 months"
```
##説明
･オプション d "1 months"
> システム日付の1ヵ月後を指定する。

･オプション '+フォーマット'
> %Y：年(西暦4桁)、%m：月(01～12)にてYYYYMMを取得し、DD部分に01を付加する。

# 正しい方法
## コマンド
```shell-session
date '+%Y%m01' -d "`date '+%Y-%m-01'` 1 months"
```
## 説明
･ 逆引用符`date '+%Y-%m-01'`
> システム日付のYYYYMMを取得し、DD部分に01を付加する。つまり当月の1日の日付を作る。

･オプション d "`date '+%Y-%m-01'` 1 months"
> 当月の1日の1ヵ月後を指定する。

･オプション '+フォーマット'
> %Y：年(西暦4桁)、%m：月(01～12)にてYYYYMMを取得し、DD部分に01を付加する。



# 問題になった箇所
## 現象
シェルの中で来月1日を取得する部分で、2015年1月29日の処理が上手く動きませんでした。
※現象を再現するために、オプションdに日付を付けた形で1ヵ月後を取っています。

```shell-session
$ date '+%Y%m01' -d '2015-01-27 1 months'
20150201
$ date '+%Y%m01' -d '2015-01-28 1 months'
20150201
$ date '+%Y%m01' -d '2015-01-29 1 months'
20150301
$ date '+%Y%m01' -d '2015-01-30 1 months'
20150301
$ date '+%Y%m01' -d '2015-01-31 1 months'
20150301
$ date '+%Y%m01' -d '2015-02-01 1 months'
20150301
$
```

## 説明
オプションdにて1 monthsを実施した際に、dateコマンドは2015年1月29日⇒2015年2月29日と解釈するようです。ただ、2015年の2月は28日までなので、溢れた1日分を2月28日に加算して2015年3月1日とするようです。信じられない話です。。。

## 検証
ということは、誤った方法だと翌月が前月より少ない日数の月で上手く行かなくなると思われます。
〔2015年1月〕

```shell-session
$ date '+%Y%m%d' -d '2015-01-27 1 months'
20150227
$ date '+%Y%m%d' -d '2015-01-28 1 months'
20150228
$ date '+%Y%m%d' -d '2015-01-29 1 months'
20150301　★
$ date '+%Y%m%d' -d '2015-01-30 1 months'
20150302　★
$ date '+%Y%m%d' -d '2015-01-31 1 months'
20150303　★
$ date '+%Y%m%d' -d '2015-02-01 1 months'
20150301
$
```

〔2015年5月〕

```shell-session
$ date '+%Y%m%d' -d '2015-05-29 1 months'
20150629
$ date '+%Y%m%d' -d '2015-05-30 1 months'
20150630
$ date '+%Y%m%d' -d '2015-05-31 1 months'
20150701　★
$ date '+%Y%m%d' -d '2015-06-01 1 months'
20150701
$
```

〔2015年8月〕

```shell-session
$ date '+%Y%m%d' -d '2015-08-30 1 months'
20150930
$ date '+%Y%m%d' -d '2015-08-31 1 months'
20151001　★
$ date '+%Y%m%d' -d '2015-09-01 1 months'
20151001
$
```

〔2015年10月〕

```shell-session
$ date '+%Y%m%d' -d '2015-10-30 1 months'
20151130
$ date '+%Y%m%d' -d '2015-10-31 1 months'
20151201　★
$ date '+%Y%m%d' -d '2015-11-01 1 months'
20151201
$
```

## 参考

```shell-session
$ cal 2015
                               2015

         1月                    2月                    3月
日 月 火 水 木 金 土   日 月 火 水 木 金 土   日 月 火 水 木 金 土
             1  2  3    1  2  3  4  5  6  7    1  2  3  4  5  6  7
 4  5  6  7  8  9 10    8  9 10 11 12 13 14    8  9 10 11 12 13 14
11 12 13 14 15 16 17   15 16 17 18 19 20 21   15 16 17 18 19 20 21
18 19 20 21 22 23 24   22 23 24 25 26 27 28   22 23 24 25 26 27 28
25 26 27 28 29 30 31                          29 30 31

         4月                    5月                    6月
日 月 火 水 木 金 土   日 月 火 水 木 金 土   日 月 火 水 木 金 土
          1  2  3  4                   1  2       1  2  3  4  5  6
 5  6  7  8  9 10 11    3  4  5  6  7  8  9    7  8  9 10 11 12 13
12 13 14 15 16 17 18   10 11 12 13 14 15 16   14 15 16 17 18 19 20
19 20 21 22 23 24 25   17 18 19 20 21 22 23   21 22 23 24 25 26 27
26 27 28 29 30         24 25 26 27 28 29 30   28 29 30
                       31
         7月                    8月                    9月
日 月 火 水 木 金 土   日 月 火 水 木 金 土   日 月 火 水 木 金 土
          1  2  3  4                      1          1  2  3  4  5
 5  6  7  8  9 10 11    2  3  4  5  6  7  8    6  7  8  9 10 11 12
12 13 14 15 16 17 18    9 10 11 12 13 14 15   13 14 15 16 17 18 19
19 20 21 22 23 24 25   16 17 18 19 20 21 22   20 21 22 23 24 25 26
26 27 28 29 30 31      23 24 25 26 27 28 29   27 28 29 30
                       30 31
        10月                   11月                   12月
日 月 火 水 木 金 土   日 月 火 水 木 金 土   日 月 火 水 木 金 土
             1  2  3    1  2  3  4  5  6  7          1  2  3  4  5
 4  5  6  7  8  9 10    8  9 10 11 12 13 14    6  7  8  9 10 11 12
11 12 13 14 15 16 17   15 16 17 18 19 20 21   13 14 15 16 17 18 19
18 19 20 21 22 23 24   22 23 24 25 26 27 28   20 21 22 23 24 25 26
25 26 27 28 29 30 31   29 30                  27 28 29 30 31
```