Вернуть даты окончания месяца меньше указанной даты и остановиться на 12 датах в оболочке - PullRequest
0 голосов
/ 30 сентября 2019

Есть странный алгоритм, в котором мне нужно возвращать даты, которые являются датами окончания месяца, меньшими или равными данной дате окончания месяца.

По сути, мы создаем динамический диапазон дат, который будет использоватьсяв файле SQL. Поэтому я хочу сказать, что, учитывая эту дату 20200315, верните мне все даты окончания месяца меньше, чем указанная дата, но ОСТАНОВИТЕСЬ в сентябре 2019 года. Кроме того, игнорируйте октябрь 2019 года.

Итак, учитывая 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

сделано

1 Ответ

1 голос
/ 01 октября 2019

Код, приведенный в вопросе, по-видимому, не учитывает дату ввода, которая сама по себе является фактическим EOM (Конец месяца).

Одна идея для обращения к дате ввода, которая является EOM, будетдобавить 1 день к дате ввода, подталкивая нас к «следующему» месяцу (в этот момент EOM «предыдущего» месяца == наша дата ввода);для всех других дат МНВ «предыдущего» месяца будет таким же (например, «МНВ предыдущего» будет одинаковым для 20200315 и 20200316 (20200315 + 1 день)).

Чтобы найти «предыдущий» месяцМНВ мы возьмем спецификацию за месяц (начало месяца) и вычтем 1 день. [ПРИМЕЧАНИЕ: спецификацию можно найти, установив для компонента 'day' даты значение '01']

Одна идея кодирования:

$ 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
...