GNU 系の date コマンドでは -d オプションにより、ある時刻からの相対的な日時を取得できる。
例1:今日 (2018/07/16(月)) から3日後
$ date -d '3 days' +%Y/%m/%d\(%a\)
2018/07/19(木)
例2:今日 (2018/07/16(月)) の次の日曜日
$ date -d 'next sunday' +%Y/%m/%d\(%a\)
2018/07/22(日)
例3:2018/07/07(土) の1年前
$ date -d '20180707 1 year ago' +%Y/%m/%d\(%a\)
2017/07/07(金)
例4:今日 (2018/07/16(月)) から来週の日曜日
$ date -d "next week sunday" +%Y/%m/%d\(%a\)
2018/07/29(日)
本題
1年前の次の日曜日の日時を取得することを考える。
直感的には $ date -d 'last year next sunday' で取得できそうであるが、実行結果は以下の通り。
$ date -d 'last year next sunday' +%Y/%m/%d\(%a\)
2017/07/22(土)
日曜日を取得したいにも関わらず土曜日を取得してしまう。
これは date コマンドが曜日の計算を優先して計算してから、去年の日時を計算しているため。
解決策
以下のように求めることができる。
$ date -d "1 year ago `expr 7 - \`date -d '1 year ago' +%w\`` day" +%Y/%m/%d\(%a\)
2017/07/23(日)
+%w を用いると日曜日を 0 として 0 〜 6 までの数値で曜日を算出できる。
これにより去年の日時の曜日を計算し、去年のに日時に一週間分の日数である 7 からその曜日分を引いた日数だけ、去年の日時に加算する。
下記のように n 年前、n 年後の日時の次の日曜日の取得にも一応適応できる。
$ date -d "2 year ago `expr 7 - \`date -d '2 year ago' +%w\`` day" +%Y/%m/%d\(%a\)
2016/07/17(日)
$ date -d "1 year `expr 7 - \`date -d '1 year' +%w\`` day" +%Y/%m/%d\(%a\)
2019/07/21(日)