PHP - Local vs UTC Time Comparison with Timezone Offset - php

Given a variable unix timestamp and a fixed timezone offset in seconds, how can you tell if local time is past 8am.
For example, take the following variables:
$timestamp = time();
$timezone_offset = -21600; //i think that's -8hrs for pacific time

if(date("H", $timestamp + $timezone_offset) >= 8){
// do something
}
Assuming you consider even a millisecond past 8:00:00 is "past 8am".

You set your timezone in PHP using date_default_timezone_set() and then use PHP's datetime functions like date or DateTime object to check the time according to the set timezone. PHP will do the right thing for you and adjust the time to the specified timezone.
$timestamp = 1354794201;
date_default_timezone_set("UTC"); // set time zone to UTC
if (date("H", $timestamp) >= 8) { // check to see if it's past 8am in UTC
echo "This time stamp is past 8 AM in " . date_default_timezone_get() . "\n";
}
date_default_timezone_set("America/New_York"); // change time zone
if (date("H", $timestamp) >= 8) { // Check to see if it's past 8am in EST
echo "This time stamp is past 8 AM in " . date_default_timezone_get() . "\n";
}
Output from this code
/* This time stamp is past 8 AM in UTC */
You can do the same thing with DateTime as well...
$timestamp = 1354794201;
$date = new DateTime("#{$timestamp}"); // create the DateTime object using a Unix timestamp
$date->setTimeZone(new DateTimeZone("UTC")); // set time zone to UTC
if ($date->format("H") >= 8) { // check to see if it's past 8am in UTC
echo "This time stamp is past 8 AM in {$date->getTimezone()->getName()}\n";
}
$date->setTimeZone(new DateTimeZone("America/New_York")); // change time zone
if ($date->format("H") >= 8) { // Check to see if it's past 8am in EST
echo "This time stamp is past 8 AM in {$date->getTimezone()->getName()}\n";
}
Output from the above code is also...
/* This time stamp is past 8 AM in UTC */
Unix time is time zone agnostic. That's the point of using Unix time as a transport layer. You never have to worry about time zones until it comes time to translate your time stamp from Unix time to a formatted date.

Related

Ensuring Unix time in PHP

My code assumes that zero represents the beginning of the Unix epoch, 1970-01-01 00:00. I upgraded an installation of PHP and now, all of a sudden, zero represents 1970-01-01 01:00 (as verified with date('Y-m-d H:i', 0)). So apparently there is a time zone matter. I put the same code into a sandbox and got 1969-12-31 16:00. I have several unit tests that are broken as a result of this. Time zones do not and should not come into play here.
How can I ensure that date-time functions such as date() always converts zero to 1970-01-01 00:00 regardless of the time zone setting on the particular installation?
Using gmdate() you'll always get 1970-01-01 00:00 for 0, no matter what timezone your server is in:
<?php
date_default_timezone_set('Europe/Berlin');
echo "Europe/Berlin:\n";
echo "gmdate: ".gmdate('d.m.y H:i', 0) . "\n";
echo "date: ".date('d.m.y H:i', 0) . "\n";
date_default_timezone_set('America/Los_Angeles');
echo "\nAmerica/Los_Angeles:\n";
echo "gmdate: ".gmdate('d.m.y H:i', 0) . "\n";
echo "date: ".date('d.m.y H:i', 0) . "\n";
/* OUTPUT:
Europe/Berlin:
gmdate: 01.01.70 00:00
date: 01.01.70 01:00
America/Los_Angeles:
gmdate: 01.01.70 00:00
date: 31.12.69 16:00
*/
https://3v4l.org/FechC
You need to set the default time zone to GMT if you want to use date() like that. For example:
date_default_timezone_set('GMT');
echo date('Y-m-d H:i [I] [e] [O]',0);
The above will show (no matter what the server has been set to):
1970-01-01 00:00 [0] [GMT] [+0000]
Without the date_default_timezone_set('GMT'), or even set to Europe/London, you will get a different result at different times of the year.
From the PHP manual;
date — Format a local time/date
gmdate — Format a GMT/UTC date/time
The solution is to get the timezone setting, set it aside, change the timezone to UTC, perform the calculations, and reset the timezone to its original setting.
So if my original function looked like this:
public function format($argument = null)
{
// Perform some calculations involving date() and strtotime().
return $result;
}
Now it looks like this:
public function format($argument = null)
{
$timezone = date_default_timezone_get();
date_default_timezone_set('UTC');
$result = ...; // Perform some calculations involving date() and strtotime().
date_default_timezone_set($timezone);
return $result;
}

Convert European date to UNIX while factoring in timezone and summer time?

