PHP/MySQL randomly failed to parse the correct datetime - php

I'm getting an issue with datetime when inserting to the MySQL. I cannot tell if it was caused by PHP, Apache server or MySQL server which parsed the datetime to "1969-12-31 18:00:00". It happens vey randomly. While everyone has no problem insert the PHP date to MySQL, one or two users failed to get a proper datetime value from the same code. Those users are not consistent.
In PHP:
$thetime = date('Y-m-d H:i:s');
So, I guess there is nothing wrong with that line, unless the server returns the wrong datetime.
I'm using MyISAM. I also suspect MyISAM caused the problem if 2 clients inserting 2 records at the same time.
It could be Apache server is not doing its job properly. It might return the wrong datetime.
My question is that how I point out what caused the problem.

you can check the variables as recommended in here
mysql> show variables like 'date%format';
+-----------------+-------------------+
| Variable_name | Value |
+-----------------+-------------------+
| date_format | %Y-%m-%d |
| datetime_format | %Y-%m-%d %H:%i:%s |
+-----------------+-------------------+
2 rows in set (0.00 sec)
source: https://serverfault.com/questions/313400/datetime-format-changed-between-mysql-5-0-and-5-1

Related

Converting CURDATE() to my local date with MySQL

I'm using Godaddy's MySQL database. Since their timezone is MST UTC -7, I needed to modify my code. I figured out how to do it when using NOW() function. However Im struggling while converting result of CURDATE() to my local date. Topics in the website didnt help it. I dont have privilege to change timezone of mysql since it is shared host. The problem about CURDATE() is, since there is 10 hours difference between server and my country, dates will be different at somepoint.
What I have tried so far
First attempt
SELECT convert_tz(CURDATE(),'-07:00','+03:00')
this query returns following output in the mysql.
convert_tz(CURDATE(),'-07:00','+03:00')
2016-05-14 10:00:00
I didnt try yet since still dates are the same but this code probably done the work. But the problem is about the time comes after date.CURDATE should return only date. I think it returns the differences between two timezones which equals to 10 hours but I think it is gonna cause problem when Im comparing 2 dates.
Second attempt
SELECT convert_tz(CURDATE(),'MST','EEST');
Since server's timezone is MST and my timezone is EEST, I tried in this way but it returns NULL.
The question is what should I do to just return date without that 10:00:00 there. or is there any better way?
There are a couple of problems with your approach.
First, CURDATE() returns a date, not a datetime.
Second, you need to convert the current date and time from the server's time zone to your time zone before truncating the time portion. This means using NOW() inside, not CURDATE().
Third, you need to use the correct abbreviations for the correct time zones for both sides of the conversion, for the entire year. CONVERT_TZ() will return NULL if either time zone is unrecognized.
In this case, MST/MDT is called "MST7MDT" and EET/EEST is called "EET" in the MySQL time zone tables. It's surprising that Go Daddy doesn't set their server clocks to UTC -- that's sort of a de facto standard for server clocks, but assuming not, "MST7MDT" is probably the most correct value.
mysql> SELECT DATE(CONVERT_TZ(NOW(),'MST7MDT','EET'));
+-----------------------------------------+
| DATE(CONVERT_TZ(NOW(),'MST7MDT','EET')) |
+-----------------------------------------+
| 2016-05-14 |
+-----------------------------------------+
1 row in set (0.00 sec)
Or, you could use the more intuitive localized names for the time zones. I believe these values would also be correct, an would accommodate summer and time changes correctly:
mysql> SELECT DATE(CONVERT_TZ(NOW(),'America/Denver','Europe/Bucharest'));
+-------------------------------------------------------------+
| DATE(CONVERT_TZ(NOW(),'America/Denver','Europe/Bucharest')) |
+-------------------------------------------------------------+
| 2016-05-14 |
+-------------------------------------------------------------+
1 row in set (0.00 sec)
Try to convert you date into string using CAST, and then get a substring.
SELECT SUBSTRING_INDEX( CAST(CONVERT_TZ(CURDATE(),'-07:00','+03:00') AS char), ':', -1)
Should return
2016-05-14 10:00

converting UTC to local time automatically using PHP

