Using Class::Date

The Class::Date package can be very useful with Class::DBI.

For example:

Package Film; __PACKAGE__->has_a (created_date => 'Class::Date', inflate => 'new', deflate => 'string');

You can even do this as shorthand (thanks to Bodo Shulze for the tip):

Film->has_a( created_date => 'Class::Date' );

-- then, later --

my $film = Film->retrieve($id); print $film->created_date; print $film->created_date->mdy; print ($film->created_date - Class::Date->now)->day; print $film->created_date->string $film->created_date("2004-2-20"); $film->created_date(undef); $film->update;
 * 1) prints current date/time format
 * 1) prints mm/dd/yy
 * 1) prints number of days, to the decimal place
 * 1) prints mysql string 'yyyy-mm-dd hh:mm:ss'
 * 1) change created date
 * 1) undef Class::Date value will default to current date when deflated

An additional example, from Bodo:

package main; use Foo; use Class::Date; Foo->create({ date => Class::Date->now }); my $row = Foo->retrieve($id); my $date = $row->date;

In string context the $date object automatically gets stringified.

If you want a different output format, change the has_a to something like:

Foo->has_a( date   => 'Class::Date',    inflate => sub {              # German date format                   $Class::Date::DATE_FORMAT = "%d.%m.%Y - %H:%M:%S";                 Class::Date->new(shift) }    );

-- Bodo

There is more info about Class::Date at http://hacks.dlux.hu/Class-Date/manual.html.

A Comment from Shngn:

The following code relies on the database's date format when it converts the date to a string on a query: Film->has_a( created_date => 'Class::Date' );

This won't work with the default Oracle date format of 'DD-MON-YY' (6-DEC-1977 for example). This can be fixed in Oracle by changing the default date format.

-- Shngn

MySQL date fields can have the value '0000-00-00 00:00:00' in some databases (and other values that may not be parsed). In that scenario, you might to use the following method which turns such values into undefined values.

# Generic is better sub date_field_inflate($) { my $fieldname = shift; return sub { my $arg = shift; my $class = shift; if ( substr($arg, 0, 4) eq "0000" ) { $class->{$fieldname} = undef; return undef; }       return Class::Date->new($arg) } }  # Then __PACKAGE__->has_a(some_date=> 'Class::Date',   inflate => date_field_inflate('some_date'),    deflate => 'string'  );

-- Romuald