[Dbix-class] Re: Patch for DBIx::Class::InflateColumn::DateTime
Sergio Salvi
sergio.lists at salvi.ca
Fri Oct 5 23:26:19 GMT 2007
On 9/19/07, Ash Berlin <ash at firemirror.com> 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 =3D> { data_type =3D> 'datetime', extra =3D> { timezone =3D>
> "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
-------------- next part --------------
Index: t/89inflate_datetime.t
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- t/89inflate_datetime.t (revision 3805)
+++ t/89inflate_datetime.t (working copy)
@@ -10,7 +10,7 @@
eval { require DateTime::Format::MySQL };
plan skip_all =3D> "Need DateTime::Format::MySQL for inflation tests" if $=
@;
=
-plan tests =3D> 8;
+plan tests =3D> 16;
=
# inflation test
my $event =3D $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 =3D $schema->resultset('EventTZ')->create({
+ starts_at =3D> DateTime->new(year=3D>2007, month=3D>12, day=3D>31, tim=
e_zone =3D> "America/Chicago" ),
+ created_on =3D> DateTime->new(year=3D>2006, month=3D>1, day=3D>31,
+ hour =3D> 12, minute =3D> 34, second =3D> 56, time_zone =3D> "Amer=
ica/Chicago" ),
+});
+
+my $starts_at =3D $event_tz->starts_at;
+is("$starts_at", '2007-12-31T00:00:00', 'Correct date/time using timezone'=
);
+
+my $created_on =3D $event_tz->created_on;
+is("$created_on", '2006-01-31T12:34:56', 'Correct timestamp using timezone=
');
+
+my $loaded_event =3D $schema->resultset('EventTZ')->find( $event_tz->id );
+
+isa_ok($loaded_event->starts_at, 'DateTime', 'DateTime returned');
+$starts_at =3D $loaded_event->starts_at;
+is("$starts_at", '2007-12-31T00:00:00', 'Loaded correct date/time using ti=
mezone');
+my $time_zone =3D $starts_at->time_zone->name;
+is("$time_zone", 'America/Chicago', 'Correct timezone');
+
+isa_ok($loaded_event->created_on, 'DateTime', 'DateTime returned');
+$created_on =3D $loaded_event->created_on;
+is("$created_on", '2006-01-31T12:34:56', 'Loaded correct timestamp using t=
imezone');
+$time_zone =3D $created_on->time_zone->name;
+is("$time_zone", 'America/Chicago', 'Correct timezone');
+
Index: t/lib/DBICTest/Schema/EventTZ.pm
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- 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 =3D> { data_type =3D> 'integer', is_auto_increment =3D> 1 },
- starts_at =3D> { data_type =3D> 'datetime' },
- created_on =3D> { data_type =3D> 'timestamp' }
+ starts_at =3D> { data_type =3D> 'datetime', extra =3D> { timezone =3D> "=
America/Chicago" } },
+ created_on =3D> { data_type =3D> 'timestamp', extra =3D> { timezone =3D>=
"America/Chicago" } },
);
=
__PACKAGE__->set_primary_key('id');
Index: t/lib/DBICTest/Schema.pm
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- 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
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- 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 =3D> { data_type =3D> 'datetime', extra =3D> { timezone =
=3D> "America/Chicago" } }
+ );
+
=3Dhead1 DESCRIPTION
=
This module figures out the type of DateTime::Format::* class to =
@@ -55,6 +61,11 @@
return unless defined($info->{data_type});
my $type =3D lc($info->{data_type});
$type =3D 'datetime' if ($type =3D~ /^timestamp/);
+ my $timezone;
+ if ( exists $info->{extra} and exists $info->{extra}->{timezone} and def=
ined $info->{extra}->{timezone} ) {
+ $timezone =3D $info->{extra}->{timezone};
+ }
+
if ($type eq 'datetime' || $type eq 'date') {
my ($parse, $format) =3D ("parse_${type}", "format_${type}");
$self->inflate_column(
@@ -62,10 +73,17 @@
{
inflate =3D> sub {
my ($value, $obj) =3D @_;
- $obj->_datetime_parser->$parse($value);
+ my $dt =3D $obj->_datetime_parser->$parse($value);
+ if ( defined $timezone ) {
+ $dt->set_time_zone($timezone);
+ }
+ return $dt;
},
deflate =3D> sub {
my ($value, $obj) =3D @_;
+ if ( defined $timezone ) {
+ $value->set_time_zone($timezone);
+ }
$obj->_datetime_parser->$format($value);
},
}
More information about the DBIx-Class
mailing list