53

Since MySQL evidently cannot automatically insert the function now() in a datetime field in adding new records like some other databases, based on comments, I'm explicitly trying to insert it using an SQL statement. (People seem to think timestamp with curdate() is not the answer due to the various limitations of timestamp.) There are numerous articles on the web suggesting inserting now() using SQL should work.

When I try to insert the date time using the SQL statement, however, the field does not populate with the current time/date, but it only gives me the default 0000-00-, etc. This is probably a syntax error, but it's driving me crazy, so I am posting it.

mysql_query("INSERT INTO users (first, last, whenadded) VALUES ('$first', '$last', now())"; 

It inserts first and last, but nothing for when added, leaving 0000-00-00, etc. in the whenadded field.

The field type is datetime, it has no collation, attributes, null default or extra. BTW, I tried putting now() in single quotes... It threw an error.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
user1260310
  • 2,229
  • 9
  • 49
  • 67
  • 5
    Strange, what you show should work. Are you sure it's a proper DATETIME field? Anyway, the comments are incorrect, you can automate this using `DEFAULT CURRENT_TIMESTAMP` and `ON UPDATE CURRENT_TIMESTAMP` http://dev.mysql.com/doc/refman/5.0/en/timestamp-initialization.html – Pekka Mar 23 '12 at 14:57
  • Can what works for TIMESTAMP (CURRENT_TIMESTAMP) also work for Datetime? http://bugs.mysql.com/bug.php?id=27645 Am shying away from Timestamp due to what people describe as its date limitations. will try resetting field type – user1260310 Mar 23 '12 at 15:34
  • Ugh, my mistake. Sorry. This indeed seems to work for TIMESTAMP fields only, which is a shame. But the query you show above *should* work – Pekka Mar 23 '12 at 15:39
  • @Pekka - despite the name, `CURRENT_TIMESTAMP` works for me as a default value for a DateTime column. – ToolmakerSteve Aug 09 '20 at 21:37
  • Also useful sometimes is MySQL's `UTC_TIMESTAMP()`. Again, despite the name (timestamp), it also works when setting a `DateTime` column to this value. E.g. `"UPDATE mytable SET MyDateTimeField=UTC_TIMESTAMP() WHERE MyID={$theID};"` – ToolmakerSteve Aug 09 '20 at 21:47

9 Answers9

94

NOW() normally works in SQL statements and returns the date and time. Check if your database field has the correct type (datetime). Otherwise, you can always use the PHP date() function and insert:

date('Y-m-d H:i:s')

But I wouldn't recommend this.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Ronan
  • 1,482
  • 11
  • 11
  • 3
    -1: NOW() does not work for DATETIME type. It only works for TIMESTAMP. So I recommend using PHP for this (when using DATETIME type). – Ivo Pereira Jun 03 '13 at 14:06
  • 25
    @IvoPereira Actually, `NOW()` does work for `DATETIME`. Using php to generate timestamps isn't a bad solution. But the timezones across between the servers running php and the MySQL Servers need to be in sync. – Chris Henry Jun 28 '13 at 22:46
  • Actually this is the optimal approach for current date, time or both. – Lucian Minea Aug 04 '15 at 17:11
  • 1
    y wouldnt you recommend it – bubakazouba Jul 21 '16 at 15:09
  • 1
    Really depends on your servers cluster. If everything runs on one server, you can use this method. Otherwise you can have timezones problems. All in all, I always prefer using native functions that hacks. NOW() exists in SQL so I'd rather find out why it's not working and fix it than hack my way around it. – Ronan Jul 21 '16 at 16:26
20

You forgot to close the mysql_query command:

mysql_query("INSERT INTO users (first, last, whenadded) VALUES ('$first', '$last', now())");

Note that last parentheses.

dakshbhatt21
  • 3,558
  • 3
  • 31
  • 40
ckwolfling
  • 211
  • 2
  • 6
9

Like Pekka said, it should work this way. I can't reproduce the problem with this self-contained example:

<?php
    $pdo = new PDO('mysql:host=localhost;dbname=test;charset=utf8', 'localonly', 'localonly');
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);

    $pdo->exec('
        CREATE TEMPORARY TABLE soFoo (
            id int auto_increment,
            first int,
            last int,
            whenadded DATETIME,
            primary key(id)
        )
    ');
    $pdo->exec('INSERT INTO soFoo (first,last,whenadded) VALUES (0,1,Now())');
    $pdo->exec('INSERT INTO soFoo (first,last,whenadded) VALUES (0,2,Now())');
    $pdo->exec('INSERT INTO soFoo (first,last,whenadded) VALUES (0,3,Now())');

    foreach( $pdo->query('SELECT * FROM soFoo', PDO::FETCH_ASSOC) as $row ) {
        echo join(' | ', $row), "\n";
    }

Which (currently) prints

1 | 0 | 1 | 2012-03-23 16:00:18
2 | 0 | 2 | 2012-03-23 16:00:18
3 | 0 | 3 | 2012-03-23 16:00:18

And here's (almost) the same script using a TIMESTAMP field and DEFAULT CURRENT_TIMESTAMP:

<?php
    $pdo = new PDO('mysql:host=localhost;dbname=test;charset=utf8', 'localonly', 'localonly');
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);

    $pdo->exec('
        CREATE TEMPORARY TABLE soFoo (
            id int auto_increment,
            first int,
            last int,
            whenadded TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
            primary key(id)
        )
    ');
    $pdo->exec('INSERT INTO soFoo (first,last) VALUES (0,1)');
    $pdo->exec('INSERT INTO soFoo (first,last) VALUES (0,2)');
    sleep(1);
    $pdo->exec('INSERT INTO soFoo (first,last) VALUES (0,3)');

    foreach( $pdo->query('SELECT * FROM soFoo', PDO::FETCH_ASSOC) as $row ) {
        echo join(' | ', $row), "\n";
    }

Conveniently, the timestamp is converted to the same datetime string representation as in the first example - at least with my PHP/PDO/mysqlnd version.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
VolkerK
  • 95,432
  • 20
  • 163
  • 226
6

The only reason I can think of is you are adding it as string 'now()', not function call now().
Or whatever else typo.

SELECT NOW();

to see if it returns correct value?

Your Common Sense
  • 156,878
  • 40
  • 214
  • 345
3

Currently, and with the new versions of Mysql can insert the current date automatically without adding a code in your PHP file. You can achieve that from Mysql while setting up your database as follows:

enter image description here

Now, any new post will automatically get a unique date and time. Hope this can help.

Jodyshop
  • 656
  • 8
  • 12
2

What about SYSDATE() ?

<?php
  $db = mysql_connect('localhost','user','pass');
  mysql_select_db('test_db');

  $stmt = "INSERT INTO `test` (`first`,`last`,`whenadded`) VALUES ".
          "('{$first}','{$last}','SYSDATE())";
  $rslt = mysql_query($stmt);
?>

Look at Difference between NOW(), SYSDATE() & CURRENT_DATE() in MySQL for more info about NOW() and SYSDATE().

Community
  • 1
  • 1
Benas
  • 2,106
  • 2
  • 39
  • 66
2

now()

worked for me . but my field type is date only and yours is datetime. i am not sure if this is the case

Shuhad zaman
  • 3,156
  • 32
  • 32
  • 1
    it will surely works for all date type column in MySQL, i have been using that for the past three years now – Michael Jun 11 '16 at 18:57
1

These both work fine for me...

<?php
  $db = mysql_connect('localhost','user','pass');
  mysql_select_db('test_db');

  $stmt = "INSERT INTO `test` (`first`,`last`,`whenadded`) VALUES ".
          "('{$first}','{$last}','NOW())";
  $rslt = mysql_query($stmt);

  $stmt = "INSERT INTO `users` (`first`,`last`,`whenadded`) VALUES ".
          "('{$first}', '{$last}', CURRENT_TIMESTAMP)";
  $rslt = mysql_query($stmt);

?>

Side note: mysql_query() is not the best way to connect to MySQL in current versions of PHP.

DismissedAsDrone
  • 185
  • 1
  • 1
  • 7
  • Thanks everyone! I found the stupid mistake..In debugging I commented out the the wrong version of the query. Ugh. Btw, what is the preferred way to execute the query if not mysql_query. – user1260310 Mar 23 '12 at 21:46
0

Just go to the column whenadded and change the default value to CURRENT_TIMESTAMP

Ekane 3
  • 160
  • 1
  • 12