From: Ash Berlin Date: Sun, 7 Oct 2007 21:50:33 +0000 (+0000) Subject: Timezone support for InflateColumn::DateTime (sergio) X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=dda9af557c2385fb280d95dce3c4638a65bf9dd8;p=dbsrgits%2FDBIx-Class-Historic.git Timezone support for InflateColumn::DateTime (sergio) --- diff --git a/Changes b/Changes index 649e5e8..3246944 100644 --- a/Changes +++ b/Changes @@ -6,6 +6,8 @@ Revision history for DBIx::Class context; this makes things like func('DISTINCT') work as expected - Many-to-many relationships now warn if the utility methods would clash + - InflateColumn::DateTime now accepts an extra parameter of timezone + to set timezone on the DT object (thanks Sergio Salvi) 0.08007 2007-09-04 19:36:00 - patch for Oracle datetime inflation (abram@arin.net) diff --git a/lib/DBIx/Class/InflateColumn/DateTime.pm b/lib/DBIx/Class/InflateColumn/DateTime.pm index df92390..a650d69 100644 --- a/lib/DBIx/Class/InflateColumn/DateTime.pm +++ b/lib/DBIx/Class/InflateColumn/DateTime.pm @@ -24,6 +24,12 @@ Then you can treat the specified column as a L object. print "This event starts the month of ". $event->starts_when->month_name(); +If you want to set a specific timezone for that field, use: + + __PACKAGE__->add_columns( + starts_when => { data_type => 'datetime', extra => { timezone => "America/Chicago" } } + ); + =head1 DESCRIPTION This module figures out the type of DateTime::Format::* class to @@ -55,6 +61,11 @@ sub register_column { return unless defined($info->{data_type}); my $type = lc($info->{data_type}); $type = 'datetime' if ($type =~ /^timestamp/); + my $timezone; + if ( exists $info->{extra} and exists $info->{extra}{timezone} and defined $info->{extra}{timezone} ) { + $timezone = $info->{extra}{timezone}; + } + if ($type eq 'datetime' || $type eq 'date') { my ($parse, $format) = ("parse_${type}", "format_${type}"); $self->inflate_column( @@ -62,10 +73,13 @@ sub register_column { { inflate => sub { my ($value, $obj) = @_; - $obj->_datetime_parser->$parse($value); + my $dt = $obj->_datetime_parser->$parse($value); + $dt->set_time_zone($timezone) if $timezone; + return $dt; }, deflate => sub { my ($value, $obj) = @_; + $value->set_time_zone($timezone) if $timezone; $obj->_datetime_parser->$format($value); }, } diff --git a/t/89inflate_datetime.t b/t/89inflate_datetime.t index a3bc582..d92340c 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 => 8; +plan tests => 17; # inflation test my $event = $schema->resultset("Event")->find(1); @@ -42,3 +42,31 @@ my $created_cron = $created->created_on; isa_ok($created->created_on, 'DateTime', 'DateTime returned'); is("$created_cron", '2006-06-23T00:00:00', 'Correct date/time'); + + +# Test "timezone" parameter +my $event_tz = $schema->resultset('EventTZ')->create({ + starts_at => DateTime->new(year=>2007, month=>12, day=>31, time_zone => "America/Chicago" ), + created_on => DateTime->new(year=>2006, month=>1, day=>31, + hour => 13, minute => 34, second => 56, time_zone => "America/New_York" ), +}); + +my $starts_at = $event_tz->starts_at; +is("$starts_at", '2007-12-31T00:00:00', 'Correct date/time using timezone'); + +my $created_on = $event_tz->created_on; +is("$created_on", '2006-01-31T12:34:56', 'Correct timestamp using timezone'); +is($event_tz->created_on->time_zone->name, "America/Chicago", "Correct timezone"); + +my $loaded_event = $schema->resultset('EventTZ')->find( $event_tz->id ); + +isa_ok($loaded_event->starts_at, 'DateTime', 'DateTime returned'); +$starts_at = $loaded_event->starts_at; +is("$starts_at", '2007-12-31T00:00:00', 'Loaded correct date/time using timezone'); +is($starts_at->time_zone->name, 'America/Chicago', 'Correct timezone'); + +isa_ok($loaded_event->created_on, 'DateTime', 'DateTime returned'); +$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'); + diff --git a/t/lib/DBICTest/Schema.pm b/t/lib/DBICTest/Schema.pm index 7ebd040..b2e4099 100644 --- a/t/lib/DBICTest/Schema.pm +++ b/t/lib/DBICTest/Schema.pm @@ -34,7 +34,7 @@ __PACKAGE__->load_classes(qw/ 'Producer', 'CD_to_Producer', ), - qw/SelfRefAlias TreeLike TwoKeyTreeLike Event NoPrimaryKey/, + qw/SelfRefAlias TreeLike TwoKeyTreeLike Event EventTZ NoPrimaryKey/, qw/Collection CollectionObject TypedObject/, qw/Owners BooksInLibrary/ ); diff --git a/t/lib/DBICTest/Schema/EventTZ.pm b/t/lib/DBICTest/Schema/EventTZ.pm new file mode 100644 index 0000000..9922962 --- /dev/null +++ b/t/lib/DBICTest/Schema/EventTZ.pm @@ -0,0 +1,19 @@ +package DBICTest::Schema::EventTZ; + +use strict; +use warnings; +use base qw/DBIx::Class::Core/; + +__PACKAGE__->load_components(qw/InflateColumn::DateTime/); + +__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" } }, +); + +__PACKAGE__->set_primary_key('id'); + +1;