我有一个简单的代码,它工作但不是按预期的。我的代码的主要建议是将给定日期减少到目标日期2012-01-31,
但结果是:
2017-10-28
2017-09-28
2017-08-28
2017-07-28
2017-06-28
2017-05-28
2017-04-28
2017-03-28
2017-02-28
2017-01-28
2016-12-28
2016-11-28
2016-10-28
2016-09-28
2016-08-28
2016-07-28
2016-06-28
2016-05-28
2016-04-28
2016-03-28
2016-02-28
2016-01-28
...
代码:
#!/bin/bash
d=2017-10-31
while [ "$d" != 2012-01-31 ]; do
echo $d
d=$(date -I -d "$d -1 month")
done
我真的希望正确的月份如下:
2017-10-31
2017-09-30
2017-08-31
2017-07-31
2017-06-30
2017-05-31
2017-04-30
2017-03-31
2017-02-28
2017-01-31
2016-12-31
2016-11-30
2016-10-31
2016-09-30
2016-08-31
2016-07-31
2016-06-30
2016-05-31
2016-04-30
2016-03-31
2016-02-29
2016-01-31
...
我该如何设法做到这一点?
答案 0 :(得分:1)
也许不是减去一个月(这种行为而臭名昭着),而是减去当月的天数
!/bin/bash
d=2017-10-31
while [ "$d" != 2012-01-31 ]; do
echo $d
days_in_month==$(cal $(date +"%m %Y" -d $d) | awk 'NF {DAYS = $NF}; END {print DAYS}')
d=$(date -I -d "$d $days_in_month day ago")
done
答案 1 :(得分:1)
假设您的开始日期始终是月中的最后一天,如果您使用此算法,则可以让date
负责每月的计算天数:
date = date +1 day -1 month -1 day
即,首先将日期翻到下个月的第一天,然后简单地减去一个月以获得当月的第一天,最后只需减去1天即可获得上个月的最后一天。
例如:
#!/bin/bash
d=2017-10-31
while [ "$d" != 2012-01-31 ]; do
echo $d
d=$(date -I -d "$(date -I -d "$(date -I -d "$d +1 day") 1 month ago") 1 day ago")
done
注意1 day ago
代替-1 day
,因为后者可以被date
(已知问题)解释为时区。
或者,您可以手动将日期设置为01
(使用suffix removal ${d%-*}
的shell参数展开),然后使用1 day
简单地减去date
:
d=2017-10-31
while [ "$d" != 2012-01-31 ]; do
echo $d
d=$(date -I -d "${d%-*}-01 1 day ago")
done
输出(在两种情况下):
2017-10-31
2017-09-30
2017-08-31
2017-07-31
2017-06-30
2017-05-31
2017-04-30
...
答案 2 :(得分:1)
更容易生成月初,并在没有查看日期的情况下完成月末的小技巧
$ d=2017-10-31; bd=$(date -I -d "$d +1 month");
while [ $d != 2012-01-31 ];
do
bd=$(date -I -d "$bd - 1 month");
d=$(date -I -d "$bd - 1 day");
echo $d;
done
2017-10-31
2017-09-30
2017-08-31
2017-07-31
...
2016-07-31
2016-06-30
2016-05-31
2016-04-30
2012-03-31
2012-02-29
2012-01-31