Formatting MySQL / Server timestamp with php? - php

I have a created a timestamp in MySQL that changes when an account is updated by a users, and this timestamp is echoed on the page. However it is displaying the server time rather than my local time. I can't set the timezone in MySQL, I tried. What is another way to change this, and how can it be implemented?

The problem with timestamp datatype is that
MySQL converts TIMESTAMP values from the current time zone to UTC for
storage, and back from UTC to the current time zone for retrieval.
(This does not occur for other types such as DATETIME.) By default,
the current time zone for each connection is the server's time. The
time zone can be set on a per-connection basis. As long as the time
zone setting remains constant, you get back the same value you store.
If you store a TIMESTAMP value, and then change the time zone and
retrieve the value, the retrieved value is different from the value
you stored.
So, it does not really matter what your timezone setting in php is, you need to set either mysql's timezone on a session basis using
SET time_zone = timezone
command, or you need to store the timezone of the client along with the timestamp and adjus the value based on the stored timezone. I would use the latter approach, since a client technically can change timezones and if the client access the timestamp data from a different timezone, then different data will be returned by mysql.

When echoing from a database add in some "filters" seemed to do the trick
<?php echo $row['field name']; strtotime(date("Y-m-d", 1310571061)); ?>
Without the above code it displayed the timestamp as: 2016-02-09 00:00:00
With the above code it displays thus: Tuesday, February 09, 2016

Related

Any disadvantage using SET time_zone in MySQL PHP

I am using timestamp fields in my databases and my PHP software has its own time management system based on users timezone. I want to use timestamp fields for certain kind of data (created or modified when) and also be able to use te DEFAULT CURRENT_TIMESTAMP for the columns.
Is there any disadvantage setting the timezone to UTC using, SET time_zone = '+00:00', each time the session is created. I have four separate databases which the software uses and currently, I am setting the current timezone to UTC.
I don't want to use DATETIME as they are larger in size and also I won't be able to use DEFAULT CURRENT_TIMESTAMP as the timezone of the server might have an offset.
You should not use SET time_zone if your backend already uses all the logic into converting user's timezone correctly, because you're wasting resources unnecessarily. The UTC timezone should be into the metadata of the DB, where always the DB transactions will work with them.
By the way, TIMESTAMP columns always will be stored in UTC, so you don't need to setting that, unless your columns are datetime (not the case, i think).
When you insert a TIMESTAMP value, MySQL converts it from your
connection’s time zone to UTC for storage. When you query a TIMESTAMP
value, MySQL converts the UTC value back to your connection’s time
zone. Notice that this conversion does not occur for other temporal
data types such as DATETIME.
So you have two options:
Set the timezone in your transactions working with time in your sql;
Working with unix timezones into backend and only showing the correct converted time in the frontend to user.
I prefer the second one.
When dealing with date/time for entry date and/or modified date, it is better to use normal VARCHAR with the length of around 200 (or any other value that fits the full date) in order to store the full date and process your date/time in your PHP script. This gives you the flexibility to view your time based on the timezone defined in your PHP code. Click here to see available timezones in PHP.
You can also format the date/time in any possible format you want by simply using the date_format of PHP.
I have given a reference code below.
//This is the way you define your timezone in PHP code
date_default_timezone_set('Asia/Beirut');
//You can capture the date/time by using the below code. This will store "2017-05-28 23:55:34"
$date_time_registered = date('Y-m-d H:i:s');
//Retrieve the date/time and re-format it as you require. Below code will output "May", full month.
$retrieve_month_only = date_create($row['your_store_date_time']);
$retrieve_month_formatted = date_format($retrieve_month_only, 'F');
echo $retrieve_month_formatted;
You can refer to this link to find out about PHP date/time formatting.

How can i insert real time of an event into database using php mysqli?

