I have achieved this type of functionality via a console application running as a scheduled task that polls the database every X minutes to see if any emails need to be sent.
I am assuming UserProfile
is a database table holding your user list.
To achieve this I would add an additional column to this table to store the last sent Date/Time. This is necessary as when you start sending by timezone you obviously cannot send all the emails at the same time each day and will need to track which ones have been sent or which ones need to be sent.
Also due to the nature of this type of task if for some reason it fails or isn't running for some reason you may need to "catch-up" i.e. send any missed emails (although this may not be a requirement for you) which can also be achieved by checking the last sent column.
Assuming you want to send an email at (or as close to) 11:30am local time to each user the following code should work:
IList<UserProfile> users = // Load user profile from database
foreach(UserProfile user in user){
// Work out this users local time by converting UTC to their local TimeZone
DateTime localDateTime = TimeZoneInfo.ConvertTimeFromUtc(DateTime.UtcNow, user.TimeZoneId);
if(user.LastSent.HasValue && user.LastSent.Value.Date == localDateTime.Date){
// Already sent an email today
continue;
}
if(localDateTime.Hour >= 11 && localDateTime.Minute >= 30){
// After 11:30am so send email (this could be much later than 11:30 depending on other factors)
if(SendEmail(user.EmailId)){
// Update last sent that must be in local time
user.LastSent = Converter.ToLocalTime(DateTime.UtcNow, user.TimeZoneId);
// Save User entity
// UserPersistence.Save(user);
}
}
}
Now as a caveat the code above will send an email as soon as 11:30 has been reached PROVIDED that the code is running and dependent on volume of users/latency of sending each email etc. If you have a scheduled task running every 5 minutes then obviously the accuracy is going to be to the nearest 5 minutes so it may not send until 11:35am. You could run the scheduled task more frequently if you want more accuracy. Another consideration is that if you have 30000 users in the same time zone then the latency of sending that volume of emails will naturally mean that not all can be sent at exactly 11:30am.
That said the code above should get you started in the right direction.