My application needs to send an email to all users at 6:00PM, on their local time.
The server is configured to GMT.
I have a function that is being called at the beginning of each hour.
How do I find out which timezones (PHP timezones) are now at 6:00PM?
(this way I can query the data base and find all users set to this timezone and send them the email).
Also is it possible to do it without iterating over the entire timezone array?
Thanks.
My previous answer wasn't too great since daylight savings time precludes you from defining timezones in absolute offsets from GMT. Here's a better solution, assuming you're storing timezones in one of these formats. This script should be run every 15 minutes on the quarter-hour.
// Target local time in hours (6:00 PM = 18:00)
$targetHour = 18;
// Get timestamp of nearest quarter-hour.
// (Assuming this is being run by cron on-the-quarter-hour by server time)
date_default_timezone_set('GMT');
$currentHourTimestamp = (round(time() / 900) * 900);
// Calculate offset in hours to target hour
$targetDateTime = new dateTime('#' . $currentHourTimestamp, new DateTimeZone('GMT'));
$targetDateTime->setTime($targetHour, 0, 0);
$targetOffset = $targetDateTime->getTimestamp() - $currentHourTimestamp;
// You can get this from the database with a
// 'SELECT DISTINCT timezones FROM users' query or similar
$timezonesUsed = array('America/Los_Angeles', 'America/Phoenix', 'Europe/Budapest', 'Europe/Dublin');
$matchingTimezones = array();
foreach($timezonesUsed as $localTimezone)
{
// throws an Exception if timezone is not recognized
$localDateTimezone = new DateTimeZone($localTimezone);
$localOffset = $localDateTimezone->getOffset($targetDateTime);
if($localOffset == $targetOffset)
$matchingTimezones[] = $localTimezone;
}
// Now send emails to users in database with timezones in $matchingTimezones
Edit: Adapted script to use quarter-hours per Catcall's suggestion.
Related
I'm building an application that shows specific times on a given day. This application is meant to serve ppl worldwide.
I do all the calculation with a TZ in an hour format (-4 / 2 / 9.5 / -1 ETC). (don't worry. the hour tz is after DST calculations)
Now, I would like to show the user his local time. due to dev reasons, i can use only the hour tz for this calculation.
after a lot of tries, i maneged to write a piece of code that seems to work. (tested it for few timezones, negetive and positive)
I am wondering if my code is ok? could i do it in a more efficent way? do this code support infinite date range?
here is the code:
static function current_local_time_zmanim($tz)
/*
* This function will get the number of hours off set (the time zone that Full_Zmanim_calculation() is using to make the calcukation) and will return the current local time and date.
*/ {
$tz= ($tz * 3600);// calculatoin: (hour offset(tz. can be -4 or 4) * 3600). eg: (-4*3600) or (3*3600)// converting the hour tz to TIMESTAMP
$date_utc = new DateTime(null, new DateTimeZone("UTC")); // current time in UTC.
$utctime= $date_utc->getTimestamp(); // current time in UTC TIMESTAMP
$date_utc->setTimestamp($utctime + ($tz));// keep in mind that tz can be either positive or negetive
$localtime= $date_utc->format('H:i');
echo "<br> local time: $localtime <br> ";
return $localtime;
}
What do you think?
Thanks!
I am using Laravel 4 and trying to calculate the difference of the Time on Server and the Time Save in Database in hours. Here is the code:
Time on Server=timeNowOnServer // 2016-02-03 19:05:43
Time saved in Database = setTime // 18:00:00
$timeNowOnServer = null;
$setTime = null;
$timeZone = $company->time_zone;
$company->save();
// My Time
$hour = substr($company->emp_auto_logout_time, 0, 2);
$setTime = Carbon::createFromTime($hour);
// Server Time Same as Mine
$timeNowOnServer = Carbon::now();
$timeNowOnServerSameAsMine = $timeNowOnServer->setTimezone($timeZone);
// Time Differnce Between SetTime and TimeOnServerSameAsMine
$timeDiff = $setTime->diffInHours($timeNowOnServerSameAsMine, $abs = false);
If Server Time is 14:00:00 for example and Set Time is 19:00:00. My time zone is GMT +5 Pakistan.
What I'm doing is, adding setting Server Time according to user time by giving time zone in the 3rd last line of the above given code.
When I use diffInHour it instead of giving me 0 it gives me -5 or 5. It means it's useing UTC (Server Time) and that's why give wrong difference in hours.
Can someone please let me know where I'm wrong?
You're trying to diff time in different time zones. A time difference (interval) is an absolute value, it doesn't depend on time zone. One second is always one second, be it UTC or Europe/Moscow.
Try without time zone (to be correct - using default server's time zone)
$timeDiff = $setTime->diffInHours($timeNowOnServer, $abs = false);
Always calc intervals using timestamps or the same time zone (doesn't matter exactly which one) for both DT values.
I am learning some PHP. I have a script which checks to see if a JSON file exists. If it does not exist; it will populate it with some YQL and some data. If it exists, it will not do anything as it is better for cache and speed.
In my code; I have this line (currently only doing every 3 hours (10800)):
if ( !file_exists($cache) || filemtime($cache) < ( time() - 10800 ) ) {
What I want do is, despite the server time, I want to use the UK GMT timezone and check to see if it is 00.01 past midnight, if it is, that is when I want to update the script. Every day at 00.01 midnight in the UK. Now I have heard PHP supports timezone but I only want it on this script?
This is what I have tried.
// TIMEZONE
date_default_timezone_set("Europe/London");
$date = $date();
$timestr = $time();
$timestamp = strtotime('today midnight');
// VARS
$cache = '../media/js/data.json';
// VALIDATION
// -- The cache is new
if ( !file_exists($cache) || filemtime($cache) < ( time() - timestamp ) ) {
another approach would be as mentioned would be cron jobs. you mentioned you want uk time zone , in that case please set your php.ini time zone to UK. this is how you do it
//add this line or replace within your php.ini file
; Defines the default timezone used by the date functions
date.timezone = "Europe/London"
and then set the cron job.
I'm using some stuff like that
$timezone = "Your timezone";
$tmpTZ = date_default_timezone_get();
date_default_timezone_set($timezone);
// some code to generate the date
date_default_timezone_set($tmpTZ);
Putting that in a small function an your ready to go.
The easiest solution will be usage of Cron, just calculate the difference between 2 timezones, and add task on the calculated time
http://www.thegeekstuff.com/2009/06/15-practical-crontab-examples/
I am working on project in which i am converting the time according to user location. i.e if user belongs to ALASKA then then all the information will be shown according to his countries timezone.I did some conversion but i am getting wrong time in case of user has a Daylight timezone (DST) which changes frequently.
Here is my code snippet.
date_default_timezone_set('UTC');
$offset=$_SESSION['gmtoffset'];
echo date('Y-m-d H:i:s',strtotime(date('Y-m-d H:i:s'))-(-$offset));
So in this case how do i maintain this timezone? what is the exact way for this time related conversions?
Any guidance and idea will be appreciated.
Thanks
Here's a simple solution
Javascript:
var timeZone = new Date().getTimezoneOffset();
document.cookie="tz=" + (timeZone/(-60));
Then PHP:
if(!empty($_COOKIE['tz']) && $_COOKIE['tz']>=-12 && $_COOKIE['tz']<=13){
$offset = $_COOKIE['tz'];
$tz = timezone_name_from_abbr(null, $offset * 3600, true);
if($tz === false) $tz = timezone_name_from_abbr(null, $offset * 3600, false);
date_default_timezone_set($tz);
}else{
date_default_timezone_set('UTC');
}
I am a bit uncertain to what in particular you are asking, but hopefully this will help.
If your question is regarding detecting that the user is in the Alaska time zone, then read:
How to detect user's timezone?
If your question is about picking a time zone by country, then read:
In PHP, how can I get Timezone from offset and country?
If you are wanting to understand Alaskan time zones, recognize that there are three different legal zones, and seven different IANA/Olson/TZ time zones (that PHP can use):
http://en.wikipedia.org/wiki/Time_in_Alaska
Don't try to treat a time zone as a numeric value. See "TimeZone != Offset" in the timezone tag wiki.
If you are wanting to manipulate dates with time zones in PHP, see the example in the PHP documentation for date_default_timezone_set.
If you just want to work with UTC, then there's no reason to do anything with time zones at all. The browser can always convert UTC to and from the user's local time zone, whatever that might be. Just create your JavaScript Date objects with a UTC timestamp integer, or parse from a UTC format, such as YYYY-MM-DDTHH:MM:SSZ.
To eliminate browser inconsistencies, you might want to use a library instead, such as moment.js:
// here's one way
var m = moment('2013-05-31T12:34:56Z');
// here's another
var m = moment.utc('2013-05-31 12:34:56','YYYY-MM-DD HH:mm:ss');
// pretty much anything else you might want to do...
We have a battle system where people can pick a match time to challenge another player. To create a match the user needs to pick a date. Currently a user picks the day, hour, minute, and pm/am from a dropdown list. If the user selects 5/20/2012 # 1PM, the system adds the hours and minutes from the start of the day. Here's a quick sample to get a better understanding of what I'm talking about:
$time = strtotime('today', $inputdate);
$time = $time + $hours + $minutes;
the value of $hours changes if the users selects AM or PM. It's pretty basic:
Everything was working fine until people started have timezone issues. For example, if player A creates a match at 1:PM, then player B will see the match starts at 1:PM, but he/she will have different timezones!
The problem is that I don't know the problem :/
I don't know how to fix the timezone issue. I have been creating functions in the hopes that everything will fall together, but no luck.
What I have:
User profiles have a timezone options.
A function that gets the raw timestamp and returns the formatted time based on the user's timezone.
A function that gets a timestamp and converts it to another timestamp
based on the user's timezone.
I'm lost and I can't seem to fix the issue, I can code, but right now I'm not thinking logical. I took me one hour to write this and try to explain it how I could, since I myself don't know how to make it work. Some advice is appreciated.
I need a function to convert a timestamp to UTC-5:
function input_date($timestamp)
{
global $vbulletin;
$timestamp = (int)$timestamp;
if (strlen((string)$timestamp) == 10)
{
$hour = 3600.00;
$offset = $vbulletin->userinfo['timezoneoffset'];//sample -8
$ds = (int)$vbulletin->userinfo['dstonoff'];//DST
$fluff = $hour*($offset+5.00);
$timestamp = $timestamp+$fluff+($ds*$hour);
return $timestamp;//return timestamp in UTC-5 format..
}
else
{
return 0;
}
}
Essentially everything in the database should be stored using a single timezone, preferably one which is not affected by DST. The standard option here is UTC.
If you know the user's timezone by its name, you can use that to generate your time:
// Player A creates match at 1PM Europe/London
$timezone = 'Europe/London';
$localTime = '2012-03-01 13:00:00';
// work out UNIX timestamp using that timezone (making it timezone independent)
date_default_timezone_set($timezone);
$timestamp = strtotime($localTime);
// store $timestamp in the database
// Player B views the timestamp with timezone America/Los_Angeles
$timezone = 'America/Los_Angeles';
date_default_timezone_set($timezone);
var_dump(date('c', $timestamp)); // see manual for more output formats
If you have the timezones stored as their abbreviations (e.g. "CET", "GMT"), then use timezone_name_from_abbr to get the correct timezone name.