Bug 578683

Summary: date --date="last month" is off by one
Product: [Fedora] Fedora Reporter: Dave Jones <davej>
Component: coreutilsAssignee: Ondrej Vasik <ovasik>
Status: CLOSED NOTABUG QA Contact: Fedora Extras Quality Assurance <extras-qa>
Severity: medium Docs Contact:
Priority: low    
Version: 13CC: jeff, kdudka, ovasik, pfrields, sdodson, twaugh
Target Milestone: ---   
Target Release: ---   
Hardware: All   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2010-04-01 04:11:51 EDT Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:

Description Dave Jones 2010-04-01 00:05:02 EDT
(00:01:40:davej@gelk:Mail)$ date
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 ?
Comment 1 Ondrej Vasik 2010-04-01 04:11:51 EDT
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.
Comment 2 Adam Jackson 2010-04-06 13:04:07 EDT
That's the dumbest thing I've ever heard.
Comment 3 Jeffrey C. Ollie 2010-04-06 13:41:17 EDT
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".
Comment 4 Adam Jackson 2010-04-06 14:29:30 EDT
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.
Comment 5 Ondrej Vasik 2010-04-06 14:43:51 EDT
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...
Comment 6 Dave Jones 2010-04-06 15:40:18 EDT
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.
Comment 7 Ondrej Vasik 2010-04-07 02:05:31 EDT
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".