bash

Date calculations in bash and trying to assign the output in env vars


I'm trying to do some date/time calculations in bash that don't work as expected at the console and when I add them to environment variables, I get very odd results.

As an example:

$ date
Thu Jul 24 15:37:19 UTC 2025
$ date +%s
1753371482
$ date -d 'next hour' +"%Y-%m-%d %H:10:00"
2025-07-24 16:10:00
$ date -d 'next hour' +"%Y-%m-%d %H:10:00" | date +%s
1753371508

You can see the actual time difference is ~33 minutes but when converting to seconds, it's only a 26s difference.

And I'm trying to convert to seconds so I can perform a difference calculation for a sleep timer to run a script on the 10th minute of every hour but then when I add them to environment variables, I get even stranger output:

EPOCH_START=$(date +%s)
NEXT_RUN=`date -d 'next hour' +"%Y-%m-%d %H:10:00" | date +%s`
EXEC_TIME=$(( $EPOCH_START - $NEXT_RUN ))

echo $EPOCH_START
echo $NEXT_RUN
echo $EXEC_TIME

echo "Next run time in ${EXEC_TIME} seconds..."

sleep ${EXEC_TIME}

In the above, $EPOCH_START and $NEXT_RUN have the same value.


Solution

  • Date does not read from stdin unless -f - is passed. A cleaner way is to store next date on a variable

    EPOCH_START=$(date '+%s')
    NEXT_RUN_D=$(date -d 'next hour' +"%Y-%m-%d %H:10:00")
    NEXT_RUN=$(date -d "$NEXT_RUN_D" '+%s')
    EXEC_TIME=$(( $NEXT_RUN - $EPOCH_START ))
    
    echo "$EPOCH_START"
    echo "$NEXT_RUN"
    echo "$EXEC_TIME"
    
    echo "Next run time in ${EXEC_TIME} seconds..."
    
    #sleep ${EXEC_TIME}
    
    1753373599
    1753377000
    3401
    Next run time in 3401 seconds...
    

    Notes: backtick are deprecated in favor of $(). Always pass scripts through shellcheck to check for errors/best practices.