[Rt-commit] rt branch, timezones_in_charts, updated. rt-3.8.7-312-g7b51ac9
Ruslan Zakirov
ruz at bestpractical.com
Tue Mar 30 16:04:05 EDT 2010
The branch, timezones_in_charts has been updated
via 7b51ac9707cdd344fc10e0a1080d065852571106 (commit)
via 032d166ed543b8bdcadbe158756b58cda84e6bd2 (commit)
via 24310a2caadd7ee53a53775c31d784c6d26bc377 (commit)
via 7fc38ab9b96eb605b592a5d94fd4f14d5a235f68 (commit)
via 8588d163279d0ef9cd373bfc450831ffb5a32ee8 (commit)
from e5e4b610bb4428980c36aa7bf0ea94458c4beac5 (commit)
Summary of changes:
UPGRADING | 4 ++
docs/timezones_in_charts.pod | 84 ++++++++++++++++++++++++++++++++++++++++
etc/RT_Config.pm.in | 12 ++++++
lib/RT/Report/Tickets.pm | 48 ++++++++++++++++++----
lib/RT/Report/Tickets/Entry.pm | 13 ++++--
5 files changed, 147 insertions(+), 14 deletions(-)
create mode 100644 docs/timezones_in_charts.pod
- Log -----------------------------------------------------------------
commit 8588d163279d0ef9cd373bfc450831ffb5a32ee8
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date: Tue Mar 30 21:34:47 2010 +0400
introduce new option ChartsTimezonesInDB and implement Pg and mysql
diff --git a/lib/RT/Report/Tickets.pm b/lib/RT/Report/Tickets.pm
index 05f0100..c34d1cb 100644
--- a/lib/RT/Report/Tickets.pm
+++ b/lib/RT/Report/Tickets.pm
@@ -185,20 +185,50 @@ sub _FieldToFunction {
if ($field =~ /^(.*)(Hourly|Daily|Monthly|Annually)$/) {
my ($field, $grouping) = ($1, $2);
my $alias = $args{'ALIAS'} || 'main';
+
+ my $func = "$alias.$field";
+
+ my $db_type = RT->Config->Get('DatabaseType');
+ if ( RT->Config->Get('ChartsTimezonesInDB') ) {
+ my $tz = $self->CurrentUser->UserObj->Timezone
+ || RT->Config->Get('Timezone')
+ || 'UTC';
+ if ( lc $tz eq 'utc' ) {
+ # do nothing
+ }
+ elsif ( $db_type eq 'Pg' ) {
+ $func = "timezone('UTC', $func)";
+ $func = "timezone(". $self->_Handle->dbh->quote($tz) .", $func)";
+ }
+ elsif ( $db_type eq 'mysql' ) {
+ $func = "CONVERT_TZ($func, 'UTC', "
+ . $self->_Handle->dbh->quote($tz)
+ .")";
+ }
+ else {
+ $RT::Logger->warning(
+ "ChartsTimezonesInDB config option"
+ ." is not supported on $db_type."
+ );
+ }
+ }
+
# Pg 8.3 requires explicit casting
- $field .= '::text' if RT->Config->Get('DatabaseType') eq 'Pg';
- if ( $grouping =~ /Hourly/ ) {
- $args{'FUNCTION'} = "SUBSTR($alias.$field,1,13)";
+ $func .= '::text' if $db_type eq 'Pg';
+
+ if ( $grouping eq 'Hourly' ) {
+ $func = "SUBSTR($func,1,13)";
}
- if ( $grouping =~ /Daily/ ) {
- $args{'FUNCTION'} = "SUBSTR($alias.$field,1,10)";
+ if ( $grouping eq 'Daily' ) {
+ $func = "SUBSTR($func,1,10)";
}
- elsif ( $grouping =~ /Monthly/ ) {
- $args{'FUNCTION'} = "SUBSTR($alias.$field,1,7)";
+ elsif ( $grouping eq 'Monthly' ) {
+ $func = "SUBSTR($func,1,7)";
}
- elsif ( $grouping =~ /Annually/ ) {
- $args{'FUNCTION'} = "SUBSTR($alias.$field,1,4)";
+ elsif ( $grouping eq 'Annually' ) {
+ $func = "SUBSTR($func,1,4)";
}
+ $args{'FUNCTION'} = $func;
} elsif ( $field =~ /^(?:CF|CustomField)\.{(.*)}$/ ) { #XXX: use CFDecipher method
my $cf_name = $1;
my $cf = RT::CustomField->new( $self->CurrentUser );
commit 7fc38ab9b96eb605b592a5d94fd4f14d5a235f68
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date: Tue Mar 30 22:01:36 2010 +0400
add documentation describing timezones in DBs for charts
diff --git a/docs/timezones_in_charts.pod b/docs/timezones_in_charts.pod
new file mode 100644
index 0000000..0033222
--- /dev/null
+++ b/docs/timezones_in_charts.pod
@@ -0,0 +1,84 @@
+=head1 INTRO
+
+Every date in RT's DB is stored in UTC format. This affects charts
+groupped by time periods (Annually, Monthly, etc.). To produce
+charts that are in a specific timezone we have to use DB's specific
+functions to convert time. Each DB has very different requirements.
+
+=head1 CONFIGURATION
+
+This code is experimental and you can turn it on and off using
+boolean option $ChartsTimezonesInDB in the RT config.
+
+=head1 DATABASE SPECIFIC NOTES
+
+=head2 mysql
+
+Time can not just be converted using numeric time shift as this
+shift value depends on day saving time properties of the time zone.
+
+mysql since 4.1.3 supports named timezones, but you have to fill
+special tables with up to date data. On modern systems it's Usually
+very easy:
+
+ mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -u root mysql
+
+mysql's doc recommends to restart server. Read more about timezones
+in mysql in the following document
+http://dev.mysql.com/doc/refman/5.0/en/time-zone-support.html .
+
+=head2 Postgres
+
+Postgres database uses system's functions to deal with timezones.
+You shouldn't do anything particular except making sure that
+data in F</usr/share/zoneinfo> is up to date. On some systems
+this means upgrading a system package.
+
+=head3 Note for users of Pg 7.2 and older or users upgraded from those
+
+You should be sure that timestamps in RT DB have no TZ set. TIMESTAMP
+column type in Postgres prior to Pg 7.3 has timezone info by default.
+In newer versions it's not the case anymore. If you have such system
+then you should alter columns.
+
+=head2 Other databases
+
+There is no implementation for other DBs, yet.
+
+=head1 FOR DEVELOPERS
+
+=head2 Postgres
+
+We use timestamp type for all datetime fields. It either has timezone
+info or not, by default since Pg 7.3 it has no timezone. Conversion is
+kinda tricky:
+
+ timezone('Europe/Moscow', timezone('UTC', column_without_tz_info))
+ timezone('to_tz', timezone('from_tz', column_without_tz_info))
+ http://www.postgresql.org/docs/7.4/static/functions-datetime.html#FUNCTIONS-DATETIME-ZONECONVERT
+
+This function flips HAS_TZ flag on the argument. First call makes
+no conversion, but flips HAS_TZ flag. So next call flips it back
+and does actual conversion.
+
+http://www.postgresql.org/docs/7.4/static/datatype-datetime.html#DATATYPE-TIMEZONES
+
+=head2 mysql
+
+Once there is a timezone info loaded in tables on the server
+we have all the same set of named timezones like in system
+and DateTime (DateTime project has copy of the TZ data in a module).
+
+CONVERT_TZ(TS, from, to) exists since mysql 4.1.3. Note that it
+takes timestamp, so supports limitted range (usuall 1970-2038).
+
+=head2 Oracle
+
+Look at FROM_TZ function.
+
+=head2 SQLite
+
+As far as I can see has no support.
+
+=cut
+
commit 24310a2caadd7ee53a53775c31d784c6d26bc377
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date: Tue Mar 30 23:57:00 2010 +0400
handle possible TZ shifts in "date is not set" detection
diff --git a/lib/RT/Report/Tickets/Entry.pm b/lib/RT/Report/Tickets/Entry.pm
index 4f2a8a3..525fb98 100644
--- a/lib/RT/Report/Tickets/Entry.pm
+++ b/lib/RT/Report/Tickets/Entry.pm
@@ -65,17 +65,20 @@ sub LabelValue {
my $field = shift;
my $value = $self->__Value( $field );
+ $RT::Logger->error("boo: $value");
+
if ( $field =~ /(Daily|Monthly|Annually|Hourly)$/ ) {
my $re;
- $re = qr{1970-01-01 00} if $field =~ /Hourly$/;
- $re = qr{1970-01-01} if $field =~ /Daily$/;
- $re = qr{1970-01} if $field =~ /Monthly$/;
- $re = qr{1970} if $field =~ /Annually$/;
+ # it's not just 1970-01-01 00:00:00 because of timezone shifts
+ # and conversion from UTC to user's TZ
+ $re = qr{19(?:70-01-01|69-12-31) [0-9]{2}} if $field =~ /Hourly$/;
+ $re = qr{19(?:70-01-01|69-12-31)} if $field =~ /Daily$/;
+ $re = qr{19(?:70-01|69-12)} if $field =~ /Monthly$/;
+ $re = qr{19(?:70|69)} if $field =~ /Annually$/;
$value =~ s/^$re/Not Set/;
}
return $value;
-
}
eval "require RT::Report::Tickets::Entry_Vendor";
commit 032d166ed543b8bdcadbe158756b58cda84e6bd2
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date: Tue Mar 30 23:57:51 2010 +0400
describe ChartsTimezonesInDB in the config
diff --git a/etc/RT_Config.pm.in b/etc/RT_Config.pm.in
index 4ad1411..3f415fc 100755
--- a/etc/RT_Config.pm.in
+++ b/etc/RT_Config.pm.in
@@ -1470,6 +1470,18 @@ Set(
'others' => "$RT::BasePath/share/fonts/DroidSans.ttf",
);
+=item C<$ChartsTimezonesInDB>
+
+Dates are stored using UTC timezone in the DB, so charts groupped
+by dates and time are not representative. Set C<$ChartsTimezonesInDB>
+to a true value to enable timezones conversions using DB's
+capabilities. You may need to do some work on DB side to use this
+feature, read more in F<docs/timezones_in_charts.pod>.
+
+=cut
+
+Set( $ChartsTimezonesInDB, 0 );
+
=item C<@Active_MakeClicky>
MakeClicky detects various formats of data in headers and email
commit 7b51ac9707cdd344fc10e0a1080d065852571106
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date: Wed Mar 31 00:03:51 2010 +0400
update upgrading
diff --git a/UPGRADING b/UPGRADING
index 1aaccdb..d8962d3 100644
--- a/UPGRADING
+++ b/UPGRADING
@@ -18,6 +18,10 @@ If you are using MySQL, please read the instructions in UPGRADING.mysql as
well.
*******
+UPGRADING FROM 3.8.7 and earlier - Changes:
+
+New option ChartsTimezonesInDB in the config.
+
UPGRADING FROM 3.8.6 and earlier - Changes:
For MySQL and Oracle users:
-----------------------------------------------------------------------
More information about the Rt-commit
mailing list