Erin Santos
Erin Santos

Reputation: 179

Subtracting Dates in Unix

is there a way to subtract a month from a date or at least 30 days in unix.

example:

[yyy-mm-dd] - 30 days

2011-07-23 - 30 days

By the way, the date can be any date depending on the user input.

Thanks.

Upvotes: 4

Views: 25607

Answers (4)

smRaj
smRaj

Reputation: 1306

#Current Date
 date +'%Y:%m:%d'
 2013:10:04

#Date a month ago
 date --date='-1 month' +'%Y:%m:%d. Last month was %B.'
 2013:09:04. Last month was September.
#%B prints out locale's full month name. 

Type "info coreutils date invocation" in terminal and learn more. Section: 28.7 Relative items in date strings. File: coreutils.info

EDIT: Looks OP wants to have the user input of date.

#Nov 1 2012 can be  modified to suit user's input. 
 date --date="$(date -d "Nov 1 2012")-1 month" +'%Y:%m:%d'
 2012:10:01

Upvotes: 0

glenn jackman
glenn jackman

Reputation: 246744

For an arbitrary date,

$ date -d "2011-07-23 - 1 month" "+%F"
2011-06-23
$ date -d "2011-07-23 - 30 days" "+%F"
2011-06-23
$ date -d "2011-08-23 - 1 month" "+%F"
2011-07-23
$ date -d "2011-08-23 - 30 days" "+%F"
2011-07-24

This is GNU date


Without GNU date, you can fall back to perl. The Time::Piece and Time::Seconds module should be available in perl 5.12

perl -MTime::Piece -MTime::Seconds -e '
    print "date\t-1 month\t-30 days\n";
    while (@ARGV) {
        my $t = Time::Piece->strptime(shift, "%Y-%m-%d");
        print $t->ymd, "\t";
        print $t->add_months(-1)->ymd, "\t";
        $t -= 30*ONE_DAY; 
        print $t->ymd, "\n";
    }
' 2011-07-23 2011-08-23
date    -1 month    -30 days
2011-07-23  2011-06-23  2011-06-23
2011-08-23  2011-07-23  2011-07-24

Upvotes: 6

jlliagre
jlliagre

Reputation: 30813

There is no both straightforward and portable way, all other replies so far are using Gnu specific extensions.

This should work on any Unix:

date "+%Y %-m %-d" |
(
  read y m d
  m=$(($m - 1))
  [ $m = 0 ] && { m=12; y=$(($y - 1)); }
  [ $d = 31 -a \( $m = 4 -o $m = 6 -o $m = 9 -o $m = 11 \) ] && d=30
  [ $d -gt 28 -a $m = 2 ] && d=28
  printf "%04d:%02d:%02d\n" $y $m $d
)

Upvotes: 4

Vaibs_Cool
Vaibs_Cool

Reputation: 6156

Try this

date -d "30 days ago" "+%Y%m%d00"

Upvotes: 3

Related Questions