Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top
$ date -d "Apr 1 2016 - 1 month" +%B

gives me "March", which is great - the month that comes before April is March. If I do this however:

$ date -d "$(date -d "Apr 1 2016") - 1 month" +%B

it gives me "February". This is causing a bug in some more complex code I have. Why are these 2 commands showing different results?

share|improve this question
    
Both gave me March – cuonglm Feb 20 at 15:04
1  
As explained by Thomas, this is dependent upon your timezone. My DST changes on March 13th - yours probably does not, so you may not see this behavior on the same dates, or possibly at all if you have no DST changes. – Tal Feb 20 at 16:08
up vote 10 down vote accepted

You can see the problem by turning on the shell trace:

+ date -d 'Apr 1 2016 - 1 month' +%B
March
++ date -d 'Apr 1 2016'
+ date -d 'Fri Apr  1 00:00:00 EDT 2016 - 1 month' +%B
February

When you use the output of the inner date command, it is at the very beginning of April, and when subtracting a month runs into the discontinuity due to EST/EDT changing:

+ date -d 'Fri Apr  1 00:00:00 EDT 2016 - 1 month'
Mon Feb 29 23:00:00 EST 2016

Your results, of course, will vary according to your local timezone settings. Turning on the trace will show the timezone (in my case, EDT).

The reason why the results differ is that in the latter case you have given more information to date, made its parameter more specific, i.e., the specific time of day. In the first part, that was not specified, giving date more leeway about how to determine the date/time to display.

share|improve this answer
    
I now realize that this has to do with the daylight savings time (mine are here: timeanddate.com/time/zone/canada/edmonton), but I'm still not following why the date command appears to be interpreting the same date differently in a subshell than in the main shell. If I run a script with: date -d "Apr 1 2016"; date -d "$(date -d "Apr 1 2016")", I get exactly the same result, including the same timezone tag - why is removing a month from both giving different results? – Tal Feb 20 at 15:23
    
Oh - your last edit makes it clear. Thanks – Tal Feb 20 at 15:27

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.