NAME

DateTime::Locale::FromCLDR - DateTime Localised Data from Unicode CLDR

SYNOPSIS

use DateTime::Locale::FromCLDR;
my $locale = DateTime::Locale::FromCLDR->new( 'ja-Kana-JP' ) ||
    die( DateTime::Locale::FromCLDR->error );
my $locale = DateTime::Locale::FromCLDR->new( 'ja-Kana-JP', calendar => 'japanese' ) ||
    die( DateTime::Locale::FromCLDR->error );
my $array = $locale->am_pm_abbreviated;
my $array = $locale->available_formats;
$locale->calendar( 'hebrew' );
my $str = $locale->calendar;
# a Locale::Unicode object that stringifies to the initial locale value (ja-Kana-JP)
my $obj = $locale->code;
my $str = $locale->date_at_time_format_full;
my $str = $locale->date_at_time_format_long;
my $str = $locale->date_at_time_format_medium;
my $str = $locale->date_at_time_format_short;
my $str = $locale->date_format_default;
my $str = $locale->date_format_full;
my $str = $locale->date_format_long;
my $str = $locale->date_format_medium;
my $str = $locale->date_format_short;
my $str = $locale->date_formats;
my $str = $locale->datetime_format;
my $str = $locale->datetime_format_default;
my $str = $locale->datetime_format_full;
my $str = $locale->datetime_format_long;
my $str = $locale->datetime_format_medium;
my $str = $locale->datetime_format_short;
my $str = $locale->day_format_abbreviated;
my $str = $locale->day_format_narrow;
my $str = $locale->day_format_short;
my $str = $locale->day_format_wide;
my $str = $locale->day_period_format_abbreviated( $datetime_object );
my $str = $locale->day_period_format_narrow( $datetime_object );
my $str = $locale->day_period_format_wide( $datetime_object );
my $str = $locale->day_period_stand_alone_abbreviated( $datetime_object );
my $str = $locale->day_period_stand_alone_narrow( $datetime_object );
my $str = $locale->day_period_stand_alone_wide( $datetime_object );
my $hashref = $locale->day_periods;
my $str = $locale->day_stand_alone_abbreviated;
my $str = $locale->day_stand_alone_narrow;
my $str = $locale->day_stand_alone_short;
my $str = $locale->day_stand_alone_wide;
my $str = $locale->default_date_format_length;
my $str = $locale->default_time_format_length;
my $str = $locale->era_abbreviated;
my $str = $locale->era_narrow;
my $str = $locale->era_wide;
my $str = $locale->first_day_of_week;
my $str = $locale->format_for( 'yMEd' );
my $str = $locale->gmt_format(0);
my $str = $locale->gmt_format(3600);
my $str = $locale->gmt_format(-3600);
my $str = $locale->gmt_format(-3600, width => 'short');
my $str = $locale->gmt_format(-3600, { width => 'short' });
# Alias for method 'code'
my $obj = $locale->id;
my $array = $locale->interval_format( GyMEd => 'd' );
my $hashref = $locale->interval_formats;
my $greatest_diff = $locale->interval_greatest_diff( $datetime_object_1, $datetime_object_2 );
my $str = $locale->language;
my $str = $locale->language_code;
# Alias for method 'language_code'
my $str = $locale->language_id;
# Locale::Unicode object
my $obj = $locale->locale;
# Equivalent to $locale->locale->as_string
my $str = $locale->locale_as_string;
# As per standard, it falls back to 'wide' format if it is not available
my $str = $locale->metazone_daylight_long( metazone => 'Taipei' );
my $str = $locale->metazone_daylight_short( metazone => 'Taipei' );
my $str = $locale->metazone_generic_long( metazone => 'Taipei' );
my $str = $locale->metazone_generic_short( metazone => 'Taipei' );
my $str = $locale->metazone_standard_long( metazone => 'Taipei' );
my $str = $locale->metazone_standard_short( metazone => 'Taipei' );
my $str = $locale->month_format_abbreviated;
my $str = $locale->month_format_narrow;
my $str = $locale->month_format_wide;
my $str = $locale->month_stand_alone_abbreviated;
my $str = $locale->month_stand_alone_narrow;
my $str = $locale->month_stand_alone_wide;
# Language name in English. Here: Japanese
my $str = $locale->name;
# Alias for the method 'native_name'
my $str = $locale->native_language;
# Language name in the locale's original language. Here: 日本語
my $str = $locale->native_name;
# The local's script name in the locale's original language. Here: カタカナ
my $str = $locale->native_script;
# The local's territory name in the locale's original language. Here: 日本
my $str = $locale->native_territory;
# The local's variant name in the locale's original language. Here: undef since there is none
my $str = $locale->native_variant;
my $str = $locale->native_variants;
# Returns 1 or 0
my $bool = $locale->prefers_24_hour_time;
my $str = $locale->quarter_format_abbreviated;
my $str = $locale->quarter_format_narrow;
my $str = $locale->quarter_format_wide;
my $str = $locale->quarter_stand_alone_abbreviated;
my $str = $locale->quarter_stand_alone_narrow;
my $str = $locale->quarter_stand_alone_wide;
# The locale's script name in English. Here: Katakana
my $str = $locale->script;
# The locale's script ID, if any. Here: Kana
my $str = $locale->script_code;
# Alias for method 'script_code'
my $str = $locale->script_id;
# The locale's territory name in English. Here: Japan
my $str = $locale->territory;
# The locale's territory ID, if any. Here: JP
my $str = $locale->territory_code;
# Alias for method 'territory_code'
my $str = $locale->territory_id;
my $str = $locale->time_format_default;
my $str = $locale->time_format_full;
my $str = $locale->time_format_long;
my $str = $locale->time_format_medium;
my $str = $locale->time_format_short;
# Time patterns for 'full', 'long', 'medium', and 'short' formats
my $array = $locale->time_formats;
my $str = $locale->timezone_city( timezone => 'Asia/Tokyo' );
my $str = $locale->timezone_format_fallback;
my $str = $locale->timezone_format_gmt;
my $str = $locale->timezone_format_gmt_zero;
my $str = $locale->timezone_format_hour;
my $str = $locale->timezone_format_region;
my $str = $locale->timezone_format_region_daylight;
my $str = $locale->timezone_format_region_standard;
my $str = $locale->timezone_daylight_long( timezone => 'Europe/London' );
my $str = $locale->timezone_daylight_short( timezone => 'Europe/London' );
my $str = $locale->timezone_generic_long( timezone => 'Europe/London' );
my $str = $locale->timezone_generic_short( timezone => 'Europe/London' );
my $str = $locale->timezone_standard_long( timezone => 'Europe/London' );
my $str = $locale->timezone_standard_short( timezone => 'Europe/London' );
# The locale's variant name, if any, in English. Here undef, because there is none
my $str = $locale->variant;
# The locale's variant ID, if any. Here undef, since there is none
my $str = $locale->variant_code;
# Alias for method 'variant_code'
my $str = $locale->variant_id;
my $array = $locale->variants;
# The CLDR data version. For example: 45.0
my $str = $locale->version;

# To get DateTime to use DateTime::Locale::FromCLDR for the locale data
my $dt = DateTime->now(
    locale => DateTime::Locale::FromCLDR->new( 'en' ),
);

Enabling fatal exceptions:

use v5.34;
use experimental 'try';
no warnings 'experimental';
try
{
    my $locale = DateTime::Locale::FromCLDR->new( 'en', fatal => 1 );
    # Missing the 'offset' argument
    my $str = $locale->format_gmt;
    # More code
}
catch( $e )
{
    say "Oops: ", $e->message;
}

Or, you could set the global variable $FATAL_EXCEPTIONS instead:

use v5.34;
use experimental 'try';
no warnings 'experimental';
$DateTime::Locale::FromCLDR::FATAL_EXCEPTIONS = 1;
try
{
    my $locale = DateTime::Locale::FromCLDR->new( 'en' );
    # Missing the 'offset' argument
    my $str = $locale->format_gmt;
    # More code
}
catch( $e )
{
    say "Oops: ", $e->message;
}

VERSION

v0.6.0

DESCRIPTION

This is a powerful replacement for DateTime::Locale and DateTime::Locale::FromData that use static data from over 1,000 pre-generated modules, whereas DateTime::Locale::FromCLDR builds a locale object to access its Unicode CLDR (Common Locale Data Repository) data from SQLite data made available with Locale::Unicode::Data

It provides the same API as DateTime::Locale, but in a dynamic way. This is important since in the Unicode LDML specifications, a locale inherits from its parent's data.

Once a data is retrieved by a method, it is cached to avoid waste of time.

It also adds a few methods to access the locale at time patterns, such as date_at_time_format_full, and native_variants

It also provides key support for day period

It also provides support for interval datetime, and a method to find the greatest datetime difference element between 2 datetimes, as well as a method to get all the available format patterns for intervals, and a method to retrieve the components of an specific interval patterns

It adds the short format for day missing in DateTime::Locale::FromData

Note that in CLDR parlance, there are standard pattern formats. For example full, long, medium, short or also abbreviated, short, wide, narrow providing various level of conciseness.

CONSTRUCTOR

new

# Japanese as spoken in Japan
my $locale = DateTime::Locale::FromCLDR->new( 'ja-JP' ) ||
    die( DateTime::Locale::FromCLDR->error );
