diff --git a/NEWS b/NEWS
index 09587ea2edf468a766c725340f59a281a3027da4..7758b361f6cd11f7f10bdd04b1ab98b682a21d5a 100644
--- a/NEWS
+++ b/NEWS
@@ -134,6 +134,8 @@ documents those changes that are of interest to users and admins.
  -- BLUEGENE - New blocks in dynamic mode will only be made in the system
     when the block is actually needed for a job, not when testing.
  -- BLUEGENE - Don't remove larger block used for small block until job starts.
+ -- Add new squeue output format and sort option of "%L" to print a job's time 
+    left (time limit minus time used).
 
 * Changes in SLURM 2.0.4
 ========================
diff --git a/doc/man/man1/squeue.1 b/doc/man/man1/squeue.1
index cb8bd339cded2f1aff602277fe5ddf25da4ff83a..30a0b685fd70ea921c8054fe15d3f91918dffdf0 100644
--- a/doc/man/man1/squeue.1
+++ b/doc/man/man1/squeue.1
@@ -162,6 +162,12 @@ This reports the value of the \fBsrun \-\-minthreads\fR option.
 Time limit of the job or job step in days\-hours:minutes:seconds. 
 The value may be "NOT_SET" if not yet established or "UNLIMITED" for no limit.
 .TP
+\fB%L\fR
+Time left for the job to execute in days\-hours:minutes:seconds. 
+This value is calculated by subtracting the job's time used from its time 
+limit.
+The value may be "NOT_SET" if not yet established or "UNLIMITED" for no limit.
+.TP
 \fB%m\fR
 Minimum size of memory (in MB) requested by the job
 .TP
diff --git a/src/smap/job_functions.c b/src/smap/job_functions.c
index b8442114dd74068d30b360f9705e05a535cc1eae..4e12675ca8551597d235fabdcc531f5edadb85af 100644
--- a/src/smap/job_functions.c
+++ b/src/smap/job_functions.c
@@ -247,7 +247,7 @@ static void _print_header_job(void)
 		main_xcord = 1;
 		main_ycord++;
 	} else {
-		printf("JOBID ");
+		printf("   JOBID ");
 		printf("PARTITION ");
 #ifdef HAVE_BG
 		printf("        BG_BLOCK ");
diff --git a/src/squeue/opts.c b/src/squeue/opts.c
index d9f1b0686d1dcc6acd08ee3814205ae4f67d8231..49b161245b8f66a13ffd7fc2e92c4afeef9b8568 100644
--- a/src/squeue/opts.c
+++ b/src/squeue/opts.c
@@ -458,7 +458,7 @@ extern int parse_format( char* format )
 				                           right_justify, 
 				                           suffix );
 			else if (field[0] == 'S')
-				step_format_add_time_start( params.format_list, 
+				step_format_add_time_start( params.format_list,
 				                            field_size, 
 				                            right_justify, 
 				                            suffix );
@@ -473,8 +473,9 @@ extern int parse_format( char* format )
 				                           right_justify, 
 				                           suffix );
 			else
