6

I am using date (GNU coreutils) 8.22 and having some trouble to calculate a date after a given one.

Say I want to use 1st of February, for example:

$ date -d'1 February'
Sun Feb  1 00:00:00 CET 2015

Then I want to add a week to the date. So far, so good:

$ date -d '1 February + 1 week'
Thu Feb  8 00:00:00 LMT 0001

But if I add something as the first item not being 1, it fails and returns something incorrect:

$ date -d '1 February + 2 weeks'  # returns as if it was +1 week
Fri Feb  8 00:00:00 LMT 0002      # but Fri instead of Thu, also LMT 0002

However, if we add more parameters in the front, it works:

$ date -d '1 February + 0 minutes + 2 week' # works since we added 0/1 unit before
Tue Feb 15 00:01:00 LMT 0000
$ date -d '1 February + 1 minute + 1 day + 1 week' # works fine
Fri Feb  9 00:01:00 LMT 0001
$ date -d '1 February + 1 minute + 25 day + 7 week'  # works since 1st parameter is 1!
Mon Apr 16 00:01:00 LMT 0001

Note this not happen if we provide relative dates:

$ date -d 'today + 1 week'
Wed Jul  1 12:20:03 CEST 2015
$ date -d 'today + 2 week'    # works fine
Wed Jul  8 12:20:12 CEST 2015

So, why is date considering the first parameter always as 1 and some weird action if the date is given with a specific date?

  • It doesn't return the same value as one, if you look closely it has changed thu to fri, and LMT to 0002 – 123 Jun 24 '15 at 10:28
  • Uhms, true. Will edit to reflect the main point: it does not work as intended. – fedorqui Jun 24 '15 at 10:33
  • 1
    It would appear that it is changing the year, try date -d '1 February + 1 weeks' +"%m-%d-%y" vs date -d '1 February + 2 weeks' +"%m-%d-%y" – 123 Jun 24 '15 at 10:34
  • 1
    Guessing it is getting confused somehow, as if you specify the year with the date then it works as intended date -d '1 February 0001 + 2 weeks'. Also if you just put 1 February + 2 it increments the year by 1. And if you put '1 February + 2 + 2 weeks' it works correctly. So i guess it sees, 1 February + 2(years) (1)weeks. Because even in your working example it has still incremented the year by one. – 123 Jun 24 '15 at 10:40
  • I'm not sure why it even works with 1 February... try it with the right date format e.g. Feb 1 or February 1: date -d 'Feb 1 +2 week' or date -d 'February 5 +3 week'... – don_crissti Jun 24 '15 at 10:53
4

Okay so i did some research and it is interpretting the first number as the year, it would appear that the + and entirely superficial and completely ignored.

Using your examples.

$ date -d'1 February'
Sun Feb  1 00:00:00 CET 2015

Works entirely as expected as no year is supplied.

$ date -d '1 February + 1 week'
Thu Feb  8 00:00:00 LMT 0001

Almost looks right but you will notice that the year has changed to 0001 as the + is ignored and so the the command is seen as

 {1 February 1} {+ 1}{week}
      date      

The {+1} appears to be default for any period of time after the date.


Another one of your example that appears to work but doesn't

$ date -d '1 February + 1 minute + 25 day + 7 week'  # works since 1st parameter is 1!
Mon Apr 16 00:01:00 LMT 0001

As you can see the year has been incremented to 0001. The minutes have been referenced so increment by the default 1, and then all further commands are not part of the date so are incremented accordingly.


As further proof of it working this way take this example that does work

$date -d '1 February 4 5 weeks'
Sun Mar  7 00:00:00 LMT 0004

and works the same as

$date -d '1 February + 4 + 5 weeks'
Sun Mar  7 00:00:00 LMT 0004

Meaning the +'s are ignored and the first number after them is seen as the year if the year is not previously specified.

Obviously if you want to subtract that must be explictly stated, although is still ignored if the year has not been specified for the first number.

$date -d '1 February -4 weeks'
Sun Feb  8 00:00:00 LMT 0004
                         ^
                         Year incremented by 4.

Although if you use it in a format specified in the man page i.e

$date -d ' Feb 2 -4 weeks'
Mon Jan  5 00:00:00 GMT 2015

Then it will work entirely as intended without any year required :)

  • 1
    To your edit, so it was also my fault because I was providing the date in a non-standard way. Thanks again! – fedorqui Jun 24 '15 at 13:10
  • 1
    @fedorqui Thats what happens when they make date so flexible with input :) – 123 Jun 24 '15 at 13:30
2

It appears to be interpreting the 2nd digit as the year and then assuming 1 week(s), so always add a year, as this year then I think you will get what you desire. eg.

christian@fujiu1404:~$ date -u -d'1 feb this year -2 weeks'
Sun Jan 18 00:00:00 UTC 2015
christian@fujiu1404:~$ date -u -d'1 feb this year +2 weeks'
Sun Feb 15 00:00:00 UTC 2015
christian@fujiu1404:~$ date -u -d'1 feb this year +3 weeks'
Sun Feb 22 00:00:00 UTC 2015
  • 1
    The number after LMT/UTC/GMT is the year... – 123 Jun 24 '15 at 11:02
  • Yes Year not minute offset, I'll update. – X Tian Jun 24 '15 at 11:04
  • Very nice research also, thanks a lot for it! – fedorqui Jun 24 '15 at 11:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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