I have dates in the following format for a set of past events:
year-m-day hour:second
e.g. 2014-05-25 20:41
These dates are based on Brussels time (GMT + 1hr + (1hr summer time)).
I am attempting to calculate how much time has passed since an event started by taking this date/time and minusing it from current date/time as follows:
$current_time = time();
$event_time = date('2014-05-25 20:41');
echo ($current_time - $event_time)
However, due to the timezone, the date is two hours ahead of Unix time.
Is there a simple way to accurately convert from Brussels summer time to Unix bearing in mind summer time kicks in each year on a different date?
You can set time zone and use DateTime::diff() function and DateInterval::format():
date_default_timezone_set('Europe/Brussels');
$dateNow = new DateTime();
$dateBefore = new DateTime('2014-05-25 20:41') ;
$interval = $dateNow->diff($dateBefore);
echo $interval->format('%h hours %i min ago') . PHP_EOL;
Which shows:
0 hours 37 min ago
And to just convert date to unix time DateTime::format('U') or DateTime::getTimestamp() like that:
echo $dateNow->format('U') . PHP_EOL
echo $dateNow->getTimestamp() . PHP_EOL;

strtotime is different with timezone

Seems I don't quite understand much the function strtotime. My case is I would like to compare the current time (now) with a specific time on specific timezone
For example the specific time is "this Monday at 14:00:00" at the timezone "America/New_York":
$specificTime = strtotime("monday this week 14:00:00 America/New_York");
My current code is:
$now = strtotime("now America/New_York");
if ($now > $specificTime) {
//do something
}
But I have figured it out that $now above is 6 hours ahead with current time. The number 6 I guess from offset -05:00 of America/New_York, plus with 1 hour daylight saving.
it should remove timezone out of $now, it will work correctly:
$now = strtotime("now");
if ($now > $specificTime) {
//do something
}
Could someone give the explain why strtotime("now America/New_York") is 6 hours ahead with strtotime("now), why they are not equivalent? really confused.
P.S: I am on GMT+07:00.
Simple debugging:
<?php
$now = strtotime("now America/New_York");
echo date('r', $now);
// Thu, 28 Nov 2013 16:39:51 +0100
... shows that such command is doing this:
Calculate local time in my default time zone (10:39:51 +0100)
Return timestamp that corresponds to 10:39:51 in New York time (-0500)
Doing date manipulation with strings is terribly complicated. Just imagine you'd try to do math with string functions: strtofloat('one plus square root of half hundred')—there'd be plenty of room for mistakes. So my advise is to keep it simple and only use with simple expressions when there's some benefit, such as strtotime('+1 day').
If you need to work with different time zones, I suggest you use proper DateTime objects. If you choose to work with Unix timestamps, forget about time zones: Unix timestamps do not have time zone information at all.
You can use DateTime for this. I believe settings a timezone in strtotime is not valid.
$specificTime = new DateTime("monday this week 14:00:00", new DateTimeZone("America/New_York")));
$now = new DateTime("now", new DateTimeZone("America/New_York"));
You can then compare unix timestamp with this:
if ($now->getTimestamp() > $specificTime->getTimestamp()) {
// do something ...
}
There is time offset between each timezone.
strtotime() function will return the Unix timestamp according the timezone.
It will use the default time zone unless a time zone is specified in that parameter.
The default time zone it the return value of date_default_timezone_get();
Look the code below:
<?php
// UTC
echo date_default_timezone_get(), "\n";
// 2013-11-28 14:41:37
echo date('Y-m-d H:i:s', strtotime("now America/New_York")), "\n";
// 2013-11-28 09:41:37
echo date('Y-m-d H:i:s', strtotime("now")), "\n";

How to store expiration time?

I want to store the expiration time in database. I am using the below code to store expiration time with +1 year.
$cdate = time();
$date = $cdate + 365*24*60*60;
$date = date("Y-m-d H:i:s",$date);
but its not storing the correct time it stores 2014-08-10 07:55:14 but time on storing is 2014-08-10 01:25:14.
Aslo not sure its Am or Pm .
Thanks.
Time/date functions in PHP are using timezones to determine your local time. So if your server is in timezone GMT+6 that means that the date() function will return you the date/time that is 6 hours before GMT.
You can check the date_default_timezone_set() function manual to find out how PHP is selecting your timezone.
To set your timezone, you can use date_default_timezone_set() before calling date function or you can set you php.ini setting date.timezone to your timezone.
For the second part of your question - when formatting time using the date() function the H format character will return 24-hour format of an hour with leading zeros.
try this
<?php
$timezone1 = "America/Los_Angeles";
date_default_timezone_set($timezone1);
$cdate = time();
$date1 = $cdate + 365*24*60*60;
$date = date("Y-m-d H:i:s a",$date1);
echo $date;
$timezone = "Asia/Calcutta";
date_default_timezone_set($timezone);
$cdate = time();
$date1 = $cdate + 365*24*60*60;
$date = date("Y-m-d H:i:s a",$date1);
echo $date;
?>
you can set timezone for your location.And also refer this codepad-FIDDLE
As others have mentioned, it is calculating the time based on your server (local) time.
I suggest you store the time in GMT and then adjust it to your desired timezone as necessary.
You can use strtotime() to calculate 1 year from now (no need to calculate it yourself) and use gmdate() to get the timestamp in GMT.
echo "Next Year in local time: ". date("Y-m-d H:i:s", strtotime("+1 year")) ."\n";
echo "Next year in GMT: " . gmdate ("Y-m-d H:i:s", strtotime ("+1 year")) . "\n";
// Output:
// Next Year in local time: 2014-08-10 15:25:09
// Next year in GMT: 2014-08-10 08:25:09

