Commit 615cfb88 authored by lpsolit%gmail.com's avatar lpsolit%gmail.com

Bug 182238: Allow users to choose what time zone to display times in - Patch by…

Bug 182238: Allow users to choose what time zone to display times in - Patch by Fré©ric Buclin <LpSolit@gmail.com> r/a=mkanat
parent 68c8ee64
......@@ -51,6 +51,7 @@ use Bugzilla::Flag;
use File::Basename;
use File::Spec::Functions;
use DateTime::TimeZone;
use Safe;
# This creates the request cache for non-mod_perl installations.
......@@ -463,6 +464,16 @@ sub hook_args {
return $class->request_cache->{hook_args};
}
sub local_timezone {
my $class = shift;
if (!defined $class->request_cache->{local_timezone}) {
$class->request_cache->{local_timezone} =
DateTime::TimeZone->new(name => 'local');
}
return $class->request_cache->{local_timezone};
}
sub request_cache {
if ($ENV{MOD_PERL}) {
require Apache2::RequestUtil;
......@@ -699,4 +710,10 @@ is unreadable or is not valid perl, we C<die>.
If you are running inside a code hook (see L<Bugzilla::Hook>) this
is how you get the arguments passed to the hook.
=item C<local_timezone>
Returns the local timezone of the Bugzilla installation,
as a DateTime::TimeZone object. This detection is very time
consuming, so we cache this information for future references.
=back
......@@ -62,7 +62,9 @@ sub SETTINGS {
default => ${Bugzilla->languages}[0] },
# 2007-07-02 altlist@gmail.com -- Bug 225731
quote_replies => { options => ['quoted_reply', 'simple_reply', 'off'],
default => "quoted_reply" }
default => "quoted_reply" },
# 2008-08-27 LpSolit@gmail.com -- Bug 182238
timezone => { subclass => 'Timezone', default => 'local' },
}
};
......
......@@ -69,6 +69,12 @@ sub REQUIRED_MODULES {
module => 'Date::Format',
version => '2.21'
},
# 0.28 fixed some important bugs in DateTime.
{
package => 'DateTime',
module => 'DateTime',
version => '0.28'
},
{
package => 'PathTools',
module => 'File::Spec',
......
......@@ -604,7 +604,15 @@ sub create {
},
# Format a time for display (more info in Bugzilla::Util)
time => \&Bugzilla::Util::format_time,
time => [ sub {
my ($context, $format) = @_;
return sub {
my $time = shift;
return format_time($time, $format);
};
},
1
],
# Bug 120030: Override html filter to obscure the '@' in user
# visible strings.
......
......@@ -50,6 +50,7 @@ use Bugzilla::Classification;
use Bugzilla::Field;
use Scalar::Util qw(blessed);
use DateTime::TimeZone;
use base qw(Bugzilla::Object Exporter);
@Bugzilla::User::EXPORT = qw(is_available_username
......@@ -349,6 +350,22 @@ sub settings {
return $self->{'settings'};
}
sub timezone {
my $self = shift;
if (!defined $self->{timezone}) {
my $tz = $self->settings->{timezone}->{value};
if ($tz eq 'local') {
# The user wants the local timezone of the server.
$self->{timezone} = Bugzilla->local_timezone;
}
else {
$self->{timezone} = DateTime::TimeZone->new(name => $tz);
}
}
return $self->{timezone};
}
sub flush_queries_cache {
my $self = shift;
......@@ -1884,6 +1901,11 @@ value - the value of this setting for this user. Will be the same
is_default - a boolean to indicate whether the user has chosen to make
a preference for themself or use the site default.
=item C<timezone>
Returns the timezone used to display dates and times to the user,
as a DateTime::TimeZone object.
=item C<groups>
Returns an arrayref of L<Bugzilla::Group> objects representing
......
# -*- Mode: perl; indent-tabs-mode: nil -*-
#
# The contents of this file are subject to the Mozilla Public
# License Version 1.1 (the "License"); you may not use this file
# except in compliance with the License. You may obtain a copy of
# the License at http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
# The Original Code is the Bugzilla Bug Tracking System.
#
# The Initial Developer of the Original Code is Frédéric Buclin.
# Portions created by Frédéric Buclin are Copyright (c) 2008 Frédéric Buclin.
# All rights reserved.
#
# Contributor(s): Frédéric Buclin <LpSolit@gmail.com>
package Bugzilla::User::Setting::Timezone;
use strict;
use DateTime::TimeZone;
use base qw(Bugzilla::User::Setting);
use Bugzilla::Constants;
sub legal_values {
my ($self) = @_;
return $self->{'legal_values'} if defined $self->{'legal_values'};
my @timezones = DateTime::TimeZone->all_names;
# Remove old formats, such as CST6CDT, EST, EST5EDT.
@timezones = grep { $_ =~ m#.+/.+#} @timezones;
# Append 'local' to the list, which will use the timezone
# given by the server.
push(@timezones, 'local');
return $self->{'legal_values'} = \@timezones;
}
1;
__END__
=head1 NAME
Bugzilla::User::Setting::Timezone - Object for a user preference setting for desired timezone
=head1 DESCRIPTION
Timezone.pm extends Bugzilla::User::Setting and implements a class specialized for
setting the desired timezone.
=head1 METHODS
=over
=item C<legal_values()>
Description: Returns all legal timezones
Params: none
Returns: A reference to an array containing the names of all legal timezones
=back
......@@ -50,6 +50,7 @@ use Bugzilla::Constants;
use Date::Parse;
use Date::Format;
use DateTime;
use Text::Wrap;
# This is from the perlsec page, slightly modified to remove a warning
......@@ -398,36 +399,39 @@ sub wrap_hard {
sub format_time {
my ($date, $format) = @_;
# If $format is undefined, try to guess the correct date format.
my $show_timezone;
# If $format is undefined, try to guess the correct date format.
if (!defined($format)) {
if ($date =~ m/^(\d{4})[-\.](\d{2})[-\.](\d{2}) (\d{2}):(\d{2})(:(\d{2}))?$/) {
my $sec = $7;
if (defined $sec) {
$format = "%Y-%m-%d %T";
$format = "%Y-%m-%d %T %Z";
} else {
$format = "%Y-%m-%d %R";
$format = "%Y-%m-%d %R %Z";
}
} else {
# Default date format. See Date::Format for other formats available.
$format = "%Y-%m-%d %R";
# Default date format. See DateTime for other formats available.
$format = "%Y-%m-%d %R %Z";
}
# By default, we want the timezone to be displayed.
$show_timezone = 1;
}
else {
# Search for %Z or %z, meaning we want the timezone to be displayed.
# Till bug 182238 gets fixed, we assume Bugzilla->params->{'timezone'}
# is used.
$show_timezone = ($format =~ s/\s?%Z$//i);
}
# str2time($date) is undefined if $date has an invalid date format.
my $time = str2time($date);
if (defined $time) {
$date = time2str($format, $time);
$date .= " " . Bugzilla->params->{'timezone'} if $show_timezone;
# strptime($date) returns an empty array if $date has an invalid date format.
my @time = strptime($date);
if (scalar @time) {
# strptime() counts years from 1900, and months from 0 (January).
# We have to fix both values.
my $dt = DateTime->new({year => 1900 + $time[5],
month => ++$time[4],
day => $time[3],
hour => $time[2],
minute => $time[1],
second => $time[0],
# Use the timezone specified by the server.
time_zone => Bugzilla->local_timezone});
# Now display the date using the user's timezone.
$dt->set_time_zone(Bugzilla->user->timezone);
$date = $dt->strftime($format);
}
else {
# Don't let invalid (time) strings to be passed to templates!
......
......@@ -1183,7 +1183,7 @@ if (scalar(@bugowners) > 1 && Bugzilla->user->in_group('editbugs')) {
$vars->{'splitheader'} = $cgi->cookie('SPLITHEADER') ? 1 : 0;
$vars->{'quip'} = GetQuip();
$vars->{'currenttime'} = time();
$vars->{'currenttime'} = localtime(time());
# The following variables are used when the user is making changes to multiple bugs.
if ($dotweak && scalar @bugs) {
......
......@@ -292,7 +292,7 @@ sub wrap {
# We create a Chart object so we can validate the parameters
my $chart = new Bugzilla::Chart($cgi);
$vars->{'time'} = time();
$vars->{'time'} = localtime(time());
$vars->{'imagebase'} = $cgi->canonicalise_query(
"action", "action-wrap", "ctype", "format", "width", "height");
......
......@@ -226,7 +226,7 @@ foreach my $tbl (@tbl_names) {
$vars->{'col_field'} = $col_field;
$vars->{'row_field'} = $row_field;
$vars->{'tbl_field'} = $tbl_field;
$vars->{'time'} = time();
$vars->{'time'} = localtime(time());
$vars->{'col_names'} = \@col_names;
$vars->{'row_names'} = \@row_names;
......
......@@ -33,11 +33,13 @@ BEGIN {
use_ok(Bugzilla::Util);
}
# We need to override Bugzilla->params so we can get an expected value when
# Bugzilla::Util::format_time() calls ask for the 'timezone' parameter.
# This will also prevent the tests from failing on site that do not have a
# data/params file containing 'timezone' yet.
Bugzilla->params->{'timezone'} = "TEST";
# We need to override user preferences so we can get an expected value when
# Bugzilla::Util::format_time() calls ask for the 'timezone' user preference.
Bugzilla->user->settings->{'timezone'}->{'value'} = "local";
# We need to know the local timezone for the date chosen in our tests.
# Below, tests are run against Nov. 24, 2002.
my $tz = Bugzilla->local_timezone->short_name_for_datetime(DateTime->new(year => 2002, month => 11, day => 24));
# we don't test the taint functions since that's going to take some more work.
# XXX: test taint functions
......@@ -58,7 +60,7 @@ is(lsearch(\@list,'kiwi'),-1,'lsearch 3 (missing item)');
is(trim(" fg<*\$%>+=~~ "),'fg<*$%>+=~~','trim()');
#format_time();
is(format_time("2002.11.24 00:05"),'2002-11-24 00:05 TEST','format_time("2002.11.24 00:05")');
is(format_time("2002.11.24 00:05:56"),'2002-11-24 00:05:56 TEST','format_time("2002.11.24 00:05:56")');
is(format_time("2002.11.24 00:05"), "2002-11-24 00:05 $tz",'format_time("2002.11.24 00:05") is ' . format_time("2002.11.24 00:05"));
is(format_time("2002.11.24 00:05:56"), "2002-11-24 00:05:56 $tz",'format_time("2002.11.24 00:05:56")');
is(format_time("2002.11.24 00:05:56", "%Y-%m-%d %R"), '2002-11-24 00:05', 'format_time("2002.11.24 00:05:56", "%Y-%m-%d %R") (with no timezone)');
is(format_time("2002.11.24 00:05:56", "%Y-%m-%d %R %Z"), '2002-11-24 00:05 TEST', 'format_time("2002.11.24 00:05:56", "%Y-%m-%d %R %Z") (with timezone)');
is(format_time("2002.11.24 00:05:56", "%Y-%m-%d %R %Z"), "2002-11-24 00:05 $tz", 'format_time("2002.11.24 00:05:56", "%Y-%m-%d %R %Z") (with timezone)');
......@@ -43,5 +43,7 @@
"quote_replies" => "Quote the associated comment when you click on its reply link",
"quoted_reply" => "Quote the full comment",
"simple_reply" => "Reference the comment number only",
"timezone" => "Timezone used to display dates and times",
"local" => "Same as the server",
}
%]
......@@ -54,11 +54,7 @@
<div class="bz_query_head" align="center">
<span class="bz_query_timestamp">
[% IF Param('timezone') %]
<b>[% time2str("%a %b %e %Y %T %Z", currenttime, Param('timezone')) %]</b><br>
[% ELSE %]
<b>[% time2str("%a %b %e %Y %T", currenttime) %]</b><br>
[% END %]
<b>[% currenttime FILTER time('%a %b %e %Y %T %Z') FILTER html %]</b><br>
</span>
[% IF debug %]
......
......@@ -25,9 +25,11 @@
height = 350
%]
[% time = time FILTER time('%Y-%m-%d %H:%M:%S') FILTER html %]
[% PROCESS global/header.html.tmpl
title = "Chart"
header_addl_info = time2str("%Y-%m-%d %H:%M:%S", time)
header_addl_info = time
%]
<div align="center">
......
......@@ -66,6 +66,8 @@
[% col_field_disp FILTER html %]
[% END %]
[% time = time FILTER time('%Y-%m-%d %H:%M:%S') FILTER html %]
[% PROCESS global/header.html.tmpl
style = "
.t1 { background-color: #ffffff } /* white */
......@@ -74,7 +76,7 @@
.t4 { background-color: #c3d3ed } /* darker blue */
.ttotal { background-color: #cfffdf } /* light green */
"
header_addl_info = time2str("%Y-%m-%d %H:%M:%S", time)
header_addl_info = time
%]
[% IF debug %]
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment