adjust time zone - php

How would I take a stored date, like 2011-01-30 18:23:49, and adjust it to any chosen timezone? Is there a simple way such as simply defining the time zone by abbreviation or adding/subtracting x amount of hours?
Basically I want users to be able to choose their time zone and this default date be adjusted to fit theirs.

Have the user choose their time zone
Use that zone name or offset with date_default_timezone_set to set the default time zone used in date functions throughout the rest of script execution.
Use date('Z') to get that time zone's offset from GMT in seconds
Convert your stored date to a timestamp with strtotime -- UNIX timestamps are always GMT, so you now have the time in GMT.
Add the offset from step 3 to convert that time to the user's time zone.
Use date again to format the timestamp as a string in the desired display format.
Example:
$user_timezone = 'America/Los_Angeles';
$stored_time = '2011-01-30 18:23:49';
date_default_timezone_set($user_timezone);
$timestamp = strtotime($stored_time);
$local_timestamp = $timestamp + date('Z');
$local_date = date('Y-m-d H:i:s', $local_timestamp);
echo $local_date;

Here comes my solution. I tested it with America/Los_Angeles as the servers timezone, and my timezone as the users. I assume that the time is stored using the servers timezone.
<?php
// My (user) timezone
$user_timezone = 'Europe/Berlin';
// Server timezone
$stored_timezone = 'America/Los_Angeles';
// Date/Time stored in your DB, using timezone of the server (yours, that is)
$stored_datetime = '2011-01-29 22:40:00'; // this is the current time in L.A.
// Setting default to servers timezone if not done before
date_default_timezone_set($stored_timezone);
// converting to unix timestamp
$stored_timestamp = strtotime($stored_datetime);
// setting default to users timezone
date_default_timezone_set($user_timezone);
// converting to timestamp
$user_datetime = date('Y-m-d H:i:s', $stored_timestamp);
// setting default back to servers timezone
date_default_timezone_set($stored_timezone);
echo $user_datetime; // output is my current time

Related

Why is the difference between timestamp unix time and time() incorrect?

I'm trying do execute a php script with cron after 4 hours after saving an record in database. My problem here is not with cron, all here works fine(I'm sure of this because I'm receiving test mails from daemon cron every 4 hours as it should).
The problem is when I calculate the difference between the timestamp, converted to unix, and the current time and then execute some script.
But the diff bewtween these two times are adding 3 hours more to them and I don't know why but my script executes after 7 hours, instead of 4 hours. Can anyone help me please?
My code looks like this:
<?php
require_once('some-path/wp-load.php');
global $wpdb;
$constant= 4*3600;
$table = 'notifications';
$data = $wpdb->get_results("SELECT * FROM $table WHERE status = 'pending'");
$time = time();
foreach ($data as $r){
$temp_data = strtotime($r->date_created);
if ($time - $temp_data > $constant){
$email = $r->email;
$message = 'test';
$subject = 'test';
$headers = 'From: test <test#test.com>' . "\r\n";
$headers .= 'Content-type: text/html; charset=utf-8' . "\r\n";
$mail_client = wp_mail($email, $subject, $message, $headers);
if($mail_client){
$wpdb->update($tabel, array('status' => 'sent'), array('id_raport'=>$r->id_raport), array('%s'), array('%d'));
}
}
}
Example of date from database Using strtotime(): 1458814621, Directly from database "2016-03-24 10:17:01"
Now, I know I can do something like this to get the real localtime:
date_default_timezone_set('Europe/Bucharest');
$date = date('m/d/Y h:i:s a', time());
$time = strtotime($date);
Update.
But this returns the same thing as the time() method.
Now, I know I can do something like this to get the real localtime:
date_default_timezone_set('Europe/Bucharest');
$date = date('m/d/Y h:i:s a', time());
$time = strtotime($date);
A UNIX timestamp is not "local". A UNIX timestamp is the same all over the world. What you're doing in this code is merely converting a timestamp (time()) to a human readable format, and then reinterpreting it into a timestamp; the result is identical to the original time() value (or at least it should be!).
A human readable date/time format, such as you receive from MySQL (2016-03-24 10:17:01) is incomplete without a timezone. There are more than 24 different absolute points in time at which it is "2016-03-24 10:17:01" somewhere in the world. That timestamp by itself doesn't mean very much.
When you convert it into a UNIX timestamp using strtotime, it must take in additional information to convert such an ambiguous relative time format into an absolute point in time. That information comes from date_default_timezone_set, or whatever is set equivalently in your php.ini.
Your problem almost certainly just boils down to the timezone PHP assumes when doing strtotime not being the same timezone as what your MySQL datetime string is actually for. E.g., if your MySQL datetime expresses the time for UTC, but strtotime assumes Bucharest as the timezone to use, you'll see a difference of a few hours in the resulting absolute point in time.
Simply set/use the correct timezone in your PHP code; think about/be aware/decide on what timezone your MySQL dates are actually stored in.
Also see Does PHP time() return a GMT/UTC Timestamp?
The value returned by time() (a timestamp) is the number of seconds since Jan 1, 1970, 00:00:00 UTC. It is an absolute value.
The value you retrieve from the database (2016-03-24 10:17:01) is a relative value. It can represent different timestamps, depending on what time zone you use.
How to use the DateTime and DateTimeZone classes:
// Timestamp generated from PHP code
// Current time
$date1 = new DateTime(); // it uses the default timezone set in php.ini
// or by a previous call to date_default_timezone_set()
// be more specific
$date2 = new DateTime('now', new DateTimeZone('US/Eastern'));
// $date1 and $date2 represent the same moment in time ("now")
echo(($date1 == $date2) ? 'Yes' : 'No'); // It displays "Yes"
// Display them as timestamps
echo($date1->format('U')); // 1458816551
echo($date2->format('U')); // also 1458816551
// Display $date1 as human-readable format:
echo($date1->format('Y-m-d H:i:s e'));
// It displays: 2016-03-24 12:49:11 Europe/Bucharest
// Change $date1 to use the same timezone as $date2
$date1->setTimezone(new DateTimeZone('US/Eastern'));
echo($date1->format('Y-m-d H:i:s e'));
// Now it displays: 2016-03-24 06:49:11 US/Eastern
// It provides easy ways to generate another date:
$date3 = clone $date1; // create a duplicate
$date3->add(new DateInterval('P2D')); // modify the duplicate
// $date3 is 2 days in the future
echo($date3->format('Y-m-d H:i:s e'));
// It displays: 2016-03-26 06:49:11 US/Eastern
// Get the difference between $date3 and $date1
$diff = $date3->diff($date1)
// you get the difference in date components (days, hours, minutes etc).
print_r($diff);
A date-time value you extract from the database is incomplete. It lacks the timezone. If you stored the value in the database in the past then you should know what timezone it uses. If you get the datetime from the database using SELECT NOW() then the timezone is the default timezone used by the server. It is stored in the system_time_zone server variable and can be queried with SELECT ##system_time_zone
The query:
SELECT NOW() AS now, ##system_time_zone AS tz
returns the local date and time and the timezone used by the MySQL server.
You can use them to create a DateTime object to work with, as in the example code provided above.
As a general rule, always use a single time for the values you store as datetime in the database. I suggest using UTC because everything is relative to it and it doesn't observe DST. Or you can use columns of type TIMESTAMP instead (absolute timestamp do not care about timezones and DST) but they are more difficult to handle.

DateTime->format("U") doesn't return a value with timezone info

In PHP 5.2, I'm using the following code to get a timestamp from a DateTime object.
$dateTime = new DateTime("now", new DateTimeZone("America/Los_Angeles") );
echo $dateTime->format("U");
the problem is that format("U") simply returns server timestamp, which is UTC.
How do I make it to return a timestamp from Pacific Time Zone (Los Angeles) ?
Your concept for timestamp is not right, timestamp is timezone independent, it is defined as the number of seconds that have elapsed since midnight Coordinated Universal Time (UTC), 1 January 1970.
Try setting timezone at top of PHP script. I think timestamps are always UTC. Use date() function to format it into what you need.
// set timezone to pacific time
date_default_timezone_set('America/Los_Angeles');

epoch time conversion

how can I convert this epoch time to human readable date time
1331515367
I used the following code but this gives me the current time in my zone
$time = 1331515367
echo date('Y-m-d H:i:s', $time);
thannks
Dates generated on your server are going to be in whatever time zone your server says to use. If you want to change it use: http://php.net/manual/en/datetime.configuration.php
date.timezone ="timezone";
For a list of time zones: http://php.net/manual/en/timezones.php
All of this was found using this google search: php date timezone
https://www.google.com/search?sourceid=chrome&ie=UTF-8&q=php+date+timezone

How can I apply a timezone offset provided through JS?

Let's say I detect the users timezone offset with:
var tz = (new Date).getTimezoneOffset()/60;
and send the value of -5 to PHP, so:
<?php
date_default_timezone_set('UTC');
$tz = $_POST['tz']; // -5
$date = strtotime('now');
I want to store the timestamp as UTC in the database, but when displayed to the user I want to apply the timezone offset. So assuming $tz is -5 for EST, how can I apply it to the timestamp in order to display a date('M d Y H:i') in my local timezone ?
Bonus question: How can I have it show time for PST only? I assume by finding the PST offset and just specifying a hardcoded PST number to the equation that will be used in the original answer.

How to determine UTC offset from server timezone?

I've found many examples about UTC tables and php date methods to convert it, but I still miss a simple way after got server date, to converting it into an user timezone selection on my web page.
On this page http://vkham.com/UTC.html I've found a clear guide to understand the range, but I don't know how to connect for example "Europe/Rome" on the table, so there is something more clear about it?
I know the timezone of my server (America/Chicago) but I still don't know a way to change it from UTC method to a different timezone selected from the user machine (for example "Europe/Rome")
I tryied something, but I'still miss something, and i don't know what is it:
<?php
$timezone = date ("e");
$date = date ('Y-m-d H:i:s');
print $date." - this is my server date, and his timezone is - $timezone<br/>";
$user_timezone = "Europe/Rome"; // there is a way to convert Europe/Rome to UTC -13?
$selected_timezone = "-13"; // is -13 like Europe/Rome in all cases or only because my server is America/Chicago?
$date_user = date ("Y-m-d H:i:s $selected_timezone");
$str_date_user = strtotime ($date_user);
$new_user_date = date ('Y-m-d H:i:s', $str_date_user);
print $new_user_date . " - this is my server date, and his timezone is - $user_timezone";
?>
Doesn't exist a way to convert Europe/Rome to -13 for UTC timezone?
Is -13 like Europe/Rome in all cases or only because my server is America/Chicago?
You can use gmdate to generate a date that is displaying the UTC time - whatever timezone your server is running in. Then you can simply add the timezone difference as hours * 3600 to the timestamp you use for generating the date to get the user's time.
A different way would be setting the local time temporary to the user's timezone by using date_default_timezone_set.
A simple example for the first idea would be the following:
<?php
$offset = -13 * 3600; // timezone offset for UTC-13
$utcTime = gmdate( 'd.m.Y H:i' );
$userTime = gmdate( 'd.m.Y H:i', time() + $offset );
?>

Categories