I have been trying to use the DateTime->DefaultLanguage() and now 
DateTime->DefaultLocale() with no success. The following is a description of the 
problem and a possible solution:

The problem is as follows, the DateTime constructor does not use the DefaultLocale 
value when creating a new instance (it will always default to 'en_US'). 

A script to highlight the problem:

#!/usr/bin/perl -w
use DateTime;
use strict;

# Change default locale
print DateTime->DefaultLocale(), "\n"; # outputs: 'en_US', correct
print DateTime->DefaultLocale( 'fr_CA' ), "\n"; # outputs: 'fr_CA', correct
print DateTime->DefaultLocale(), "\n"; # still outputs: 'fr_CA' still correct

# Create 3 dates
my $t0 = DateTime->today();  # default locale should be 'fr_CA'
my $t1 = DateTime->today( locale => 'fr_CA'); # forcing locale to be 'fr_CA'
my $t2 = DateTime->today( locale => 'es_ES' ); # forcing another locale

# and print
print "Today: " . $t0->strftime( '%B' ) . "\n"; # Prints 'July'. Incorrect
print "Today: " . $t1->strftime( '%B' ) . "\n"; # Prints 'juillet', correct.
print "Today: " . $t2->strftime( '%B' ) . "\n"; # Prints 'julio', I'm assuming this is 
correct since I don't know es from ru :)


I looked at DateTime.pm and found that the default value of the locale is used once 
while creating $BasicValidate. Once this assignement is done no amount of calling 
DefaultLocale() will change the $BasicValidate hash ref, and since this BasicValidate 
(and associated NewValidate) hash reference  is created during loading it will always 
default to 'en_US'.

The call to DefaultLocale should only occur when it is needed (ie: just before 
actually validating the parameters). After having looked at where BasicValidate and 
NewValidate are used,  I have applied the following changes to the new function:

Current Version:
--------------------------
sub new
{
    my $class = shift;
    my %p = validate( @_,  $NewValidate );
    .....


New Version:
----------------------
sub new
{
    my $class = shift;
    my %p = validate( @_,  { %$NewValidate,
          locale    => { type => SCALAR | OBJECT,
                     default => __PACKAGE__->DefaultLocale } } );
    .....

 <<DateTime.patch>> 
Not quite elegant, but the default value will be used every time new() is called. I 
have not done extensive testing, I have just started using the package yesterday and 
I'm not familiar with all of it's functionality, but from what I can see everywhere 
else the BasicValidate (or a "descendant") is used the default clause is deleted.

I guess another solution would be to change Params::Validate to accept callback 
functions for default value. But that's for another mailing list...  :) .

Serge


Serge L�ger
PWGSC, Senior Informatics Specialist

Attachment: DateTime.patch
Description: DateTime.patch

Reply via email to