diff --git modules/node/node.module modules/node/node.module
index 4c7db51..9958d32 100644
--- modules/node/node.module
+++ modules/node/node.module
@@ -985,8 +985,6 @@ function node_save($node) {
 
   try {
     field_attach_presave('node', $node);
-    // Let modules modify the node before it is saved to the database.
-    module_invoke_all('node_presave', $node);
     global $user;
 
     // Determine if we will be inserting a new node.
@@ -994,6 +992,20 @@ function node_save($node) {
       $node->is_new = empty($node->nid);
     }
 
+    // Set the timestamp fields.
+    if (empty($node->created)) {
+      $node->created = REQUEST_TIME;
+    }
+    // The changed timestamp is always updated for bookkeeping purposes,
+    // for example: revisions, searching, etc.
+    $node->changed = REQUEST_TIME;
+
+    $node->timestamp = REQUEST_TIME;
+    $update_node = TRUE;
+
+    // Let modules modify the node before it is saved to the database.
+    module_invoke_all('node_presave', $node);
+
     if ($node->is_new || !empty($node->revision)) {
       // When inserting either a new node or a new node revision, $node->log
       // must be set because {node_revision}.log is a text column and therefore
@@ -1025,18 +1037,6 @@ function node_save($node) {
       unset($node->vid);
     }
 
-    // Set the timestamp fields.
-    if (empty($node->created)) {
-      $node->created = REQUEST_TIME;
-    }
-    // The changed timestamp is always updated for bookkeeping purposes (revisions, searching, ...)
-    if (empty($node->changed)) {
-      $node->changed = REQUEST_TIME;
-    }
-
-    $node->timestamp = REQUEST_TIME;
-    $update_node = TRUE;
-
     // Save the node and node revision.
     if ($node->is_new) {
       // For new nodes, save new records for both the node itself and the node
diff --git modules/node/node.test modules/node/node.test
index 4b7d4bb..88203a4 100644
--- modules/node/node.test
+++ modules/node/node.test
@@ -925,7 +925,7 @@ class NodeSaveTestCase extends DrupalWebTestCase {
   }
 
   function setUp() {
-    parent::setUp();
+    parent::setUp('node_presave_test');
     // Create a user that is allowed to post; we'll use this to test the submission.
     $web_user = $this->drupalCreateUser(array('create article content'));
     $this->drupalLogin($web_user);
@@ -952,7 +952,7 @@ class NodeSaveTestCase extends DrupalWebTestCase {
       'nid' => $test_nid,
       'is_new' => TRUE,
     );
-    $node = node_submit((object)$node);
+    $node = node_submit((object) $node);
 
     // Verify that node_submit did not overwrite the user ID.
     $this->assertEqual($node->uid, $this->web_user->uid, t('Function node_submit() preserves user ID'));
@@ -965,6 +965,63 @@ class NodeSaveTestCase extends DrupalWebTestCase {
     $node_by_title = $this->drupalGetNodeByTitle($title);
     $this->assertTrue($node_by_title, t('Node load by node title.'));
   }
+
+  /**
+   * Check that the "created" and "changed" timestamps are set correctly when
+   * saving a new node or updating an existing node.
+   */
+  function testTimestamps() {
+    // Use the default timestamps.
+    $edit = array(
+      'uid' => $this->web_user->uid,
+      'type' => 'article',
+      'title' => $this->randomName(8),
+    );
+
+    node_save((object) $edit);
+    $node = $this->drupalGetNodeByTitle($edit['title']);
+    $this->assertEqual($node->created, REQUEST_TIME, t('Creating a node sets default "created" timestamp.'));
+    $this->assertEqual($node->changed, REQUEST_TIME, t('Creating a node sets default "changed" timestamp.'));
+
+    // Store the timestamps.
+    $created = $node->created;
+    $changed = $node->changed;
+
+    node_save($node);
+    $node = $this->drupalGetNodeByTitle($edit['title']);
+    $this->assertEqual($node->created, $created, t('Updating a node preserves "created" timestamp.'));
+
+    // Programmatically set the timestamps using hook_node_presave.
+    $node->title = 'testing_node_presave';
+
+    node_save($node);
+    $node = $this->drupalGetNodeByTitle('testing_node_presave');
+    $this->assertEqual($node->created, 280299600, t('Saving a node uses "created" timestamp set in presave hook.'));
+    $this->assertEqual($node->changed, 979534800, t('Saving a node uses "changed" timestamp set in presave hook.'));
+
+    // Programmatically set the timestamps on the node.
+    $edit = array(
+      'uid' => $this->web_user->uid,
+      'type' => 'article',
+      'title' => $this->randomName(8),
+      'created' => 280299600, // Sun, 19 Nov 1978 05:00:00 GMT
+      'changed' => 979534800, // Drupal 1.0 release.
+    );
+
+    node_save((object) $edit);
+    $node = $this->drupalGetNodeByTitle($edit['title']);
+    $this->assertEqual($node->created, 280299600, t('Creating a node uses user-set "created" timestamp.'));
+    $this->assertNotEqual($node->changed, 979534800, t('Creating a node doesn\'t use user-set "changed" timestamp.'));
+
+    // Update the timestamps.
+    $node->created = 979534800;
+    $node->changed = 280299600;
+
+    node_save($node);
+    $node = $this->drupalGetNodeByTitle($edit['title']);
+    $this->assertEqual($node->created, 979534800, t('Updating a node uses user-set "created" timestamp.'));
+    $this->assertNotEqual($node->changed, 280299600, t('Updating a node doesn\'t use user-set "changed" timestamp.'));
+  }
 }
 
 /**
diff --git modules/node/tests/node_presave_test.info modules/node/tests/node_presave_test.info
new file mode 100644
index 0000000..e8a5c95
--- /dev/null
+++ modules/node/tests/node_presave_test.info
@@ -0,0 +1,8 @@
+; $Id$
+name = "Node module presave tests"
+description = "Support module for hook_node_presave testing."
+package = Testing
+version = VERSION
+core = 7.x
+files[] = node_presave_test.module
+hidden = TRUE
diff --git modules/node/tests/node_presave_test.module modules/node/tests/node_presave_test.module
new file mode 100644
index 0000000..a3256a5
--- /dev/null
+++ modules/node/tests/node_presave_test.module
@@ -0,0 +1,18 @@
+<?php
+// $Id$
+
+/**
+ * @file
+ * Dummy module implementing node related hooks to test API interaction with
+ * the Node module.
+ */
+
+/**
+ * Implements hook_node_presave().
+ */
+function node_presave_test_node_presave($node) {
+  if ($node->title == 'testing_node_presave') {
+    $node->created = 280299600; // Sun, 19 Nov 1978 05:00:00 GMT
+    $node->changed = 979534800; // Drupal 1.0 release.
+  }
+}
