407

What is the correct format to pass to the date() function in PHP if I want to insert the result into a MySQL datetime type column?

I've been trying date('Y-M-D G:i:s') but that just inserts "0000-00-00 00:00:00" everytime.

John
  • 1
  • 13
  • 98
  • 177
Alex
  • 6,497
  • 11
  • 47
  • 58
  • 3
    since you're not supplying a parameter to date do you actually want to record the current time? – Mark Elliot Feb 07 '10 at 00:28
  • I know this question is 12 yo. But nowadays it would be beneficial to use \DateTime and the convertion functions it offers – theking2 Apr 18 '22 at 14:32

14 Answers14

827

The problem is that you're using 'M' and 'D', which are a textual representations, MySQL is expecting a numeric representation of the format 2010-02-06 19:30:13

Try: date('Y-m-d H:i:s') which uses the numeric equivalents.

edit: switched G to H, though it may not have impact, you probably want to use 24-hour format with leading 0s.

John
  • 1
  • 13
  • 98
  • 177
Mark Elliot
  • 75,278
  • 22
  • 140
  • 160
  • 60
    this has to be one of the single most common datetime formats anyone would ever need. should be a built in php global or part of the date function itself (e.g., 'c', 'r') – But those new buttons though.. Jun 09 '16 at 17:49
  • 52
    Why this is not the case I do not know. I have to refer to stack overflow every. single. functioning. time. – Mazatec Aug 02 '16 at 17:17
  • 18
    It's faster to come here, than search in my code for a usage like this. – MRodrigues Oct 20 '16 at 13:53
  • 97
    Just thought of a cute mnemonic for remembering the format: "**Y**our **m**y **d**ate not **His** ". works on so many levels :) – IzzEps Jan 12 '17 at 19:59
  • This is the correct answer and when I'm not using a framework and have to write SQL, this answer is useful. But for me, I don't usually code at this level any more unless I'm writing some little script to do a specific thing that I don't care about. – Halfstop Mar 30 '17 at 15:05
  • The only issue with this is it assumes you don't already have the date as some other kind of string, in which case see SandroMarques' answer below. – Chris Pink Jul 28 '17 at 10:53
  • 3
    There should be a php shorthand for this as there is for ISO 8601 and RFC 2822 – But those new buttons though.. Mar 01 '18 at 18:30
  • 1
    This is an enitrely correct answer which provides the date in one of the exact formats spcified by MySQL, _but_ using format 'c' (e.g. '2004-02-12T15:19:21+00:00') also works because it seems that MySQL entirely ignores any non-numeric characters beyond the seconds ('2004-02-12T15:19:21Hello' also works). NB This means that the time-zone information included in this format is ignored by MySQL, but this is the same as using 'Y-m-d H:i:s', which specifies no time zone anyway—whenever you are using dates in MySQL you need to make sure you are using a consistent time zone. – WebSmithery Sep 11 '20 at 16:04
  • upvote if you come daily just to copy this date('Y-m-d H:i:s') :) – Alex Aug 24 '22 at 05:33
127

From the comments of php's date() manual page:

<?php $mysqltime = date ('Y-m-d H:i:s', $phptime); ?>

You had the 'Y' correct - that's a full year, but 'M' is a three character month, while 'm' is a two digit month. Same issue with 'D' instead of 'd'. 'G' is a 1 or 2 digit hour, where 'H' always has a leading 0 when needed.

John
  • 1
  • 13
  • 98
  • 177
Tim Lytle
  • 17,549
  • 10
  • 60
  • 91
  • 1
    Thanks @Pekka - I remember when you and I had roughly the same rep - you've been pretty active. – Tim Lytle Feb 07 '10 at 00:42
  • 2
    yeah, I'm working a lot right now, and SO is my favourite pastime in between :) that will change again. – Pekka Feb 07 '10 at 00:50
44

Here's an alternative solution: if you have the date in PHP as a timestamp, bypass handling it with PHP and let the DB take care of transforming it by using the FROM_UNIXTIME function.