How to get seconds elapsed since midnight

Using PHP how do you get the number of seconds elapsed since midnight of the current day?
All i've tried right now is:
$hour=substr(date("h:i:s"),0,2);
$minute=substr(date("h:i:s"),3,2);
echo $hour."\r\n";
echo $minute."\r\n";
...but it doesn't return the correct server time of the response and I don't know how to do that.
This should work.
echo time() - strtotime("today");
This will only show your servers timezone though.
Simplest I believe would be dividing the current time (in seconds) by the number of seconds in a day (60*60*24) and taking the remainder:
(time() % 86400)
If you are using DateTime:
$timeDiff = $time->diff(new \DateTime("today"));
$timeDiffSec = $timeDiff->h* 3600 + $timeDiff->i*60 + $timeDiff->s;
echo (date('G') * 3600 + date('i') * 60);
Multiply the current hour by the number of seconds in each hour and add it to the number of minutes multiplied by the number of seconds in each minute.
I think you want to get time from start of the day to current hours and seconds of the day, this can be done like this, you will still need to set your timezone time in place of 'Asia/Karachi'. This gets correct time since midnight in user's timezone instead of server's timezone time.
Here is working link:
http://codepad.viper-7.com/ykJC2R
//Get current time timestamp
$time_now = time();
//Create DateTime class object
$date = new DateTime();
//Set timestamp to DateTime object
$date->setTimestamp( $time_now );
//Set timezone so that code don't get server's timezone midnight time
$date->setTimezone(new DateTimeZone('Asia/Karachi'));
//Print current time in user's timezone
echo $date->format('Y-m-d H:i') . "<br />";
//Get time stamp for midnight tonight
$date->modify('today midnight');
$midnight_time = $date->getTimestamp();
//Print midnight time in user's timezone
echo $date->format('Y-m-d H:i') . "<br />";
//Now you will need to subtract midnight time from current time in user's timezone
$seconds_since_midnight = $time_now - $midnight_time;
//Print seconds since midnight in your timezone
echo $seconds_since_midnight;
The shortest solution would probably be this:
$time = "12:34:56";
echo strtotime("{$time}UTC", 0);
The reason this works is that strtotime uses the second parameter to determine the date part of the time string. In this case, I'm using 0, which means the full string results in 1970-01-01 12:34:56 UTC. strtotime then returns the UNIX timestamp (the number of seconds elapsed since 1970-01-01 00:00:00 UTC). Note: the first parameter has UTC appended to prevent the time being interpreted as local.
DateTime (with microseconds)
A faster (3×) and more precise alternative to the already mentioned DateTime::diff solution:
$date = new DateTime;
[$h, $m, $s] = explode(':', $date->format('H:i:s.u'));
echo $h * 3600 + $m * 60 + $s;
Based on your comment, if you are receiving the time as a string and want to calculate the number of seconds from that time:
$time = strtotime($_GET['time']); // Do some verification before this step
$midnight = strtotime("00:00"); // Midnight measured in seconds since Unix Epoch
$sinceMidnight = $time - $midnight; // Seconds since midnight
There you go. Read into time() function of PHP and strtotime().
In Carbon, the number of seconds elapsed since midnight can be found like this:
$seconds_since_midnight = $dt->secondsSinceMidnight();
And though there's no minutes since midnight I suppose you do:
$minutes_since_midnight = (int) floor($dt->secondsSinceMidnight()/60);
echo time() - strtotime('today');
I'm keeping the rule that operations on numbers are always faster than operations on strings. When the numbers are integers, operations are even faster (because CPU registers are always "integer wide", means have 32-bit or 64-bit and all other non-floating point types are converted to integer before any operation is performed).
Anyway, I found such solution to count seconds till midnight with timezone include:
$tillmidnight = 86400 - (time() - mktime(0, 0, 0));
You wanted to get seconds elapsed since midnight so:
$sincemidnight = time() - mktime(0, 0, 0);
It is good to review your php.ini also and set your time zone (date.timezone under [Date] section) there. If you do not have access to php.ini, you can set your time zone in PHP code using date_default_timezone_set(); function.

Categories