Reputation: 53
I've been searching alot and I can't seem to find a solution.
I have a PHP web page where I can schedule email alerts at specific times. I select the date and time of when the alert is to be sent. This is stored in MySQL table in UNIX format. I have a job that executes every 15 minutes and sends the emails if the date+time is in the past - this all works perfectly except I need to extend it for my USA colleagues. I am based in Ireland so I will need to manage the different timezones all across the US. I am planning on adding a select list of timezones that the user will have to select once they register...at least thats a start. Managing timezones is fine because I reckon all I need to do is minus the time different from the server time and then save the date time in unix format. DST is a different issue tho - does anyone have any ideas on how to overcome this?
I have read that using UTC as the base time but even if that is the case wont I still have the same issue?
Thanks a mil!
Upvotes: 5
Views: 1445
Reputation: 8509
Your times are already in UNIX timestamp format so all you need is to calculate time difference (offset) of user. For example Ireland is in UTC/UTC+1
timezone. So all you need is to do the math like james_t mentioned in his comment. If you need user from Ireland to get an email in 9:00pm UTC+1
you have to send it in 8:00pm UTC
. So what's an idea?
Allow users to select timezone which means they select offset from UTC. Keep it somewhere in database (your users table or some other table, doesn't matter).
Convert offset in seconds:
$delta_time = -1 * $offset * 3600
Then calculate your trigger-time:
$trigger_time = time() + $delta_time;
Now you have time when your email sender can fire in right moment depending on user's timezone settings.
For example:
$offset = 1; // summer in Ireland
$server_time = time(); // at the moment 1350509127
$delta_time = -1 * $offset * 3600; // -3600
$trigger_time = $server_time + $delta_time; // 1350505527
All you need is to compare $trigger_time
with UNIX timestamp from your database and decide to send an email (or not).
Ofc, it's not bad idea to use PHP timezones instead of pure +/- offset and stay updated when DST changes apply on certain locations.
Make some test, this is not that hard.
This is just a general idea, not complete working solution.
To calculate time-difference in seconds between any two timezones you can use something like this:
function delta_offset($server_timezone, $user_timezone) {
$dt = new DateTime('now', new DateTimeZone($server_timezone));
$offset_server = $dt->getOffset();
$dt->setTimezone(new DateTimeZone($user_timezone));
$offset_user = $dt->getOffset();
return $offset_user - $offset_server;
}
To get an offset in seconds:
$server_tz = "Europe/London";
$user_tz = "America/New_York";
$offset = delta_offset($server_tz, $user_tz); // offset in sec.
Create some output:
$dt = new DateTime('now', new DateTimeZone('UTC'));
echo "<pre>UTC date/time: " . $dt->format('l, F jS, <b>H:i:s</b>') . "\n";
$dt = new DateTime('now', new DateTimeZone($server_tz));
echo "London date/time: " . $dt->format('l, F jS, <b>H:i:s</b>') . "\n";
$dt = new DateTime('now', new DateTimeZone($user_tz));
echo "New York date/time: " . $dt->format('l, F jS, <b>H:i:s</b>') . "\n\n";
echo "Time difference between London (UK) and New York (USA) is: <b>$offset_h</b> ($offset s)</pre>";
Output in browser (in moment of writing this post):
UTC date/time: Wednesday, October 17th, 22:32:27
London date/time: Wednesday, October 17th, 23:32:27
New York date/time: Wednesday, October 17th, 18:32:27
Time difference between London (UK) and New York (USA) is: -5:00 (-18000 s)
In this case offset is -5 hours (-18000 seconds) but it automatically changes if DST rules change for any of timezones given as function-arguments.
Delta-offset provides information how much earlier or later you have to send an email to user in different timezone and all you need now is to do simple +/- delta-offset
with your email-sender's scheduler.
Hope this may help you to get right solution for your problem.
Imagine this situation.
Your current server-time is X
and its 7:00pm
at the moment in Ireland. I live in Serbia and we have same DST rules but I’m one hour after (UTC+1/UTC+2). Difference between your and my time is +3600 seconds
(1 hour).
Now you have to send an email to me in 10:00pm
(it’s 9:00pm in Ireland
).
X
.-1 * +3600 = -3600
(delta-offset multiplied with -1).X + 10800
(3 hours later).X + 10800 + delta-offset = X + 7200
(2 hours later).Formula to check if actual time is equal or greater than trigger-time (sending time) is:
current_timestamp >= trigger_timestamp + delta_offset
where delta-offset from delta_offset()
function must be multiplied with -1
to use in formula.
Now you can send email when you want and be sure it will be sent using user's local time (ofc, if user timezone settings are correct).
Note: Difference from this example (Serbia - Ireland = +1 hour) is different during DST changes which means that 1 hour every year we're in same timezone (0 delta-offset
), and one hour we have +2 hours delta-offset
. This is possible because DST changes are applied 1 hour earlier in Serbia so when our time is changed +1 you have to wait 60 minutes before same change applies to Ireland-time *then we're +2) and same thing when we bring back clock to normal time (0 difference).
Upvotes: 3