Im using MySQL with PHP, and the project is a kind of notification manager
if some one does some thing, a new notification need to be posted in the common post-ground
the issue is - we have users from multiple timezones, currently Im using "datetime" as the field type, so what ever I enter converts into UTC
for example: Im from India(+5:30) and if I create a notification at 21/3/2015 22:50:00, it is saving in DB as 21/3/2015 17:20:00
storing works perfectly well from all zones, but while retrieving it shows for me as 21/3/2015 17:20:00(UTC) but Im expecting in my timezone(IST +5:30) so what Im expecting is 21/3/2015 22:50:00.
is there a way to mention in the query itself to get the time converted in the fetching itself?
or any other way to convert and process further?
any help on this is greatly appreciated.
Thank you
You can use the function convert_tz so while selecting you can use the following
mysql> select convert_tz('2015-03-21 17:20:00','+00:00','+05:30') as ist_time;
+---------------------+
| ist_time |
+---------------------+
| 2015-03-21 22:50:00 |
+---------------------+
1 row in set (0.00 sec)
All you need to do is to change the hard coded date '2015-03-21 17:20:00' to your column name in the selection.
You can get your client TimeZone through JSTZ
In your php file, you can simply convert the date after you received the from mysql:
$date = new DateTime($date . " " . "UTC");
$date->setTimezone(new DateTimeZone($timeZoneTo));//$timeZoneTo you get it from JSTZ

Why date stored in MySQL is all wrong?

I am building a PHP to MySQL webpage and I didn't notice it until now. My date from form field which is posted to PHP script is sent to MySQL table for storage. Even though in the date field within the form is being displayed correctly and POST date value is verified to be exact, it is not going into my MySQL table correctly. For some odd reason, the year is 2006 not 2012. However, the time is correct.
Here is my Form date field:
<input type=text id="date" name="srdate" value=<?php echo date("m/d/y"); ?>
Date Column in my MySQL table is of TYPE DATE.
I did check the date stored in my table and it has wrong date not year 2012 but 2006.
Any Idea,
MySQL's only acceptable date input format is YYYY-MM-DD HH:MM:SS. The date you're generating in PHP will look like (for today) 06/12/12 which MySQL will try to parse, but see as 12th December, 2006, and not the actual June 12/2012.
As well, note that your code is gaping wide open for SQL injection attacks. Read up and learn how to prevent those before you go ANY FARTHER with this code. Otherwise your server is going to get pwn3d.
You need to use the yyyy-mm-dd syntax.
While I'd expect MySQL to throw an error when trying to insert 06/12/12 it apparently parses it as 2006-12-12:
mysql> SELECT cast('06/12/12' as date);
+--------------------------+
| cast('06/12/12' as date) |
+--------------------------+
| 2006-12-12 |
+--------------------------+
1 row in set (0.00 sec)
mysql> SELECT cast('2012-06-12' as date);
+----------------------------+
| cast('2012-06-12' as date) |
+----------------------------+
| 2012-06-12 |
+----------------------------+
1 row in set (0.00 sec)
From the manual:
Although MySQL tries to interpret values in several formats, date parts must always be given in year-month-day order (for example, '98-09-04'), rather than in the month-day-year or day-month-year orders commonly used elsewhere (for example, '09-04-98', '04-09-98').

Weird strtotime Conversion of MySQL timestamp

I have a MySQL field that gives me timestamp in the format: YYYY-MM-DD HH:MM:SS. The default is CURRENT_TIMESTAMP. Now, when I try to convert it to Unix timestamp, I get some weird results.
Actually, I am using this function to calculate relative time. It outputs negative integers even though MySQL timestamp is only a couple of seconds older. I am at a loss as to what's wrong.
I also found some weird issues. For example, in MySQL,
mysql> select from_unixtime(1289206455);
+---------------------------+
| from_unixtime(1289206455) |
+---------------------------+
| 2010-11-08 14:24:15 |
+---------------------------+
1 row in set (0.03 sec)
In PHP CLI:
php -r "echo date('Y-m-d h:m:s', 1289206455);"
2010-11-08 09:11:15
The supposed output (in both cases) should be: 2010-11-08 02:54:15 source.
So there seems to be a difference in times in PHP and MySQL. How can I sync them? I am on Ubuntu 11.04 XAMPP.
Thanks
You need to set the timezone.
date_default_timezone_set($zone);
http://php.net/manual/en/function.date-default-timezone-set.php
MySQL: http://dev.mysql.com/doc/refman/5.5/en/server-system-variables.html#sysvar_time_zone (#Idg thanks)

Storing datetime as UTC in PHP/MySQL

