Carbon Time Difference of Local Time and Server Time - php

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.

Related

How to get the duration of an inserted time by inserting another one with minute:seconds:milliseconds?

I am making a game mode in which I am trying to get the time a player has arrived at their destination after starting the mode and to do this I am using the insert of a date when it starts the mode it inserts a date and after reaching the your destination it registers another date and with both dates it calculates the time it took to get to the destination, with this I'm using date H:i:s (hours, minutes, seconds) but I need to take the time out and leave milliseconds after seconds example: i:s:u (minutes, seconds, milliseconds) but I'm not able to do this, I've tried it in several ways, basically everything works as follows:
1. I add in the player array a current date with hour, minutes, seconds;
$this->game[$player->getName()] = ["start" => strtotime('now')];
2. After the Player arrives at his destination he calculates the time of his trajectory creating another current date with already registered and using date and mktime to do the join and give a visual of time to the player;
$time = date('H:i:s', mktime(0, 0, str_replace("-", "", $this->game[$player->getName()]["start"] - strtotime('now'))));
3. Send the pretty message to the player about the time of his trajectory then time will be something like this: 01:45:23 (minute:seconds:milliseconds).
$player->sendMessage("You beat your time record by ".$time);
This is my method of doing, if you have another better method with the milli seconds added I accept the suggestion! Maybe there might be some errors in my code that I'm still not sure if they work correctly as the subtraction to calculate and join the current time with the previous one, tell me if it's right and if it is not correct correct me or do better. Thank you
Use microtime which returns the current Unix timestamp with microseconds
$game = [];
$game['start'] = microtime(true);
// Do stuff
sleep(3); // Without the sleep, start and end are the 'same'
$game['end'] = microtime(true);
$elapsedTime = ($game['end'] - $game['start']);
$minutes = floor($elapsedTime / 60);
$seconds = $elapsedTime % 60;
$milliseconds = number_format($elapsedTime - floor($elapsedTime),3);

Apply time offset to get current time

My server has 5 hours difference from my current location time. After I record an event I'd like to display current local time. My time is stored in db as DATETIME value (0000:00:00 00:00:00).
I can get offset time in seconds with PHP like this:
$offset = date('Z');
So, the time from db will be:
$time = '2016-03-31 01:40:13';
But if my time is offset by -18000 sec, i.e. -5 hrs, the display time should be
2016-03-30 20:40:13
So I've attempted:
echo date('Y:m:d H:i:s', mktime(strtotime($time + $offset)));
But it looks convoluted...
setlocale(LC_TIME,'YOUR_LOCALE'); for strftime formatting
AND
date_default_timezone_set('YOUR_TIMEZONE'); for timezone settings

PHP scheduled email alerts using preselected timezone

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!
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.
Update:
To calculate time-difference in seconds between any two timezones you can use something like this:
function delta_offset()
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.
Update #2 - Example (theory)
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).
Current time is X.
Delta-offset is -1 * +3600 = -3600 (delta-offset multiplied with -1).
Sending time on your location in 10:00 pm is X + 10800 (3 hours later).
Sending time on my location in 10 pm is 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).

calculate which timezones have a specific current local time on PHP

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.

One hour difference in date and time after adding Daylight Saving Time offset in php

HI All,
I'm trying to match today's date and time at Atalanta to a database value. I'm testing following code.
$date = new DateTime();
$newToday = $date->format('Y-m-d H:i:s');
$dateTimeArr = split(" ",$newToday);
$dateArr = split("-", $dateTimeArr[0]);
$timeArr = split(":",$dateTimeArr[1]);
$testTime = date("Y-m-d H:i",mktime($timeArr[0]+4, $timeArr[1], $timeArr[2], $dateArr[1], $dateArr[2], $dateArr[0])); // 4 is Daylight Saving Time offset
When I run the code, I found that there is 1 hour time difference if I check the time at http://www.timetemperature.com/tzga/atlanta.shtml
I'm adding the day light saving offset which 4 hours, but still the time I get is 1 hour more than the actual time. Why this difference is seen ? How to rectify this ?
EDIT
My server is at different time zone than Atalanta. I want to handle the time difference without knowing the timezones. For this, for each city we have added timezone offset in database.
Use the DateTime and DateTimeZone objects:
//EDT = Eastern Daylight Saving Time
$x = new DateTime(null, new DateTimeZone('EDT'));
echo $x->format("Y-m-d H:i")
I think that if you use America/New_York (which is in the same timezone as Atlanta) as the timezone, it will change accordingly between normal and daylight saving time.
$x = new DateTime(null, new DateTimeZone('America/New_York'));
echo $x->format("Y-m-d H:i")
Both versions output the same time for me.
Have you checked your server's (the computer that executes the actual PHP script) time? See if it has the right time

Categories