Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Sending Email to Different Time Zones At the Same Time Each Day

Tags:

java

timezone

gmt

Turns out this seems to be a complex subject, please tell me if my approach is too simple.

Basically what i'm trying to do is send an email reminder to a list of users (only when they have a reminder coming up, but that is besides the point) at 7 am every morning. Of course 7 am is at a different time based on the server location for everyone all over the world.

The plan is to collect to GMT offset hour via javascript from the user when they register:

var today = new Date();  
var offset = -(today.getTimezoneOffset()/60);

Simple enough, I now know the offset hour and store that in a database along with the rest of the users data. Now server side I have a TimerTask set up that runs every hour. I collect the system hour (say its 5 am), see how far away from my target time that is (in this case 2 (7-5)), get the system offset hour (in this case its -5), then pull all users from the database that have a GMT offset hour of -3 (-5 + 2), then do the email sending etc. At this point im assuming I know its 7 am for everyone whos time zone offset is -3 and I can continue with the process. This will run again the next hour and collect all users with a time zone offset of -4. Is this something that will actually work, or am I missing something?

Calendar systemTime = Calendar.getInstance();
int targetHour = 7;
int currentHour = systemTime.get(Calendar.HOUR_OF_DAY); //Its 5 am.
int difference = targetHour - currentHour; //2
int zoneOffset = systemTime.get(Calendar.ZONE_OFFSET) / (1000*60*60); //-5
int targetZone = zoneOffset + difference; //-3

List<User> users = userDAO.findByZoneOffset(targetZone);
for(User user : users) {
    //Send email or whatever I want to do with these users.
}

I understand its possible that the client time zone may be set incorrectly and therefore product an off result, but im willing to take that risk as its not absolutely necessary for the reminders to go out at exactly 7 am, just preferable.

like image 228
ryandlf Avatar asked Dec 10 '12 07:12

ryandlf


People also ask

How do you write multiple time zones in an email?

Reference to a specific time and zone would follow standard guidelines with the zone in parentheses: 4:42 p.m. (PST), 11:03 a.m. (MDT), 2:30 p.m. (CST), 10:00 P.M. (EST). AP on the other hand advises to capitalize the full name of each time zone: Pacific/Mountain/Central/Eastern Standard Time.

How does Java handle different time zones?

If you cannot change the OS or the JVM timezone, you can still convert a Java Date/Time or Timestamp to a specific time zone using the following two JDBC methods: PreparedStatement#setTimestamp(int parameterIndex, Timestamp x, Calendar cal) – to convert the timestamp that goes to the database.

How do you clarify time zones in email?

Abbreviations for time zones may be enclosed in parentheses or brackets, but don't enclose them in commas (2:30 p.m. EST). Do use commas if the time zone is spelled out (2:30 p.m., Eastern Standard Time). UTC offsets may be preferred in international publications (e.g., UTC-05:00 for EST).


1 Answers

The plan is to collect to GMT offset hour via javascript from the user when they register

That won't be enough to get a time zone consistently. It doesn't take account of daylight saving time. So if the user is anywhere that observes daylight saving time, they'll either get emails at 6am for about half the year, or they'll get emails at 8am for about half the year. You may well be better off guessing their time zone based on IP geolocation + offset.

I have a TimerTask set up that runs every hour.

I would suggest running more often than that. Otherwise, you may well find that you end up waking up just before you would send an email - so you then go back to sleep, and send the email at 7:59 next time... which may be 8:59 with your current scheme, based on client DST changes. At that point you're nearly two hours off your intended send time!

I collect the system hour

Don't do that, either. At this point there are two time zones to take account of - and your server time zone is completely irrelevant. Use UTC until you convert into the client's local time. It's going to make life much simpler. If you're still using Calendar, you can do this simply by setting its time zone.

Looking at your code, it looks like you also could end up missing a bunch of users completely, if you're checking by exact match of hour. If you end up running once at (say) 3:59 and then once at 4:01, you'd miss anyone who had to be run at 4. I would suggest keeping track of when you last sent a mail to each user - or possibly when you last ran - and use that to make sure you always catch everyone.

Finally, I'd strongly advise that you use Joda Time. It's a much cleaner date/time API, which will help you to think about the right concepts to use at the right point in your code.

like image 188
Jon Skeet Avatar answered Sep 25 '22 21:09

Jon Skeet