Everywhere I read about converting time to a user's timezone says that the best method is to store a date and time in UTC then just add the user's timezone offset to this time.
How can I store a date in UTC time? I use the MySQL DATETIME field.
When adding a new record to MySQL in my PHP code I would use now() to insert into MySQL DATETIME.
Would I need to use something different than now() to store UTC time?
MySQL: UTC_TIMESTAMP()
Returns the current UTC date and time
as a value in 'YYYY-MM-DD HH:MM:SS' or
YYYYMMDDHHMMSS.uuuuuu format,
depending on whether the function is
used in a string or numeric context
PHP: gmdate()
Also PHP date_default_timezone_set() is used in PHP to set the current time zone for the script. You can set it to the client time zone so all the formatting functions return the time in his local time.
In truth though I had a hard time getting this to work and always stumble into some gotcha. Eg. time information returned from MySQL is not formatted as 'UTC' so strtotime transforms it into a local time if you are not careful. I'm curious to hear if someone has a reliable solution for this problem, one that doesn't break when dates traverse media boundaries (HTTP->PHP->MySQL and MySQL->PHP->HTTP), also considering XML and RSS/Atom.
I would suggest inserting the date in UTC time zone. This will save you a lot of headaches in the future with daylight saving problems.
INSERT INTO abc_table (registrationtime) VALUES (UTC_TIMESTAMP())
When I query my data I use the following PHP script:
<?php
while($row = mysql_fetch_array($registration)) {
$dt_obj = new DateTime($row['message_sent_timestamp'] ." UTC");
$dt_obj->setTimezone(new DateTimeZone('Europe/Istanbul'));
echo $formatted_date_long=date_format($dt_obj, 'Y-m-d H:i:s');
}
?>
You can replace the DateTimeZone value with one of the available PHP timezones.
NOW() gives you the time (including the timezone offset) of the system running your database. To get UTC date/time you should use UTC_TIMESTAMP() as described in the MySQL Reference Manual.
https://dba.stackexchange.com/questions/20217/mysql-set-utc-time-as-default-timestamp
Quoting all the answer from above link in case of delete:
To go along with #ypercube's comment that CURRENT_TIMESTAMP is stored as UTC but retrieved as the current timezone, you can affect your server's timezone setting with the --default_time_zone option for retrieval. This allows your retrieval to always be in UTC.
By default, the option is 'SYSTEM' which is how your system time zone is set (which may or may not be UTC!):
mysql> SELECT ##global.time_zone, ##session.time_zone;
+--------------------+---------------------+
| ##global.time_zone | ##session.time_zone |
+--------------------+---------------------+
| SYSTEM | SYSTEM |
+--------------------+---------------------+
1 row in set (0.00 sec)
mysql> SELECT CURRENT_TIMESTAMP();
+---------------------+
| CURRENT_TIMESTAMP() |
+---------------------+
| 2012-09-25 16:28:45 |
+---------------------+
1 row in set (0.00 sec)
You can set this dynamically:
mysql> SET ##session.time_zone='+00:00';
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT ##global.time_zone, ##session.time_zone;
+--------------------+---------------------+
| ##global.time_zone | ##session.time_zone |
+--------------------+---------------------+
| SYSTEM | +00:00 |
+--------------------+---------------------+
1 row in set (0.00 sec)
Or permanently in your my.cnf:
[mysqld]
**other variables**
default_time_zone='+00:00'
Restart your server, and you will see the change:
mysql> SELECT ##global.time_zone, ##session.time_zone;
+--------------------+---------------------+
| ##global.time_zone | ##session.time_zone |
+--------------------+---------------------+
| +00:00 | +00:00 |
+--------------------+---------------------+
1 row in set (0.00 sec)
mysql> SELECT CURRENT_TIMESTAMP();
+---------------------+
| CURRENT_TIMESTAMP() |
+---------------------+
| 2012-09-25 20:27:50 |
+---------------------+
1 row in set (0.01 sec)
As #Haluk suggests, you can store the date as a UTC datetime .
I'm complementing his answer for situations when the date you want to insert comes from PHP code, and adding some details about how it works :
$pdo = new PDO('mysql:host=mydbname.mysql.db;dbname=mydbname', 'myusername', 'mypassword');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$insertStmt = $pdo->prepare("insert into test (last_modified)"
." values(:last_modified)");
$insertStmt->bindParam(':last_modified', $lastModified, PDO::PARAM_STR);
$lastModified = gmdate("Y-m-d H:i:s");
$insertStmt->execute();
Actually datetime in PHP doesn't have a timezone associated to it. What is passed to PDO is just a string, in one of the formats recognized by MySQL, representing the date in UTC timezone. For example if the date is 2015-10-21 19:32:33 UTC+2:00, the code above just tells MySQL to insert 2015-10-21 17:32:33. gmtdate("Y-m-d H:i:s") gives you the current date in such a format. In any case, all you need to do is build the string representing the date you want to insert in UTC time.
Then, when you read the date, you have to tell PHP that the timezone of the date you just retrieved is UTC. Use the code in Haluk's answer for this.
Random: UTC_TIMESTAMP(6) for time with 6 digits of microseconds.
MySQL 5.7+
As per (https://dev.mysql.com/doc/refman/8.0/en/time-zone-support.html) set the timezone upon connection:
SET TIME_ZONE = 'UTC';
After that all datetime functions should be in UTC.
Refrain from using TIMESTAMP() it is not Y2038 save.

Categories