Index: includes/batch.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/batch.inc,v
retrieving revision 1.29
diff -u -p -r1.29 batch.inc
--- includes/batch.inc	27 Dec 2008 19:12:09 -0000	1.29
+++ includes/batch.inc	11 Jan 2009 10:44:37 -0000
@@ -263,6 +263,8 @@ function _batch_process() {
 
     // If we are in progressive mode, break processing after 1 second.
     if ($batch['progressive'] && timer_read('batch_processing') > 1000) {
+      // Record elapsed wall clock time. 
+      $current_set['elapsed'] = round((microtime(TRUE) - $current_set['start']) * 1000, 2);
       break;
     }
   }
@@ -289,11 +291,16 @@ function _batch_process() {
 
     $current    = $total - $remaining + $finished;
     $percentage = $total ? floor($current / $total * 100) : 100;
+    $elapsed    = $current_set['elapsed'];
+    // Estimate remaining with percentage in floating format.
+    $estimate   = $elapsed * ($total - $current) / $current;
     $values     = array(
       '@remaining'  => $remaining,
       '@total'      => $total,
       '@current'    => floor($current),
       '@percentage' => $percentage,
+      '@elapsed'    => format_interval($elapsed / 1000),
+      '@estimate'   => format_interval($estimate / 1000),
     );
     $message = strtr($progress_message, $values);
     if (!empty($message)) {
@@ -360,7 +367,8 @@ function _batch_finished() {
         include_once DRUPAL_ROOT . '/' . $batch_set['file'];
       }
       if (function_exists($batch_set['finished'])) {
-        $batch_set['finished']($batch_set['success'], $batch_set['results'], $batch_set['operations']);
+        // Format the elapsed time when batch complete.
+        $batch_set['finished']($batch_set['success'], $batch_set['results'], $batch_set['operations'], format_interval($batch_set['elapsed'] / 1000));
       }
     }
   }
Index: includes/form.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/form.inc,v
retrieving revision 1.311
diff -u -p -r1.311 form.inc
--- includes/form.inc	10 Jan 2009 05:23:49 -0000	1.311
+++ includes/form.inc	11 Jan 2009 10:44:42 -0000
@@ -2501,8 +2501,9 @@ function form_clean_id($id = NULL, $flus
  *     'init_message': message displayed while the processing is initialized.
  *       Defaults to t('Initializing.').
  *     'progress_message': message displayed while processing the batch.
- *       Available placeholders are @current, @remaining, @total and @percent.
- *       Defaults to t('Remaining @remaining of @total.').
+ *       Available placeholders are @current, @remaining, @total, @percentage,
+ *       @estimate and @elapsed.
+ *       Defaults to t('Completed @current of @total.').
  *     'error_message': message displayed if an error occurred while processing
  *       the batch.
  *       Defaults to t('An error has occurred.').
@@ -2539,6 +2540,8 @@ function batch_set($batch_definition) {
       'sandbox' => array(),
       'results' => array(),
       'success' => FALSE,
+      'start' => microtime(TRUE),
+      'elapsed' => 0,
     );
     // Use get_t() to allow batches at install time.
     $t = get_t();
Index: modules/simpletest/simpletest.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/simpletest/simpletest.module,v
retrieving revision 1.32
diff -u -p -r1.32 simpletest.module
--- modules/simpletest/simpletest.module	8 Jan 2009 18:57:32 -0000	1.32
+++ modules/simpletest/simpletest.module	11 Jan 2009 10:44:44 -0000
@@ -434,12 +434,12 @@ function _simpletest_batch_operation($te
   $context['finished'] = 1 - $size / $max;
 }
 
-function _simpletest_batch_finished($success, $results, $operations) {
+function _simpletest_batch_finished($success, $results, $operations, $elapsed) {
   if (isset($results['test_id'])) {
     $_SESSION['test_id'] = $results['test_id'];
   }
   if ($success) {
-    drupal_set_message(t('The tests have finished running.'));
+    drupal_set_message(t('The tests finished in @elapsed.', array('@elapsed' => $elapsed)));
   }
   else {
     drupal_set_message(t('The tests did not successfully finish.'), 'error');