# Okinawan as spoken in Japan Southern islands
my $locale = DateTime::Locale::FromCLDR->new( 'ryu-Kana-JP-t-de-t0-und-x0-medical' ) ||
    die( DateTime::Locale::FromCLDR->error );

use Locale::Unicode;
my $loc = Locale::Unicode->new( 'fr-FR' );
my $locale = DateTime::Locale::FromCLDR->new( $loc ) ||
    die( DateTime::Locale::FromCLDR->error );

Specifying a calendar ID other than the default gregorian:

my $locale = DateTime::Locale::FromCLDR->new( 'ja-JP', calendar => 'japanese' ) ||
    die( DateTime::Locale::FromCLDR->error );

or, using an hash reference:

my $locale = DateTime::Locale::FromCLDR->new( 'ja-JP', { calendar => 'japanese' } ) ||
    die( DateTime::Locale::FromCLDR->error );

Instantiate a new DateTime::Locale::FromCLDR object based on a locale provided, and returns it. By default, it uses the calendar gregorian, but you can specify a different one with the calendar option.

You can provide any locale, even complex one as shown above, and only its core part will be retained. So, for example:

my $locale = DateTime::Locale::FromCLDR->new( 'ryu-Kana-JP-t-de-t0-und-x0-medical' ) ||
    die( DateTime::Locale::FromCLDR->error );
say $locale; # ryu-Kana-JP

If an error occurs, it sets an exception object and returns undef in scalar context, or an empty list in list context, or possibly a special DateTime::Locale::FromCLDR::NullObject in object context. See "error" for more information.

The object is overloaded and stringifies into the core part of the original string provided upon instantiation.

The core part is comprised of the language ID, an optional script ID, an optional territory ID and zero or multiple variant IDs. See Locale::Unicode and the LDML specifications for more information.

METHODS

All methods are read-only unless stated otherwise.

am_pm_abbreviated

This is an alias for am_pm_format_abbreviated

am_pm_format_abbreviated

my $array = $locale->am_pm_format_abbreviated;

Returns an array reference of the terms used to represent am and pm

The array reference could be empty if the locale does not support specifying am/pm

For example:

my $locale = DateTime::Locale::FromCLDR->new( 'en' );
my $ampm = $locale->am_pm_abbreviated
say @$ampm; # AM, PM

my $locale = DateTime::Locale::FromCLDR->new( 'ja' );
my $ampm = $locale->am_pm_abbreviated
say @$ampm; # 午前, 午後

my $locale = DateTime::Locale::FromCLDR->new( 'fr' );
my $ampm = $locale->am_pm_abbreviated
say @$ampm; # Empty

See "calendar_term" in Locale::Unicode::Data

am_pm_format_narrow

Same as am_pm_format_abbreviated, but returns the narrow format of the AM/PM terms.

my $locale = DateTime::Locale::FromCLDR->new( 'en' );
say $locale->am_pm_format_narrow;

am_pm_format_wide

Same as am_pm_format_abbreviated, but returns the wide format of the AM/PM terms.

my $locale = DateTime::Locale::FromCLDR->new( 'en' );
say $locale->am_pm_format_wide;

am_pm_standalone_abbreviated

Same as am_pm_format_abbreviated, but returns the abbreviated stand-alone format of the AM/PM terms.

my $locale = DateTime::Locale::FromCLDR->new( 'en' );
say $locale->am_pm_standalone_abbreviated;

am_pm_standalone_narrow

Same as am_pm_format_abbreviated, but returns the narrow stand-alone format of the AM/PM terms.

my $locale = DateTime::Locale::FromCLDR->new( 'en' );
say $locale->am_pm_standalone_narrow;

am_pm_standalone_wide

Same as am_pm_format_abbreviated, but returns the wide stand-alone format of the AM/PM terms.

my $locale = DateTime::Locale::FromCLDR->new( 'en' );
say $locale->am_pm_standalone_wide;

available_formats

my $locale = DateTime::Locale::FromCLDR->new( 'en' );
my $array = $locale->available_formats;

Returns an array reference of all the format ID available for this locale

See "calendar_available_format" in Locale::Unicode::Data

available_format_patterns

my $locale = DateTime::Locale::FromCLDR->new( 'en' );
my $ref = $locale->available_format_patterns;

Returns an hash reference of all the available format ID to their corresponding pattern for the locale

See "calendar_available_format" in Locale::Unicode::Data

calendar

my $locale = DateTime::Locale::FromCLDR->new( 'ja-Kana-JP', calendar => 'japanese' ) ||
    die( DateTime::Locale::FromCLDR->error );
my $str = $locale->calendar; # japanese
$locale->calendar( 'gregorian' );

Sets or gets the calendar ID used to perform queries along with the given locale

code

my $obj = $locale->code;

Returns the Locale::Unicode object either received or created upon object instantiation.

date_at_time_format_full

my $str = $locale->date_at_time_format_full;

Returns the full date at time pattern

For example:

my $locale = DateTime::Locale::FromCLDR->new( 'en' );
say $locale->date_at_time_format_full;
# EEEE, MMMM d, y 'at' h:mm:ss a zzzz
# Tuesday, July 23, 2024 at 1:26:38 AM UTC

my $locale = DateTime::Locale::FromCLDR->new( 'fr' );
say $locale->date_at_time_format_full;
# EEEE d MMMM y 'à' HH:mm:ss zzzz
# mardi 23 juillet 2024 à 01:27:11 UTC

date_at_time_format_long

Same as date_at_time_format_full, but returns the long format pattern.

my $locale = DateTime::Locale::FromCLDR->new( 'en' );
say $locale->date_at_time_format_long;
# MMMM d, y 'at' h:mm:ss a z
# July 23, 2024 at 1:26:11 AM UTC

date_at_time_format_medium

Same as date_at_time_format_full, but returns the medium format pattern.

my $locale = DateTime::Locale::FromCLDR->new( 'en' );
say $locale->date_at_time_format_medium;
# MMM d, y 'at' h:mm:ss a
# Jul 23, 2024 at 1:25:43 AM

date_at_time_format_short

Same as date_at_time_format_full, but returns the short format pattern.

my $locale = DateTime::Locale::FromCLDR->new( 'en' );
say $locale->date_at_time_format_short;
# M/d/yy 'at' h:mm a
# 7/23/24 at 1:25 AM

date_format_default

This is an alias to date_format_medium

date_format_full

my $locale = DateTime::Locale::FromCLDR->new( 'en' );
say $locale->date_format_full;
# EEEE, MMMM d, y
# Tuesday, July 23, 2024

Returns the full date pattern

See also "calendar_format_l10n" in Locale::Unicode::Data

date_format_long

Same as date_format_full, but returns the long format pattern.

my $locale = DateTime::Locale::FromCLDR->new( 'en' );
say $locale->date_format_long;
# MMMM d, y
# July 23, 2024

date_format_medium

Same as date_format_full, but returns the medium format pattern.

my $locale = DateTime::Locale::FromCLDR->new( 'en' );
say $locale->date_format_long;
# MMM d, y
# Jul 23, 2024

date_format_short

Same as date_format_full, but returns the short format pattern.

my $locale = DateTime::Locale::FromCLDR->new( 'en' );
say $locale->date_format_short;
# M/d/yy
# 7/23/24

date_formats

my $now = DateTime->now( locale => 'en' );
my $ref = $locale->date_formats;
foreach my $type ( sort( keys( %$ref ) ) )
{
    say $type, ":";
    say $ref->{ $type };
    say $now->format_cldr( $ref->{ $type } ), "\n";
}

Would produce:

full:
EEEE, MMMM d, y
Tuesday, July 23, 2024

long:
MMMM d, y
July 23, 2024

medium:
MMM d, y
Jul 23, 2024

short:
M/d/yy
7/23/24

Returns an hash reference with the keys being: full, long, medium, short and their value the result of their associated date format methods.

datetime_format

This is an alias for datetime_format_medium

datetime_format_default

This is also an alias for datetime_format_medium

datetime_format_full

my $locale = DateTime::Locale::FromCLDR->new( 'en' );
say $locale->datetime_format_full;
# EEEE, MMMM d, y, h:mm:ss a zzzz
# Tuesday, July 23, 2024, 1:53:27 AM UTC

Returns the full datetime pattern

See also "calendar_datetime_format" in Locale::Unicode::Data

datetime_format_long

Same as datetime_format_full, but returns the long format pattern.

my $locale = DateTime::Locale::FromCLDR->new( 'en' );
say $locale->datetime_format_long;
# MMMM d, y, h:mm:ss a z
# July 23, 2024, 1:57:02 AM UTC

datetime_format_medium

Same as datetime_format_full, but returns the medium format pattern.

my $locale = DateTime::Locale::FromCLDR->new( 'en' );
say $locale->datetime_format_medium;
# MMM d, y, h:mm:ss a
# Jul 23, 2024, 2:03:16 AM

datetime_format_short

Same as datetime_format_full, but returns the short format pattern.

my $locale = DateTime::Locale::FromCLDR->new( 'en' );
say $locale->datetime_format_short;
# M/d/yy, h:mm a
# 7/23/24, 2:04 AM

day_format_abbreviated

my $locale = DateTime::Locale::FromCLDR->new( 'en' );
my $days = $locale->day_format_abbreviated;
say @$days;
# Mon, Tue, Wed, Thu, Fri, Sat, Sun

