Linux 每月正确减少一个日期
我有一个简单的代码,它是工作,但不是预期的。我的代码的主要建议是将给定日期缩短到目标日期2012-01-31 但结果是:Linux 每月正确减少一个日期,linux,bash,shell,date,datetime,Linux,Bash,Shell,Date,Datetime,我有一个简单的代码,它是工作,但不是预期的。我的代码的主要建议是将给定日期缩短到目标日期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 20
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
...
我怎样才能做到这一点呢?也许你可以减去当前月份的天数,而不是减去一个月(因为这种行为而臭名昭著)
!/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
也许你可以减去当前月份的天数,而不是减去一个月(这种行为是臭名昭著的)
!/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
假设您的开始日期始终是当月的最后一天,如果使用此算法,您可以让
date
计算每月的天数:
date = date +1 day -1 month -1 day
也就是说,首先将日期翻转到下个月的第一天,然后只需减去一个月即可得到当月的第一天,最后只需减去一天即可得到上个月的最后一天
例如:
#!/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天前
代替-1天
,因为后者可以通过日期
解释为时区(已知的gotcha)
或者,您可以手动将日期设置为
01
(使用shell的参数展开),然后简单地用日期减去1天
:
d=2017-10-31
while [ "$d" != 2012-01-31 ]; do
echo $d
d=$(date -I -d "${d%-*}-01 1 day ago")
done
输出为(在两种情况下):
假设您的开始日期始终是当月的最后一天,如果使用此算法,您可以让date
计算每月的天数:
date = date +1 day -1 month -1 day
也就是说,首先将日期翻转到下个月的第一天,然后只需减去一个月即可得到当月的第一天,最后只需减去一天即可得到上个月的最后一天
例如:
#!/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天前
代替-1天
,因为后者可以通过日期
解释为时区(已知的gotcha)
或者,您可以手动将日期设置为01
(使用shell的参数展开),然后简单地用日期减去1天
:
d=2017-10-31
while [ "$d" != 2012-01-31 ]; do
echo $d
d=$(date -I -d "${d%-*}-01 1 day ago")
done
输出为(在两种情况下):
在不检查日期的情况下,生成月初和获取月底的小技巧更容易
$ 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
在不检查日期的情况下,生成月初和获取月底的小技巧更容易
$ 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