DateTime::Locale has a very comprehensive list of date and time formats for various locales and countries. I would like to use it in emails to customers, depending on which country the customer is from.
Unfortunately, it is a little hard to understand from the documentation how to actually use the functions for a medium or a long date. For example, DateTime::Locale::de_DE lists these date formats (excerpt) in the doc:
Long 2008-02-05T18:30:30 = 5. Februar 2008 1995-12-22T09:05:02 = 22. Dezember 1995 -0010-09-15T04:44:23 = 15. September -10 Medium 2008-02-05T18:30:30 = 05.02.2008 1995-12-22T09:05:02 = 22.12.1995 -0010-09-15T04:44:23 = 15.09.-010
This is great. According to DateTime::Locale::Base there are methods in the locale object to get these formats: $locale->date_format_long()
and $locale->date_format_medium()
.
After some googling I came up with Sinan Ünür's blog, where he shows this code (excerpt):
for my $locale ( qw(ar da de en_GB es fr ru tr) ) { $dt->set_locale( $locale ); print_date( $dt ); } sub print_date { my ($dt) = @_; my $locale = $dt->locale; printf( "In %s: %s\n", $locale->name, $dt->format_cldr($locale->date_format_full) ); }
So the format that comes out of these methods is a cldr format. Cool. But what Sinan shows looks tedius. In short, it would be:
for (qw( ar da de en_GB es fr ru tr )) {
my $dt2 = DateTime->now( locale => $_ );
printf "%s: %s\n", $_, $dt2->format_cldr($dt2->locale->date_format_long);
}
In order to make that shorter, I could of course do something like this:
package DateTime;
sub stringify_long {
return $_[0]->format_cldr($_[0]->locale->date_format_long);
}
package Main;
use strict; use warnings;
use DateTime;
my $dt = DateTime->now( locale => 'de_DE' );
print $dt->stringify_long;
But I don't want to do that. So my question: Is there a way to stringify a DateTime object according to one of these formats from its locale with a build-in method that I am missing?
I'm not sure what your opposition is to Sinan Ünür's method, so I don't know if this will appeal to you or not, but you can specify a formatter object to control stringification of DateTime
objects:
use DateTime;
use DateTime::Format::CLDR;
use DateTime::Locale;
my $locale = DateTime::Locale->load('de_DE');
my $formatter = DateTime::Format::CLDR->new(
pattern => $locale->date_format_long,
locale => $locale
);
my $dt = DateTime->now( locale => $locale, formatter => $formatter );
print $dt;
or
use DateTime;
use DateTime::Format::CLDR;
use DateTime::Locale;
my $locale = DateTime::Locale->load('de_DE');
my $dt = DateTime->now( locale => $locale );
my $formatter = DateTime::Format::CLDR->new(
pattern => $locale->date_format_long,
locale => $locale
);
$dt->set_formatter($formatter);
print $dt;
The nice thing about this approach is that once you've set a formatter, printing the date is easy-peasy.