Returns an array reference of week day names abbreviated format with Monday first and Sunday last.

See also "calendar_term" in Locale::Unicode::Data

day_format_narrow

Same as day_format_abbreviated, but returns the narrow format days.

my $locale = DateTime::Locale::FromCLDR->new( 'en' );
my $days = $locale->day_format_abbreviated;
say @$days;
# M, T, W, T, F, S, S

day_format_short

Same as day_format_abbreviated, but returns the short format days.

my $locale = DateTime::Locale::FromCLDR->new( 'en' );
my $days = $locale->day_format_short;
say @$days;
# Mo, Tu, We, Th, Fr, Sa, Su

day_format_wide

Same as day_format_abbreviated, but returns the wide format days.

my $locale = DateTime::Locale::FromCLDR->new( 'en' );
my $days = $locale->day_format_wide;
say @$days;
# Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday

day_period_format_abbreviated

my $dt = DateTime->new( year => 2024, hour => 7 );
my $locale = DateTime::Locale::FromCLDR->new( 'en' );
say $locale->day_period_format_abbreviated( $dt );
# in the morning

my $dt = DateTime->new( year => 2024, hour => 13 );
my $locale = DateTime::Locale::FromCLDR->new( 'en' );
say $locale->day_period_format_abbreviated( $dt );
# in the afternoon

my $dt = DateTime->new( year => 2024, hour => 7 );
my $locale = DateTime::Locale::FromCLDR->new( 'ja-Kana-JP' );
say $locale->day_period_format_abbreviated( $dt );
# 朝
# which means "morning" in Japanese

my $dt = DateTime->new( year => 2024, hour => 13 );
my $locale = DateTime::Locale::FromCLDR->new( 'fr' );
say $locale->day_period_format_abbreviated( $dt );
# après-midi

Returns a string representing the localised expression of the period of day the DateTime object provided is.

If nothing relevant could be found somehow, this will return an empty string. undef is returned only if an error occurred.

This is used to provide the relevant value for the token B or b in the Unicode LDML format patterns

See also "calendar_term" in Locale::Unicode::Data, "day_period" in Locale::Unicode::Data and DateTime::Format::Unicode

day_period_format_narrow

Same as day_period_format_abbreviated, but returns the narrow format of day period.

my $dt = DateTime->new( year => 2024, hour => 7 );
my $locale = DateTime::Locale::FromCLDR->new( 'en' );
say $locale->day_period_format_narrow( $dt );
# in the morning

day_period_format_wide

Same as day_period_format_abbreviated, but returns the wide format of day period.

my $dt = DateTime->new( year => 2024, hour => 7 );
my $locale = DateTime::Locale::FromCLDR->new( 'en' );
say $locale->day_period_format_wide( $dt );
# in the morning

day_period_stand_alone_abbreviated

my $dt = DateTime->new( year => 2024, hour => 7 );
my $locale = DateTime::Locale::FromCLDR->new( 'en' );
say $locale->day_period_stand_alone_abbreviated( $dt );
# morning

my $dt = DateTime->new( year => 2024, hour => 13 );
my $locale = DateTime::Locale::FromCLDR->new( 'en' );
say $locale->day_period_stand_alone_abbreviated( $dt );
# afternoon

my $dt = DateTime->new( year => 2024, hour => 7 );
my $locale = DateTime::Locale::FromCLDR->new( 'ja-Kana-JP' );
say $locale->day_period_stand_alone_abbreviated( $dt );
# ""

The previous example would yield nothing, and as per the LDML specifications, you would need to use the localised AM/PM instead.

my $dt = DateTime->new( year => 2024, hour => 13 );
my $locale = DateTime::Locale::FromCLDR->new( 'fr' );
say $locale->day_period_stand_alone_abbreviated( $dt );
# ap.m.

Returns a string representing the localised expression of the period of day the DateTime object provided is.

If nothing relevant could be found somehow, this will return an empty string. undef is returned only if an error occurred.

This is used to provide a stand-alone word that can be used as a title, or in a different context.

See also "calendar_term" in Locale::Unicode::Data, "day_period" in Locale::Unicode::Data and DateTime::Format::Unicode

day_period_stand_alone_narrow

Same as day_period_stand_alone_abbreviated, but returns the narrow stand-alone version of the day period.

my $dt = DateTime->new( year => 2024, hour => 13 );
my $locale = DateTime::Locale::FromCLDR->new( 'fr' );
say $locale->day_period_stand_alone_narrow( $dt );
# ap.m.

day_period_stand_alone_wide

Same as day_period_stand_alone_abbreviated, but returns the wide stand-alone version of the day period.

my $dt = DateTime->new( year => 2024, hour => 13 );
my $locale = DateTime::Locale::FromCLDR->new( 'fr' );
say $locale->day_period_stand_alone_wide( $dt );
# après-midi

day_periods

my $locale = DateTime::Locale::FromCLDR->new( 'en' );
my $hash = $locale->day_periods;
# Would return an hash reference like:
{
    midnight => ["00:00", "00:00"],
    morning1 => ["06:00", "12:00"],
    noon => ["12:00", "12:00"],
    afternoon1 => ["12:00", "18:00"],
    evening1 => ["18:00", "21:00"],
    night1 => ["21:00", "06:00"],
}

Returns an hash reference of day period token and values of 2-elements array (start time and end time in hours and minutes)

day_stand_alone_abbreviated

my $locale = DateTime::Locale::FromCLDR->new( 'en' );
my $days = $locale->day_stand_alone_abbreviated;
say @$days;
# Mon, Tue, Wed, Thu, Fri, Sat, Sun

Returns an array reference of week day names in abbreviated format with Monday first and Sunday last.

This is often identical to the format type.

See the LDML specifications for more information on the difference between the format and stand-alone types.

day_stand_alone_narrow

Same as day_stand_alone_abbreviated, but returns the narrow format days.

my $locale = DateTime::Locale::FromCLDR->new( 'en' );
my $days = $locale->day_stand_alone_narrow;
say @$days;
# M, T, W, T, F, S, S

day_stand_alone_short

Same as day_stand_alone_abbreviated, but returns the short format days.

my $locale = DateTime::Locale::FromCLDR->new( 'en' );
my $days = $locale->day_stand_alone_short;
say @$days;
# Mo, Tu, We, Th, Fr, Sa, Su

day_stand_alone_wide

Same as day_stand_alone_abbreviated, but returns the wide format days.

my $locale = DateTime::Locale::FromCLDR->new( 'en' );
my $days = $locale->day_stand_alone_wide;
say @$days;
# Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday

default_date_format_length

This returns the string medium

default_time_format_length

This returns the string medium

era_abbreviated

my $array = $locale->era_abbreviated;
say @$array;
# BC, AD

Returns an array reference of era names in abbreviated format.

See also "calendar_eras_l10n" in Locale::Unicode::Data

era_narrow

Same as era_abbreviated, but returns the narrow format eras.

my $locale = DateTime::Locale::FromCLDR->new( 'en' );
my $array = $locale->era_narrow;
say @$array;
# B, A

era_wide

Same as era_abbreviated, but returns the wide format eras.

my $locale = DateTime::Locale::FromCLDR->new( 'en' );
my $array = $locale->era_wide;
say @$array;
# Before Christ, Anno Domini

error

Used as a mutator, this sets an exception object and returns an DateTime::Locale::FromCLDR::NullObject in object context (such as when chaining), or undef in scalar context, or an empty list in list context.

The DateTime::Locale::FromCLDR::NullObject class prevents the perl error of Can't call method "%s" on an undefined value (see perldiag). Upon the last method chained, undef is returned in scalar context or an empty list in list context.

fatal

$cldr->fatal(1); # Enable fatal exceptions
$cldr->fatal(0); # Disable fatal exceptions
my $bool = $cldr->fatal;

Sets or get the boolean value, whether to die upon exception, or not. If set to true, then instead of setting an exception object, this module will die with an exception object. You can catch the exception object then after using try. For example:

use v.5.34; # to be able to use try-catch blocks in perl
use experimental 'try';
no warnings 'experimental';
try
{
    my $cldr = DateTime::Locale::FromCLDR->new( 'en', fatal => 1 );
    # Forgot the 'offset':
    my $str = $locale->format_gmt;
}
catch( $e )
{
    say "Error occurred: ", $e->message;
    # Error occurred: No value for width was provided.
}

first_day_of_week

my $integer = $locale->first_day_of_week;

Returns an integer ranging from 1 to 7 where 1 means Monday and 7 means Sunday.

This represents what is the first day of the week for this locale

Since the information on the first day of the week pertains to a territory, if the locale you provided does not have such information, this method will find out the likely subtag to get the locale's rightful territory

See the LDML specifications about likely subtags for more information.

For example:

my $locale = DateTime::Locale::FromCLDR->new( 'en' );

Since there is no territory associated, this will look up the likely subtag to find the target locale is en-Latn-US, and thus the territory for en is US and first day of the week is 7

Another example:

my $locale = DateTime::Locale::FromCLDR->new( 'fr-Latn' );

This will ultimately get the territory FR and first day of the week is 1

# Okinawan as spoken in the Japanese Southern islands
my $locale = DateTime::Locale::FromCLDR->new( 'ryu' );

This will become ryu-Kana-JP and thus the territory would be JP and first day of the week is 7

This information is cached in the current object, like for all the other methods in this API.

format_for