I'm trying to add datetime for check record changes. I'm using datetime datatype in table.
`date_added` datetime DEFAULT '0000-00-00 00:00:00',
I use following php built-in function using for datetime column in the query
date("Y-m-d H:i:s");
Problem is that this function date("Y-m-d H:i:s"); giving me two different date and time when i check in same time on server.
Localhost Result
date("Y-m-d H:i:s"); == 2016-07-12 13:10:04
Server Result
date("Y-m-d H:i:s"); == 2016-07-12 05:08:07
So when i use TimeAgo function on date_added column it is giving me wrong time, I mean the server time. For example I add a record then function will return me Record Added 8 Hours Ago so its totally wrong. I would like to know how can i add real time of an event into database that i can show using TimeAgo() function.
Is there any way to do that without change the server timezone, because if I change the timezone then it will be showing correct time only for those who are in the same region but what will be get others? I think they will face same issue.
I wanted to develop something like Facebook DateTime Functionality.
Can any one guide me how can I achieve this kind functionality? I would like to appreciate. Thank You
Instead of fiddling with timezones, why not just do
ALTER TABLE `your_table`
CHANGE `date_added` `date_added`
TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
This will change your column from a DATE column to a TIMESTAMP column, converting all the dates to their respective UTC timestamps in the process.
When a new row is inserted, it will use the current timestamp as a value. Timestamps are always in UTC, so you don't have to change the timezone on your MySql server, nor supply the date when inserting a new row.
If you cannot or want not change your columns, you can also just select the timestamp via
SELECT UNIX_TIMESTAMP('date_added') FROM your_table;
For your TimeAgo, you can then just do
$now = new DateTime;
$dateAdded = new DateTime("#$yourTimestampFromDb");
$dateAdded->setTimezone($now->getTimezone());
$timeSinceAdded = $dateAdded->diff($now);
When you supply a timestamp to DateTime, it will always use UTC regardless of your default server timezone set. Consequently, you have to either convert $dateAdded to the default timezone (as shown above) or convert $timeSinceAdded to UTC.
To change the dateTime to the currently visiting user's timezone, you either
need to have this information in your database, e.g. because you are asking registered users to supply this information
or you determine it at runtime, usually by doing a GeoIP lookup on the visiting user's IP or by sending the DateTime Offset from the user's browser.
In any case, you then just change both DateTimes to that timezone. This is easily done via setTimezone().
The $timeSinceAdded will then be a DateInterval object, which you can use like this
echo $timeSinceAdded->format('%a total days');
Please refer to the links for further details, for instance on the available format modifiers.
If you're accessing the same database server from clients with different timezone settings, you could also insert and check the date/time fields in sql:
INSERT INTO my_table SET date_added = NOW();
and then also check with something like
SELECT * FROM my_table WHERE TIMESTAMPDIFF(SECOND, date_added, NOW()) > 3600;
to select rows that are older than 1 hour.
Your question is a bit ambiguous but i'll try to explain a workaround that i think should fix this issues.
If you allow other users to add or update your database then, you should be having some information about them, like which city/continent they are coming from. You might also have telephone contacts and more about them.
If it is true that you possess such information about your users in your database then use that information to detect and load their timezone when they log into your system.
You can have a table with all the timezones or create an array that will hold all the known timezones so that when you call
date_default_timezone_set('continent/city')
function you can dynamically change the parameters to suit the current users timezone and later use that to affect date added field.
Problem
TimeAgo/nicetime function uses strtotime() to convert your datetime field value to unix timestamp. You receive a number of seconds since January 1 1970 00:00:00 UTC until the date you passed as a string. Then time() function returns the number of seconds until now, and nicetime compares the difference. The problem is in strtotime, when we send to it the text like "2016-07-12 05:08:07", it has no idea what time zone that is in and how it should be converted to UTC, so it uses the best guess, often incorrect.
Quick Solution
Specify the time zone of your date that you pass into nicetime() function. Instead of doing this:
$date = '2016-07-04 17:45'; // get from database
print nicedate($date);
try this:
$date = '2016-07-04 17:45';
print nicedate($date . ' America/Denver');
// mind the gap --------^
That should fix it.
Before one blindly goes ahead and starts comparing times, or performing date / time calculations on values retrieved from a database, it is essential that we understand the individual database's configuration settings to ensure our calculations are correct.
It should be noted that the MySQL timezone variable's default setting is SYSTEM at MySQL startup. The SYSTEM value is obtained from the the operating system's GLOBAL time_zone environment variable.
MySQL's default timezone variable can be initialised to a different value at start-up by providing the following command line option:
--default-time-zone=timezone
Alternatively, if you are supplying the value in an options file, you should use the following syntax to set the variable:
--default-time-zone='timezone'
If you are a MySQL SUPER user, you can set the SYSTEM time_zone variable at runtime from the MYSQL> prompt using the following syntax:
SET GLOBAL time_zone=timezone;
MySQL also supports individual SESSION timezone values which defaults to the GLOBAL time_zone environment variable value. To change the session timezone value during a SESSION, use the following syntax:
SET time_zone=timezone;
In order to interrogate the existing MYSQL timezone setting values, you can execute the following SQL to obtain these values:
SELECT ##global.time_zone, ##session.time_zone;
It should be noted also that:
The current session time zone setting affects display and storage of time values that are zone-sensitive. This includes the values displayed by functions such as NOW() or CURTIME(), and values stored in and retrieved from TIMESTAMP columns. Values for TIMESTAMP columns are converted from the current time zone to UTC for storage, and from UTC to the current client time zone for retrieval.
To obtain values in UTC time, use the UTC_DATE(), UTC_TIME() or UTC_TIMESTAMP() functions instead. To convert to another time zone, pass the value of the appropriate UTC function return to convert_tz(), which requires the zoneinfo tables to be generated (see below).
In your circumstances, if you DO NOT want to / CAN NOT change the SERVER time_zone value, you will have to explicitly set the individual SESSION timezone values for each client connection which will enable you to draw a line in the sand and have a known base from which you can convert and display a facebook user's post time into a viewer's local timezone.
To explicitly set the session timezone when connecting, issue the following command:
SET SESSION time_zone = '+10:00';
When you explicitly set the SESSION time_zone, and store a TIMESTAMP value, the server converts it from the client's time_zone to UTC and stores the UTC value (Internally the server stores a TIMESTAMP value). When you select data from the database, the opposite conversion takes place and provides the client with a UTC time in the client's timezone.
On the topic of data types and time zone's, in PHP you are better off using the DatTimeZone class if you would like to improve the accuracy of your date and time values by facilitating daylight saving aware dates and times.
As noted earlier, if your database is MySQL, you can load / generate the zoneinfo tables with the following command:
mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -u root mysql
* where root is the username to be substituted.
Performing the generation of the zoneinfo tables allows you to use the convert_tz() function which accurately converts dates and times from one time zone to another, like so:
select DATE_FORMAT(convert_tz(now(), 'UTC', 'Australia/Perth'), '%e/%c/%Y %H:%i') AS PERTH_TIME;
PERTH_TIME;
+-----------------+
| PERTH_TIME |
+-----------------+
| 19/7/2016 19:42 |
+-----------------+
Additionally, you can generate an array of UTC time zones programmatically by calling the static function listIdentifiers() in the PHP DateTimeZone class.
May the force be with you.

