Why date stored in MySQL is all wrong? - php

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').

Related

php mysql UTC timestamp

I'm in the early stage of building a mysql table that will hold data from two timezones. Both my machine and the server are in the America/Los_Angeles time zone. The timezone table is not loaded in the mysql server, but elsewhere on this site, I've read this is not necessary as long as php handles the queries - php will write the UTC offset to mysql. Mysql datatype is TIMESTAMP. Sample data has been inserted with a php script that includes the following statement:
if($company == 'HOS_CIN' or $company == 'HOS_FER') {
date_default_timezone_set("America/New_York");
}
Then two php scripts were used to display the data in a browser. One included the above statement and one did not. The one with the statement displayed the time as noon EST, and the one without displayed the time as noon PST. If mysql had stored the UTC offset, shouldn't there have been a three-hour difference in the times displayed?
Php version 5.3.3, mysql version 5.0.95
You have to face the following limits regarding PHP and MySQL:
MySQL does not have any column type that allows to store a local time with time zone information.
PHP cannot pass complex data types (such as DateTime instances) to MySQL, everything needs to be stringified, and MySQL doesn't have a syntax to pass a date literal with time zone information.
In practice it isn't as bad as it may seem because you don't normally need the local time of the user who inserted the information: you just need to know the exact moment in time the stored date refers to and (optionally) the time zone in which the stored date has to be displayed. And there're basically three sensible ways to do so:
Use a format that's unaffected by time zones, e.g. a Unix timestamp stored as INT.
Use a date column type with explicit time zone information, e.g. a TIMESTAMP column (not to be confused with Unix timestamps) where time zone is always UTC.
Use a date column type with implicit time zone information, e.g. a DATE or DATETIME column where you have decided that all dates belong to a given time zone, possibly UTC.
The difference between #2 and #3 is whether MySQL is aware of the time zone or it's something only you and your code know.
Whatever approach you chose, it's necessary that all the programs that are expected to do time zone conversions are instructed about what time zone to use:
PHP needs the time zone to generate/display Unix timestamps and to convert from/to the local time typed/expected by user and the one expected/printed by MySQL, e.g.:
$user_date = new DateTime('2016-10-03 00:00:00', new DateTimeZone('Europe/Berlin'));
$user_date->setTimezone(new DateTimeZone('UTC'));
echo $user_date->format('c');
MySQL needs the time zone when you use TIMESTAMP columns, to convert from/to the local time, e.g.:
mysql> create table foo(
-> foo int(10) unsigned auto_increment,
-> my_date timestamp,
-> primary key (foo)
-> );
Query OK, 0 rows affected (0.00 sec)
mysql> set ##time_zone = '+01:00';
Query OK, 0 rows affected (0.00 sec)
mysql> insert into foo (my_date) values ('2016-12-27 18:50:00');
Query OK, 1 row affected (0.00 sec)
mysql> set ##time_zone = '-07:00';
Query OK, 0 rows affected (0.00 sec)
mysql> insert into foo (my_date) values ('2016-12-27 18:50:00');
Query OK, 1 row affected (0.00 sec)
mysql> select * from foo order by 1;
+-----+---------------------+
| foo | my_date |
+-----+---------------------+
| 1 | 2016-12-27 10:50:00 |
| 2 | 2016-12-27 18:50:00 |
+-----+---------------------+
2 rows in set (0.00 sec)
mysql> set ##time_zone = '+09:30';
Query OK, 0 rows affected (0.00 sec)
mysql> select * from foo order by 1;
+-----+---------------------+
| foo | my_date |
+-----+---------------------+
| 1 | 2016-12-28 03:20:00 |
| 2 | 2016-12-28 11:20:00 |
+-----+---------------------+
2 rows in set (0.00 sec)

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

PHP/MySQL randomly failed to parse the correct datetime

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

MySQL- inserting a date into a varchar and then converting back to date when querying