my $locale = DateTime::Locale::FromCLDR->new( 'en' );
my $pattern = $locale->format_for( 'Bhm' );

Provided with the format ID of an available format and this will return the localised CLDR pattern.

Keep in mind that the CLDR formatting method of DateTime does not recognise all the CLDR pattern tokens. Thus, for example, if you chose the standard available pattern Bhm, this method would return the localised pattern h:mm B. However, DateTime does not understand the token B

my $now = DateTime->now( locale => "en", time_zone => "Asia/Tokyo" );
# Assuming $now = 2024-07-23T21:39:39
say $now->format_cldr( 'h:mm B' );
# 9:39 B

But B is the day period, which can be looked up with "day_period" in Locale::Unicode::Data, which provides us with the day period token night1, which itself can be looked up with "calendar_term" in Locale::Unicode::Data and gives us the localised string at night. Thus the proper CLDR formatting really should be 9:39 at night

You can use DateTime::Format::Unicode instead of the default DateTime CLDR formatting if you want to get better support for all CLDR pattern tokens.

With Japanese:

my $locale = DateTime::Locale::FromCLDR->new( 'ja' );
my $pattern = $locale->format_for( 'Bhm' );
# BK:mm
my $now = DateTime->now( locale => "ja", time_zone => "Asia/Tokyo" );
say $now->format_cldr( 'BK:mm' );
# B9:54

But, this should have yielded: 夜9:54 instead.

format_gmt

my $locale = DateTime::Locale::FromCLDR->new( 'en' );
# Get the offset in seconds from the UTC
my $offset = $dt->offset;
my $str = $locale->gmt_format( $offset );
# The 'width' is 'long' by default
my $str = $locale->gmt_format( $offset, width => 'short' );

This returns a localised and formatted GMT timezone given an offset in seconds of the datetime from UTC.

For example:

  • GMT

  • UTC

  • Гринуич

Optionally, you can provide the width option that may have the value long (default), or short

If the offset is 0, meaning this is the GMT time, then the localised representation of GMT is returned using timezone_format_gmt_zero, otherwise it will use the GMT format provided by timezone_format_gmt and timezone_format_hour for the formatting of the hours, minutes and possibly seconds.

Also, if the option width is provided with a value short, then the GMT hours, minutes, seconds formatting will not be zero padded.

For example:

  • GMT+03:30

    Long

  • GMT+3:30

    Short

  • UTC-03.00

    Long

  • UTC-3

    Short

  • Гринуич+03:30

    Long

See the LDML specifications for more information.

format_timezone_location

my $locale = DateTime::Locale::FromCLDR->new( 'en' );
my $str = $locale->format_timezone_location( timezone => 'Europe/Rome' );
# "Italy Time"
my $str = $locale->format_timezone_location( timezone => 'America/Buenos_Aires' );
# "Buenos Aires Time"

Returns a properly formatted timezone based on the locale and the given timezone provided in an hash or hash reference.

Note that, if the given timezone is, what is called by the LDML specifications, a "Golden Time Zone", then it represents a territory, and the localised territory name is used instead of the localised exemplar city for that timezone. For example:

my $locale = DateTime::Locale::FromCLDR->new( 'en' );
my $str = $locale->format_timezone_location( timezone => 'Asia/Taipei' );

would yield Taiwan Time, because Asia/Taipei is the primary timezone for Taiwan.

format_timezone_non_location

my $locale = DateTime::Locale::FromCLDR->new( 'ja' );
my $str = $locale->format_timezone_non_location(
    timezone => 'America/Los_Angeles',
    type => 'standard',
);
# アメリカ太平洋標準時
my $locale = DateTime::Locale::FromCLDR->new( 'en' );
my $str = $locale->format_timezone_non_location(
    timezone => 'America/Vancouver',
    type => 'standard',
);
# Pacific Time (Canada)
my $str = $locale->format_timezone_non_location(
    timezone => 'America/Phoenix',
    type => 'standard',
);
# Mountain Time (Phoenix)
my $str = $locale->format_timezone_non_location(
    timezone => 'America/Whitehorse',
    type => 'standard',
);
# Pacific Time (Whitehorse)

Returns a properly formatted timezone based on the locale, the given timezone and the type provided in an hash or hash reference.

This is using a complexe algorithm defined by the LDML specifications

The type can only be generic, standard, or daylight:

  • generic

    Quoting from the LDML specifications, "[t]he generic time is so-called wall-time; what clocks use when they are correctly switched from standard to daylight time at the mandated time of the year.". See here too.

    Quoting from the LDML specifications:

    • Generic non-location format

      Reflects "wall time" (what is on a clock on the wall): used for recurring events, meetings, or anywhere people do not want to be overly specific. For example, 10 am Pacific Time will be GMT-8 in the winter, and GMT-7 in the summer.

      For example:

      • Pacific Time (long)

      • PT (short)

    • Generic partial location format

      Reflects "wall time": used as a fallback format when the generic non-location format is not specific enough.

      For example:

      • Pacific Time (Canada) (long)

      • PT (Whitehorse) (short)

    • Generic location format

      Reflects "wall time": a primary function of this format type is to represent a time zone in a list or menu for user selection of time zone. It is also a fallback format when there is no translation for the generic non-location format. Times can also be organized hierarchically by country for easier lookup.

      For example:

      • France Time

      • Italy Time

      • Japan Time

      • United States

        • Chicago Time

        • Denver Time

        • Los Angeles Time

        • New York Time

      • United Kingdom Time

    Note that "[a] generic location format is constructed by a part of time zone ID representing an exemplar city name or its country as the final fallback."

    See also the LDML specifications

  • standard or daylight

    "Reflects a specific standard or daylight time, which may or may not be the wall time. For example, 10 am Pacific Standard Time will be GMT-8 in the winter and in the summer."

    For example:

    • Pacific Standard Time (long)

    • PST (short)

    • Pacific Daylight Time (long)

    • PDT (short)

has_dst

my $locale = DateTime::Locale::FromCLDR->new( 'en' );
my $bool = $locale->has_dst( 'Asia/Tokyo' );
# 0
my $bool = $locale->has_dst( 'America/Los_Angeles' );
# 1

Returns true if the given timezone is using daylight saving time, and false otherwise.

The result is cached to ensure repeating calls for the same timezone are returned even faster.

If an error occurred, this will set an exception object, and returns undef in scalar context, or an empty list in list context.

How does it work? Very simply, this generates a DateTime object based on the current year and given timezone both for January 1st and July 1st, and get the timezone offset for each. If they do not match, the timezone has daylight saving time.

id

This is an alias for locale

interval_format

my $locale = DateTime::Locale::FromCLDR->new( 'en' );
my $array = $locale->interval_format( GyMEd => 'G' );
# ["E, M/d/y G", " – ", "E, M/d/y G", "E, M/d/y G – E, M/d/y G"]
my $array = $locale->interval_format( GyMEd => 'M' );
# ["E, M/d/y", " – ", "E, M/d/y G", "E, M/d/y – E, M/d/y G"]
my $array = $locale->interval_format( GyMEd => 'd' );
# ["E, M/d/y", " – ", "E, M/d/y G", "E, M/d/y – E, M/d/y G"]
my $array = $locale->interval_format( GyMEd => 'y' );
# ["E, M/d/y", " – ", "E, M/d/y G", "E, M/d/y – E, M/d/y G"]

Provided with a format ID and a greatest difference token, and this will return an array reference composed of the following 4 elements:

1. the first part
2. the separator
3. the second part
4. the full interval pattern

If nothing is found for the given format ID and greatest difference token, an empty array reference will be returned.

If an error occurred, this will set an error object and return undef in scalar context and an empty list.

With DateTime::Format::Unicode, you can do something like:

my $fmt = DateTime::Format::Unicode->new(
    pattern => 'GyMEd',
    locale  => 'en',
);
my $str = $fmt->format_interval( $dt1, $dt2 );

This will use this method interval_format

If nothing is found, you can use the fallback pattern, which is something like this (varies from locale to locale): {0} - {1}

my $array = $locale->interval_format( default => 'default' );
# ["{0}", " - ", "{1}", "{0} - {1}"]

However, note that not all locales have a fallback pattern, so even the query above may return an empty array.

For example, as of version 45.0 (2024) of the CLDR data:

# German:
my $locale = DateTime::Locale::FromCLDR->new( 'de' );
my $array = $locale->interval_format( default => 'default' );
# []

# French:
my $locale = DateTime::Locale::FromCLDR->new( 'fr' );
my $array = $locale->interval_format( default => 'default' );
# []

# Italian:
my $locale = DateTime::Locale::FromCLDR->new( 'it' );
my $array = $locale->interval_format( default => 'default' );
# []

interval_formats

my $locale = DateTime::Locale::FromCLDR->new( 'en' );
my $ref = $locale->interval_formats;

This would return something like:

