返回月份的结束日期小于给定的日期,并在shell中的12个日期处停止

问题描述 投票:-1回答:1

具有一种奇怪的算法,其中我需要返回月末日期小于或等于给定月末日期的日期。

我们本质上是在创建动态范围的日期,这些日期将在SQL文件中使用。所以我想说,给定这个日期20200315,请给我返回比给定日期短的所有月份结束日期,但要在2019年9月停止。还请忽略2019年10月。

因此给定20200331,您将返回...

20200331
20200229
20200131
20191231
20191130
20190930

如果给我20200731,它将返回...

20200731
20200630
20200531
20200430
20200331
20200229
20200131
20191231
20191130
20190930

现在这是另一个要求。它必须以12天为上限!!因此,如果给我20201130,它将返回...

20201130
20201031
20200930
20200831
20200731
20200630
20200531
20200430
20200331
20200229
20200131
20191231

相信此作品

for i in {1..11}
do
    thisDate=`date -d "$(date -d ${prevDate} +%Y-%m-01) -1 day" +%Y%m%d`
    if ((${thisDate} < 20190930)); then
        break
    elif ((${thisDate} == 20191031)); then
        prevDate=${thisDate}
        (( i += 1 ))
    else
        dateRange="${dateRange}'${thisDate}',"
        prevDate=${thisDate}
        (( i += 1 ))
fi

完成

linux bash shell unix ksh
1个回答
0
投票

问题中提供的代码似乎没有考虑输入日期,该输入日期本身就是实际的EOM(月末)。

解决输入日期为EOM的一个想法是在输入日期加上1天,从而将我们推入下个月(此时,上一个月的EOM ==输入日期);对于所有其他日期,“上一个”月的EOM将相同(例如,对于20200315和20200316,“上一个” EOM将相同(20200315 + 1天))。

要查找“上一个”月份的EOM,我们将获取给定月份的BOM(月初)并减去1天。 [注意:可以通过将日期的'day'组件设置为'01'来找到BOM。

一个编码思路:

$ cat lasteom

# assumes input is in format: YYYYMMDD
# if no input then default to 'today'

prevdate=${1:-$(date '+%Y%m%d')}

# add one day to push an EOM input date into 'next' month;
# for all dates we then truncate the month to get the BOM (ie, set day component to '01')

workdate=$(date -d "${prevdate} +1 day" +%Y%m01)

i=1

while (( i <= 12 ))
do
        # at this point 'workdate' is YYYYMM01; subtract 1 day to get previous month's EOM

        lasteom=$(date -d "${workdate} -1 day" +%Y%m%d)

        # break if we're working with a EOM < 20190930

        [[ "${lasteom}" < '20190930' ]] && break

        # determine new workdate as BOM (Beginning Of Month) of our new lasteom

        workdate="${lasteom:0:6}"01

        # skip? print? exit loop?

        case ${lasteom} in
                20191031)       continue                       ;;
                20190930)       echo "${lasteom}" ; break      ;;
                *)              echo "${lasteom}" ; (( i++ ))  ;;
        esac
done

$ lasteom 20200315
20200229
20200131
20191231
20191130
20190930                    # skipped 20191030; stop @ 20190930

$ lasteom 20200331
20200331
20200229
20200131
20191231
20191130
20190930                    # skipped 20191030; stop @ 20190930

$ lasteom 20200731
20200731
20200630
20200531
20200430
20200331
20200229
20200131
20191231
20191130
20190930                    # skipped 20191030; stop @ 20190930

$ lasteom 20201130
20201130
20201031
20200930
20200831
20200731
20200630
20200531
20200430
20200331
20200229
20200131
20191231                    # stop @ 12 lines of output

$ lasteom 20200930
20200930
20200831
20200731
20200630
20200531
20200430
20200331
20200229
20200131
20191231
20191130
20190930                    # 12 lines is also 20190930
© www.soinside.com 2019 - 2024. All rights reserved.