As for the problems with the lack of congratulations in the presence of birthday people, or multiple sending, I think the author needs to adjust the logic of work with time. The main idea seems to me to be quite correct, and it looks like if I correctly understand the following: the task runs every 15 minutes (ideally if run with cron is configured), if its start occurs not in the interval between the "congratulation time" and "the buffer time" the task simply ends (for example, you have a congratulation time of 00:15 and a buffer for 6 hours, then the task will be formed every 15 minutes only if the current time is in the range from 00:15 to 06:15 (that is, 00: 15 + 6 hours), everything else it will still be started every 15 minutes and immediately terminate.The buffer was introduced solely to eliminate the launch of tasks for activity instead of cron, or other circumstances when the launch at the appointed time was unsuccessful. But if not to enter additional conditions, then in all we need a congratulation every 15 minutes, and there is such a condition, with each successful congratulation we remember the time and so, if at the next start in the "right" time interval we can control, whether there has already been a congratulation in this interval and if so, we are completing the task. Here in this condition there is an error leading either to complete disregard of congratulations, or to duplication, everything depends only on time combinations
I think the author can easily find in his code the condition about which I'm talking about.