View Issue Details

IDProjectCategoryView StatusLast Update
0009140mantisbtotherpublic2014-06-11 14:51
ReporterBlue Ninja Assigned Tograngeway  
PrioritynormalSeverityminorReproducibilityalways
Status closedResolutionno change required 
Product Version1.2.0a1 
Summary0009140: Blank due date on issue update shouldn't account for time zone.
Description

When I update an issue and leave the due date field blank, a value of "1970-01-01 00:05:01" is placed into the database. My GMT offset is 5, so I think what's happening is that the null date defaults to "1970-01-01 00:00:01" (incidentally, why is that, instead of just leaving the column null?), which seems to be the "special date" that corresponds to a null value. However, the local time offset seems to be applied to this date, thus changing it before storing it in the DB. As a result, modified issues show up as being due at 5am a very, very long time ago! :-)

When there is a null date for that field being written, it should be set AFTER any time zone adjustments. Or, it should "un-adjust" for the time zone, such that after it is adjusted, the end result is the original, correct "1970-01-01 00:00:01" value.

Tagspatch
Attached Files
due_date_with_null_values.patch (10,912 bytes)   
Index: mantisbt/admin/schema.php
===================================================================
--- mantisbt/admin/schema.php	(revision 5358)
+++ mantisbt/admin/schema.php	(working copy)
@@ -405,7 +405,7 @@
 $upgrade[] = Array( 'AddColumnSQL', Array( db_get_table( 'mantis_project_version_table' ), "
 	obsolete		L		NOTNULL DEFAULT \" '0' \"" ) );
 $upgrade[] = Array( 'AddColumnSQL', Array( db_get_table( 'mantis_bug_table' ), "
-    due_date        T       NOTNULL DEFAULT '" . db_null_date() . "' " ) );
+    due_date        T       NULL DEFAULT '" . db_null_date() . "' " ) );
 
 $upgrade[] = Array( 'AddColumnSQL', Array( db_get_table( 'mantis_custom_field_table' ), "
   filter_by 		L 		NOTNULL DEFAULT \" '1' \"" ) );
Index: mantisbt/bug_change_status_page.php
===================================================================
--- mantisbt/bug_change_status_page.php	(revision 5358)
+++ mantisbt/bug_change_status_page.php	(working copy)
@@ -176,7 +176,7 @@
 	<td>
 	<?php
 	    print "<input ".helper_get_tab_index()." type=\"text\" id=\"due_date\" name=\"due_date\" size=\"20\" maxlength=\"10\" value=\"".$t_date_to_display."\">";
-		date_print_calendar( );
+		date_print_calendar( "due_date", "due_date_calendar_trigger" );
 	?>
 	</td>
 </tr>
Index: mantisbt/bug_report_advanced_page.php
===================================================================
--- mantisbt/bug_report_advanced_page.php	(revision 5358)
+++ mantisbt/bug_report_advanced_page.php	(working copy)
@@ -118,7 +118,7 @@
 		$f_view_state			= gpc_get_int( 'view_state', config_get( 'default_bug_view_status' ) );
 		$f_due_date				=gpc_get_string( 'due_date', '');
 
-		if ( $f_due_date == '' ) {
+		if ( is_blank ( $f_due_date ) ) {
 			$f_due_date = date_get_null();
 		}
 
@@ -231,7 +231,7 @@
 	<td>
 	<?php
 	    print "<input ".helper_get_tab_index()." type=\"text\" id=\"due_date\" name=\"due_date\" size=\"20\" maxlength=\"10\" value=\"".$t_date_to_display."\">";
-		date_print_calendar();
+		date_print_calendar( "due_date", "due_date_calendar_trigger" );
 	?>
 	</td>
 </tr>
Index: mantisbt/bug_update.php
===================================================================
--- mantisbt/bug_update.php	(revision 5358)
+++ mantisbt/bug_update.php	(working copy)
@@ -79,7 +79,7 @@
 	$t_bug_data->summary			= gpc_get_string( 'summary', $t_bug_data->summary );
 	$t_bug_data->due_date 				= gpc_get_string( 'due_date', $t_bug_data->due_date);
 
-	if ( is_blank ( $t_bug_data->due_date ) ) {
+	if ( date_is_null( $t_bug_data->due_date ) ) {
 		$t_bug_data->due_date = date_get_null( );
 	} else {
 		$t_bug_data->due_date = db_unixtimestamp ( $t_bug_data->due_date, true ) + 1;
Index: mantisbt/bug_update_advanced_page.php
===================================================================
--- mantisbt/bug_update_advanced_page.php	(revision 5358)
+++ mantisbt/bug_update_advanced_page.php	(working copy)
@@ -190,8 +190,8 @@
 ?>
 	</td>
 
+	<!-- Due Date -->
 <?php if ( access_has_bug_level( config_get( 'due_date_view_threshold' ), $f_bug_id ) ) { ?>
-	<!-- Due Date -->
 	<td class="category">
 		<?php echo lang_get( 'due_date' ) ?>
 	</td>
@@ -207,11 +207,11 @@
 			$t_date_to_display = date( config_get( 'short_date_format' ), $t_bug->due_date );
 		}
 	    print "<input ".helper_get_tab_index()." type=\"text\" id=\"due_date\" name=\"due_date\" size=\"20\" maxlength=\"10\" value=\"".$t_date_to_display."\">";
-		date_print_calendar( );
+		date_print_calendar( "due_date", "due_date_calendar_trigger" );
 	?>
 	</td>
 	<?php } else {
-		if ( $t_bug->due_date != $t_null_date  ) print_date( config_get( 'short_date_format' ), $t_bug->due_date  ); }?>
+		if ( !date_is_null( $t_bug->due_date )  ) print_date( config_get( 'short_date_format' ), $t_bug->due_date  ); }?>
 	</td>
 <?php } else { ?>
 		<!-- spacer -->
Index: mantisbt/core/bug_api.php
===================================================================
--- mantisbt/core/bug_api.php	(revision 5358)
+++ mantisbt/core/bug_api.php	(working copy)
@@ -78,7 +78,7 @@
 		var $_stats = null;
 		
 		#due date
-		var $due_date = '';
+		var $due_date = null;
 	}
 
 	#===================================
@@ -198,7 +198,10 @@
 		if( !is_int( $p_bug_row['last_updated'] ) )
 			$p_bug_row['last_updated']	= db_unixtimestamp( $p_bug_row['last_updated'] );
 		if( !is_int( $p_bug_row['due_date'] ) ) 
+			if( !date_is_null( $p_bug_row['due_date']) )
 			$p_bug_row['due_date']	= db_unixtimestamp( $p_bug_row['due_date'] );
+			else
+				$p_bug_row['due_date'] = '';
 		$g_cache_bug[ (int)$p_bug_row['id'] ] = $p_bug_row;
 
 		if( !is_null( $p_stats ) ) {
@@ -394,7 +397,7 @@
 	function bug_is_overdue( $p_bug_id ) {
 		$t_due_date = bug_get_field( $p_bug_id, 'due_date');
 		if (  ! date_is_null( $t_due_date)  ) {
-			$t_now = db_unixtimestamp();
+			$t_now = db_unixtimestamp(time());
 			if ( $t_now > $t_due_date ) {
 				if ( !bug_is_resolved( $p_bug_id ) ) {
 					return true;
@@ -502,9 +505,10 @@
 		}
 
 		#check due_date format
-		if ( !is_blank( $p_bug_data->due_date ) ) {
+		if ( !date_is_null( $p_bug_data->due_date ) && !is_blank( $p_bug_data->due_date ) ) {
 			$c_due_date	= db_bind_timestamp( $p_bug_data->due_date, true );
-		}
+		} else
+			$c_due_date = null;
 
 		$t_bug_table				= db_get_table( 'mantis_bug_table' );
 		$t_bug_text_table			= db_get_table( 'mantis_bug_text_table' );
@@ -954,10 +958,10 @@
 			trigger_error( ERROR_BUG_DUPLICATE_SELF, ERROR );  # never returns
 	    }
 
-		if ( !is_blank( $p_bug_data->due_date ) ) {
+		if ( !date_is_null( $p_bug_data->due_date ) ) {
 			$c_due_date	= db_bind_timestamp( $p_bug_data->due_date, true);
 		} else {
-			$c_due_date = db_null_date();
+			$c_due_date = null;
 		}
 
 		$t_old_data = bug_get( $p_bug_id, true );
@@ -1045,8 +1049,8 @@
 		history_log_event_direct( $p_bug_id, 'sponsorship_total', $t_old_data->sponsorship_total, $p_bug_data->sponsorship_total );
 		history_log_event_direct( $p_bug_id, 'sticky', $t_old_data->sticky, $p_bug_data->sticky );
 		
-		history_log_event_direct( $p_bug_id, 'due_date', ( $t_old_data->due_date != db_unixtimestamp( db_null_date() ) ) ? $t_old_data->due_date : null, 
-														 ( $p_bug_data->due_date != db_unixtimestamp( db_null_date() ) ) ? $p_bug_data->due_date : null );
+		history_log_event_direct( $p_bug_id, 'due_date', ( !date_is_null($t_old_data->due_date) ) ? $t_old_data->due_date : null, 
+														 ( !date_is_null($p_bug_data->due_date) ) ? $p_bug_data->due_date : null );
 
 		# Update extended info if requested
 		if ( $p_update_extended ) {
@@ -1407,10 +1411,15 @@
 			#dates
 			case 'last_updated':
 			case 'date_submitted':
-			case 'due_date':
 				$c_value = db_bind_timestamp( $p_value );
 				break;			
 			
+			case 'due_date':
+				if( date_is_null( $p_value ) )
+					$c_value = null;
+				else
+					$c_value = db_bind_timestamp( $p_value );
+			
 			default:
 				trigger_error( ERROR_DB_FIELD_NOT_FOUND, WARNING );
 				break;
Index: mantisbt/core/database_api.php
===================================================================
--- mantisbt/core/database_api.php	(revision 5358)
+++ mantisbt/core/database_api.php	(working copy)
@@ -715,13 +715,13 @@
 	 * @return string Formatted Date for DB insertion e.g. 1970-01-01 00:00:00 ready for database insertion
 	 * @todo review date handling
 	 */
-	function db_timestamp( $p_date=null, $p_gmt = false ) {
+	function db_timestamp( $p_date, $p_gmt = false ) {
 		global $g_db;
 
 		if ( null !== $p_date ) {
 			$p_timestamp = $g_db->UnixTimeStamp($p_date, $p_gmt);
 		} else {
-			$p_timestamp = time();
+			trigger_error();
 		}
 		return $g_db->BindTimeStamp($p_timestamp) ;
 	}
@@ -733,13 +733,13 @@
 	 * @return int unix timestamp of a date
 	 * @todo review date handling
 	 */
-	function db_unixtimestamp( $p_date=null, $p_gmt = false ) {
+	function db_unixtimestamp( $p_date, $p_gmt = false ) {
 		global $g_db;
 
 		if ( null !== $p_date ) {
 			$p_timestamp = $g_db->UnixTimeStamp($p_date, $p_gmt);
 		} else {
-			$p_timestamp = time();
+			trigger_error();
 		}
 		return $p_timestamp ;
 	}
Index: mantisbt/core/date_api.php
===================================================================
--- mantisbt/core/date_api.php	(revision 5358)
+++ mantisbt/core/date_api.php	(working copy)
@@ -25,13 +25,13 @@
 	# --------------------
 	# checks if date is null
 	function date_is_null( $p_date ) {
-		return $p_date == date_get_null();
+		return $p_date === null || is_blank($p_date);
 	}
 
 	# --------------------
 	# gets null date 
 	function date_get_null() {
-		return db_unixtimestamp( db_null_date() );
+		return null;
 	}
 
 	# --------------------
@@ -165,7 +165,7 @@
 	# prints calendar icon and adds required javascript files.
 	# button_name is name of button that will display calendar icon
 	# in caste there are more than one calendar on page
-	function date_print_calendar ( $p_button_name = 'trigger' ) {
+	function date_print_calendar ( $p_field_name, $p_button_name = 'trigger' ) {
 		# @@@ (thraxisp) this may want a browser check  ( MS IE >= 5.0, Mozilla >= 1.0, Safari >=1.2, ...)
         if ( ( ON == config_get( 'dhtml_filters' ) ) && ( ON == config_get( 'use_javascript' ) ) ){
 			echo "<style type=\"text/css\">@import url(javascript/jscalendar/calendar-blue.css);</style>\n";
@@ -179,8 +179,20 @@
 			$t_format = config_get( 'short_date_format' );
 			$t_new_format = str_replace( '-', '-%', $t_format );
 			$t_format = "%".$t_new_format;
-			echo "\" onClick=\"return showCalendar ('sel1', '".$t_format."', 24, true)\" />";
+			#echo "\" onClick=\"return showCalendar ('sel1', '".$t_format."', 24, true)\" />";
+			echo "\" />";
+			?>
+<script type="text/javascript">
+	Calendar.setup(
+		{
+			inputField : "<?php echo $p_field_name; ?>", // ID of the input field
+			ifFormat : "<?php echo $t_format; ?>", // the date format
+			button : "<?php echo $p_button_name; ?>" // ID of the button
 		}
+	);
+</script>
+			<?php
+		}
 	}
 	# --------------------
 	# creates javascript calendar objects, point to input element ($p_field_name) that
Index: mantisbt/core/history_api.php
===================================================================
--- mantisbt/core/history_api.php	(revision 5358)
+++ mantisbt/core/history_api.php	(working copy)
@@ -317,8 +317,8 @@
 				$t_field_localized = lang_get( 'sponsorship_total' );
 				break;
 			case 'due_date':
-				$p_old_value = date( config_get( 'short_date_format' ), (int)$p_old_value );
-				$p_new_value = date( config_get( 'short_date_format' ), (int)$p_new_value );
+				$p_old_value = (!date_is_null($p_old_value)) ? date( config_get( 'short_date_format' ), (int)$p_old_value ) : 'none';
+				$p_new_value = (!date_is_null($p_new_value)) ? date( config_get( 'short_date_format' ), (int)$p_new_value ) : 'none';
 				$t_field_localized = lang_get( 'due_date' );				
 				break;
 			default:
due_date_with_null_values.patch (10,912 bytes)   

Relationships

has duplicate 0009231 closedjreese unfilled Due Date or reported in easy view 

Activities

grangeway

grangeway

2008-05-12 16:14

reporter   ~0017815

can you test against trunk ?

Paul

Blue Ninja

Blue Ninja

2008-05-12 16:18

reporter   ~0017816

This is using the latest source from svn (5268), as well as the last few revisions.

giallu

giallu

2008-05-13 03:07

reporter   ~0017817

I wonder why we just couldn't use a null value to identify, you know, null values

Blue Ninja

Blue Ninja

2008-05-31 20:44

reporter   ~0017975

Note that this seems to be affecting this site as well, as many issues in this tracker now have due dates of 1-1-1970 :-)

vboctor

vboctor

2008-06-01 02:42

manager   ~0017977

I wanted to use null as well when due dates are not set. I asked sm1go about the reason and he may have mentioned something related to database portability. We should ask him again when he is on the IRC channel. I would like to have the due date working fine (i.e. no 1970 due dates) by the time we release 1.2.0a2.

giallu

giallu

2008-06-01 04:23

reporter   ~0017978

Last edited: 2008-06-01 04:38

Oh. this reminds me I actually asked him about the topic:

<pre>
May 29 08:50:43 giallu I still can't understand why we can't store "null" for a null date
May 29 08:51:00 smig1o check bug_get_field function
May 29 08:51:11 smig1o it trigger error
May 29 08:51:19 smig1o if field value == NULL
May 29 08:51:46 smig1o thats why all fields in mantis database are NOT NULL
May 29 08:51:56 giallu mmm so what's in optional fields when I'm not filling those
May 29 08:52:19 smig1o no idea
May 29 08:52:27 smig1o 0
May 29 08:52:31 smig1o empty string??
</pre>

Blue Ninja

Blue Ninja

2008-06-01 04:57

reporter   ~0017979

Interesting. As a developer, it seems incredible to me that an application would be unable to deal with null values in a database, as they are encountered and expected quite frequently in nearly all database applications, and this makes me wonder if this doesn't indicate a critical design flaw at a lower level.

I've always thought and been taught that coding "special values" as placeholders for null was bad practice, and this does go against many design guidelines. Perhaps it would be best to fix whatever is wrong with bug_get_field? Surely that would be a cleaner approach than writing special code to pretend that certain values really mean null (as it is now), and then doing extra work to un-adjuzt those values with respect to the time zone, all to sidestep the issue of not just using nulls?

Anyhow, that's just my thoughts on it. One way or the other, hopefully it gets resolved! Thanks.

jreese

jreese

2008-06-02 09:06

reporter   ~0017990

I have to agree with Giallu and Blue Ninja; I think the best course of action would be to enhance bug_get_field() to see NULL and return null for any appropriate fields (eg, just due date for now), rather than trying to store a false date. This has been bugging me ever since due dates were pushed into trunk...

mthibeault

mthibeault

2008-06-03 11:32

reporter   ~0017999

Tracked the due date bug up to adodb. The UnixTimeStamp function doesn't use the $is_gmt parameter of adodb_mktime and the default of $is_gmt is false.

Reference:
adodb.inc.php:2505-2522
adodb-time.inc.php:1199

sergioan

sergioan

2008-06-04 11:03

reporter   ~0018005

Though I agreed on using "null" value for data=nothing, on this particular case, I rather will use the same TimeStamp as the one use for the creation of the issue.
That way, the issue will have a "reasonable" date but at the same time, it will be DUE. It will bring inmediate attention and from there on, who has the permissions can set the correct value. This will work in a simple manner and at least, will keep the ugly date out till a fix is in place.

Blue Ninja

Blue Ninja

2008-06-04 11:09

reporter   ~0018006

I don't think making an issue default to being due immediately is very helpful, because in many projects and issues, there is no need for a specific due date. This will require that someone with higher access than a reporter manually update every single issue posted to remove an unnecessary due date that can't even be set to nothing to begin with.

While in some cases for internal commercial projects a due date is assigned to most (or even all) issues, there are a great many cases where it is either not used, or needs to be set by someone with a higher access level than "Reporter". And in both of these cases, defaulting it to be due immediately will cause more unnecessary work to "cleanup" the bad data for each issue.

At least, that's my personal take on it.

sergioan

sergioan

2008-06-04 11:19

reporter   ~0018007

Taken Note. The difference on my side is that normally, the reporters don't input a due date (or are not allowed to) cause they don't have the knowledge to know the time frame need it for the issue.
On the other side, there is already an issue requesting due date linked to Project - Category - (Maybe assigned).
That will be a sort of adding the projection or ETA to the "assigned" Date.

Anyway. The good part is that we can see how open is a system and the different ways to use it.
Cheers

giallu

giallu

2008-06-05 02:33

reporter   ~0018010

I also agree with Blue Ninja, possibly because I use milestones (a.k.a unreleased versions) to target issues, so bugs are due to when the release is made...

svecpetr

svecpetr

2008-06-12 00:36

reporter   ~0018062

Last edited: 2008-06-12 00:36

It seems to like that nobody want's to correct it :(

jreese

jreese

2008-06-12 07:59

reporter   ~0018067

This is being worked on by Paul.

mthibeault

mthibeault

2008-06-12 15:56

reporter   ~0018068

due_date_with_null_values.patch

Proposing a solution that involves null database values.
Patch against trunk revision 5358.

Supp

Supp

2009-01-22 18:16

reporter   ~0020690

When used with 1.2a2 or 1.2a3
this patch supresses all traces of 'overdue' status
e.g. overdue items are not red, etc.

Just want you to know (being fully aware of alpha/beta status of due date
function)

grangeway

grangeway

2014-05-27 14:38

reporter   ~0040654

Marking this as resolved - no change required - appears to be fixed in newer releases of MantisBT.

I'm struggling to reproduce this, and the date submitted timestamp for this issue of 2008, is before we converted due dates (or well, dates in general) to integer values due to issues with using DateTime fields in the DB with things like this.

If anyone is still reading this, and can come up with a more modern / current bug report on the functionality, that can be easily reproduced, we can look at getting the new issue(s) fixed properly.