mysql> insert into a_table values(FROM_UNIXTIME(1231634282));
Query OK, 1 row affected (0.00 sec)

mysql> select * from a_table;

+---------------------+
| a_date              |
+---------------------+
| 2009-01-10 18:38:02 |
+---------------------+
JAL
  • 21,295
  • 1
  • 48
  • 66
  • This is an elegant solution.Thanks :) – kta Mar 15 '14 at 13:22
  • That's the best option, if you can work on timestamps. Let super-fast DB do everything, it can, instead of waiting for super-slow PHP! – trejder Dec 11 '14 at 13:31
  • 4
    @trejder, Who told you that doing it in mysql is faster than doing it in php? Doing it in PHP is better because the DB usually is the bottleneck and you want to **get in and out asap**. – Pacerier Jan 15 '15 at 07:57
  • @Pacerier Hey, don't scream at me. I'm just a tiny developer with nearly-zero experience in DB. I'm just repeating, what I was always been told. At least in case of PHP vs. Oracle and PL/SQL. Yell at those, why are spreading wrong gossips! :> – trejder Jan 15 '15 at 08:39
  • 1
    @Pacerier the DB is the bottleneck if you have a poorly built DB, or are running too many small queries instead of a more robust effective single query, or in a lot of cases if you rely on an ORM to manage the database. Solid SQL with a well indexed relational database is not slow. – mopsyd May 01 '15 at 19:37
  • 3
    @mopsyd, The DB is the bottleneck because [scaling it horizontally](https://en.wikipedia.org/wiki/Shard_(database_architecture)) requires complexity. Compare that to webservers that can be duplicated across the globe without any code changes. – Pacerier May 24 '15 at 15:38
  • 1
    If the query fails, is logged somewhere, and you have to debug it, then the timestamp is much harder to read than the formatted date string described by @tim-lytle. – humbads Jun 11 '19 at 17:33
31

I use the following PHP code to create a variable that I insert into a MySQL DATETIME column.

$datetime = date_create()->format('Y-m-d H:i:s');

This will hold the server's current Date and Time.

Steffan
  • 536
  • 5
  • 15
16
$date_old = '23-5-2016 23:15:23'; 
//Date for database
$date_for_database = date ('Y-m-d H:i:s'", strtotime($date_old));

//Format should be like 'Y-m-d H:i:s'`enter code here`
John
  • 1
  • 13
  • 98
  • 177
Ali Umair
  • 690
  • 7
  • 10
  • 2
    Although this code may answer the question, providing additional context regarding _why_ and/or _how_ it answers the question would significantly improve its long-term value. Please [edit] your answer to add some explanation, and to fix your formatting problems. – Toby Speight May 03 '16 at 12:00
11

I use this function (PHP 7)

function getDateForDatabase(string $date): string {
    $timestamp = strtotime($date);
    $date_formated = date('Y-m-d H:i:s', $timestamp);
    return $date_formated;
}

Older versions of PHP (PHP < 7)

function getDateForDatabase($date) {
    $timestamp = strtotime($date);
    $date_formated = date('Y-m-d H:i:s', $timestamp);
    return $date_formated;
}
SandroMarques
  • 6,070
  • 1
  • 41
  • 46
  • I've voted up your answer because it worked after I edited the first line; `function getDateForDatabase(string $date) : string {` to `function getDateForDatabase($date) {` Why the type declarations throw an error I don't know enough PHP to tell. – Chris Pink Jul 28 '17 at 09:10
  • "Argument 1 passed to getDateForDatabase() must be an instance of string, string given," - my input was a string, – Chris Pink Jul 28 '17 at 09:12
9

Format time stamp to MySQL DATETIME column :

strftime('%Y-%m-%d %H:%M:%S',$timestamp);
Ahmed Saber
  • 489
  • 1
  • 9
  • 21
8

Format MySQL datetime with PHP

$date = "'".date('Y-m-d H:i:s', strtotime(str_replace('-', '/', $_POST['date'])))."'";
Taryn
  • 242,637
  • 56
  • 362
  • 405
dev4092
  • 2,820
  • 1
  • 16
  • 15
8

There is no need no use the date() method from PHP if you don't use a timestamp. If dateposted is a datetime column, you can insert the current date like this:

$db->query("INSERT INTO table (dateposted) VALUES (now())");
Adam
  • 25,960
  • 22
  • 158
  • 247
5

Using DateTime class in PHP7+:

function getMysqlDatetimeFromDate(int $day, int $month, int $year): string
{
 $dt = new DateTime();
 $dt->setDate($year, $month, $day);
 $dt->setTime(0, 0, 0, 0); // set time to midnight

 return $dt->format('Y-m-d H:i:s');
}
The Onin
  • 5,068
  • 2
  • 38
  • 55
  • 1
    I can only recommend the use of \DateTime. It can construct a PHP date directly from a MySQL string and observes the timezone your server app is working in. – theking2 Apr 18 '22 at 14:35
4

A small addendum to accepted answer: If database datetime is stored as UTC (what I always do), you should use gmdate('Y-m-d H:i:s') instead of date("Y-m-d H:i:s").

Or, if you prefer to let MySQL handle everything, as some answers suggest, I would insert MySQL's UTC_TIMESTAMP, with the same result.

Note: I understood the question referring to current time.

John
  • 1
  • 13
  • 98
  • 177
Bruno
  • 580
  • 5
  • 14
  • Good answer. All the other answers seem to miss the subtle issues surrounding the timezone. I mean, how do you know your SQL server's timezone, or your webserver's, or the user? Bare calls to date() or NOW() seem like timezone bug magnets. – Chris Nadovich Jul 26 '21 at 02:06
  • @ChrisNadovich, mysql's timezone can be displayed with "SELECT @@global.time_zone;". Default is "SYSTEM", server's TZ. "0:00" is UTC. For apache, you may use SSI's ''. It may different for PHP. For a user, "date +%Z" in a terminal (but any process may override it). – Bruno Jul 26 '21 at 09:29
  • Well, of course, @bruno. Nevertheless, not talking about timezones at all seems to be a flaw in the "preferred" answers here. I mean, wouldn't it be nice if we could use 'Y-m-d H:i:s e' and have SQL automatically store an unambiguous time from consideration of that 'e' as it automatically deals with the Y, m, d, H, i, and s. – Chris Nadovich Jul 26 '21 at 17:30
  • Yes @ChrisNadovich For me, the only non-ambiguous system is to have the server using UTC. And then making conversions on client side, for user usage only. Any different setting on server imply we cannot guarantee the relative order of two records (think about a record inserted 1m before winter/summer time change, a second one 1mn later, with the server clock going backwards 1h in-between). – Bruno Jul 26 '21 at 17:57
2

This has been driving me mad looking for a simple answer. Finally I made this function that seems to catch all input and give a good SQL string that is correct or at least valid and checkable. If it's 1999-12-31 it's probably wrong but won't throw a bad error in MySQL.

function MakeSQLDate($date) {
    if (is_null($date)) {
        //use 1999-12-31 as a valid date or as an alert
        return date('Y-m-d', strtotime('1999-12-31'));
    }

    if (($t = strtotime($date)) === false) {
        //use 1999-12-31 as a valid date or as an alert
        return date('Y-m-d', strtotime('1999-12-31'));
    } else {
        return date('Y-m-d H:i:s', strtotime($date));
    }
}
  • 1
    If you're having to check for `null` then something is very wrong with your upstream data! – John Jul 07 '20 at 05:59
2

This is a more accurate way to do it. It places decimals behind the seconds giving more precision.

$now = date('Y-m-d\TH:i:s.uP', time());

Notice the .uP.

More info: https://stackoverflow.com/a/6153162/8662476

Maurici Abad
  • 1,012
  • 9
  • 20
0

IMO in addition to the date() function options provided in the previous answers, you should carefully consider its use the server time zone setting which may be different from the database one. If the UTC time zone is needed then the gmdate() function (it has the same options of date()) will be more convenient for the specific case.