{
    Bh => [qw( B h )],
    Bhm => [qw( B h m )],
    d => ["d"],
    default => ["default"],
    Gy => [qw( G y )],
    GyM => [qw( G M y )],
    GyMd => [qw( d G M y )],
    GyMEd => [qw( d G M y )],
    GyMMM => [qw( G M y )],
    GyMMMd => [qw( d G M y )],
    GyMMMEd => [qw( d G M y )],
    H => ["H"],
    h => [qw( a h )],
    hm => [qw( a h m )],
    Hm => [qw( H m )],
    hmv => [qw( a h m )],
    Hmv => [qw( H m )],
    Hv => ["H"],
    hv => [qw( a h )],
    M => ["M"],
    Md => [qw( d M )],
    MEd => [qw( d M )],
    MMM => ["M"],
    MMMd => [qw( d M )],
    MMMEd => [qw( d M )],
    y => ["y"],
    yM => [qw( M y )],
    yMd => [qw( d M y )],
    yMEd => [qw( d M y )],
    yMMM => [qw( M y )],
    yMMMd => [qw( d M y )],
    yMMMEd => [qw( d M y )],
    yMMMM => [qw( M y )],
}

Returns an hash reference of all available interval format IDs and their associated greatest difference token

The default interval format pattern is something like {0} – {1}, but this changes depending on the locale and is not always available.

{0} is the placeholder for the first datetime and {1} is the placeholder for the second one.

See "interval_formats" in Locale::Unicode::Data

interval_greatest_diff

my $locale = DateTime::Locale::FromCLDR->new( 'en' );
my $diff = $locale->interval_greatest_diff( $dt1, $dt2 );

my $locale = DateTime::Locale::FromCLDR->new( 'en' );
my $diff = $locale->interval_greatest_diff( $dt1, $dt2, day_period_first => 1 );
# or, using an hash reference instead:
# my $diff = $locale->interval_greatest_diff( $dt1, $dt2, { day_period_first => 1 } );

Provided with 2 DateTime objects, and this will compute the greatest difference.

Quoting from the LDML specifications:

"The data supplied in CLDR requires the software to determine the calendar field with the greatest difference before using the format pattern. For example, the greatest difference in "Jan 10-12, 2008" is the day field, while the greatest difference in "Jan 10 - Feb 12, 2008" is the month field. This is used to pick the exact pattern."

If both DateTime objects are identical, this will return an empty string.

You can alter the inner working of the algorithm by providing the option day_period_first with a true value. This will prioritise the day period over the AM/PM (morning vs afternoon). What this means, is that if you have two datetimes, one with an hour at 10:00 and another one at 13:00, by default, the algorithm used in web browser, will return a (component for AM/PM) highlighting the difference between morning and afternoon. However, if you pass the option day_period_first, then, this method will prioritise the day periods difference and return B (component for day periods).

This is important, because of the way almost all, but 4 locales (bg, id, uz and zu), have sliced up their day periods.

For the locale en, for example, the day periods are:

  • midnight

    00:00 00:00

  • morning1

    06:00 12:00

  • noon

    12:00 12:00

  • afternoon1

    12:00 18:00

  • evening1

    18:00 21:00

  • night1

    21:00 06:00

As you can see, there are no occurrence of a day period that spans both morning and afternoon, and thus, because of those data, this method would always return, by default, a instead of B

For the table of the CLDR components, see "Format Patterns" in Locale::Unicode::Data

If an error occurred, an exception object is set and undef is returned in scalar context, and an empty list in list context.

is_dst

my $locale = DateTime::Locale::FromCLDR->new( 'en' );
my $dt = DateTime->new( year => 2024, month => 7, day => 1, time_zone => 'Asia/Tokyo' );
my $bool = $locale->is_dst( $dt );
# 0
my $dt = DateTime->new( year => 2024, month => 7, day => 1, time_zone => 'America/Los_Angeles' );
my $bool = $locale->is_dst( $dt );
# 1

Returns true if the given timezone is using daylight saving time, and false otherwise.

The result is cached to ensure repeating calls for the same timezone are returned even faster.

If an error occurred, this will set an exception object, and returns undef in scalar context, or an empty list in list context.

How does it work? Very simply, this generates a DateTime object based on the current year and given timezone both for January 1st and July 1st, and get the timezone offset for each. If they do not match, the timezone has daylight saving time.

is_ltr

my $locale = DateTime::Locale::FromCLDR->new( 'en' );
my $bool = $locale->is_ltr;
# 1

# Hebrew:
my $locale = DateTime::Locale::FromCLDR->new( 'he' );
my $bool = $locale->is_ltr;
# 0

Returns true if the locale is written left-to-right, or false otherwise.

is_rtl

my $locale = DateTime::Locale::FromCLDR->new( 'en' );
my $bool = $locale->is_ltr;
# 0

# Hebrew:
my $locale = DateTime::Locale::FromCLDR->new( 'he' );
my $bool = $locale->is_ltr;
# 1

Returns true if the locale is written right-to-left, or false otherwise.

language

my $locale = DateTime::Locale::FromCLDR->new( 'ja' );
my $str = $locale->language;
# Japanese

Returns the name of the locale in English

language_code

my $locale = DateTime::Locale::FromCLDR->new( 'ja-Kana-JP' );
my $str = $locale->language_code;
# ja
my $locale = DateTime::Locale::FromCLDR->new( 'ryu-JP' );
my $str = $locale->language_code;
# ryu

Returns the language ID part of the locale

language_id

This is an alias for language_code

locale

Returns the current Locale::Unicode object used in the current object.

locale_number_system

my $locale = DateTime::Locale::FromCLDR->new( 'en' );
my $array = $locale->locale_number_system;
# ["latn", ["0","1","2","3","4","5","6","7","8","9"]]
my $locale = DateTime::Locale::FromCLDR->new( 'ar' );
my $array = $locale->locale_number_system;
# ["arab", ["٠","١","٢","٣","٤","٥","٦","٧","٨","٩"]]

This returns array reference containing 2 elements for the locale, crawling along the inheritance tree until it finds a proper match:

0. the numbering system

For example: latn

1. an array reference of digits, starting from 0, in the locale's own writing.

For example: ["0","1","2","3","4","5","6","7","8","9"]

metazone_daylight_long

my $locale = DateTime::Locale::FromCLDR->new( 'en' );
my $str = $locale->metazone_daylight_long( metazone => 'Atlantic' );
# Atlantic Daylight Time
# America/Guadeloupe

my $locale = DateTime::Locale::FromCLDR->new( 'fr' );
my $str = $locale->metazone_daylight_long( metazone => 'Atlantic' );
# heure d’été de l’Atlantique

This returns the localised metazone name for the daylight saving time mode and long format for the given metazone ID.

If nothing can be found, an empty string is returned.

If an error occurred, an exception object is set, and undef is returned in scalar context, or an empty list in list context.

metazone_daylight_short

my $locale = DateTime::Locale::FromCLDR->new( 'en' );
my $str = $locale->metazone_daylight_short( metazone => 'Atlantic' );
# ADT

my $locale = DateTime::Locale::FromCLDR->new( 'fr' );
my $str = $locale->metazone_daylight_short( metazone => 'Atlantic' );
# HEA

This returns the localised metazone name for the daylight saving time mode and short format for the given metazone ID.

If nothing can be found, an empty string is returned.

If an error occurred, an exception object is set, and undef is returned in scalar context, or an empty list in list context.

metazone_generic_long

my $locale = DateTime::Locale::FromCLDR->new( 'en' );
my $str = $locale->metazone_generic_long( metazone => 'Atlantic' );
# Atlantic Time

my $locale = DateTime::Locale::FromCLDR->new( 'fr' );
my $str = $locale->metazone_generic_long( metazone => 'Atlantic' );
# heure de l’Atlantique

This returns the localised metazone name for the generic time and long format for the given metazone ID.

If nothing can be found, an empty string is returned.

If an error occurred, an exception object is set, and undef is returned in scalar context, or an empty list in list context.

metazone_generic_short

my $locale = DateTime::Locale::FromCLDR->new( 'en' );
my $str = $locale->metazone_generic_short( metazone => 'Atlantic' );
# AT

my $locale = DateTime::Locale::FromCLDR->new( 'fr' );
my $str = $locale->metazone_generic_short( metazone => 'Atlantic' );
# HA

This returns the localised metazone name for the generic time and short format for the given metazone ID.

If nothing can be found, an empty string is returned.

If an error occurred, an exception object is set, and undef is returned in scalar context, or an empty list in list context.

metazone_standard_long

my $locale = DateTime::Locale::FromCLDR->new( 'en' );
my $str = $locale->metazone_standard_long( metazone => 'Atlantic' );
# Atlantic Standard Time

my $locale = DateTime::Locale::FromCLDR->new( 'fr' );
my $str = $locale->metazone_standard_long( metazone => 'Atlantic' );
# heure normale de l’Atlantique

This returns the localised metazone name for the standard time and long format for the given metazone ID.

If nothing can be found, an empty string is returned.

If an error occurred, an exception object is set, and undef is returned in scalar context, or an empty list in list context.

metazone_standard_short

my $locale = DateTime::Locale::FromCLDR->new( 'en' );
my $str = $locale->metazone_standard_short( metazone => 'Atlantic' );
# AST

my $locale = DateTime::Locale::FromCLDR->new( 'fr' );
my $str = $locale->metazone_standard_short( metazone => 'Atlantic' );
# HNA

This returns the localised metazone name for the standard time and short format for the given metazone ID.

If nothing can be found, an empty string is returned.

If an error occurred, an exception object is set, and undef is returned in scalar context, or an empty list in list context.

month_format_abbreviated

my $locale = DateTime::Locale::FromCLDR->new( 'en' );
my $array = $locale->month_format_abbreviated;
say @$array;
# Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec

Returns an array reference of month names in abbreviated format from January to December.

See also "calendar_term" in Locale::Unicode::Data

