使用Unicode的CLDR本地化应用程序

v5.0.0 2023-10-03 10:00 UTC

README

Packagist Downloads Code Quality

CLDR 包通过利用Unicode通用区域数据仓库(CLDR)建立的数据和约定,促进了您应用程序的国际化。它提供了诸如领土、语言、天……的名称等宝贵的区域信息,以及数字、货币、日期和时间、单位、序列和列表的格式化器。

注意

该包针对 CLDR版本45修订72

示例用法

<?php

use ICanBoogie\CLDR\Numbers\Currency;

/* @var ICanBoogie\CLDR\Repository $repository */

# You get a locale from the repository, here the locale for French.
$fr = $repository->locale_for('fr');

# You can use a locale instance as an array
echo $fr['characters']['auxiliary'];                // [á å ä ã ā ē í ì ī ñ ó ò ö ø ú ǔ]
echo $fr['delimiters']['quotationStart'];           // «
echo $fr['territories']['TF'];                      // Terres australes françaises

# You can localize it and get its local name
echo $fr->localized($fr)->name;                      // Français

# You can use it to format numbers, percents, currencies, lists…
echo $fr->format_number(12345.67);                  // 12 345,67
echo $fr->format_percent(.1234567);                 // 12 %
echo $fr->format_currency(12345.67, 'EUR');         // 12 345,67 €
echo $fr->format_list([ "Un", "deux", "trois" ]);   // Un, deux et trois

# You can get the default calendar for a locale and access its data
$calendar = $fr->calendar;
echo $calendar['days']['format']['wide']['sun'];    // dimanche
echo $calendar->wide_days['sun'];                   // dimanche

# You can use the calendar to format dates, times, or both
$datetime = '2018-11-24 20:12:22 UTC';
echo $calendar->format_date($datetime, 'long');     // 24 novembre 2018
echo $calendar->format_time($datetime, 'long');     // 20:12:22 UTC
echo $calendar->format_datetime($datetime, 'full'); // samedi 24 novembre 2018 à 20:12:22 UTC

# Alternatively, you can localize a DateTimeInterface and get formatted dates of various lengths
$datetime = new \DateTime('2013-11-04 20:21:22 UTC');
$fr_datetime = new \ICanBoogie\CLDR\Dates\LocalizedDateTime($datetime, $fr);
echo $fr_datetime->as_full;                         // lundi 4 novembre 2013 à 20:21:22 UTC
echo $fr_datetime->as_long;                         // 4 novembre 2013 à 20:21:22 UTC
echo $fr_datetime->as_medium;                       // 4 nov. 2013 20:21:22
echo $fr_datetime->as_short;                        // 04/11/2013 20:21

# You can format units
$units = $repository->locale_for('en')->units;
echo $units->duration_hour->name;                   // hours
echo $units->duration_hour->short_name;             // h
echo $units->duration_hour(1);                      // 1 hour
echo $units->duration_hour(23);                     // 23 hours
echo $units->duration_hour(23)->as_short;           // 23 hr
echo $units->duration_hour(23)->as_narrow;          // 23h

# You can format a unit per another unit
echo $units->volume_liter(12.345)->per($units->duration_hour);
// 12.345 liters per hour
echo $units->volume_liter(12.345)->per($units->duration_hour)->as_short;
// 12.345 L/h
echo $units->volume_liter(12.345)->per($units->duration_hour)->as_narrow;
// 12.345L/h

# You can format sequences of units
$units->sequence->angle_degree(5)->duration_minute(30)->as_narrow;
// 5° 30m
$units->sequence->length_foot(3)->length_inch(2)->as_short;
// 3 ft, 2 in

# You can access plural rules
$repository->plurals->rule_for(1.5, 'fr'); // one
$repository->plurals->rule_for(2, 'fr');   // other
$repository->plurals->rule_for(2, 'ar');   // two

# You can access currencies and their localized data
$euro = Currency::of('EUR');
$fr_euro = $euro->localized($fr);
echo $fr_euro->name;
echo $fr_euro->name_for(1);      // euro
echo $fr_euro->name_for(10);     // euros
echo $fr_euro->format(12345.67); // 12 345,67 €

