Red Hat Bugzilla – Bug 578683
date --date="last month" is off by one
Last modified: 2015-01-04 17:31:19 EST
Thu Apr 1 00:01:43 EDT 2010
(00:01:43:davej@gelk:Mail)$ date --date="last month"
Sun Feb 28 23:01:52 EST 2010
Confused by the TZ change ?
Thanks for report. No, it's not confused, it works as expected, date just substracts one month from the date and then translates it into the new timestamp in format you want. Because of the daylightsaving change this month you have this one hour difference - but that's expected. See FAQ (http://www.gnu.org/software/coreutils/faq/coreutils-faq.html#The-date-command-is-not-working-right_002e) for more details, closing NOTABUG.
That's the dumbest thing I've ever heard.
The result may seem non-intuitive, but it's the way the math works out:
Start with "Thu Apr 1 00:01:43 EDT 2010" and convert to UTC:
$ TZ=UTC date --date="Thu Apr 1 00:01:43 EDT 2010"
Thu Apr 1 04:01:43 UTC 2010
Subtract one month (still in UTC):
$ TZ=UTC date --date="Thu Apr 1 04:01:43 UTC 2010 - 1 month"
Mon Mar 1 04:01:43 UTC 2010
Then convert UTC to EST instead of EDT (since the DST switch happens in March):
$ TZ=EST date --date="Mon Mar 1 04:01:43 UTC 2010"
Sun Feb 28 23:01:43 EST 2010
Also, think of it this way - if the United States didn't observe daylight savings, "Thu Apr 1 00:01:43 EDT 2010" is actually "Wed Mar 31 23:01:43 EST 2010".
It's the way the math works because it applies DST correction at a different place than a rational human would. You can call that a feature if you like, but it's still intensely dumb.
Yep, I see your point, there are many such "dumb troubles" (like invalid date in the case of 2:XX time in the day of DST correction change). It may look dumb, but the grammar of date is very complex(and obviously not perfect for everyone). But it is predictable (and it is possible to write scripts which will cover even those DST issues).
If you have any idea how to improve the grammar without regressions, feel free to propose it... but it is not so easy as it looks at first sight...
another example of spectacular failure.
$ export thismonth=$(date "+%Y-3-30")
$ date -d "$thismonth 1 month ago"
Tue Mar 2 00:00:00 EST 2010
the "1 month ago" feature seems so broken, it seems too dangerous to use.
It's not failure - it's just what you requested ... not from human, but from computer. Let's be computer for a while:
30th March - 1 Month => 30th February ... ah-there is no such ... so we are back in March and the answer is 2nd March.
Maybe some "human logic" option would be nice compromise, but I'm not sure if it will be acceptable by upstream (and easy to implement). Just to be sure - what's the answer of the comment #6 for you? February 27th? Ok - maybe, as it is one day before last day of previous month... and what about the same with March 2nd from human perspective? Will it be February 2nd? Yep, it seems so... but how to map 31 days of March on 28(usually) days of February? I still think that current "computer logic" is more predictable than "human one".