PHP, MySQL - How to display correct time of posted artical depends of client timezone

I'm working on some website (news portal) in PHP and MySQL. I have a rubric last post with time when news are posted. My timezone and server timezone is GMT+2. I want to display a time correctly to all clients from all time zones. Example, if news is posted at 13:05 at my timezone to display for clients from GMT+3 14:05, for clients from GMT+4 zone 15:05, for GMT+1 12:05, and so on. How to do that? What is solution and what is a best way to store date and time in MySQL database for that purpose? I'm also integrate Carbon in my website but I can't find method for that.
What we do in our company is we store all times in GMT. Even though we are in South-Africa. Then based on the user's location we convert the time to display correctly. There are a number of ways to determine where a user is located and convert the time, however the easiest method is to just ask them where they live and store that information.
Keep dates in timestamp.
Store timezones for all clients.
After establishing connection to database run query like that:
SET ##session.time_zone = "+02:00";
or
SET ##session.time_zone = "Europe/Warsaw";
Where timezone offset or name is value stored for client.
All timestamp values will be returned from queries in defined timezone.
While storing values in db store in UTC timezone something like below
date_default_timezone_set('UTC');
Then while displaying the values get the user timezone using any timezone js and send the timezone to server using ajax and store it in SESSION variable and while displayin the date add that timezone.
For example
1)Download the timezone js from https://bitbucket.org/pellepim/jstimezonedetect/src
Following will give you the timezone
var tz = jstz.determine(); // Determines the time zone of the browser client
var timezone=tz.name(); // Returns the name of the time zone eg "Europe/Berlin"
Make ajax call like below
$.post("scripts/set_timezone.php", { timezone: timezone} );
and in set_timezone.php have code
session_start();
$_SESSION['user_timezone'] = $_POST['timezone'];
and while displaying display as follows
$date = new DateTime('2012-01-23 05:00:00', new DateTimeZone('UTC'));
$date->setTimezone(new DateTimeZone($_SESSION['user_timezone']));//This will from the session e.g Asia/Kolkata
$time= $date->format('Y-m-d H:i:s');

Convert UTC timestamp from database into Users Local time

Question: How do I Display a UTC timestamp from a database table in a users local time? Is there any way to do this with php?
Extra Context \/
I have an application that saves the date records are added to the database.I am saving the records in the database using mysql UTC_TIMESTAMP(). I then want to display the record to the user in their local time in my Smarty template.
{$dateAdded|smarty_modifier:"%D %R %Z"}
I have tried smarty, date_format as the modifier but I just get the UTC time and the persons timezone, which of course is correct but not the result that I want.
02/11/11 20:32 Pacific Standard Time
I need the time so be set to the user's local time
02/11/11 12:32 Pacific Standard Time
Is it correct to store the date of the transaction in UTC, and how do I display that UTC to the user in their local time? Is there a way to pull the date out of the database so that it is set to the users current local time?
You can use date_default_timezone_set() prior invoking the Smarty template. That defines directly how the UTC timestamps are adapted to the expected output timezone.

TIMESTAMP vs. DATETIME for `created` and `updated` columns

I'm using PHP/MySQL and I've always used DATETIME to store created and updated values, but I'm thinking there may be a better way.
Should I be using TIMESTAMP instead, and if so, why?
The documentation states:
TIMESTAMP values are converted from the current time zone to UTC for storage, and converted back from UTC to the current time zone for retrieval. (This occurs only for the TIMESTAMP data type, not for other types such as DATETIME.) By default, the current time zone for each connection is the server's time. The time zone can be set on a per-connection basis, as described in Section 9.6, “MySQL Server Time Zone Support”. As long as the time zone setting remains constant, you get back the same value you store. If you store a TIMESTAMP value, and then change the time zone and retrieve the value, the retrieved value is different from the value you stored. This occurs because the same time zone was not used for conversion in both directions. The current time zone is available as the value of the time_zone system variable.
So you may want to use TIMESTAMP if you want your date/time stored in UTC instead of in the current time zone.
Timestamps are stored in UTC time in the database. Then, depending on your timezone setting, any time you fetch it it will automatically adjust the offset appropriately. If you are concerned with setting timezones for your application then definitely go with Timestamps.

Categories