I have to use a varchar field in a mysql database to store a date, and I need to be able to query on this date later on as if it was a date field.
What format should the date go into the database? date()?
How do I convert a string to a date in mysql?
Thanks!
As i seen from your comment you are using wordpress so in that already have function to use date with format which you want
use below LINK to get_option and also have default parameter to get. like
<?php echo get_option( $option, $default ); ?>
where $default = 'date_format' - Default date format; set in General Options.
let me know if i can help u more.
MySQL provides DATETIME data type. But CHAR or VARCHAR should be fine, depending on what you need.
For the format, this is the standard format as per wiki. YYYY-MM-DD HH:MM:SS, for date only, this should do: YYYY-MM-DD.
Also check out the STR_TO_DATE function.
Here is an example:
SELECT STR_TO_DATE('01,5,2013','%d,%m,%Y')
will return a date of
'2013-05-01'
Please read the documentation
http://dev.mysql.com/doc/refman/5.6/en/date-and-time-functions.html
STR_TO_DATE()
If you just wanna query the data, as if it was a date, you can do it like this...
SELECT * FROM table1 WHERE DATE_FORMAT(STR_TO_DATE(yourColumn,'%m/%d/%Y %x:%x:%x'), '%Y-%m-%d 23:59:59') >= NOW()
This will select all readocrds that have a date greater than or equal to today
In my opinion there is no problem. If you like to store a date as varchar, it is okay. If you like to use the data with date functions later, it is also okay. The difference is only in the way MySQL stores the data. If you use varchar to store a date, you need more memory, but you can store other strings too. You can try it yourself:
mysql> SELECT YEAR("2013-06-18");
+--------------------+
| YEAR("2013-06-18") |
+--------------------+
| 2013 |
+--------------------+
1 row in set (0,00 sec)
You can even compare strings with dates like this:
mysql> SELECT DATE(NOW())="2013-06-18";
+--------------------------+
| DATE(NOW())="2013-06-18" |
+--------------------------+
| 1 |
+--------------------------+
1 row in set (0,00 sec)
If you don't trust this tests, you can first put the data into a test table with a field of type varchar. I have done it with the same result.

What are the pros and cons of the various date/time field types in MySQL?

Date and time in MySQL can be stored as DATETIME, TIMESTAMP, and INTEGER (number of seconds since 01/01/1970). What are the benefits and drawbacks of each, particularly when developing under a LAMP stack?
TIMESTAMP is stored in a MySQL proprietary method (though it's basically just a string consisting of year, month, day, hour, minutes and seconds) and additionally, a field of type TIMESTAMP is automatically updated whenever the record is inserted or changed and no explicit field value is given:
mysql> create table timestamp_test(
id integer not null auto_increment primary key,
val varchar(100) not null default '', ts timestamp not null);
Query OK, 0 rows affected (0.00 sec)
mysql> insert into timestamp_test (val) values ('foobar');
Query OK, 1 row affected (0.00 sec)
mysql> select * from timestamp_test;
+----+--------+----------------+
| id | val | ts |
+----+--------+----------------+
| 1 | foobar | 20090122174108 |
+----+--------+----------------+
1 row in set (0.00 sec)
mysql> update timestamp_test set val = 'foo bar' where id = 1;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> select * from timestamp_test;
+----+---------+----------------+
| id | val | ts |
+----+---------+----------------+
| 1 | foo bar | 20090122174123 |
+----+---------+----------------+
1 row in set (0.00 sec)
mysql>
DATETIME is the standard data type for dates and times which works in conjunction with the date and time functions in MySQL. I'd probably use this in practice
Storing dates in INTEGER format is not recommended, as you are opening a real can of worms due to interesting problems like time zones, leap years and the like - at least if you intend to query the database based on specific dates stored in that field.
I would save data using the DATETIME or DATE fields in MySQL. At least, if you are going to store date values up to the year 2038: http://en.wikipedia.org/wiki/Year_2038_problem. If you're on a system that stores integers differently, you may not have this issue.
It is still easy to compare date values or even timestamps.
SELECT * FROM myTable WHERE startDate > '2009-01-01'
SELECT * FROM myTable WHERE UNIX_TIMESTAMP(startDate) > 1232541482
Well I guess the following would help clarify.
Date and time can be stored in a DATETIME field in mysql.
TIMESTAMP is used if you wish to timestamp when a row was created - the field will be automatically filled in on creation.
Using an integer for a Date is slightly overkill since this is essentially what DATETIME does but does all the time consuming conversions for you.
Is there a particular benefit or drawback you are interested in finding out about?
Timestamp in mysql can be very tricky. If not declared carefully you may end up with field that automatically changes its value on every row update (even if you dont update it explicitly).
http://dev.mysql.com/doc/refman/5.0/en/timestamp.html
If you need millisecond fidelity for a timestamp, you need to save it as an Integer. Use caution though, this can complicate things.

Categories