From: Johannes Plunien Date: Sun, 26 Oct 2008 20:57:28 +0000 (+0100) Subject: floating timezone warning X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=47cd9169a3e76ad3cf7aa04aaa8eb8b32c6c9e85;p=dbsrgits%2FDBIx-Class-Historic.git floating timezone warning --- diff --git a/lib/DBIx/Class/InflateColumn/DateTime.pm b/lib/DBIx/Class/InflateColumn/DateTime.pm index 393a178..dc33f24 100644 --- a/lib/DBIx/Class/InflateColumn/DateTime.pm +++ b/lib/DBIx/Class/InflateColumn/DateTime.pm @@ -47,6 +47,42 @@ It's also possible to explicitly skip inflation: starts_when => { data_type => 'datetime', inflate_datetime => 0 } ); +=head1 WARNING + +You'll notice some warning about floating timezone if you set timezone in your schema but +didn't set it when creating/updating a row: + + __PACKAGE__->add_columns( + starts_when => { data_type => 'datetime', extra => { timezone => "America/Chicago" } } + ); + + my $event = $schema->resultset('EventTZ')->create({ + starts_at => DateTime->new(year=>2007, month=>12, day=>31, ), + }); + +To avoid this, you have three options: + +=over + +=item Fix your broken code + + my $event = $schema->resultset('EventTZ')->create({ + starts_at => DateTime->new(year=>2007, month=>12, day=>31, time_zone => "America/Chicago" ), + }); + +=item Suppress the warning by doing either ... + + __PACKAGE__->add_columns( + starts_when => { data_type => 'datetime', extra => { timezone => "America/Chicago", floating_tz_ok => 1 } } + ); + +=item ... or ... + +Set environment variable DBIC_FLOATING_TZ_OK to some true value. + +=back + + =head1 DESCRIPTION This module figures out the type of DateTime::Format::* class to @@ -111,6 +147,7 @@ sub register_column { $timezone = $info->{extra}{timezone}; } + my $floating_tz_ok = $info->{extra}{floating_tz_ok} ? 1 : 0; my $undef_if_invalid = $info->{datetime_undef_if_invalid}; if ($type eq 'datetime' || $type eq 'date') { @@ -128,7 +165,14 @@ sub register_column { }, deflate => sub { my ($value, $obj) = @_; - $value->set_time_zone($timezone) if $timezone; + if ($timezone) { + warn "You're using a floating timezone, please see the documentation of" + . " DBIx::Class::InflateColumn::DateTime for an explanation" + if ref( $value->time_zone ) eq 'DateTime::TimeZone::Floating' + and not $floating_tz_ok + and not $ENV{DBIC_FLOATING_TZ_OK}; + $value->set_time_zone($timezone); + } $obj->_datetime_parser->$format($value); }, } diff --git a/t/89inflate_datetime.t b/t/89inflate_datetime.t index 2cc3030..54cc1ad 100644 --- a/t/89inflate_datetime.t +++ b/t/89inflate_datetime.t @@ -10,7 +10,7 @@ my $schema = DBICTest->init_schema(); eval { require DateTime::Format::MySQL }; plan skip_all => "Need DateTime::Format::MySQL for inflation tests" if $@; -plan tests => 27; +plan tests => 28; # inflation test my $event = $schema->resultset("Event")->find(1); @@ -77,6 +77,25 @@ $created_on = $loaded_event->created_on; is("$created_on", '2006-01-31T12:34:56', 'Loaded correct timestamp using timezone'); is($created_on->time_zone->name, 'America/Chicago', 'Correct timezone'); +# Test floating timezone warning +# We expect one warning +SKIP: { + skip "ENV{DBIC_FLOATING_TZ_OK} was set, skipping", 1 if $ENV{DBIC_FLOATING_TZ_OK}; + $SIG{__WARN__} = sub { + like( + shift, + qr/You're using a floating timezone, please see the documentation of DBIx::Class::InflateColumn::DateTime for an explanation/, + 'Floating timezone warning' + ); + }; + my $event_tz_floating = $schema->resultset('EventTZ')->create({ + starts_at => DateTime->new(year=>2007, month=>12, day=>31, ), + created_on => DateTime->new(year=>2006, month=>1, day=>31, + hour => 13, minute => 34, second => 56, ), + }); + delete $SIG{__WARN__}; +}; + # This should fail to set my $prev_str = "$created_on"; $loaded_event->update({ created_on => '0000-00-00' }); diff --git a/t/lib/DBICTest/Schema/EventTZ.pm b/t/lib/DBICTest/Schema/EventTZ.pm index 9922962..8445aa1 100644 --- a/t/lib/DBICTest/Schema/EventTZ.pm +++ b/t/lib/DBICTest/Schema/EventTZ.pm @@ -11,7 +11,7 @@ __PACKAGE__->table('event'); __PACKAGE__->add_columns( id => { data_type => 'integer', is_auto_increment => 1 }, starts_at => { data_type => 'datetime', extra => { timezone => "America/Chicago" } }, - created_on => { data_type => 'timestamp', extra => { timezone => "America/Chicago" } }, + created_on => { data_type => 'timestamp', extra => { timezone => "America/Chicago", floating_tz_ok => 1 } }, ); __PACKAGE__->set_primary_key('id');