[unix] In a unix shell, how to get yesterday's date into a variable?

I've got a shell script which does the following to store the current day's date in a variable 'dt':

date "+%a %d/%m/%Y" | read dt
echo ${dt}

How would i go about getting yesterdays date into a variable?

Basically what i'm trying to achieve is to use grep to pull all of yesterday's lines from a log file, since each line in the log contains the date in "Mon 01/02/2010" format.

Thanks a lot

This question is related to unix datetime shell ksh hp-ux

The answer is


If your HP-UX installation has Tcl installed, you might find it's date arithmetic very readable (unfortunately the Tcl shell does not have a nice "-e" option like perl):

dt=$(echo 'puts [clock format [clock scan yesterday] -format "%a %d/%m/%Y"]' | tclsh)
echo "yesterday was $dt"

This will handle all the daylight savings bother.


$var=$TZ;
TZ=$TZ+24;
date;
TZ=$var;

Will get you yesterday in AIX and set back the TZ variable back to original


ksh93:

dt=${ printf "%(%a %d/%m/%Y)T" yesterday; }

or:

dt=$(printf "%(%a %d/%m/%Y)T" yesterday)

The first one runs in the same process, the second one in a subshell.


I have shell script in Linux and following code worked for me:

#!/bin/bash
yesterday=`TZ=EST+24 date +%Y%m%d` # Yesterday is a variable
mkdir $yesterday # creates a directory with  YYYYMMDD format

For Hp-UX only below command worked for me:

TZ=aaa24 date +%Y%m%d

you can use it as :

ydate=`TZ=aaa24 date +%Y%m%d`

echo $ydate


Here is a ksh script to calculate the previous date of the first argument, tested on Solaris 10.

#!/bin/ksh
 sep=""
 today=$(date '+%Y%m%d')
 today=${1:-today}
 ty=`echo $today|cut -b1-4` # today year
 tm=`echo $today|cut -b5-6` # today month
 td=`echo $today|cut -b7-8` # today day
 yy=0 # yesterday year
 ym=0 # yesterday month
 yd=0 # yesterday day

 if [ td -gt 1 ];
 then
         # today is not first of month
         let yy=ty       # same year
         let ym=tm       # same month
         let yd=td-1     # previous day
 else
         # today is first of month
         if [ tm -gt 1 ];
         then
                 # today is not first of year
                 let yy=ty       # same year
                 let ym=tm-1     # previous month
                 if [ ym -eq 1 -o ym -eq 3 -o ym -eq 5 -o ym -eq 7 -o ym -eq 8 -o ym -     eq 10 -o ym -eq 12 ];
                 then
                         let yd=31
                 fi
                 if [ ym -eq 4 -o ym -eq 6 -o ym -eq 9 -o ym -eq 11 ];
                 then
                         let yd=30
                 fi
                 if [ ym -eq 2 ];
                 then
                         # shit... :)
                         if [ ty%4 -eq 0 ];
                         then
                                 if [ ty%100 -eq 0 ];
                                 then
                                         if [ ty%400 -eq 0 ];
                                         then
                                         #echo divisible by 4, by 100, by 400
                                                 leap=1 
                                         else
                                         #echo divisible by 4, by 100, not by 400
                                                 leap=0
                                         fi
                                 else
                                         #echo divisible by 4, not by 100
                                         leap=1 
                                 fi
                         else
                                 #echo not divisible by 4
                                 leap=0 # not divisible by four
                         fi
                         let yd=28+leap
                 fi
         else
                 # today is first of year
                 # yesterday was 31-12-yy
                 let yy=ty-1     # previous year
                 let ym=12
                 let yd=31
         fi
 fi
 printf "%4d${sep}%02d${sep}%02d\n" $yy $ym $yd

Tests

bin$ for date in 20110902 20110901 20110812 20110801 20110301 20100301 20080301 21000301 20000301 20000101 ; do yesterday $date; done
20110901
20110831
20110811
20110731
20110228
20100228
20080229
21000228
20000229
19991231

