# How to know last Sunday of month

i try writing script on ESXI and i need add "if last Sunday of month". I try

``````date -d @\$(( \$(date -d \$(date -d @\$(( \$(date +%s) + 2678400 )) +%Y%m01) +%s) - 604800 )) +%d
``````

It can not work, but it work on Debian.

On ESXI now output August

• I expected that `date -d "\$year-\$month-01 +1 month -1 week Sunday"` would work, given that "The explicit mention of a day of the week will forward the date (only if necessary) to reach that day of the week in the future", but it seems to be ignored when preceded by an absolute date. – Toby Speight Dec 15 '16 at 12:15
• @TobySpeight ah, indeed. I was mislead by the "if last sunday", thanks. – terdon Dec 15 '16 at 12:30
• @TobySpeight determine whether a date is the last Sunday of a month. I weel try your version – Nikita Dec 15 '16 at 12:37

I believe the question is

Given a particular date, can I determine whether it is the last Sunday in the month?

and not the more general question

Given a particular month, on what day is its last Sunday?

Given that, we can divide the problem in two:

• Is the date a Sunday?
• Is it the last week of the month?

For the first part, the test is easy enough:

``````date -d "\$date" +%a  # outputs "Sun" for a Sunday
``````

We can test that:

``````test \$(date -d "\$date" +%a) = Sun  # success if \$date is a Sunday
``````

Now, to test whether it's the last week of the month, we can add one week to the date, and see if that gives us one of the first 7 days of the next month:

``````test \$(date -d "\$date + 1week" +%e) -le 7
``````

Since the weekday of `\$date + 1week` is the same as that of `\$date`, we can generate both parts of the test in one go, and use a Bash regular expression test:

``````if [[ \$(date -d "\$date + 1week" +%d%a) =~ 0[1-7]Sun ]]
then
echo "\$date is the last Sunday of the month!"
fi
``````

Tested:

``````\$ ./330571.sh 2016-12-01
\$ ./330571.sh 2016-12-04
\$ ./330571.sh 2016-12-25
2016-12-25 is the last Sunday of the month!
\$ ./330571.sh 2017-01-28
\$ ./330571.sh 2017-01-29
2017-01-29 is the last Sunday of the month!
``````
• Ok, but ESXI not understand 1week. "\$date + 1week" may replace on date -d @\$(( \$(date +%s) + 604800)) – Nikita Dec 15 '16 at 16:32
• I was assuming the GNU implementation of `date` - if you can't install that, then I guess you're stuck with the one you're given. Seems like you've found a suitable workaround, anyway. – Toby Speight Dec 15 '16 at 16:40

You can do this with `cal` and `awk`:

``````\$ cal | awk '/^ *[0-9]/ { d=\$1 } END { print d }'
25
``````

## Explanation

`cal` prints the current month with Sunday as the first column (by default):

``````\$ cal
December 2016
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 31
``````

The `awk` command matches for lines starting with zero or more spaces, followed by a digit, and stores the first field into variable `d`. At the end, `d` will be the last Sunday of the current month.

• In ESXI not command cal or ncal. – Nikita Dec 15 '16 at 12:28
• @Nikita Noted. Please see my other answer. I have not actually used ESXI, but have presented the basis for a solution using only the date command. – parkamark Dec 15 '16 at 14:20
``````if ( (( \$(date +%d -d "\$now") > `expr \$(date +%d -d "\$(date +%Y -d "\$now")/\$(date +%m -d "\$now")/1 month day ago") - 7` )) && (( \$(date +%w -d "\$now") == 6 )) );
then echo "Today (\$now) is BLACK SABBATH"
fi
``````
New contributor
Laza is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.