]> git.ipfire.org Git - thirdparty/bugzilla.git/commitdiff
Bug 515515: For clients, mid-air collision results when user's timezone preference...
authorFrank Becker <Frank@Frank-Becker.de>
Fri, 2 Apr 2010 12:49:22 +0000 (14:49 +0200)
committerFrédéric Buclin <LpSolit@gmail.com>
Fri, 2 Apr 2010 12:49:22 +0000 (14:49 +0200)
r/a=mkanat

Bugzilla/Util.pm
process_bug.cgi

index 1d5785d34b63c39cd8e402629acec577bf2780dd..d8be89246d6daf28e329405ff8377210dd63b948 100644 (file)
@@ -40,7 +40,7 @@ use base qw(Exporter);
                              diff_arrays
                              trim wrap_hard wrap_comment find_wrap_point
                              format_time format_time_decimal validate_date
-                             validate_time
+                             validate_time datetime_from
                              file_mod_time is_7bit_clean
                              bz_crypt generate_random_password
                              validate_email_syntax clean_text
@@ -463,6 +463,46 @@ sub format_time {
     return trim($date);
 }
 
+sub datetime_from {
+    my ($date, $timezone) = @_;
+
+    # strptime($date) returns an empty array if $date has an invalid
+    # date format.
+    my @time = strptime($date);
+
+    unless (scalar @time) {
+        # If an unknown timezone is passed (such as MSK, for Moskow),
+        # strptime() is unable to parse the date. We try again, but we first
+        # remove the timezone.
+        $date =~ s/\s+\S+$//;
+        @time = strptime($date);
+    }
+
+    return undef if !@time;
+
+    # strptime() counts years from 1900, and months from 0 (January).
+    # We have to fix both values.
+    my $dt = DateTime->new({
+        year   => $time[5] + 1900,
+        month  => $time[4] + 1,
+        day    => $time[3],
+        hour   => $time[2],
+        minute => $time[1],
+        # DateTime doesn't like fractional seconds.
+        # Also, sometimes seconds are undef.
+        second => int($time[0] || 0),
+        # If a timezone was specified, use it. Otherwise, use the
+        # local timezone.
+        time_zone => Bugzilla->local_timezone->offset_as_string($time[6]) 
+                     || Bugzilla->local_timezone,
+    });
+
+    # Now display the date using the given timezone,
+    # or the user's timezone if none is given.
+    $dt->set_time_zone($timezone || Bugzilla->user->timezone);
+    return $dt;
+}
+
 sub format_time_decimal {
     my ($time) = (@_);
 
@@ -939,6 +979,15 @@ This routine is mainly called from templates to filter dates, see
 Returns a number with 2 digit precision, unless the last digit is a 0. Then it 
 returns only 1 digit precision.
 
+=item C<datetime_from($time, $timezone)>
+
+Returns a DateTime object given a date string. If the string is not in some
+valid date format that C<strptime> understands, we return C<undef>.
+
+You can optionally specify a timezone for the returned date. If not
+specified, defaults to the currently-logged-in user's timezone, or
+the Bugzilla server's local timezone if there isn't a logged-in user.
+
 =back
 
 
index 7df7b1c5f02e50e45bb0bb6a572953ad0070b73c..0432dc94f3bfc40c170d24d1748057ce17193c89 100755 (executable)
@@ -163,31 +163,34 @@ print $cgi->header() unless Bugzilla->usage_mode == USAGE_MODE_EMAIL;
 
 # Check for a mid-air collision. Currently this only works when updating
 # an individual bug.
-if (defined $cgi->param('delta_ts')
-    && $cgi->param('delta_ts') ne $first_bug->delta_ts)
+if (defined $cgi->param('delta_ts'))
 {
-    ($vars->{'operations'}) =
-        Bugzilla::Bug::GetBugActivity($first_bug->id, undef,
-                                      scalar $cgi->param('delta_ts'));
-
-    $vars->{'title_tag'} = "mid_air";
+    my $delta_ts_z = datetime_from($cgi->param('delta_ts'));
+    my $first_delta_tz_z =  datetime_from($first_bug->delta_ts);
+    if ($first_delta_tz_z ne $delta_ts_z) {
+       ($vars->{'operations'}) =
+           Bugzilla::Bug::GetBugActivity($first_bug->id, undef,
+                                         scalar $cgi->param('delta_ts'));
+
+       $vars->{'title_tag'} = "mid_air";
     
-    ThrowCodeError('undefined_field', { field => 'longdesclength' })
-        if !defined $cgi->param('longdesclength');
-
-    $vars->{'start_at'} = $cgi->param('longdesclength');
-    # Always sort midair collision comments oldest to newest,
-    # regardless of the user's personal preference.
-    $vars->{'comments'} = Bugzilla::Bug::GetComments($first_bug->id,
-                                                     "oldest_to_newest");
-    $vars->{'bug'} = $first_bug;
-    # The token contains the old delta_ts. We need a new one.
-    $cgi->param('token', issue_hash_token([$first_bug->id, $first_bug->delta_ts]));
+       ThrowCodeError('undefined_field', { field => 'longdesclength' })
+           if !defined $cgi->param('longdesclength');
+
+       $vars->{'start_at'} = $cgi->param('longdesclength');
+       # Always sort midair collision comments oldest to newest,
+       # regardless of the user's personal preference.
+       $vars->{'comments'} = Bugzilla::Bug::GetComments($first_bug->id,
+                                                        "oldest_to_newest");
+       $vars->{'bug'} = $first_bug;
+       # The token contains the old delta_ts. We need a new one.
+       $cgi->param('token', issue_hash_token([$first_bug->id, $first_bug->delta_ts]));
     
-    # Warn the user about the mid-air collision and ask them what to do.
-    $template->process("bug/process/midair.html.tmpl", $vars)
-      || ThrowTemplateError($template->error());
-    exit;
+       # Warn the user about the mid-air collision and ask them what to do.
+       $template->process("bug/process/midair.html.tmpl", $vars)
+         || ThrowTemplateError($template->error());
+       exit;
+    }
 }
 
 # We couldn't do this check earlier as we first had to validate bug IDs