227

How can I print the date which is a day before current time in Bash?

5
  • Tried date but seems like there is no -d switch in Solaris 10's bash Commented Nov 10, 2009 at 19:43
  • I found another great solution by installing gnu date (coreutil package) from sunfreeware. Commented Jul 9, 2010 at 6:12
  • nor is there a -d switch in AIX's date Commented Nov 19, 2012 at 15:22
  • The --date or -d option is only available in GNU date Commented Nov 27, 2012 at 14:27
  • See stackoverflow.com/q/15374752/462865 for a DST-safe version of this question. Commented Oct 19, 2016 at 12:35

20 Answers 20

328

if you have GNU date and i understood you correctly

$ date +%Y:%m:%d -d "yesterday" 2009:11:09 

or

$ date +%Y:%m:%d -d "1 day ago" 2009:11:09 
Sign up to request clarification or add additional context in comments.

7 Comments

I found most are as suggested answer but -d switch is not found in Solaris's date
For the usage on Ubuntu with date function: $(date +%Y:%m:%d -d "1 day ago"), output is: 2013:04:21. And if you want the date 10 days before, you can use $(date +%Y:%m:%d -d "10 days ago") or $(date +%Y:%m:%d -d "10 day ago")
On OS X you can install coreutils through brew: see stackoverflow.com/questions/15374752/…
date -v-1d on OSX (minus), -v+1d (plus)
This bash function will work on both Linux and OSX. Basically it tries the GNU Linux style first. If that fails it tries the OSX style. Call it with an argument of the number of days in the past you want the date. If you pass no argument it assume 0 days. This code is a one-liner, so cut and paste should work -- no line endings assumed. date_days_past () { days_past=${1:-0}; if ! date -v-${days_past}d +%Y%m%d 2>/dev/null; then date --date="-${days_past} day" +%Y%m%d; fi }
|
63

If you have BSD (OSX) date you can do it like this:

date -j -v-1d Wed Dec 14 15:34:14 CET 2011 

Or if you want to do date calculations on an arbitrary date:

date -j -v-1d -f "%Y-%m-%d" "2011-09-01" "+%Y-%m-%d" 2011-08-31 

Comments

50
date --date='-1 day' 

2 Comments

Erros on macOS Sierra: date: illegal option -- -
You need to install the GNU version of date, available through the coreutils package, to make this syntax work on macOS. If you're using Homebrew, you can install it via brew install coreutils, after which you should be able to use GNU date through the gdate command. See: topbug.net/blog/2013/04/14/…
31

MAC OSX

For yesterday's date:

date -v-1d +%F 

where 1d defines current day minus 1 day. Similarly,

date -v-1w +%F - for previous week date

date -v-1m +%F - for previous month date

IF YOU HAVE GNU DATE,

date --date="1 day ago" 

More info: https://www.cyberciti.biz/tips/linux-unix-get-yesterdays-tomorrows-date.html

Comments

8

Advanced Bash-scripting Guide

date +%Y:%m:%d -d "yesterday" 

For details about the date format see the man page for date

date --date='-1 day' 

Comments

8

Sorry not mentioning I on Solaris system. As such, the -date switch is not available on Solaris bash.

I find out I can get the previous date with little trick on timezone.

DATE=`TZ=MYT+16 date +%Y-%m-%d_%r` echo $DATE 

3 Comments

This method is not 100% reliable (about 98% actually) if you happen to live in a place using daylight saving time.
Not exactly, you can use bash $(TZ=America/New_York date +%Y-%m-%d)
See stackoverflow.com/a/21283578/2089784 for a DST-safe version
8

Well this is a late answer,but this seems to work!!

 YESTERDAY=`TZ=GMT+24 date +%d-%m-%Y`; echo $YESTERDAY; 

Comments

7
date -d "yesterday" '+%Y-%m-%d' 

or

date=$(date -d "yesterday" '+%Y-%m-%d') echo $date 

1 Comment

That results in date: illegal option: -d on Solaris. Your answer that relies on non-portable GNU extensions to the POSIX-standard date utility for a question about the non-GNU Solaris platform.
4

Use Perl instead perhaps?

perl -e 'print scalar localtime( time - 86400 ) . "\n";' 

Or, use nawk and (ab)use /usr/bin/adb:

nawk 'BEGIN{printf "0t%d=Y\n", srand()-86400}' | adb 