-				error ("Invalid job step format specification: %c",
-				       field[0] );
+				error ( "Invalid job step format "
+					"specification: %c",
+					field[0] );
 		} else {
 			if (field[0] == 'a')
 				job_format_add_account( params.format_list,
@@ -533,7 +534,7 @@ extern int parse_format( char* format )
 				                       right_justify, 
 				                       suffix );
 			else if (field[0] == 'H')
-				job_format_add_min_sockets( params.format_list, 
+				job_format_add_min_sockets( params.format_list,
 				                           field_size, 
 				                           right_justify, 
 				                           suffix );
@@ -552,7 +553,7 @@ extern int parse_format( char* format )
 				                     field_size, 
 				                     right_justify, suffix );
 			else if (field[0] == 'J')
-				job_format_add_min_threads( params.format_list, 
+				job_format_add_min_threads( params.format_list,
 				                           field_size, 
 				                           right_justify, 
 				                           suffix );
@@ -561,6 +562,11 @@ extern int parse_format( char* format )
 				                           field_size, 
 				                           right_justify, 
 				                           suffix );
+			else if (field[0] == 'L')
+				job_format_add_time_left( params.format_list, 
+				                          field_size, 
+				                          right_justify, 
+				                          suffix );
 			else if (field[0] == 'm')
 				job_format_add_min_memory( params.format_list, 
 				                           field_size, 
@@ -601,7 +607,8 @@ extern int parse_format( char* format )
 				                        right_justify, 
 				                        suffix );
 			else if (field[0] == 'Q')
-				 job_format_add_priority_long( params.format_list,
+				 job_format_add_priority_long( 
+							params.format_list,
 							field_size,
 							right_justify,
 							suffix );
@@ -611,12 +618,13 @@ extern int parse_format( char* format )
 							right_justify,
 							suffix );
 			else if (field[0] == 'R')
-				job_format_add_reason_list(  params.format_list,
+				job_format_add_reason_list( params.format_list,
 							field_size,
 							right_justify,
 							suffix );
 			else if (field[0] == 's')
-				job_format_add_select_jobinfo( params.format_list, 
+				job_format_add_select_jobinfo( 
+							 params.format_list, 
 				                         field_size, 
 				                         right_justify, 
 				                         suffix );
@@ -647,7 +655,7 @@ extern int parse_format( char* format )
 				                          right_justify, 
 				                          suffix );
 			else if (field[0] == 'v')
-				job_format_add_reservation( params.format_list, 
+				job_format_add_reservation( params.format_list,
 				                        field_size, 
 				                        right_justify, 
 				                        suffix );
diff --git a/src/squeue/print.c b/src/squeue/print.c
index f70c8907946bffc562b9b3bd1fd894976d111f8c..cdda1b7ec36f73fcb3cf4d112a0ffc38404535f5 100644
--- a/src/squeue/print.c
+++ b/src/squeue/print.c
@@ -450,6 +450,24 @@ int _print_job_job_state_compact(job_info_t * job, int width, bool right,
 	return SLURM_SUCCESS;
 }
 
+int _print_job_time_left(job_info_t * job, int width, bool right, 
+			  char* suffix)
+{
+	if (job == NULL)	/* Print the Header instead */
+		_print_str("TIME_LEFT", width, right, true);
+	else if (job->time_limit == INFINITE)
+		_print_str("UNLIMITED", width, right, true);
+	else if (job->time_limit == NO_VAL)
+		_print_str("NOT_SET", width, right, true);
+	else {
+		time_t time_left = job->time_limit * 60 - job_time_used(job);
+		_print_secs(time_left, width, right, false);
+	}
+	if (suffix)
+		printf("%s", suffix);
+	return SLURM_SUCCESS;
+}
+
 int _print_job_time_limit(job_info_t * job, int width, bool right, 
 			  char* suffix)
 {
diff --git a/src/squeue/print.h b/src/squeue/print.h
index 05a8cda8cc9c920c7b58c4026364973aef86f25a..9fa7ebc187389e444d559b37b2905e9fdd0a6018 100644
--- a/src/squeue/print.h
+++ b/src/squeue/print.h
@@ -1,7 +1,8 @@
 /*****************************************************************************\
  *  print.h - squeue print job definitions
  *****************************************************************************
- *  Copyright (C) 2002-2006 The Regents of the University of California.
+ *  Copyright (C) 2002-2007 The Regents of the University of California.
+ *  Copyright (C) 2008-2009 Lawrence Livermore National Security
  *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
  *  Written by Joey Ekstrom <ekstrom1@llnl.gov>
  *  CODE-OCEC-09-009. All rights reserved.
@@ -16,7 +17,7 @@
  *  any later version.
  *
  *  In addition, as a special exception, the copyright holders give permission 
- *  to link the code of portions of this program with the OpenSSL library under 
+ *  to link the code of portions of this program with the OpenSSL library under
  *  certain conditions as described in each individual source file, and 
  *  distribute linked combinations including the two. You must obey the GNU 
  *  General Public License in all respects for all of the code used other than 
@@ -107,6 +108,9 @@ int job_format_add_function(List list, int width, bool right_justify,
 #define job_format_add_job_state_compact(list,wid,right,suffix) \
 	job_format_add_function(list,wid,right,suffix,  \
 	                        _print_job_job_state_compact)
+#define job_format_add_time_left(list,wid,right,suffix)	\
+	job_format_add_function(list,wid,right,suffix,	\
+	                        _print_job_time_left)
 #define job_format_add_time_limit(list,wid,right,suffix)	\
 	job_format_add_function(list,wid,right,suffix,	\
 	                        _print_job_time_limit)
@@ -196,6 +200,8 @@ int _print_job_job_state(job_info_t * job, int width, bool right_justify,
 			char* suffix);
 int _print_job_job_state_compact(job_info_t * job, int width,
 			bool right_justify, char* suffix);
+int _print_job_time_left(job_info_t * job, int width, bool right_justify, 
+			char* suffix);
 int _print_job_time_limit(job_info_t * job, int width, bool right_justify, 
 			char* suffix);
 int _print_job_time_used(job_info_t * job, int width, bool right_justify, 
diff --git a/src/squeue/sort.c b/src/squeue/sort.c
index 62bd4cad295236eb5e307d07493727f841f631a0..6f975d8f9a13b77098aea172729fd7bc1021eb4c 100644
--- a/src/squeue/sort.c
+++ b/src/squeue/sort.c
@@ -1,7 +1,8 @@
 /*****************************************************************************\
  *  sort.c - squeue sorting functions
  *****************************************************************************
- *  Copyright (C) 2002 The Regents of the University of California.
+ *  Copyright (C) 2002-2007 The Regents of the University of California.
+ *  Copyright (C) 2008-2009 Lawrence Livermore National Security.
  *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
  *  Written by Morris Jette <jette1@llnl.gov>, et. al.
  *  CODE-OCEC-09-009. All rights reserved.
@@ -57,6 +58,7 @@ static int _sort_job_by_name(void *void1, void *void2);
 static int _sort_job_by_state(void *void1, void *void2);
 static int _sort_job_by_state_compact(void *void1, void *void2);
 static int _sort_job_by_time_end(void *void1, void *void2);
+static int _sort_job_by_time_left(void *void1, void *void2);
 static int _sort_job_by_time_limit(void *void1, void *void2);
 static int _sort_job_by_time_start(void *void1, void *void2);
 static int _sort_job_by_time_used(void *void1, void *void2);
@@ -133,6 +135,8 @@ void sort_job_list(List job_list)
 			list_sort(job_list, _sort_job_by_min_threads);
 		else if (params.sort[i] == 'l')
 			list_sort(job_list, _sort_job_by_time_limit);
+		else if (params.sort[i] == 'L')
+			list_sort(job_list, _sort_job_by_time_left);
 		else if (params.sort[i] == 'm')
 			list_sort(job_list, _sort_job_by_min_memory);
 		else if (params.sort[i] == 'M')
@@ -482,13 +486,45 @@ static int _sort_job_by_time_end(void *void1, void *void2)
 	return diff;
 }
 
+static int _sort_job_by_time_left(void *void1, void *void2)
+{
+	int diff;
+	job_info_t *job1 = (job_info_t *) void1;
+	job_info_t *job2 = (job_info_t *) void2;
+	time_t time1, time2;
+
+	if ((job1->time_limit == INFINITE) || (job1->time_limit == NO_VAL))
+		time1 = INFINITE;
+	else
+		time1 = job1->time_limit - job_time_used(job1);
+	if ((job2->time_limit == INFINITE) || (job2->time_limit == NO_VAL))
+		time2 = INFINITE;
+	else
+		time2 = job2->time_limit - job_time_used(job2);
+	if (time1 > time2)
+		diff = 1;
+	else if (time1 == time2)
+		diff = 0;
+	else
+		diff = -1;
+
+	if (reverse_order)
+		diff = -diff;
+	return diff;
+}
+
 static int _sort_job_by_time_limit(void *void1, void *void2)
 {
 	int diff;
 	job_info_t *job1 = (job_info_t *) void1;
 	job_info_t *job2 = (job_info_t *) void2;
 
-	diff = job1->time_limit - job2->time_limit;
+	if (job1->time_limit > job2->time_limit)
+		diff = 1;
+	else if (job1->time_limit == job2->time_limit)
+		diff = 0;
+	else
+		diff = -1;
 
 	if (reverse_order)
 		diff = -diff;