Search code examples
bashdatemingw-w64

Why is the date command throwing an error despite successfully computing an answer?


For context I am working on a Windows machine with MINGW64. I have not had the chance to test this on a machine running Linux.

I am working with [date][1] in bash and trying to add days to a date represented as seconds since 1970-01-01 00:00:00, i.e. in format %s. I have the following Bash code:

DATE1=$(date --date=now "+%s")
echo "DATE1: ${DATE1}"
DATE2=$(date --date="$(date --date="${DATE1}" "+%s")+2 days" "+%d%b%Y %H:%M:%S")
echo "DATE2: ${DATE2}"

Which gives console output

DATE1: 156133763
date: invalid date '1561337963'
DATE2: 26Jun2019 10:59:24

In fact, DATE2 has the expected value down to the second. However the console still throws an error. Why might this error be occurring? Would it have something to do with running MINGW64?

An update:

I ran this on a Debian server I have access to. It computed the time with now like on MINGW, but returned a different error: ./test.sh: line 3: --date=1561342165: command not found. Running this on the same server with a custom date:

DATE1=$(date --date="$(date --date="19Jun2019 11:35:46" "+%d%b%Y %H:%M:%S")" "+%s")

Likewise returns

DATE1: 1560908146
date: invalid date ‘1560908146’
DATE2: 26Jun2019 12:20:08

Which actually indicates it isn't adding to the defined date at all, rather it is just adding to today's date (it's the 24th of June where I am now). Clearly, something is quite wrong!


Solution

  • If you want to convert timestamp to a date then you have to use @:

    date --date=@1561344591 '+%F %T'
    2019-06-24 04:49:51
    

    The reason why you got seemingly correct result even with the error message is because your DATE1 is now, so your inner date call produces an error and returns nothing and then the outer call is just --date=+2 days, which produces 2 days from now.

    I don't think you can use date-time in timestamp format together with relative statements, it doesn't work even with @. You have to convert your timestamp to human readable date first but even then you have to be careful. You could think that this is enough:

    date --date="$(date --date=@1561344591 "+%F %T") + 2 days" "+%F %T"
    2019-06-25 04:49:51
    

    As you can see it is still wrong and that's because +2 is parsed as a timezone. You fix it by explicitly including timezone in you conversion from timestamp:

    date --date="$(date --date=@1561344591 "+%F %T%Z") + 2 days" "+%F %T"
    2019-06-26 04:49:51
    

    In general, using bash debugging set -x and date debugging date --debug ... helps with solving such problems.