Lars Nooden wrote: > On March 29, 2021, if a relative date of '-1 month' is passed to 'date', > then the output shows March instead of February.
The date manual includes this section on relative months. The fuzz in units can cause problems with relative items. For example, ‘2003-07-31 -1 month’ might evaluate to 2003-07-01, because 2003-06-31 is an invalid date. To determine the previous month more reliably, you can ask for the month before the 15th of the current month. For example: $ date -R Thu, 31 Jul 2003 13:02:39 -0700 $ date --date='-1 month' +'Last month was %B?' Last month was July? $ date --date="$(date +%Y-%m-15) -1 month" +'Last month was %B!' Last month was June! This exactly covers the initial bug report. Because March 29, 2021 minus 1 month results in the invalid date February 29, 2021 which not being a leap year does not exist. What _should_ be the result if the date one month ago does not exist? And the answer to that will mostly depend upon what purpose the question was being asked. When dealing with time in months it also depends upon what you are needing done. If it is the 7th of the month and you want to generate a date that is also the 7th but one month later or earlier then if it is March 7th and generate February 7th then that will be fewer days difference than if it is were June 7th and deciding May 7th is the month early. Due to the nature of having a different number of days in different months. But if that was what I wanted then I would determine what was the month prior and generate a new datestamp using the current day of the month. [[Aside: Off the top of my head and hopefully without a trivial bug. I welcome corrections if I made a mistake in this. But this is still not completely general purpose. $ date "+%F %T" 2021-04-04 20:50:19 $ date "+%Y-$(date --date="$(date +%Y-%m-15) -1 month" +%m)-%d %H:%M:%S" 2021-03-04 20:50:54 *HOWEVER* that still does not handle the case of the original poster's report about what happens on March 29, 2021 minus one month? It can't be February 29th! Isn't that the same as March 1st? ]] Perhaps instead of the code using 30 day months it should use the number of days in the current month? Then on March 31, 2021 -1 month since March has 31 days that would calculate February 28, 2021. Is that better or worse? $ date --date="2021-03-31 12:00 +0000 -31 days" "+%F %T" 2021-02-28 05:00:00 Potentially worse! What happens on March 1, 2021 then? $ date --date="2021-03-01 12:00 +0000 -31 days" "+%F %T" 2021-01-29 05:00:00 In that case we skip over February entirely! Chris Elvidge wrote: > Pádraig Brady wrote: > > The current FAQ (linked below) suggests the workaround of: > > > > date --date="$(date +%Y-%m-15) -1 month" +'Last month was %B.' > > > > https://www.gnu.org/software/coreutils/faq/coreutils-faq.html#The-date-command-is-not-working-right_002e > > It's noticeable that (on my system, CYGWIN-NT and/or Raspbian) 'date -d"now > -1month"' gives a definitely wrong answer, but 'dateadd now -1mo' gives a > somewhat more reasonable answer. dateadd is from the dateutils package, > sometimes dadd and/or dateutils.dadd. > > $ date +"%Y-%m-%d %H:%M:%S" > 2021-03-30 10:37:00 > > $ date -d"now -1 month" +"%Y-%m-%d %H:%M:%S" > 2021-03-02 09:37:17 So... Here is the problem with "now". Using "now" is problematic *some* of the time. Not all of the time. Never when you are trying it on the command line in the middle of the day. But there are windows of time around DST time changes when it is problematic. If you are getting the time now and it is the middle of the day say around noon then that is far away from time changes. But almost every seasonal time change there is a bug report from someone who has an automated process that ran right at the same time as time change giving them a surprising result and they are filing a bug that it gave them the wrong answer, because there was no 2am that day, or maybe there were two 2ams that day, or something. That's why it is better to test for days using noon as a reference. And why when checking for months it is better to test for months away from the change of month. Really the 10th or the 20th would be as good as the 15th but the 15th is in the middle of every month and why it ended up getting into the FAQ recommendation. > $ dateadd now -1mo -f"%Y-%m-%d %H:%M:%S" > 2021-02-28 09:37:27 I don't know anything about dateadd and it is not part of GNU Coreutils. Bob