Skip to content

Instantly share code, notes, and snippets.

@derickr
Created April 26, 2022 12:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save derickr/f2db5932f8fc5b89531b195db867258b to your computer and use it in GitHub Desktop.
Save derickr/f2db5932f8fc5b89531b195db867258b to your computer and use it in GitHub Desktop.
Example on how to format date/time's correctly with locales using CLDR

Require the ICanBoogie/CLDR package:

composer require ICanBoogie/CLDR

Run on the command line, with:

php format.php [tzid] [locale]

Such as in:

  • php format.php Europe/Oslo nl
  • php format.php Asia/Shanghai en
<?php
require 'vendor/autoload.php';
use ICanBoogie\CLDR\Repository;
use ICanBoogie\CLDR\Cache\CacheCollection;
use ICanBoogie\CLDR\Cache\RuntimeCache;
use ICanBoogie\CLDR\Cache\FileCache;
use ICanBoogie\CLDR\Provider\CachedProvider;
use ICanBoogie\CLDR\Provider\WebProvider;
/* Input */
date_default_timezone_set($argv[1]);
$locale = $argv[2];
$datetime = new \DateTime;
/* Set up repo */
@mkdir('/tmp/cldr-cache');
$provider = new CachedProvider(
new WebProvider,
new CacheCollection([
new RunTimeCache,
new FileCache("/tmp/cldr-cache"),
])
);
$repository = new Repository($provider);
$suppData = $repository->supplemental;
/* Get locale */
$locale = $repository->locales[$locale];
/* Extract TimeZone from object */
$tz = $datetime->getTimeZone()->getName();
$tzParts = explode('/', $tz);
/* Find MetaZone */
$metaZone = $suppData['metaZones']['metazoneInfo']['timezone'];
foreach ($tzParts as $tzPart) {
$metaZone = $metaZone[$tzPart];
}
/* Pick the last one (not 100% correct, but will do) */
$standard = $daylight = '?';
$metaZone = $metaZone[count($metaZone)-1]['usesMetazone']['_mzone'];
$localeZone = $locale['timeZoneNames']['metazone'][$metaZone]['long'];
if (array_key_exists('standard', $localeZone)) {
$standard = $localeZone['standard'];
}
if (array_key_exists('daylight', $localeZone)) {
$daylight = $localeZone['daylight'];
}
/* Use locale to find override info */
$zone = $locale['timeZoneNames']['zone'];
foreach ($tzParts as $tzPart) {
$zone = $zone[$tzPart];
}
if (array_key_exists('long', $zone) ) {
foreach ($zone['long'] as $key => $value)
{
if ($key == 'standard') {
$standard = $value;
} else if ($key == 'daylight') {
$daylight = $value;
}
}
}
/* Pick right value */
$tzDescription = $datetime->format('I') == 1 ? $daylight : $standard;
/* Format date */
$calendar = $locale->calendar;
$textDate = $datetime->format('Y-m-d H:i:s');
echo $calendar->format_date($textDate, 'long'), ' ', $calendar->format_time($textDate, 'medium'), ' ', $tzDescription, "\n";
?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment