#!/bin/bash
NOW=$(date +"%s")
SOON=$(date +"%s" -d "3:00 PM Sun")
INTERVAL=$(($SOON-$NOW))
sleep $INTERVAL
GNU date allows you to specify the format of the output, as well as the date to display. So I use the format string "%s" to get the time in seconds since the epoch, and the same for the arbitrary time using the -d paramater. Get the difference, and you have the interval to sleep.
Checking for a date in the past is left as an exercise for the reader.