从bash中减去给定日期的月份

时间:2019-10-17 10:18:27

标签: linux bash shell

我想从给定的日期中减去几个月。

businessDate='2019-12-31'
diff=1
busDate=$(date --date="$businessDate -$diff month" +%Y-%m-%d)
echo "Date: $busDate"

此代码返回2019-12-01而不是2019-11-30。有人可以提出解决方案以获取正确的日期吗?

2 个答案:

答案 0 :(得分:2)

如“信息日期”中所指出的那样,用相对月份(1个月前等)计算日期是有问题的,有时会导致意外结果:

来自:29.7日期字符串中的相对项目:

  

单位为单位的绒毛可能导致相关项目出现问题。对于   例如,“ 2003-07-31 -1个月”的计算结果为2003-07-01,因为   2003-06-31是无效日期

一些解决方案:

  1. 处理“ 1个月前”作为向后移动天数的请求,其中N为max(DD,上个月的天数)。
  2. 检查结果日期是否与原始日期相同,并将日期从该月的第一天后移一天。这是处理3月/ 2月过渡所必需的。
  3. 另一种方法是在该月的第一天(将始终有效)执行日期移动,然后将日期的日期部分设置为上限,但将结果月份的最后一个日期设置为上限。

第三种方法的好处是它代表月运动。

选项#3的实现是bash有点麻烦,写python / perl代码可能更好。

IDATE=2019-12-31
N_MONTH=-1
DD_PART=$(date +'%d' -d "$IDATE")
YYYYMM=$(date +'%Y-%m' -d "$(date +'%Y-%m-01' -d "$IDATE") $N_MONTH month")
LAST_DAY_IN_YYYYMM=$(date +'%d' -d "$YYYYMM-01 +1month -1day")
if [[ "$LAST_DAY_IN_YYYYMM" -lt "$DD_PART" ]] ; then
    DD_PART=$LAST_DAY_IN_YYYYMM
fi
echo "$YYYYMM-$DD_PART"

答案 1 :(得分:0)

首先,这实际上是正确的日期! “ 2019-12-31”减去一个月将是“ 2019-11-31”,但由于我们在11月只有30天,因此它映射到12月1日。

不过,如果您想确定上个月的时间(我想这就是您想要的!),我可能会建议根据需要增加几天。请尝试以下代码:

businessDate='2019-12-3'
diff=1

thisMonth=$(date --date=$businessDate +%m)
extra=0 #extra days to reach the previous month for sure
while [ $(date --date="$businessDate -$diff month -$extra days" +%m) == $thisMonth ]
do
    extra=`expr $extra + 1`
done


busDate=$(date --date="$businessDate -$diff month -$extra days" +%Y-%m-%d)
echo "Date: $busDate"