diff --git a/core/modules/system/system.module b/core/modules/system/system.module
index 20afc296d6b477a09925a4623e1143a5514afed4..80a84033fb9ae855f54d72a25f6a04ff00bd6cfb 100644
--- a/core/modules/system/system.module
+++ b/core/modules/system/system.module
@@ -2424,6 +2424,10 @@ function _system_rebuild_module_data() {
     // Look for the info file.
     $module->info = drupal_parse_info_file(dirname($module->uri) . '/' . $module->name . '.info');
 
+    // Add the info file modification time, so the modules page can be sorted
+    // by the date modules were added or updated.
+    $module->info['mtime'] = filemtime(dirname($module->uri) . '/' . $module->name . '.info');
+
     // Skip modules that don't provide info.
     if (empty($module->info)) {
       unset($modules[$key]);
@@ -2568,6 +2572,10 @@ function _system_rebuild_theme_data() {
     $themes[$key]->filename = $theme->uri;
     $themes[$key]->info = drupal_parse_info_file($theme->uri) + $defaults;
 
+    // Add the info file modification time, so the themes page can be sorted
+    // by the date themes were added or updated.
+    $themes[$key]->info['mtime'] = filemtime($theme->uri);
+
     // Invoke hook_system_info_alter() to give installed modules a chance to
     // modify the data in the .info files if necessary.
     $type = 'theme';
diff --git a/core/modules/system/tests/module.test b/core/modules/system/tests/module.test
index 19acf608d89809bfa5e7364d5adbcdc8b3ffcf10..564cc4138a1cc636f0161795b896957599b185b3 100644
--- a/core/modules/system/tests/module.test
+++ b/core/modules/system/tests/module.test
@@ -236,6 +236,34 @@ class ModuleUnitTest extends DrupalWebTestCase {
     $poll_before_forum = $poll_position !== FALSE && $forum_position !== FALSE && $poll_position < $forum_position;
     $this->assertTrue($php_before_poll && $poll_before_forum, t('Modules were enabled in the correct order by module_enable().'));
   }
+
+  /**
+   * Tests whether the correct module metadata is returned.
+   */
+  function testModuleMetaData() {
+    // Generate the list of available modules.
+    $modules = system_rebuild_module_data();
+    // Check that the mtime field exists for the system module.
+    $this->assertTrue(!empty($modules['system']->info['mtime']), 'The system.info file modification time field is present.');
+    // Use 0 if mtime isn't present, to avoid an array index notice.
+    $test_mtime = !empty($modules['system']->info['mtime']) ? $modules['system']->info['mtime'] : 0;
+    // Ensure the mtime field contains a number that is greater than zero.
+    $this->assertTrue(is_numeric($test_mtime) && ($test_mtime > 0), 'The system.info file modification time field contains a timestamp.');
+  }
+
+  /**
+   * Tests whether the correct theme metadata is returned.
+   */
+  function testThemeMetaData() {
+    // Generate the list of available themes.
+    $themes = system_rebuild_theme_data();
+    // Check that the mtime field exists for the bartik theme.
+    $this->assertTrue(!empty($themes['bartik']->info['mtime']), 'The bartik.info file modification time field is present.');
+    // Use 0 if mtime isn't present, to avoid an array index notice.
+    $test_mtime = !empty($themes['bartik']->info['mtime']) ? $themes['bartik']->info['mtime'] : 0;
+    // Ensure the mtime field contains a number that is greater than zero.
+    $this->assertTrue(is_numeric($test_mtime) && ($test_mtime > 0), 'The bartik.info file modification time field contains a timestamp.');
+  }
 }
 
 /**