Timezone Format without colon - php

I am trying to get the timezone format to just show -6 rather than -06:00 but can't figure this out.
My current code outputs the format (since I am in central time) as -21600
SO I am trying to convert this using the following...
$time_offset_get = new \DateTime('now', new DateTimeZone(America/Chicago));
$conn_timezone_offset = $time_offset_get->format('P');
But of course, this ($conn_timezone_offset) is giving me -06:00
Is there another format code that will do this correctly or am I am doing this wrong altogether.
Overall, I am just trying to convert a timezone offset name like America/Chicago or a 3 digit timezone code into a number offset without the colon using PHP.

Use DateTime::getOffset
Returns the timezone offset in seconds from UTC on success or FALSE on
failure.
To get the offset in hours, simply divide the value by 3600.
$now = new \DateTime('now', new DateTimeZone('America/Chicago'));
$offset = $now->getOffset();
if ($offset !== false) {
$offset = round($offset / 3600);
} else {
// the error handling here
}

Related

Convert timezone offset to hours & minutes preserving sign

Suppose I have an offset like this:
$secOffset = -28800
I need it to convert in a format that is usable with MYSQL function convert_tz()
If I use gmdate("h:i", secOffset) I got 16:00 that is almost correct but It miss the minus - (that is quite important)
Alternative approach:
Suppose I have a time string America/Los_Angeles and I want to convert in a offset useful for MYSQL function convert_tz()
The final expected output is the offset from GMT so given a timezone.
For ex, having a timezone like America/Los_Angeles, the output should be:
−08:00
I'm on Magento/Zend so if any available function is on Zend I can accept answer based on it.
You should use the DateTimeZone and DateInterval classes for this:
$tzid = 'America/Los_Angeles';
$tz = new DateTimeZone($tzid);
$date = new DateTime('now', $tz);
// create a new date offset by the timezone offset
// gets the interval as hours & minutes
$offset = $tz->getOffset($date) . ' seconds';
$dateOffset = clone $date;
$dateOffset->sub(DateInterval::createFromDateString($offset));
$interval = $dateOffset->diff($date);
$formatted = $interval->format('%R%H:%I');
This is a little convoluted, as you first get the timezone offset in seconds, and then use DateTime to help convert that interval into hours/mins.

Converting GMT time to local time using timezone offset in php

I need to display user's activities date as per the current time zone.
My approach -
Getting a timezone offset from javascript and storing it to the user's profile table.
When user logged in, getting time zone offset.
current date is working fine with time zone offset-
$offsetDiff = $_SESSION['TimeZone']*60;
$UserDateTime = time() + $offsetDiff;
$currentDate = date('Y-m-d',$UserDateTime);
Dateo other then today is not working properly -
$offsetDiff = $_SESSION['TimeZone']*60;
$UserDateTime = '2014-02-10 08:58:00'; + $offsetDiff;
$monthUser = date('Y-m-d',$UserDateTime);
Can anybody please let me know how can i show correct date according to time zone offset?
You can convert a specific offset to a DateTimeZone:
$offset = '-0500';
$isDST = 1; // Daylight Saving 1 - on, 0 - off
$timezoneName = timezone_name_from_abbr('', intval($offset, 10) * 36, $isDST);
$timezone = new DateTimeZone($timezoneName);
Then you can use it in a DateTime constructor, e.g.
$datetime = new DateTime('2012-04-21 01:13:30', $timezone);
or with the setter:
$datetime->setTimezone($timezone);
In the latter case, if $datetime was constructed with a different timezone, the date/time will be converted to specified timezone.

Converting to the same timezone in php

Strangeness. It's not an edge case. Rather, let's say my server stores it's date/time in America/Toronto. I then run the it through time conversion logic incase, say, you're on the west coast. Here's the code I got:
$timestamp = '2012-07-25 16:30:00';
$to = 'America/Toronto';
$from = 'America/Toronto';
// system timezone
$system = (new DateTimeZone($from));
// desired conversion timezone
$desired = (new DateTimeZone($to));
// timestamp DateTime object
$resource = (new DateTime($timestamp, $system));
// offset
$offset = $desired->getOffset($resource);
print($offset);
The offset that is getting printed at this point is -14440 (4 hours). I don't imagine the system or database timezones are coming in here (both of which are set to America/Toronto). Any light would be appreciated on this. Confusing :(
DateTimeZone::getOffset() returns the offset in seconds from GMT (-14440 = 4 hours for America/Toronto).
Edit:
Apologies for my initial confusion with DateTime::getOffset()!
Anyway, to address the title of your question, use DateTime::setTimeZone() to convert between timezones.
This is probably what you're looking for, the offset between the 2 timezones.
// system timezone
$system = (new DateTimeZone($from));
// desired conversion timezone
$desired = (new DateTimeZone($to));
// timestamp DateTime object
$resource = (new DateTime($timestamp, $system));
$desiredDateTime = (new DateTime($timestamp, $desired));
// offset
$offset = $desired->getOffset($desiredDateTime) - $system->getOffset($resource);
print($offset);

