Guss
Guss

Reputation: 32364

Calendar calculations in bash

I want to do some calendar manipulations in bash - specifically, I want to figure out the last date of a given month (including leap-year, and a preparing a table for a lookup is not a valid solution for me).

Supposedly I have the following code:

$year=2009
$start_month=2
$end_month=10
for $month in $(seq $start_month $end_month); do
  echo "Last date of "$(date +"%B" -d "${year}-${month}-01")" is: " ???
done

I can't figure out how to do something like this. I though date -d would work like POSIX mktime and fold invalid dates to their valid equivalents, so I could say something like date -d "2009-03-00" and get '2009-02-28', but no such luck.

Is there anyway to do it using only what is available on bash in a standard GNU environment?

Upvotes: 3

Views: 8245

Answers (4)

lhunath
lhunath

Reputation: 125496

date(1)'s -d is GNU specific; so using that will only work on GNU Linux.

A more portable solution (this should even work in sh AFAIK), is this:

: $(cal 4 2009); echo $_

Upvotes: 5

mouviciel
mouviciel

Reputation: 67859

If you don't mind playing with grep/awk/perl, you can take a look at cal.

$ cal 4 2009
     April 2009
Su Mo Tu We Th Fr Sa 
          1  2  3  4
 5  6  7  8  9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30

Edit (MarkusQ): To atone for my joke solution below I'll contribute to yours:

cal 4 2009 | tr ' ' '\n' | grep -v ^$ | tail -n 1

Upvotes: 3

Steve Baker
Steve Baker

Reputation: 4373

Try: date -d 'yesterday 2009-03-01'

Intuitive I know. Earlier versions of date used to work the POSIX way.

Upvotes: 7

MarkusQ
MarkusQ

Reputation: 21950

Well, one way would be to watch the current date in a loop until the month component changes, saving the day component for one round. That would give you both the first and last day of the month, but it might be too slow.

Posted 1 April 2009

Upvotes: 1

Related Questions