month_format_narrow

Same as month_format_abbreviated, but returns the months in narrow format.

my $locale = DateTime::Locale::FromCLDR->new( 'en' );
my $array = $locale->month_format_narrow;
say @$array;
# J, F, M, A, M, J, J, A, S, O, N, D

month_format_wide

Same as month_format_abbreviated, but returns the months in wide format.

my $locale = DateTime::Locale::FromCLDR->new( 'en' );
my $array = $locale->month_format_wide;
say @$array;
# January, February, March, April, May, June, July, August, September, October, November, December

month_stand_alone_abbreviated

my $locale = DateTime::Locale::FromCLDR->new( 'en' );
my $array = $locale->month_stand_alone_abbreviated;
say @$array;
# Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec

Returns an array reference of month names in abbreviated stand-alone format from January to December.

See also "calendar_term" in Locale::Unicode::Data

Note that there is often little difference between the format and stand-alone format types.

See the LDML specifications for more information on the difference between the format and stand-alone types.

month_stand_alone_narrow

Same as month_stand_alone_abbreviated, but returns the months in narrow format.

my $locale = DateTime::Locale::FromCLDR->new( 'en' );
my $array = $locale->month_stand_alone_narrow;
say @$array;
# J, F, M, A, M, J, J, A, S, O, N, D

month_stand_alone_wide

Same as month_format_abbreviated, but returns the months in wide format.

my $locale = DateTime::Locale::FromCLDR->new( 'en' );
my $array = $locale->month_stand_alone_wide;
say @$array;
# January, February, March, April, May, June, July, August, September, October, November, December

name

my $locale = DateTime::Locale::FromCLDR->new( 'fr' );
say $locale->name; # French

my $locale = DateTime::Locale::FromCLDR->new( 'fr-CH' );
say $locale->name; # Swiss French

The locale's name in English.

See also native_name

native_language

my $locale = DateTime::Locale::FromCLDR->new( 'fr-CH' );
say $locale->native_language; # français

Returns the locale's language name as written in the locale own language.

If nothing can be found, it will return an empty string.

native_name

my $locale = DateTime::Locale::FromCLDR->new( 'fr-CH' );
say $locale->native_name; # français suisse

Returns the locale's name as written in the locale own language.

If nothing can be found, it will return an empty string.

native_script

my $locale = DateTime::Locale::FromCLDR->new( 'fr-Latn-CH' );
say $locale->native_script; # latin

my $locale = DateTime::Locale::FromCLDR->new( 'fr' );
say $locale->native_script; # undef

Returns the locale's script name as written in the locale own language.

If there is no script specified in the locale, it will return undef

If there is a script in the locale, but, somehow, it cannot be found in the locale's own language tree, it will return an empty string.

native_territory

my $locale = DateTime::Locale::FromCLDR->new( 'fr-CH' );
say $locale->native_territory; # Suisse

my $locale = DateTime::Locale::FromCLDR->new( 'fr' );
say $locale->native_territory; # undef

my $locale = DateTime::Locale::FromCLDR->new( 'en-Latn-003' );
say $locale->native_territory; # North America

my $locale = DateTime::Locale::FromCLDR->new( 'en-XX' );
say $locale->native_territory; # ''

Returns the locale's territory name as written in the locale own language.

If there is no territory specified in the locale, it will return undef

If there is a territory in the locale, but, somehow, it cannot be found in the locale's own language tree, it will return an empty string.

native_variant

my $locale = DateTime::Locale::FromCLDR->new( 'es-valencia' );
say $locale->native_variant; # Valenciano

my $locale = DateTime::Locale::FromCLDR->new( 'es' );
say $locale->native_variant; # undef

my $locale = DateTime::Locale::FromCLDR->new( 'en-Latn-005' );
say $locale->native_variant; # undef

Returns the locale's variant name as written in the locale own language.

If there is no variant specified in the locale, it will return undef, and if there is more than one variant it will return the value for the first one only. To get the values for all variants, use native_variants

If there is a variant in the locale, but, somehow, it cannot be found in the locale's own language tree, it will return an empty string.

native_variants

my $locale = DateTime::Locale::FromCLDR->new( 'ja-Latn-fonipa-hepburn-heploc' );
say $locale->native_variants;
# ["IPA Phonetics", "Hepburn romanization", ""]

Here, heploc is an empty string in the array, because it is a deprecated variant, and as such there is no localised name value for it in the CLDR data.

my $locale = DateTime::Locale::FromCLDR->new( 'es' );
say $locale->native_variants; # []

Returns an array reference of each of the locale's variant subtag name as written in the locale own language.

If there is no variant specified in the locale, it will return an empty array.

If a variant subtag cannot be found in the locale's own language tree, then an empty string will be set in the array instead.

Either way, the size of the array will always be equal to the number of variants in the locale

number_symbols

my $locale = DateTime::Locale::FromCLDR->new( 'en' );
my $ref = $locale->number_symbols;
my $ref = $locale->number_symbols( 'latn' );
# {
#     approximately => "~",
#     decimal => ".",
#     exponential => "E",
#     group => ",",
#     infinity => "∞",
#     list => ";",
#     minus => "-",
#     nan => "NaN",
#     per_mille => "‰",
#     percent => "%",
#     plus => "+",
#     superscript => "\xD7",
#     time_separator => ":",
# }

Returns an hash reference of a locale's number symbols.

If somehow, none were found, it returns an empty hash reference, so make sure to check for the size of the hash reference returned.

Upon error, it sets an exception object and returns undef in scalar context, and an empty list in list context.

Below are all the possible symbols available:

Quoted sentences are from the Unicode LDML specifications.

  • approximately

    "Symbol used to denote a value that is approximate but not exact."

    For example ~, , ,

  • currency_decimal

    "Used as the decimal separator instead of using the regular decimal separator"

    For example .

  • currency_group

    "Used as the group separator instead of using the regular group separator"

    For example .

  • decimal

    "Separates the integer and fractional part of the number."

    For example ., ٫, ,

  • exponential

    "Symbol separating the mantissa and exponent values."

    For example E, e, ×10^, ·10^

  • group

    "Separates clusters of integer digits to make large numbers more legible"

    For example ,, ٬, ., ،, ,

  • infinity

    "The infinity sign. Corresponds to the IEEE infinity bit pattern."

    For example , INF

  • list

    "Symbol used to separate numbers in a list intended to represent structured data such as an array; must be different from the decimal value."

    For example ;

  • minus

    "Symbol used to denote negative value."

    For example -

    Note that, in the CLDR data, although it is always a visually identical representation, the character itself used varies, depending on the locale used. For example: - (\x{2D}) vs - (\x{D8}\x{9C}\x{2D})

  • nan

    The NaN sign. Corresponds to the IEEE NaN bit pattern.

    For example NaN, не число

  • per_mille

    "Symbol used to indicate a per-mille (1/1000th) amount."

    For example , ؉, 0/00

  • percent

    "Symbol used to indicate a percentage (1/100th) amount."

    For example %, ٪

  • plus

    "Symbol used to denote positive value."

    For example +

  • superscript

    For example ×, (^)

  • time_separator

    This is intended to replace "any use of the timeSeparator pattern character in a date-time format pattern"

    For example :, ٫, .

number_system

my $locale = DateTime::Locale::FromCLDR->new( 'ar-EG' );
say $locale->number_system;
# arab

my $locale = DateTime::Locale::FromCLDR->new( 'ja' );
say $locale->number_system;
# latn

Returns a string representing the number system for the locale

number_systems

my $locale = DateTime::Locale::FromCLDR->new( 'ar-EG' );
my $ref = $locale->number_systems;
# {
#     finance => undef,
#     native => undef,
#     number_system => "arab",
#     traditional => undef,
# }

my $locale = DateTime::Locale::FromCLDR->new( 'ja' );
my $ref = $locale->number_systems;
# {
#     finance => "jpanfin",
#     native => undef,
#     number_system => undef,
#     traditional => "jpan",
# }

my $locale = DateTime::Locale::FromCLDR->new( 'ja' );
my $ref = $locale->number_systems;
# {
#     finance => "hantfin",
#     native => "hanidec",
#     number_system => undef,
#     traditional => "hant",
# }

Returns an hash reference containing the numbering systems for default (number_system), finance, native, and traditional. Note that not all of those properties would have a value, and thus some might be undefined.

number_system_digits

my $locale = DateTime::Locale::FromCLDR->new( 'en' );
my $digits = $locale->number_system_digits( 'latn' );
say $digits; # [0, 1, 2, 3, 4, 5, 6, 7, 8. 9];

# Japanese traditional numbering system
my $digits = $locale->number_system_digits( 'jpan' );
say $digits; # ["〇","一","二","三","四","五","六","七","八","九"];

Provided with a valid number system ID, and this will return an array reference of digits for that number system, from 0 to 9.

It sets an exception object upon error, and returns undef in scalar context, or an empty list in list context.

prefers_24_hour_time

This checks whether the locale prefers the 24H format or the 12H one and returns true (1) if it prefers the 24 hours format or false (0) otherwise.

How it finds out? It pulls the preferred time format from the CLDR data by calling time_format_preferred, and from there returns true (1) if the value is either H or k, or else false (0).

This is as specified by the Unicode LDML, which states: "the locale's actual preference for 12-hour or 24-hour time cycle is determined from the Time Data as described above in timeFormats."

