4

I want to find out the past calendar day using bash .

I have tried the following

Today's date : 20130701 Expected Output : 20130630

Code1 :

myTime=`TZ=$TZ+24 date +'%Y%m%d'`
echo $myTime

Output

20130629

Code2 :

timeB=$(date +%Y%m)
sysD=$(date +%d)
sysD=$((sysD-1))
echo $timeB$sysD

Output

2013070

Code3 :

yest=$(date --date="yesterday")
echo "$yest"

Output

date: illegal option -- date=yesterday
usage:  date [-u] mmddHHMM[[cc]yy][.SS]
        date [-u] [+format]
        date -a [-]sss[.fff]

Code4 :

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

Output

20130701

None of them gave the correct output . Can anyone please advise me the correct way to get the desired results.

OS Version : SunOS 5.10

misguided
  • 3,699
  • 21
  • 54
  • 96

4 Answers4

4

You probably have python.

python -c "import datetime; print datetime.date.today () - datetime.timedelta (days=1)"

Though, if date would support the -d flag, then that would be my preferred solution.

Owen
  • 1,726
  • 10
  • 15
  • verified that your answer works. But mate was looking for a solution is bash so accepted a bash solution :) – misguided Jul 01 '13 at 03:15
3

Based on the usage message, I don't think you're on OS X. If you are on OS X, you can use the -v flag, but only relative to the current date/time:

$ date +%Y%m%d
20130630
$ date -v-1d +%Y%m%d
20130629

If you have ksh available, you can use it. I'm not sure of the full syntax available so I don't know if you can specify the base date, but you can do it relative to today:

$ ksh -c 'printf "%(%Y%m%d)T\n" yesterday'
20130629

Solaris (as of version 10) still ships with the ridiculously old ksh88 as its default ksh. You should be able to find ksh93 (which supports the above syntax) in /usr/dt/bin/ksh:

$ /usr/dt/bin/ksh -c 'printf "%(%Y%m%d)T\n" yesterday'
20130629

If you have tclsh available, you can use it:

$ echo 'puts [clock format [clock scan "yesterday"] -format %Y%m%d]' | tclsh
20130629
$ echo 'puts [clock format [clock scan "20130701 - 1 day"] -format %Y%m%d]' | tclsh
20130630

You've already said --date doesn't work, but for completeness: On systems using the GNU version of date, you can use --date or -d:

$ date +%Y%m%d
20130630
$ date +%Y%m%d -d yesterday
20130629
$ date +%Y%m%d -d '-1 days'
20130629
$ date +%Y%m%d -d '20130701 - 1 day'
20130630
rob mayoff
  • 375,296
  • 67
  • 796
  • 848
  • Input: `ksh -c 'printf "%(%Y%m%d)T\n" yesterday'` , Output: `(%m0)T` Input: `echo 'puts [clock format [clock scan "yesterday"] -format %Y%m%d]' | tclsh` , Output: `ksh: tclsh: not found` – misguided Jun 30 '13 at 23:47
  • Try `/usr/dt/bin/dtksh -c 'printf "%(%Y%m%d)T\n" yesterday` . – rob mayoff Jun 30 '13 at 23:50
  • I did the same. It comes up with a screen , waiting for me to enter some stuff. Input `$ dtksh -c 'printf "%(%Y%m%d)T\n" yesterday` , Output: `$ ` – misguided Jul 01 '13 at 00:34
2

The system in question is most likely Solaris. This will work on Solaris:

TZ=GMT+24+<YOUR_LOCAL_TIME_ADJUSTMENT> date +'%Y%m%d'

Edit: To account for DST (example for GMT+11 / GMT+10 with DST):

actualdate=$(date +'%Y%m%d%H%M')
nondstdate=$(TZ=GMT+11 date +'%Y%m%d%H%M')

if [ $actualdate = $nondstdate ] ; then
    TZ=GMT+35 date +'%Y%m%d'
else
    TZ=GMT+34 date +'%Y%m%d'
fi

Edit 2: Bullet proofing for random TZ and DST:

gmthour=$(date -u +%k)
localhour=$(date +%k)
tz=$(( gmthour - localhour ))
echo Your Timezone is $tz
yesterdaytz=$(( 24 + tz ))
echo the offset for yesterday is $yesterdaytz

TZ=GMT+$yesterdaytz date +'%Y%m%d'
zany
  • 881
  • 1
  • 7
  • 16
  • 2
    It will fail some times unless you are in UTC. TZ has to be GMT+24-LOCAL_ADJUSTMENT, ie, for the East Coast of the US with DST, GMT+20. – Gonzalo Jun 30 '13 at 23:26
  • @zany My local time adjustment varies as per the DST , so sometimes it is +10 and sometimes +11 . How do I handle that ? – misguided Jun 30 '13 at 23:51
  • The option `-u` will switch to GMT-universal time bypassing the normal conversion to local time. Then you'd need to compare to get your current TZ. I'll try to extend the answer. – zany Jun 30 '13 at 23:55
  • Ok, the `-u` option won't help. But you can work out your current TZ by comparing the actual output to a fixed TZ. I added tested code to the answer. – zany Jul 01 '13 at 00:09
  • mate still not sure if this si printing out the correct answer `actualdate=$(date +'%Y%m%d%H%M') nondstdate=$(TZ=GMT+11 date +'%Y%m%d%H%M') echo $actualdate echo $nondstdate if [ $actualdate = $nondstdate ] ; then TZ=GMT+35 date +'%Y%m%d' else TZ=GMT+34 date +'%Y%m%d' fi echo $TZ` Output: `201307011039 201306301339 20130629` – misguided Jul 01 '13 at 00:43
  • added bash arithmetic expressions to detect the current TZ and some debugging echos. – zany Jul 01 '13 at 01:06
  • 1
    @zany mate this one works perfectly well for change in month . – misguided Jul 01 '13 at 03:14
  • @zany sorry mate , didn't consider the scenario . It still gives an error . Code `#!/bin/bash gmthour=$(date -u +%H) localhour=$(date +%H) echo $gmthour echo $localhour tz=$(( gmthour - localhour )) echo $tz` Error `22 08 MyFile.ksh: line 6: 08: value too great for base (error token is "08")` – misguided Jul 01 '13 at 22:27
  • Can you confirm that setting a TZ greater than GMT+23 is the source of the error? I guess Bash and Date won't be much use then. – zany Jul 01 '13 at 22:33
  • `tz=$(( 10#$gmthour - 10#$localhour )) echo $tz yesterdaytz=$(( 24 + tz )) echo the offset for yesterday is $yesterdaytz myTime=`TZ=GMT+$yesterdaytz date +'%Y%m%d'` output `22 08 14 the offset for yesterday is 38 myTime 20130630` expected is `20130701`, it is currently `20130702` here. – misguided Jul 01 '13 at 22:36
  • @zany this logic basically doesn't work when GMT hour is between 15-24 (DSP diff 10 hours) and 14-24(GMT diff 11 hours) – misguided Jul 01 '13 at 22:54
  • Oh sorry, I get it now. That should've been %k (hour, space padding) not %H (hour zero padding) in the test. Btw. is %z (timezone) available? – zany Jul 02 '13 at 09:02
0

GNU date

$ date "+%Y%m%d" -d 'now -1 day'
20130629
Zombo
  • 1
  • 62
  • 391
  • 407
  • His system isn't Linux. GNU date is not available here. (And it's most likely not OS X or FreeBSD.) – zany Jun 30 '13 at 23:20