diff options
author | Jeff Fearn <jfearn@redhat.com> | 2020-08-20 14:24:55 +1000 |
---|---|---|
committer | Jeff Fearn <jfearn@redhat.com> | 2020-08-20 14:24:55 +1000 |
commit | 62f52ea62badf8d16ffd7f6cedd8c3e9fb93d4f0 (patch) | |
tree | 3eb96a4b0304eca435b55a22c1a6569d3b44f4c8 /Bugzilla/Search.pm | |
parent | Bug 1554359 - Doc text awaiting approval is reset to default when another per... (diff) | |
download | bugzilla-62f52ea62badf8d16ffd7f6cedd8c3e9fb93d4f0.tar.gz bugzilla-62f52ea62badf8d16ffd7f6cedd8c3e9fb93d4f0.tar.bz2 bugzilla-62f52ea62badf8d16ffd7f6cedd8c3e9fb93d4f0.zip |
Bug 1818852 - DB error: Subtracting 1 month from 2020-03-30 yields 2020-02-30, which is out of range
Use DateTime module for date math.
Change-Id: Ifefee9e821e7a05ab22e74df4481bced8fd56b0e
Diffstat (limited to 'Bugzilla/Search.pm')
-rw-r--r-- | Bugzilla/Search.pm | 87 |
1 files changed, 31 insertions, 56 deletions
diff --git a/Bugzilla/Search.pm b/Bugzilla/Search.pm index a384b5445..a3ca60a64 100644 --- a/Bugzilla/Search.pm +++ b/Bugzilla/Search.pm @@ -2379,68 +2379,43 @@ sub SqlifyDate { my ($str) = @_; my $fmt = "%Y-%m-%d %H:%M:%S"; $str = "" if (!defined $str || lc($str) eq 'now'); + + ## REDHAT EXTENSION START 1818852 + my $dt; + # Use users timezone for creating dates + my $usr_tz = Bugzilla->user->timezone; + if ($str eq "") { - my ($sec, $min, $hour, $mday, $month, $year, $wday) = localtime(time()); - return sprintf("%4d-%02d-%02d 00:00:00", $year + 1900, $month + 1, $mday); + $dt = DateTime->now(time_zone => $usr_tz); } - - if ($str =~ /^(-|\+)?(\d+)([hdwmy])(s?)$/i) { # relative date - my ($sign, $amount, $unit, $startof, $date) = ($1, $2, lc $3, lc $4, time); - my ($sec, $min, $hour, $mday, $month, $year, $wday) = localtime($date); - if ($sign && $sign eq '+') { $amount = -$amount; } + elsif ($str =~ /^(-|\+)?(\d+)([hdwmy])(s?)$/i) { # relative date + my ($sign, $amount, $unit, $startof) = ($1, $2, lc $3, lc $4); $startof = 1 if $amount == 0; - if ($unit eq 'w') { # convert weeks to days - $amount = 7 * $amount; - $amount += $wday if $startof; - $unit = 'd'; - } - if ($unit eq 'd') { - if ($startof) { - $fmt = "%Y-%m-%d 00:00:00"; - $date -= $sec + 60 * $min + 3600 * $hour; - } - $date -= 24 * 3600 * $amount; - return time2str($fmt, $date); - } - elsif ($unit eq 'y') { - if ($startof) { - return sprintf("%4d-01-01 00:00:00", $year + 1900 - $amount); - } - else { - return sprintf( - "%4d-%02d-%02d %02d:%02d:%02d", - $year + 1900 - $amount, - $month + 1, $mday, $hour, $min, $sec - ); - } - } - elsif ($unit eq 'm') { - $month -= $amount; - $year += floor($month / 12); - $month %= 12; - if ($startof) { - return sprintf("%4d-%02d-01 00:00:00", $year + 1900, $month + 1); - } - else { - return sprintf( - "%4d-%02d-%02d %02d:%02d:%02d", - $year + 1900, - $month + 1, $mday, $hour, $min, $sec - ); - } - } - elsif ($unit eq 'h') { + $sign //= '+'; - # Special case for 'beginning of an hour' - if ($startof) { - $fmt = "%Y-%m-%d %H:00:00"; - } - $date -= 3600 * $amount; - return time2str($fmt, $date); + my %wordmap = (qw(h hour d day w week m month y year)); + die("Unable to parse '$str' as a relative date (unknown character '$unit')") + unless exists($wordmap{$unit}); + + eval { + $dt = DateTime->now(time_zone => $usr_tz); + $dt->add($wordmap{$unit} . 's' => "$sign$amount"); + }; + die "Unable to add $sign$amount $unit's" if ($@); + + if ($startof) { + $dt->truncate(to => $wordmap{$unit}); } - return undef; # should not happen due to regexp at top } - my $date = str2time($str); + + if ($dt) { + # convert local TZ for search as that is used in the DB + $dt->set_time_zone(Bugzilla->local_timezone); + return ($dt->strftime($fmt)); + } + ## REDHAT EXTENSION END 1818852 + + my $date = str2time($str, $usr_tz); if (!defined($date)) { ThrowUserError("illegal_date", {date => $str}); } |