quarter_format_abbreviated

my $locale = DateTime::Locale::FromCLDR->new( 'en' );
my $array = $locale->quarter_format_abbreviated;
say @$array;
# Q1, Q2, Q3, Q4

Returns an array reference of quarter names in abbreviated format.

See also "calendar_term" in Locale::Unicode::Data

quarter_format_narrow

Same as quarter_format_abbreviated, but returns the quarters in narrow format.

my $locale = DateTime::Locale::FromCLDR->new( 'en' );
my $array = $locale->quarter_format_narrow;
say @$array;
# 1, 2, 3, 4

quarter_format_wide

Same as quarter_format_abbreviated, but returns the quarters in wide format.

my $locale = DateTime::Locale::FromCLDR->new( 'en' );
my $array = $locale->quarter_format_wide;
say @$array;
# 1st quarter, 2nd quarter, 3rd quarter, 4th quarter

quarter_stand_alone_abbreviated

my $locale = DateTime::Locale::FromCLDR->new( 'en' );
my $array = $locale->quarter_stand_alone_abbreviated;
say @$array;
# Q1, Q2, Q3, Q4

Returns an array reference of quarter names in abbreviated format.

See also "calendar_term" in Locale::Unicode::Data

Note that there is often little difference between the format and stand-alone format types.

See the LDML specifications for more information on the difference between the format and stand-alone types.

quarter_stand_alone_narrow

Same as quarter_stand_alone_abbreviated, but returns the quarters in narrow format.

my $locale = DateTime::Locale::FromCLDR->new( 'en' );
my $array = $locale->quarter_stand_alone_narrow;
say @$array;
# 1, 2, 3, 4

quarter_stand_alone_wide

Same as quarter_stand_alone_abbreviated, but returns the quarters in wide format.

my $locale = DateTime::Locale::FromCLDR->new( 'en' );
my $array = $locale->quarter_stand_alone_wide;
say @$array;
# 1st quarter, 2nd quarter, 3rd quarter, 4th quarter

script

my $locale = DateTime::Locale::FromCLDR->new( 'ja-Kana-JP' );
my $str = $locale->script;
# Katakana

Returns the name of the locale's script in English.

If there is no script specified in the locale, it will return undef

If there is a script in the locale, but, somehow, it cannot be found in the en locale's language tree, it will return an empty string.

script_code

my $locale = DateTime::Locale::FromCLDR->new( 'ja-Kana-JP' );
my $script = $locale->script_code;
# Kana

my $locale = DateTime::Locale::FromCLDR->new( 'ja-JP' );
my $script = $locale->script_code;
# undef

Returns the locale's script ID, or undef if there is none.

script_id

This is an alias for script_code

split_interval

my $locale = DateTime::Locale::FromCLDR->new( 'en' );
my $ref = $locale->split_interval(
    pattern => $string,
    greatest_diff => 'd',
) || die( $locale->error );

This method actually calls "split_interval" in Locale::Unicode::Data and passes it all the arguments it received, so please check its documentation.

It returns the array reference it received from "split_interval" in Locale::Unicode::Data, or upon error, its sets an exception object, and returns undef in scalar context or an empty list in list context.

territory

my $locale = DateTime::Locale::FromCLDR->new( 'ja-JP' );
my $script = $locale->territory;
# Japan

my $locale = DateTime::Locale::FromCLDR->new( 'zh-034' );
my $script = $locale->territory;
# Southern Asia

my $locale = DateTime::Locale::FromCLDR->new( 'en' );
my $script = $locale->territory;
# undef

my $locale = DateTime::Locale::FromCLDR->new( 'en-XX' );
my $script = $locale->territory;
# ''

Returns the name of the locale's territory in English.

If there is no territory specified in the locale, it will return undef

If there is a territory in the locale, but, somehow, it cannot be found in the en locale's language tree, it will return an empty string.

territory_code

my $locale = DateTime::Locale::FromCLDR->new( 'ja-JP' );
my $script = $locale->territory_code;
# JP

my $locale = DateTime::Locale::FromCLDR->new( 'ja-Kana' );
my $script = $locale->territory_code;
# undef

Returns the locale's territory ID, or undef if there is none.

territory_id

This is an alias for territory_code

territory_info

my $locale = DateTime::Locale::FromCLDR->new( 'en' );
my $ref = $locale->territory_info;

which would yield:

{
    calendars => undef,
    contains => undef,
    currency => "USD",
    first_day => 7,
    gdp => 19490000000000,
    languages => [qw(
        en es zh-Hant fr de fil it vi ko ru nv yi pdc hnj haw
        frc chr esu dak cho lkt ik mus io cic cad jbo osa zh
    )],
    literacy_percent => 99,
    min_days => 1,
    parent => "021",
    population => 332639000,
    status => "regular",
    territory => "US",
    territory_id => 297,
    weekend => undef,
}

my $locale = DateTime::Locale::FromCLDR->new( 'en-GB' );
my $ref = $locale->territory_info;

which would yield:

{
    calendars => undef,
    contains => undef,
    currency => "GBP",
    first_day => 1,
    gdp => 2925000000000,
    languages => [qw(
        en fr de es pl pa ur ta gu sco cy bn ar zh-Hant it lt pt
        so tr ga gd kw en-Shaw
    )],
    literacy_percent => 99,
    min_days => 4,
    parent => 154,
    population => 65761100,
    status => "regular",
    territory => "GB",
    territory_id => 121,
    weekend => undef,
}

Returns an hash reference of information related to the ISO3166 country code associated with the locale. If the locale has no country code associated, it will expand it using the Unicode LDML rule with "likely_subtag" in Locale::Unicode::Data

Keep in mind that the default or fallback data are stored in the special territory code 001 (World). Thus, for example, if the calendars field is empty, the default value would be in 001, and would be ["gregorian"]

time_format_allowed

my $locale = DateTime::Locale::FromCLDR->new( 'en' );
my $array = $locale->time_format_allowed;

Returns an array reference of allowed time patterns for the locale's associated territory. If the locale has no territory associated with, it will check the likely subtag to derive the territory for that locale

time_format_default

This is an alias for time_format_medium

time_format_full

my $locale = DateTime::Locale::FromCLDR->new( 'en' );
say $locale->time_format_full;
# h:mm:ss a zzzz
# 10:44:07 PM UTC

Returns the full date pattern

See also "calendar_format_l10n" in Locale::Unicode::Data

time_format_long

Same as time_format_full, but returns the long format pattern.

my $locale = DateTime::Locale::FromCLDR->new( 'en' );
say $locale->time_format_long;
# h:mm:ss a z
# 10:44:07 PM UTC

time_format_medium

Same as time_format_full, but returns the medium format pattern.

my $locale = DateTime::Locale::FromCLDR->new( 'en' );
say $locale->time_format_medium;
# h:mm:ss a
# 10:44:07 PM

time_format_preferred

my $locale = DateTime::Locale::FromCLDR->new( 'en' );
my $str = $locale->time_format_preferred;

Returns a string representing the time preferred pattern for the locale's associated territory. If the locale has no territory associated with, it will check the likely subtag to derive the territory for that locale

time_format_short

Same as time_format_full, but returns the short format pattern.

my $locale = DateTime::Locale::FromCLDR->new( 'en' );
say $locale->time_format_short;
# h:mm a
# 10:44 PM

time_formats

my $now = DateTime->now( locale => 'en' );
my $ref = $locale->time_formats;
foreach my $type ( sort( keys( %$ref ) ) )
{
    say $type, ":";
    say $ref->{ $type };
    say $now->format_cldr( $ref->{ $type } ), "\n";
}

Would produce:

full:
h:mm:ss a zzzz
10:44:07 PM UTC

long:
h:mm:ss a z
10:44:07 PM UTC

medium:
h:mm:ss a
10:44:07 PM

short:
h:mm a
10:44 PM

Returns an hash reference with the keys being: full, long, medium, short and their value the result of their associated time format methods.

timezone_canonical

my $locale = DateTime::Locale::FromCLDR->new( 'en' );
my $str = $locale->timezone_canonical( timezone => 'America/Atka' );
# America/Adak

Returns the canonical version of the given timezone.

The CLDR keeps all timezones, even outdated ones for reliability and consistency, so this method helps switch a given timezone for its canonical counterpart.

If the given timezone is already the canonical one, then it is simply returned.

If none could be found somehow, an empty string would be returned.

timezone_city

my $locale = DateTime::Locale::FromCLDR->new( 'en' );
my $str = $locale->timezone_city( timezone => 'America/St_Barthelemy' );
# St. Barthélemy

my $locale = DateTime::Locale::FromCLDR->new( 'fr' );
my $str = $locale->timezone_city( timezone => 'America/St_Barthelemy' );
# Saint-Barthélemy

my $locale = DateTime::Locale::FromCLDR->new( 'ja' );
my $str = $locale->timezone_city( timezone => 'America/St_Barthelemy' );
# サン・バルテルミー

Returns a string representing the localised version of the exemplar city for a given timezone

If nothing can be found, an empty string is returned.

If an error occurred, an exception object is set, and undef is returned in scalar context, or an empty list in list context.

timezone_format_fallback

my $locale = DateTime::Locale::FromCLDR->new( 'en' );
my $str = $locale->timezone_format_fallback;
# {1} ({0})

my $locale = DateTime::Locale::FromCLDR->new( 'ja' );
my $str = $locale->timezone_format_fallback;
# {1}({0})

