diff options
author | Frank Becker <Frank@Frank-Becker.de> | 2010-04-02 14:49:22 +0200 |
---|---|---|
committer | Frédéric Buclin <LpSolit@gmail.com> | 2010-04-02 14:49:22 +0200 |
commit | 929eec53d42d93313125e17d43ccc15e0e4f348c (patch) | |
tree | a5586d4f5c93329b8f401fcfd4318e4979c4eeea | |
parent | Bug 548327: Administration page should have hooks to extend the admin links (diff) | |
download | bugzilla-929eec53d42d93313125e17d43ccc15e0e4f348c.tar.gz bugzilla-929eec53d42d93313125e17d43ccc15e0e4f348c.tar.bz2 bugzilla-929eec53d42d93313125e17d43ccc15e0e4f348c.zip |
Bug 515515: For clients, mid-air collision results when user's timezone preference differs from server's
r/a=mkanat
-rw-r--r-- | Bugzilla/Util.pm | 51 | ||||
-rwxr-xr-x | process_bug.cgi | 47 |
2 files changed, 75 insertions, 23 deletions
diff --git a/Bugzilla/Util.pm b/Bugzilla/Util.pm index 1d5785d34..d8be89246 100644 --- a/Bugzilla/Util.pm +++ b/Bugzilla/Util.pm @@ -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 diff --git a/process_bug.cgi b/process_bug.cgi index 7df7b1c5f..0432dc94f 100755 --- a/process_bug.cgi +++ b/process_bug.cgi @@ -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 |