How to convert now() into GMT +8 before insert into mysql - php

This is my sql to insert current time when a request password is made.
$stmt2 = $pdo->prepare('UPDATE authsessions SET reset_req=now(), reset_req_uuid=:reset_uuid WHERE useruuid=:user_id');
This causes a confusion because it follows the server's timezone to insert the time.
Therefore in my localhost, it inserts Asia/Kuala Lumpur time as I declared it in the page.But in the amazon server which I believe GMT it inserts accordingly. But I want to enforce it to insert time as in Asia/Kuala Lumpur.It's because the site meant to be used within Malaysia and there's no point using GMT time.
How do I make now() to convert to GMT 8+ before inserting, please?

You can convert the timezone in the statement using CONVERT_TZ (see MySQL manual).

First of all it depends on the MySQL field you are using. If you're using TIMESTAMP field it will be stored as UTC timestamp in the database. This is the most easy one, because your php connection will use the timezone of your local server. In this way you don't have to convert any timezone issues.
If you are using DATETIME field it will store the time as it is. Mysql NOW() will use the database timezone setting and you can override the setting when you connect with:
SET time_zone = '+08:00';
The other option you have is to handle the Timezone from PHP. Example:
$now = new DateTime('NOW', new DateTimeZone('Asia/Kuala_Lumpur'));
$stmt2 = $pdo->prepare('UPDATE authsessions SET reset_req=:now, reset_req_uuid=:reset_uuid WHERE useruuid=:user_id');
$stmt2->bindParam(':now', $now->format('Y-m-d H:i:s');

Related

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.

Timezone conflict between PHP and Mysql server

I have an issue with the date creation. The php server settings for timezone :
by using the date_default_timezone_get() php function, refers to UTC whereas the MSQL query for timezone i.e ##system_time_zone is referring to MST. It is a shared server, so I will not be able to make changes in the my.conf file on the server.
I want the date to be in UTC format, How do I go about making changes on the mysql server so that the Now() function and CURRENT_TIMESTAMP returns date values wrt UTC.
If I understood you right you can try and set a timezone per session from client code
SET time_zone = timezone;
Depending on whether you have timezone info imported or not it may look like
SET time_zone = 'Etc/UTC';
or
SET time_zone = '+00:00';
Further reading:
MySQL Server Time Zone Support
Try fetching date from mysql query using UTC_TIMESTAMP() instead of NOW(), UTC_TIMESTAMP() will give you date in UTC.

Modify TIMESTAMP to reflect correct TIMEZONE

So I am trying submit a timestamp into my MySQL table. It is doing it successfully using this line of code, however the time zone is incorrect. Anybody have ideas as to what needs to happen to ensure the timestamp is updated to reflect America/New York?
<input type="hidden" name="hiddenField" id="hiddenField" value=<?php $query = "UPDATE ApparatusTrouble SET _submitted_ = CURRENT_TIMESTAMP ";
Don't try to control the timezone as it's stored in the database. The timestamp will be the current time in UTC, which is to say that it's a globally understood and timezone-independent timestamp.
If you want to display the time as being in New York time, that's a question for your display logic: retrieve the UTC timestamp from the database, then convert it to New York time and display it.
TIMESTAMP storing without timezone, timezone applying by mysql server when you retriving data from Mysql, so you need properly set timezone for you mysql connection like this,
SET time_zone = 'Europe/Helsinki';
SET time_zone = "+00:00";
SET ##session.time_zone = "+00:00";
Better practice is set +00:00 for connection, and after aplying timezone on client in begin php script for example
I'd recommend using PHP to generate the timestamp if you could I would stick to using UTC (it avoids time zone confusion).
Also, the way you're doing it the client could modify the form data and submit the SQL which is not the safest way to design your code (in case you didn't know).
Also, if you generate a timestamp while PHP is processing and load it into a hidden form variable it's going to have the date of when PHP processed the form and not the time that the form was submitted.
IE.
Somewhere in the submitted form action in PHP...
<?php
...
date_default_timezone_set('UTC'); //Available since PHP 5.1
//see php date manual (http://php.net/manual/en/function.date.php)
// not sure what format CURRENT_TIMESTAMP is set to in your SQL server
$now = date("Y-m-d H:i:s", time());
$query = 'UPDATE ApparatusTrouble SET _submitted_ = ' . $now . ';';
...
?>