You have atleast 2 options

  1. Use perl:

    perl -e '@T=localtime(time-86400);printf("%02d/%02d/%02d",$T[4]+1,$T[3],$T[5]+1900)'
    
  2. Install GNU date (it's in the sh_utils package if I remember correctly)

    date --date yesterday "+%a %d/%m/%Y" | read dt
    echo ${dt}
    
  3. Not sure if this works, but you might be able to use a negative timezone. If you use a timezone that's 24 hours before your current timezone than you can simply use date.


Try the following method:

dt=`case "$OSTYPE" in darwin*) date -v-1d "+%s"; ;; *) date -d "1 days ago" "+%s"; esac`
echo $dt

It works on both Linux and OSX.


Though all good answers, unfortunately none of them worked for me. So I had to write something old school. ( I was on a bare minimal Linux OS )

$ date -d @$( echo $(( $(date +%s)-$((60*60*24)) )) )

You can combine this with date's usual formatting. Eg.

$ date -d @$( echo $(( $(date +%s)-$((60*60*24)) )) ) +%Y-%m-%d

Explanation : Take date input in terms of epoc seconds ( the -d option ), from which you would have subtracted one day equivalent seconds. This will give the date precisely one day back.


If you have access to python, this is a helper that will get the yyyy-mm-dd date value for any arbitrary n days ago:

function get_n_days_ago {
  local days=$1
  python -c "import datetime; print (datetime.date.today() - datetime.timedelta(${days})).isoformat()"
}

# today is 2014-08-24

$ get_n_days_ago 1
2014-08-23

$ get_n_days_ago 2
2014-08-22

If you are on a Mac or BSD or something else without the --date option, you can use:

date -r `expr \`date +%s\` - 86400` '+%a %d/%m/%Y'

Update: or perhaps...

date -r $((`date +%s` - 86400)) '+%a %d/%m/%Y'

Thanks for the help everyone, but since i'm on HP-UX (after all: the more you pay, the less features you get...) i've had to resort to perl:

perl -e '@T=localtime(time-86400);printf("%02d/%02d/%04d",$T[3],$T[4]+1,$T[5]+1900)' | read dt

If you don't have a version of date that supports --yesterday and you don't want to use perl, you can use this handy ksh script of mine. By default, it returns yesterday's date, but you can feed it a number and it tells you the date that many days in the past. It starts to slow down a bit if you're looking far in the past. 100,000 days ago it was 1/30/1738, though my system took 28 seconds to figure that out.

    #! /bin/ksh -p

    t=`date +%j`
    ago=$1
    ago=${ago:=1} # in days
    y=`date +%Y`

    function build_year {
            set -A j X $( for m in 01 02 03 04 05 06 07 08 09 10 11 12
                    {
                            cal $m $y | sed -e '1,2d' -e 's/^/ /' -e "s/ \([0-9]\)/ $m\/\1/g"
                    } )
            yeardays=$(( ${#j[*]} - 1 ))
    }

    build_year

    until [ $ago -lt $t ]
    do
            (( y=y-1 ))
            build_year
            (( ago = ago - t ))
            t=$yeardays
    done

    print ${j[$(( t - ago ))]}/$y

dt=$(date --date yesterday "+%a %d/%m/%Y")
echo $dt

You can use GNU date command as shown below

Getting Date In the Past

To get yesterday and earlier day in the past use string day ago:

date --date='yesterday'

date --date='1 day ago'

date --date='10 day ago'

date --date='10 week ago'

date --date='10 month ago'

date --date='10 year ago'

Getting Date In the Future

To get tomorrow and day after tomorrow (tomorrow+N) use day word to get date in the future as follows:

date --date='tomorrow'

date --date='1 day'

date --date='10 day'

date --date='10 week'

date --date='10 month'

date --date='10 year'


On Linux, you can use

date -d "-1 days" +"%a %d/%m/%Y"

Examples related to unix

Docker CE on RHEL - Requires: container-selinux >= 2.9 What does `set -x` do? How to find files modified in last x minutes (find -mmin does not work as expected) sudo: npm: command not found How to sort a file in-place How to read a .properties file which contains keys that have a period character using Shell script gpg decryption fails with no secret key error Loop through a comma-separated shell variable Best way to find os name and version in Unix/Linux platform Resource u'tokenizers/punkt/english.pickle' not found

Examples related to datetime

Comparing two joda DateTime instances How to format DateTime in Flutter , How to get current time in flutter? How do I convert 2018-04-10T04:00:00.000Z string to DateTime? How to get current local date and time in Kotlin Converting unix time into date-time via excel Convert python datetime to timestamp in milliseconds SQL Server date format yyyymmdd Laravel Carbon subtract days from current date Check if date is a valid one Why is ZoneOffset.UTC != ZoneId.of("UTC")?

Examples related to shell

Comparing a variable with a string python not working when redirecting from bash script Get first line of a shell command's output How to run shell script file using nodejs? Run bash command on jenkins pipeline Way to create multiline comments in Bash? How to do multiline shell script in Ansible How to check if a file exists in a shell script How to check if an environment variable exists and get its value? Curl to return http status code along with the response docker entrypoint running bash script gets "permission denied"

Examples related to ksh

How can I find a file/directory that could be anywhere on linux command line? Shell Script: How to write a string to file and to stdout on console? Send password when using scp to copy files from one server to another Reading file line by line (with space) in Unix Shell scripting - Issue How to get the second column from command output? Get exit code for command in bash/ksh Check if file exists and whether it contains a specific string In a unix shell, how to get yesterday's date into a variable? How to set the From email address for mailx command? How to mkdir only if a directory does not already exist?

Examples related to hp-ux

In a unix shell, how to get yesterday's date into a variable? How to get the command line args passed to a running process on unix/linux systems? What processes are using which ports on unix?