# Retrieve a list of attachments for this bug and write them into an array
# of hashes in which each hash represents a single attachment.
&::SendSQL("
- SELECT attach_id, creation_ts, mimetype, description, ispatch,
- isobsolete, isprivate, submitter_id
+ SELECT attach_id, DATE_FORMAT(creation_ts, '%Y.%m.%d %H:%i'),
+ mimetype, description, ispatch, isobsolete, isprivate, submitter_id
FROM attachments WHERE bug_id = $bugid ORDER BY attach_id
");
my @attachments = ();
$a{'ispatch'}, $a{'isobsolete'}, $a{'isprivate'}, $submitter_id)
= &::FetchSQLData();
- # Format the attachment's creation/modification date into a standard
- # format (YYYY-MM-DD HH:MM)
- if ($a{'date'} =~ /^(\d\d\d\d)(\d\d)(\d\d)(\d\d)(\d\d)(\d\d)$/) {
- $a{'date'} = "$1-$2-$3 $4:$5";
- }
-
# Retrieve a list of flags for this attachment.
$a{'flags'} = Bugzilla::Flag::match({ 'attach_id' => $a{'attachid'} });
# Retrieve a list of attachments for this bug and write them into an array
# of hashes in which each hash represents a single attachment.
&::SendSQL("
- SELECT attach_id, creation_ts, mimetype, description, ispatch,
- isobsolete, isprivate, submitter_id
+ SELECT attach_id, DATE_FORMAT(creation_ts, '%Y.%m.%d %H:%i'),
+ mimetype, description, ispatch, isobsolete, isprivate, submitter_id
FROM attachments WHERE bug_id = $bugid ORDER BY attach_id
");
my @attachments = ();
$a{'ispatch'}, $a{'isobsolete'}, $a{'isprivate'}, $submitter_id)
= &::FetchSQLData();
- # Format the attachment's creation/modification date into a standard
- # format (YYYY-MM-DD HH:MM)
- if ($a{'date'} =~ /^(\d\d\d\d)(\d\d)(\d\d)(\d\d)(\d\d)(\d\d)$/) {
- $a{'date'} = "$1-$2-$3 $4:$5";
- }
-
# Retrieve a list of flags for this attachment.
$a{'flags'} = Bugzilla::Flag::match({ 'attach_id' => $a{'attachid'} });
package Bugzilla::Util;
+use Bugzilla::Config;
+
use base qw(Exporter);
@Bugzilla::Util::EXPORT = qw(is_tainted trick_taint detaint_natural
html_quote url_quote value_quote
lsearch max min
- trim);
+ trim format_time);
use strict;
return $str;
}
+# Bug 67077
+sub format_time {
+ my ($time) = @_;
+
+ my ($year, $month, $day, $hour, $min);
+ if ($time =~ m/^\d{14}$/) {
+ # We appear to have a timestamp direct from MySQL
+ $year = substr($time,0,4);
+ $month = substr($time,4,2);
+ $day = substr($time,6,2);
+ $hour = substr($time,8,2);
+ $min = substr($time,10,2);
+ }
+ elsif ($time =~ m/^(\d{4})\.(\d{2})\.(\d{2}) (\d{2}):(\d{2})(:\d{2})?$/) {
+ $year = $1;
+ $month = $2;
+ $day = $3;
+ $hour = $4;
+ $min = $5;
+ }
+ else {
+ warn "Date/Time format ($time) unrecogonzied";
+ }
+
+ if (defined $year) {
+ $time = "$year-$month-$day $hour:$min " . &::Param('timezone');
+ }
+ return $time;
+}
+
1;
__END__
# Functions for trimming variables
$val = trim(" abc ");
+ # Functions for formatting time
+ format_time($time);
+
=head1 DESCRIPTION
This package contains various utility functions which do not belong anywhere
modify the existing string.
=back
+
+=head2 Formatting Time
+
+=over 4
+
+=item C<format_time($time)>
+
+Takes a time and appends the timezone as defined in editparams.cgi. This routine
+will be expanded in the future to adjust for user preferences regarding what
+timezone to display times in. In the future, it may also allow for the time to be
+shown in different formats.
+
+=back
+
SELECT IFNULL(fielddefs.description, bugs_activity.fieldid),
fielddefs.name,
bugs_activity.attach_id,
- bugs_activity.bug_when,
+ DATE_FORMAT(bugs_activity.bug_when,'%Y.%m.%d %H:%i'),
bugs_activity.removed, bugs_activity.added,
profiles.login_name
FROM bugs_activity LEFT JOIN fielddefs ON
if (Param("insidergroup") && !(UserInGroup(Param("insidergroup")))) {
$privacy = "AND isprivate < 1 ";
}
- SendSQL("SELECT attach_id, creation_ts, mimetype, description,
- ispatch, isobsolete, isprivate
+ SendSQL("SELECT attach_id, DATE_FORMAT(creation_ts, '%Y.%m.%d %H:%i'),
+ mimetype, description, ispatch, isobsolete, isprivate
FROM attachments WHERE bug_id = $::FORM{'bugid'} $privacy
ORDER BY attach_id");
my @attachments; # the attachments array
bug_severity, bugs.component_id, components.name, assigned_to,
reporter, bug_file_loc, short_desc, target_milestone,
qa_contact, status_whiteboard,
- date_format(creation_ts,'%Y-%m-%d %H:%i'),
- delta_ts, sum(votes.count), delta_ts calc_disp_date,
+ DATE_FORMAT(creation_ts,'%Y.%m.%d %H:%i'), delta_ts, sum(votes.count),
estimated_time, remaining_time
FROM bugs LEFT JOIN votes USING(bug_id), products, components
WHERE bugs.bug_id = $id
"priority", "bug_severity", "component_id", "component",
"assigned_to", "reporter", "bug_file_loc", "short_desc",
"target_milestone", "qa_contact", "status_whiteboard",
- "creation_ts", "delta_ts", "votes", "calc_disp_date",
+ "creation_ts", "delta_ts", "votes",
"estimated_time", "remaining_time")
{
$value = shift(@row);
- if ($field eq "calc_disp_date") {
- # Convert MySQL timestamp (_ts) to datetime format(%Y-%m-%d %H:%i)
- $disp_date = substr($value,0,4) . '-';
- $disp_date .= substr($value,4,2) . '-';
- $disp_date .= substr($value,6,2) . ' ';
- $disp_date .= substr($value,8,2) . ':';
- $disp_date .= substr($value,10,2);
- $value = $disp_date;
- }
$bug{$field} = defined($value) ? $value : "";
}
html_linebreak => sub { return $_; },
url_quote => sub { return $_; },
csv => sub { return $_; },
+ time => sub { return $_; },
},
}) || die ("Could not create Template Provider: "
. Template::Provider->error() . "\n");
default => '/'
},
+ {
+ name => 'timezone',
+ desc => 'The timezone that your SQL server lives in. If set to "" then' .
+ 'the timezone can\'t be displayed with the timestamps.',
+ type => 't',
+ default => '',
+ },
+
{
name => 'enablequips',
desc => 'Controls the appearance of quips at the top of buglists.<ul> ' .
my $result = "";
my $count = 0;
my $anyprivate = 0;
- my ($query) = ("SELECT profiles.login_name, longdescs.bug_when, " .
+ my ($query) = ("SELECT profiles.login_name, DATE_FORMAT(longdescs.bug_when,'%Y.%d.%m %H:%i'), " .
" longdescs.thetext, longdescs.isprivate " .
"FROM longdescs, profiles " .
"WHERE profiles.userid = longdescs.who " .
my ($who, $when, $text, $isprivate, $work_time) = (FetchSQLData());
if ($count) {
$result .= "\n\n------- Additional Comments From $who".Param('emailsuffix')." ".
- time2str("%Y-%m-%d %H:%M", str2time($when)) . " -------\n";
+ Bugzilla::Util::format_time($when) . " -------\n";
}
if (($isprivate > 0) && Param("insidergroup")) {
$anyprivate = 1;
my ($id) = (@_);
my @comments;
SendSQL("SELECT profiles.realname, profiles.login_name,
- date_format(longdescs.bug_when,'%Y-%m-%d %H:%i'),
+ date_format(longdescs.bug_when,'%Y.%m.%d %H:%i'),
longdescs.thetext, longdescs.work_time,
isprivate,
date_format(longdescs.bug_when,'%Y%m%d%H%i%s')
}
return $var;
} ,
+
+ # Format a time for display (more info in Bugzilla::Util)
+ time => \&Bugzilla::Util::format_time,
} ,
}
) || die("Template creation failed: " . Template->error());
flags.attach_id, attachments.description,
requesters.realname, requesters.login_name,
requestees.realname, requestees.login_name,
- flags.creation_date,
+ DATE_FORMAT(flags.creation_date,'%Y.%m.%d %H:%i'),
" .
# Select columns that help us weed out secure bugs to which the user
# should not have access.
strike => sub { return $_ } ,
url_quote => sub { return $_ } ,
csv => sub { return $_ } ,
+ time => sub { return $_ } ,
},
}
);
use Support::Files;
BEGIN {
- use Test::More tests => 10;
+ use Test::More tests => 12;
use_ok(Bugzilla::Util);
}
+# We need to override the the Param() function so we can get an expected
+# value when Bugzilla::Utim::format_time calls asks for Param('timezone').
+# This will also prevent the tests from failing on site that do not have a
+# data/params file containing Param('timezone') yet.
+sub myParam {
+ return "TEST" if $_[0] eq 'timezone';
+}
+*::Param = *myParam;
+
# we don't test the taint functions since that's going to take some more work.
# XXX: test taint functions
#trim():
is(trim(" fg<*\$%>+=~~ "),'fg<*$%>+=~~','trim()');
+
+#format_time();
+is(format_time("20021123140436"),'2002-11-23 14:04 TEST','format_time("20021123140436")');
+is(format_time("2002.11.24 00:05:56"),'2002-11-24 00:05 TEST','format_time("2002.11.24 00:05:56")');
+
+
[% END %]
</td>
- <td valign="top">[% attachment.date %]</td>
+ <td valign="top">[% attachment.date FILTER time %]</td>
[% IF show_attachment_flags %]
<td valign="top">
[% END %]
</td>
- <td valign="top">[% a.date %]</td>
+ <td valign="top">[% a.date FILTER time %]</td>
<td valign="top">
[% IF a.statuses.size == 0 %]
[% operation.who %]
</td>
<td rowspan="[% operation.changes.size %]" valign="top">
- [% operation.when %]
+ [% operation.when FILTER time %]
</td>
[% FOREACH change = operation.changes %]
[% "</tr><tr>" IF loop.index > 0 %]
<i>------- Additional Comment
<a name="c[% count %]" href="#c[% count %]">#[% count %]</a> From
<a href="mailto:[% comment.email FILTER html %]">[% comment.name FILTER html %]</a>
- [%+ comment.time %]
+ [%+ comment.time FILTER time %]
-------
</i>
[% END %]
#%]
[% filtered_desc = bug.short_desc FILTER html %]
+[% filtered_timestamp = bug.delta_ts FILTER time %]
[% UNLESS header_done %]
[% PROCESS global/header.html.tmpl
title = "Bug $bug.bug_id - $bug.short_desc"
h1 = "Bugzilla Bug $bug.bug_id"
h2 = filtered_desc
- h3 = "Last modified: $bug.calc_disp_date"
+ h3 = "Last modified: $filtered_timestamp"
style_urls = [ "css/edit_bug.css" ]
%]
[% END %]
</b>
</td>
<td align="right" width="100%">
- Opened: [% bug.creation_ts %]
+ Opened: [% bug.creation_ts FILTER time %]
</td>
</tr>
</table>
[% END %]
[% BLOCK display_created %]
- [% request.created FILTER html %]
+ [% request.created FILTER time %]
[% END %]