Как указано в «информационной дате», вычисление дат с относительным месяцем (1 месяц назад и т. Д.) Проблематично и иногда приводит к неожиданным результатам:
От: 29,7 Относительные элементы в строках даты:
Нечеткость в единицах может вызвать проблемы с относительными элементами. Например, значение «2003-07-31 -1 месяц» может быть равно 2003-07-01, поскольку 2003-06-31 является недопустимой датой
Некоторые решения:
- Рассматривать '1 месяц назад' как запрос на перемещение дней назад, где N - максимум (DD, дни в предыдущем месяце).
- Проверьте, имеет ли дата результата тот же месяц, что и исходная дата, и переместите дату на один день назад от первого дня месяца. Это необходимо для обработки перехода с марта на февраль.
- Альтернативный подход заключается в выполнении перемещения даты в первый день месяца (который всегда будет работать), а затем для ограничения дневной части даты, нопоследняя дата в итоговом месяце.
Преимущество третьего подхода состоит в том, что он используется для обозначения движения месяца.
Реализация варианта №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"