On 9/19/07, Ash Berlin <[EMAIL PROTECTED]> wrote:
> Sergio Salvi wrote:
> > Hi Matt, Ash,
> >
> > I have a patch for DBIx::Class::InflateColumn::DateTime to add support
> > for timezones. It allows one to specify that a DATE or DATETIME field
> > is stored in a specific timezone instead of the default (UTC). It's
> > here: http://scsys.co.uk:8001/9505
>
> DateTime's come out in Floating, not UTC btw.
> >
> > I've checked out trunk, wrote tests and documentation. Could you
> > please look at it and, hopefully, apply it?
> >
> > Thanks,
> > Sergio
>
> Looks like a promising start. Could you just make the following changes:
>
> - Move the TZ into the extra hash:
>
> starts_at => { data_type => 'datetime', extra => { timezone =>
> "America/Chicago" } },
>
> - Make default convert from what ever timezone the incoming $obj is to
> the one set in the column. Without this you can't guarantee that all
> values of the column have the stated timezone.
>
>
(copying the DBIC list now)
Here is the updated patch according to your suggestions. I've added
more tests also.
Let me know what you and others think.
Thanks,
Sergio
Index: t/89inflate_datetime.t
===================================================================
--- t/89inflate_datetime.t (revision 3805)
+++ t/89inflate_datetime.t (working copy)
@@ -10,7 +10,7 @@
eval { require DateTime::Format::MySQL };
plan skip_all => "Need DateTime::Format::MySQL for inflation tests" if $@;
-plan tests => 8;
+plan tests => 16;
# inflation test
my $event = $schema->resultset("Event")->find(1);
@@ -42,3 +42,32 @@
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 => 12, minute => 34, second => 56, time_zone => "America/Chicago"
),
+});
+
+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');
+
+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');
+my $time_zone = $starts_at->time_zone->name;
+is("$time_zone", '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');
+$time_zone = $created_on->time_zone->name;
+is("$time_zone", 'America/Chicago', 'Correct timezone');
+
Index: t/lib/DBICTest/Schema/EventTZ.pm
===================================================================
--- t/lib/DBICTest/Schema/EventTZ.pm (revision 3756)
+++ t/lib/DBICTest/Schema/EventTZ.pm (working copy)
@@ -1,4 +1,4 @@
-package DBICTest::Schema::Event;
+package DBICTest::Schema::EventTZ;
use strict;
use warnings;
@@ -10,8 +10,8 @@
__PACKAGE__->add_columns(
id => { data_type => 'integer', is_auto_increment => 1 },
- starts_at => { data_type => 'datetime' },
- created_on => { data_type => 'timestamp' }
+ starts_at => { data_type => 'datetime', extra => { timezone =>
"America/Chicago" } },
+ created_on => { data_type => 'timestamp', extra => { timezone =>
"America/Chicago" } },
);
__PACKAGE__->set_primary_key('id');
Index: t/lib/DBICTest/Schema.pm
===================================================================
--- t/lib/DBICTest/Schema.pm (revision 3805)
+++ t/lib/DBICTest/Schema.pm (working copy)
@@ -34,7 +34,7 @@
'Producer',
'CD_to_Producer',
),
- qw/SelfRefAlias TreeLike TwoKeyTreeLike Event NoPrimaryKey/,
+ qw/SelfRefAlias TreeLike TwoKeyTreeLike Event EventTZ NoPrimaryKey/,
qw/Collection CollectionObject TypedObject/,
qw/Owners BooksInLibrary/
);
Index: lib/DBIx/Class/InflateColumn/DateTime.pm
===================================================================
--- lib/DBIx/Class/InflateColumn/DateTime.pm (revision 3805)
+++ lib/DBIx/Class/InflateColumn/DateTime.pm (working copy)
@@ -24,6 +24,12 @@
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 @@
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,17 @@
{
inflate => sub {
my ($value, $obj) = @_;
- $obj->_datetime_parser->$parse($value);
+ my $dt = $obj->_datetime_parser->$parse($value);
+ if ( defined $timezone ) {
+ $dt->set_time_zone($timezone);
+ }
+ return $dt;
},
deflate => sub {
my ($value, $obj) = @_;
+ if ( defined $timezone ) {
+ $value->set_time_zone($timezone);
+ }
$obj->_datetime_parser->$format($value);
},
}
_______________________________________________
List: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/dbix-class
IRC: irc.perl.org#dbix-class
SVN: http://dev.catalyst.perl.org/repos/bast/DBIx-Class/
Searchable Archive: http://www.grokbase.com/group/[EMAIL PROTECTED]