-2

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

我们实质上是在创建将在 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

完毕

4

1 回答 1

1

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

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

要找到“上一个”月份的 EOM,我们将采用给定月份的 BOM(月初)并减去 1 天。[注意:可以通过将日期的“天”组件设置为“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
于 2019-09-30T22:42:17.667 回答