Came across this too ... insane!

/usr/bin/truss /usr/bin/date 2>&1 | nawk -F= '/^time\(\)/ {gsub(/ /,"",$2);printf "0t%d=Y\n", $2-86400}' | adb 

Comments

4

date --date='-1 day' 

Comments

3

Not very sexy but might do the job:

perl -e 'my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time - 86400);$year += 1900; $mon+= 1; printf ("YESTERDAY: %04d%02d%02d \n", $year, $mon, $mday)' 

Formated from "martin clayton" answer.

Comments

3

short answer (GNU format):

date +%Y-%m-%d -d "-2 day" 

if you are using OSX, but you need create for GNU compatible, install coreutils first

brew install coreutils 

then edit your profile with:

#gnu coreutils first export PATH="/usr/local/opt/coreutils/libexec/gnubin:$PATH" 

re-start your terminal, and now you able to use GNU format!

Comments

2

You could do a simple calculation, pimped with an regex, if the chosen date format is 'YYYYMM':

echo $(($(date +"%Y%m") - 1)) | sed -e 's/99$/12/' 

In January of 2020 it will return 201912 ;-) But, it's only a workaround, when date does not have calculation options and other dateinterpreter options (e.g. using perl) not available ;-)

Comments

1
yesterday=`date -d "-1 day" %F` 

Puts yesterday's date in YYYY-MM-DD format into variable $yesterday.

Comments

1
#!/bin/bash OFFSET=1; eval `date "+day=%d; month=%m; year=%Y"` # Subtract offset from day, if it goes below one use 'cal' # to determine the number of days in the previous month. day=`expr $day - $OFFSET` if [ $day -le 0 ] ;then month=`expr $month - 1` if [ $month -eq 0 ] ;then year=`expr $year - 1` month=12 fi set `cal $month $year` xday=${$#} day=`expr $xday + $day` fi echo $year-$month-$day 

4 Comments

+1 for correction, interesting method, even though it's a bit verbose.
Hi medoix, I am not able to find the meaning of ${$#}. I know that $# stands for the number of arguments to a script/function. But I am not able to relate to this. Please help.
This doesn't work for the previus day on change of month . For example today is 1 July , 2013 , the result being printed out is 2013-6-1347, whereas the expected result is 2013-6-30
Instead of the 3 lines between the "fi" try "day=echo $(cal $month $year)|tr ' ' '\n'|tail -n 1"
1

DST aware solution:

Manipulating the Timezone is possible for changing the clock some hours. Due to the daylight saving time, 24 hours ago can be today or the day before yesterday.

You are sure that yesterday is 20 or 30 hours ago. Which one? Well, the most recent one that is not today.

echo -e "$(TZ=GMT+30 date +%Y-%m-%d)\n$(TZ=GMT+20 date +%Y-%m-%d)" | grep -v $(date +%Y-%m-%d) | tail -1 

The -e parameter used in the echo command is needed with bash, but will not work with ksh. In ksh you can use the same command without the -e flag.

When your script will be used in different environments, you can start the script with #!/bin/ksh or #!/bin/bash. You could also replace the \n by a newline:

echo "$(TZ=GMT+30 date +%Y-%m-%d) $(TZ=GMT+20 date +%Y-%m-%d)" | grep -v $(date +%Y-%m-%d) | tail -1 

Comments

0

Try the below code , which takes care of the DST part as well.

if [ $(date +%w) -eq $(date -u +%w) ]; then tz=$(( 10#$gmthour - 10#$localhour )) else tz=$(( 24 - 10#$gmthour + 10#$localhour )) fi echo $tz myTime=`TZ=GMT+$tz date +'%Y%m%d'` 

Courtsey Ansgar Wiechers

Comments

0

For my case I needed a portable solution to get the number of seconds since the epoch one hour ago, and this worked on both ubuntu and macOS:

$(( $(date +%s) - 3600 )) 

Explaining this:

  • $(( )) is doing an arithmetic expansion
  • date +%s seems to be a portable way to get seconds since epoch
  • 3600 seconds in an hour

Hope this helps!

Comments

0

In 2025, bash allows

date -d "TODAY -1 DAY" +%Y%m%d 

Comments

-2
date +%Y:%m:%d|awk -vFS=":" -vOFS=":" '{$3=$3-1;print}' 2009:11:9 

1 Comment

What about if today is the 1st January?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.