Returns the fallback timezone localised format "where {1} is the metazone, and {0} is the country or city." (quoting from the LDML specifications)

Do not assume you can simply use parenthesis to format it yourself, since the format would change depending on the locale used, and even the parenthesis itself varies as shown in the example above with the Japanese language (here a double byte parenthesis).

If nothing can be found, an empty string is returned.

If an error occurred, an exception object is set, and undef is returned in scalar context, or an empty list in list context.

See the LDML specifications for more information.

timezone_format_gmt

my $locale = DateTime::Locale::FromCLDR->new( 'en' );
my $str = $locale->timezone_format_gmt;
# GMT{0}

my $locale = DateTime::Locale::FromCLDR->new( 'fr' );
my $str = $locale->timezone_format_gmt;
# UTC{0}

Returns the GMT localised format.

This needs to be used in conjonction with the timezone_format_hour to form a complete localised GMt formatted timezone.

For example:

  • GMT+03:30

    Long

  • GMT+3:30

    Short

  • UTC-03.00

    Long

  • UTC-3

    Short

  • Гринуич+03:30

    Long

If nothing can be found, an empty string is returned.

If an error occurred, an exception object is set, and undef is returned in scalar context, or an empty list in list context.

See the LDML specifications for more information.

timezone_format_gmt_zero

my $locale = DateTime::Locale::FromCLDR->new( 'en' );
my $str = $locale->timezone_format_gmt_zero;
# GMT

my $locale = DateTime::Locale::FromCLDR->new( 'fr' );
my $str = $locale->timezone_format_gmt_zero;
# UTC

Returns the GMT localised format for when the offset is 0, i.e. when this is a GMT time.

For example:

  • GMT

  • UTC

  • Гринуич

If nothing can be found, an empty string is returned.

If an error occurred, an exception object is set, and undef is returned in scalar context, or an empty list in list context.

See the LDML specifications for more information.

timezone_format_hour

my $locale = DateTime::Locale::FromCLDR->new( 'en' );
my $str = $locale->timezone_format_hour;
# ["+HH:mm", "-HH:mm"]

Returns the GMT format for hour, minute and possibly seconds, as an array reference containing 2 elements:

0. format for positive offset; and
1. format for negative offset.

If nothing can be found, an empty array reference is returned.

If an error occurred, an exception object is set, and undef is returned in scalar context, or an empty list in list context.

See the LDML specifications for more information.

timezone_format_region

my $locale = DateTime::Locale::FromCLDR->new( 'en' );
my $str = $locale->timezone_format_region;
# {0} Time

my $locale = DateTime::Locale::FromCLDR->new( 'ja' );
my $str = $locale->timezone_format_region;
# {0}時間

my $locale = DateTime::Locale::FromCLDR->new( 'es' );
my $str = $locale->timezone_format_region;
# hora de {0}

Returns a string representing the timezone localised regional format, "where {0} is the country or city." (quoting from the LDML specifications)

For example, once formatted, this would yield:

  • Japan Time

  • 日本時間

  • Hora de Japón

If nothing can be found, an empty string is returned.

If an error occurred, an exception object is set, and undef is returned in scalar context, or an empty list in list context.

timezone_format_region_daylight

my $locale = DateTime::Locale::FromCLDR->new( 'en' );
my $str = $locale->timezone_format_region_daylight;
# {0} Daylight Time

my $locale = DateTime::Locale::FromCLDR->new( 'ja' );
my $str = $locale->timezone_format_region_daylight;
# {0}夏時間

Same as timezone_format_region, but uses the daylight saving time format.

timezone_format_region_standard

my $locale = DateTime::Locale::FromCLDR->new( 'en' );
my $str = $locale->timezone_format_region_standard;
# {0} Standard Time

my $locale = DateTime::Locale::FromCLDR->new( 'ja' );
my $str = $locale->timezone_format_region_standard;
# {0}標準時

Same as timezone_format_region, but uses the daylight saving time format.

timezone_daylight_long

my $locale = DateTime::Locale::FromCLDR->new( 'en' );
my $str = $locale->timezone_daylight_long( timezone => 'Europe/London' );
# British Summer Time

Returns a string of a localised representation of a given timezone, for the daylight saving time in long format.

If none exists for the given timezone, which may often be the case, you need to use the timezone format methods instead (timezone_format_fallback, timezone_format_gmt, timezone_format_gmt_zero, timezone_format_hour, timezone_format_hour, timezone_format_region, timezone_format_region_daylight, and timezone_format_region_standard)

If nothing can be found, an empty string is returned.

If an error occurred, an exception object is set, and undef is returned in scalar context, or an empty list in list context.

See the LDML specifications for more information.

timezone_daylight_short

my $locale = DateTime::Locale::FromCLDR->new( 'en' );
my $str = $locale->timezone_daylight_short( timezone => 'Europe/London' );
# ""

my $locale = DateTime::Locale::FromCLDR->new( 'en' );
my $str = $locale->timezone_daylight_short( timezone => 'Pacific/Honolulu' );
# HDT

Same as timezone_daylight_long, but for the daylight saving time short format.

timezone_generic_long

my $locale = DateTime::Locale::FromCLDR->new( 'en' );
my $str = $locale->timezone_generic_long( timezone => 'Europe/London' );
# ""

Same as timezone_daylight_long, but for the generic long format.

timezone_generic_short

my $locale = DateTime::Locale::FromCLDR->new( 'en' );
my $str = $locale->timezone_generic_short( timezone => 'Europe/London' );
# ""

my $locale = DateTime::Locale::FromCLDR->new( 'en' );
my $str = $locale->timezone_generic_short( timezone => 'Pacific/Honolulu' );
# HST

Same as timezone_daylight_long, but for the generic short format.

timezone_id

my $locale = DateTime::Locale::FromCLDR->new( 'en' );
my $bcp47_id = $locale->timezone_id( timezone => 'America/Los_Angeles' );
# uslax

Provided with a timezone, and this returns its BCP47 time zone ID equivalent.

timezone_standard_long

my $locale = DateTime::Locale::FromCLDR->new( 'en' );
my $str = $locale->timezone_standard_long( timezone => 'Europe/London' );
# ""

Same as timezone_daylight_long, but for the standard long format.

timezone_standard_short

my $locale = DateTime::Locale::FromCLDR->new( 'en' );
my $str = $locale->timezone_standard_short( timezone => 'Europe/London' );
# ""

my $locale = DateTime::Locale::FromCLDR->new( 'en' );
my $str = $locale->timezone_standard_short( timezone => 'Pacific/Honolulu' );
# HST

Same as timezone_daylight_long, but for the standard short format.

variant

my $locale = DateTime::Locale::FromCLDR->new( 'es-valencia' );
my $script = $locale->variant;
# Valencian

my $locale = DateTime::Locale::FromCLDR->new( 'es' );
my $script = $locale->variant;
# undef

# No such thing as variant 'klingon'. Language 'tlh' exists though :)
my $locale = DateTime::Locale::FromCLDR->new( 'en-klingon' );
my $script = $locale->variant;
# ''

Returns the name of the locale's variant in English.

If there is no variant specified in the locale, it will return undef

If there is a variant in the locale, but, somehow, it cannot be found in the en locale's language tree, it will return an empty string.

variant_code

my $locale = DateTime::Locale::FromCLDR->new( 'es-valencia' );
my $script = $locale->variant_code;
# valencia

my $locale = DateTime::Locale::FromCLDR->new( 'es-ES' );
my $script = $locale->variant_code;
# undef

Returns the locale's variant ID, or undef if there is none.

variant_id

This is an alias for variant_code

variants

my $locale = DateTime::Locale::FromCLDR->new( 'es-valencia' );
my $array = $locale->variants;
# ["valencia"]

my $locale = DateTime::Locale::FromCLDR->new( 'ja-Latn-fonipa-hepburn-heploc' );
my $array = $locale->variants;
# ["fonipa", "hepburn", "heploc"]

my $locale = DateTime::Locale::FromCLDR->new( 'en' );
my $array = $locale->variants;
# []

This returns an array reference of variant subtags for this locale, even if there is no variant.

version

my $locale = DateTime::Locale::FromCLDR->new( 'en' );
say $locale->version; # 45.0

Returns the Unicode CLDR data version number.

SERIALISATION

Locale::Unicode supports Storable::Improved, Storable, Sereal and CBOR serialisation, by implementing the methods FREEZE, THAW, STORABLE_freeze, STORABLE_thaw

For serialisation with Sereal, make sure to instantiate the Sereal encoder with the freeze_callbacks option set to true, otherwise, Sereal will not use the FREEZE and THAW methods.

See "FREEZE/THAW CALLBACK MECHANISM" in Sereal::Encoder for more information.

For CBOR, it is recommended to use the option allow_sharing to enable the reuse of references, such as:

my $cbor = CBOR::XS->new->allow_sharing;

Also, if you use the option allow_tags with JSON, then all of those modules will work too, since this option enables support for the FREEZE and THAW methods.

AUTHOR

Jacques Deguest <jack@deguest.jp>

SEE ALSO

Locale::Unicode, Locale::Unicode::Data, DateTime::Format::Unicode

DateTime::Locale

COPYRIGHT & LICENSE

Copyright(c) 2024 DEGUEST Pte. Ltd.

All rights reserved.

This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.