Changing current user timezone based on server UTC offset and user UTC offset

im writing a twitter web service in php. When a user signs in, i receive this node:
<utc_offset>-18000</utc_offset>
I have to change the script's timezone so that it adapts to the user's real timezone. The only php function i have found for this is: date_default_timezone_set($timezone_identifier) but it won't let me use -18000 as a the $timezone_identifier parameter.
So, how can i change the current user timezone based on two values: Server UTC offset and User UTC offset
BTW, this is how i'm getting the server UTC offset value:
$this_tz_str = date_default_timezone_get();
$this_tz = new DateTimeZone($this_tz_str);
$now = new DateTime("now", $this_tz);
$offset = $this_tz->getOffset($now);
Any ideas? Thanks!
To get current server time
date_default_timezone_set(date_default_timezone_get());
echo date('Y-m-d H:i:s', time());
Output for Europe/Paris (my server settings; UTC+2)
2011-04-12 20:39:43
To get user's time by offset
$user_offset = '-18000';
date_default_timezone_set('UTC');
$diff = "$user_offset seconds";
if ((substr($diff,0,1) != '+') && (substr($diff,0,1) != '-')) $diff = '+' . $diff;
$usertime = strtotime($diff, time());
echo date('Y-m-d H:i:s', $usertime);
Output UTC-5 (Ecuador -> Quito time NO DST), php timezone identifier 'America/Guayaquil'.
2011-04-12 13:39:43
PHP.net manual:
Timezone offset in seconds. The offset
for timezones west of UTC is always
negative, and for those east of UTC is
always positive. (-43200 through
50400)
The date_default_timezone... functions expect a string giving something like "Africa/Luanda" or whatever.
I suggest programmatically searching through the timezone database for a matching offset. If I recall correctly, those are in minutes from UTC, so you should divide the offset you are given by 60.

PHP: Why is this code erroneously returning zero?

I'm calculating the offset between two timezones, but I'm seeing a result I don't expect (zero) with the following code:
$datetimezone_london = new DateTimeZone('Europe/London');
$datetimezone_client = new DateTimeZone('Australia/Canberra');
$now_client = new DateTime("now", $datetimezone_client);
$offset = $datetimezone_london->getOffset($now_client);
echo $offset;
If I flip the timezone strings, it works, but surely the above code should work too. What's happening?
getOffset() returns the offset to GMT in seconds, and London is currently on GMT, hence the return value is zero.
I believe what you need instead is:
$tz_london = new DateTimeZone('Europe/London');
$tz_client = new DateTimeZone('Australia/Canberra');
$time_london = new DateTime('now', $tz_london);
$time_client = new DateTime('now', $tz_client);
$offset = $time_client->getOffset() - $time_london->getOffset();
echo $offset;
This currently (in January) returns 39600 (11 hours). In July it returns 9 hours, and in mid October (where there's a short period when both Europe and Australia are in daylight saving) it returns 10 hours.
DateTimeZone::getOffset() works a bit differently that what most people think. It calculates the offset to GMT of the instance DateTimeZone offset for the date passed as parameter. The date passed as parameter is then converted to the same timezone as the instance (DST and other rules applying) and the offset is calculated for that date.
So your code right now calculates the offset to GMT of the timezone Europe/London.. Since Europe/London is on GMT right now (versus BMT), you are getting 0. (Try a date in August, you'll get 36000).
If you want the current difference between two timezones, use this code...
function timezone_diff($origin, $compareTo, $forDate = "now") {
$dtzOrigin = new DateTimeZone($origin);
$dtzCompareTo = new DateTimeZone($compareTo);
$compareDate = new DateTime($forDate);
$offsetOrigin = $dtzOrigin->getOffset($compareDate);
$offsetCompareTo = $dtzCompareTo->getOffset($compareDate);
return $offsetCompareTo - $offsetOrigin;
}

Categories