# You can access territories and their localized data
$territory = $repository->territory_for('FR');
echo $territory;                                       // FR
echo $territory->currency;                             // EUR
echo $territory->currency_at('1977-06-06');            // FRF
echo $territory->currency_at('now');                   // EUR
echo $territory->name_as('fr');        // France
echo $territory->name_as('it');        // Francia
echo $territory->name_as('ja');        // フランス
echo $repository->territory_for('FR')->first_day;        // mon
echo $repository->territory_for('EG')->first_day;        // sat
echo $repository->territory_for('BS')->first_day;        // sun
echo $repository->territory_for('AE')->weekend_start;    // fri
echo $repository->territory_for('AE')->weekend_end;      // sat
echo $territory->localized('fr')->name; // France
echo $territory->localized('it')->name; // Francia
echo $territory->localized('ja')->name; // フランス

安装

composer require icanboogie/cldr

文档

该文档分为以下部分,模仿 Unicode的文档

  • 第1部分: 核心(语言、区域、基本结构)
  • 第2部分: 通用(显示名称 & 转换等)
  • 第3部分: 数字(数字 & 货币格式化)
  • 第4部分: 日期(日期、时间、时区格式化)
  • 第5部分:比较(排序、搜索、分组)
  • 第6部分: 补充(补充数据)

入门指南

CLDR通过一个 Repository 实例表示,该实例通过一个 Provider 实例访问数据。该包提供了几个缓存机制。选择正确的提供者取决于您的需求:您可能在开发期间优先考虑灵活性或在生产中优先考虑可预测性。

优先考虑灵活性

WebProvider 通过从GitHub上托管的JSON分布 按需检索数据,提供了最大的灵活性。为了最小化Web请求,建议使用具有各自策略的缓存集合。例如,FileCache 将检索到的数据存储为PHP文件,使其能够受益于opcache。

以下示例演示了如何实例化存储库

<?php

use ICanBoogie\CLDR\Cache\CacheCollection;
use ICanBoogie\CLDR\Cache\FileCache;
use ICanBoogie\CLDR\Cache\RedisCache;
use ICanBoogie\CLDR\Cache\RuntimeCache;
use ICanBoogie\CLDR\Provider\CachedProvider;
use ICanBoogie\CLDR\Provider\WebProvider;
use ICanBoogie\CLDR\Repository;

/* @var \Redis $redis_client */

$provider = new CachedProvider(
    new WebProvider,
    new CacheCollection([
        new RunTimeCache,
        // You don't have to use Redis, this is only an example
        new RedisCache($redis_client),
        new FileCache(FileCache::RECOMMENDED_DIR)
    ])
);

$cldr = new Repository($provider);

优先考虑可预测性

为了提高可预测性,请考虑将存储库的使用限制为几个特定的区域,并将它们作为您应用程序的一部分进行分发。您可以在开发期间预先填充CLDR缓存并将其提交,或者将此步骤纳入CI/CD管道构建过程。

使用 cldr命令 加热CLDR缓存

./vendor/bin/cldr warm-up de en fr

以下示例说明了限制对缓存的数据访问的设置。当尝试检索缓存中不可用的数据时,RestrictedProvider 会抛出异常。

<?php

use ICanBoogie\CLDR\Cache\FileCache;
use ICanBoogie\CLDR\Provider\CachedProvider;
use ICanBoogie\CLDR\Provider\RestrictedProvider;
use ICanBoogie\CLDR\Repository;

$provider = new CachedProvider(
    new RestrictedProvider(),
    new FileCache(FileCache::RECOMMENDED_DIR),
);

$cldr = new Repository($provider);

持续集成

项目由 GitHub actions 进行持续测试。

Tests Code Coverage Static Analysis Code Style

行为准则

本项目遵循贡献者行为准则。参与本项目及其社区,你应遵守此准则。

贡献

有关详细信息,请参阅 CONTRIBUTING

许可证

icanboogie/cldr 依据MIT 许可证发布。