PHP use CURRENT_TIMESTAMP from eastern time zone

I have a query that looks like:
$query = "INSERT INTO `SmsServ`.`SmsReceived` (
`Id` ,
`Body` ,
`DateReceived`
)
VALUES ( NULL , "Foo" , CURRENT_TIMESTAMP);"
The problem with that query is that I will like to have eastern time as the time stamp. I have tried calling:
date_default_timezone_set("America/New_York");
At the begining of my php script but that still gives an incorrect time stamp.
You did change the php time zone. So try to change the mysql time zone aswell(php and mysql time default zones differs from each other):
mysql> SET GLOBAL time_zone = 'America/New_York';
mysql> SET SESSION time_zone = 'America/New_York';
CURRENT_TIMESTAMP in this case is not generated by PHP, but by MySQL. Your query is asking MySQL to set the current timestamp based on MySQL's server time. As such you would need to configure MySQL to use the eastern time zone, not PHP.
One thing you might consider is to just use GMT for database timestamps and do timezone and daylight savings conversions in the application. That way you don't potentially have the issue of mixed zone timestamps in the database. Of course, if you don't think you would ever have need to use anything other than Eastern time zone in your app, then this might not be important for you.
Mysql is not concerned about which timezone is using ..
As per documentation you can set the timezone to be used....if you are using MySQL 4.1.3 or +
SET GLOBAL time_zone = timezone
or
SET time_zone = timezone
NOTE : TIMEZONE settings are not populated by default. You need to populate the tables related to timezones under `mysql database . oNly after the settings you can set the timezone.

Converting Server MySQL TimeStamp To UTC

I've been using the timeago plugin (http://timeago.yarp.com/), it has been working fine on my localhost, which has its MySQL storing its data in the UTC timestamp, which the plugin needs to work.
However, when uploading my project to the server, a different type of timestamp is appearing in it MySQL database. I'm getting a timestamp like this: "Thursday, February 24, 2011 4:29 PM" from the server, whereas I need something like this: "2008-07-17T09:24:17Z"
Any idea how to convert the timestamps using php?
Edit: The timestamps stored in the wrong format in the database are automatically generated by mysql.
Edit 2: It's a field of type "timestamp" and default set to "CURRENT_TIMESTAMP" when row is being inserted in db
You are getting a weird string for MySQL, are you sure that it is in a Datetime field?
You can get a UNIX timestamp (seconds since epoch) from MySQL with the following function, this format is widely accepted over multiple platforms:
SELECT UNIX_TIMESTAMP( table.datetime_field ) as datetime_field FROM table
Using some PHP Functions you can convert this to the format you desire:
echo date( 'c', $record[ 'datetime_field' ] );
I think this would be sufficient for your problem.
SELECT UNIX_TIMESTAMP('your_date') AS your_date; in a query and
$date('whatever_format', $timestamp_from_mysql); in php
Internally a MySQL timestamp column is stored as UTC but when selecting a date MySQL will automatically convert it to the current session timezone.
When storing a date, MySQL will assume that the date is in the current session timezone and convert it to UTC for storage.
To select a timestamp column in UTC format
no matter what timezone the current MySQL session is in:
SELECT
CONVERT_TZ(`timestamp_field`, ##session.time_zone, '+00:00') AS `utc_datetime`
FROM `table_name`
You can also set the sever or global or current session timezone to UTC and then select the timestamp like so:
SELECT `timestamp_field` FROM `table_name`
I made a cheatsheet here: Should MySQL have its timezone set to UTC?
php code
<?php
$pdo = new \PDO($yourconnectionstring);
$sql = "SELECT
CONVERT_TZ(`timestamp_field`, ##session.time_zone, '+00:00') AS `utc_datetime`
FROM `table_name`";
$stmt = $pdo->prepare($sql);
$stmt->exec();
$timeVal = $stmt->fetchColumn();
if isset($timeVal) {
$dt = new \DateTimeImmutable($timeVal, new \DateTimeZone('UTC'));
echo $dt->format(\DateTime::ATOM);
}

Categories