Kapitel 18. Zend_Locale

Inhaltsverzeichnis

18.1. Einführung
18.1.1. Was ist die Lokalisierung?
18.1.2. Was ist eine Locale?
18.1.3. Wie werden Locales dargestellt?
18.1.4. Die richtige Locale auswählen
18.1.5. ZF Locale-Aware Klassen
18.1.6. Zend_Locale_Format::setOptions(array $options)
18.2. Using Zend_Locale
18.2.1. Copying, Cloning, and Serializing Locale Objects
18.2.2. isEqual() - Equality
18.2.3. Default locales
18.2.4. Set a new locale
18.2.5. Getting the language and region
18.2.6. Obtaining localized strings
18.2.7. Obtaining translations for "yes" and "no"
18.3. Normalization and Localization
18.3.1. Number normalization: getNumber($input, Array $options)
18.3.2. Number localization
18.3.3. Number testing
18.3.4. Float value normalization
18.3.5. Floating point value localization
18.3.6. Floating point value testing
18.3.7. Integer value normalization
18.3.8. Integer point value localization
18.3.9. Integer value testing
18.3.10. Numeral System Conversion
18.4. Working with Dates and Times
18.4.1. Normalizing Dates and Times
18.4.2. Testing Dates
18.4.3. Normalizing a Time
18.4.4. Testing Times
18.5. Supported Languages for Locales
18.6. Supported Regions for Locales

18.1. Einführung

Zend_Locale ist die Antwort des Zend Frameworks auf die Frage: "Wie kann man eine Anwendung für die ganze Welt nutzbar machen?". Die meisten würden sagen, "Das ist einfach, lass uns einfach alle Ausgaben in mehrere Sprachen übersetzen!". Jedoch reichen einfache Übersetzungstabellen, die Phrasen einer Sprache, einer anderen Sprache zuordnen, nicht aus. Unterschiedliche Länder haben unterschiedliche Normen bezüglich Vor- und Nachnamen, Anreden, Zahlenformaten, Zeit- und Datumsformaten, Währungen und so weiter.

Wir brauchen Lokalisierung (Localization) und entsprechend Internationalisierung (Internationalization). Beide Begriffe werden oft mit L10N und I18N abgekürzt. Dabei steht die Internationalisierung für das Vorbereiten der gesamten Anwendung für die länderunabhängige Nutzung und die Lokalisierung für die länderspezifischen Konfigurationen, wie z.B. Zeitangaben, Währungen und Zahlenformate, sowie die Übersetzung der benutzten Phrasen in die spezifische Sprache. Somit stellt die Internationalisierung das Gerüst dar und die Lokalisierung die länderspezifischen Angaben und Übersetzungen. Das Zend Framework bietet zur Unterstützung der Internationalisierung folgende Komponenten, die miteinander kombiniert werden können: Zend_Locale, Zend_Date, Zend_Measure, Zend_Translate, Zend_Currency, und Zend_TimeSync.

18.1.1. Was ist die Lokalisierung?

Lokalisierung bedeutet, dass eine Anwendung (oder Website) von verschiedenen Benutzern benutzt werden kann, die verschiedene Sprachen sprechen. Aber wie angedeutet bedeutet die Lokalisierung mehr als nur das Übersetzen der einzelnen Strings. Es beinhaltet

  • Zend_Locale - Die Verwaltung von Locales . Dient auch als Basis für andere ZF Komponenten.

  • Zend_Translate - Übersetzung von Strings.

  • Zend_Date - Lokalisierung von Zeit- und Datumsangaben.

  • Zend_Calendar - Kalenderlokalisierung (Unterstützung von nicht-Gregorianischen Kalendersystemen).

  • Zend_Currency - Lokalisierung von Währungen

  • Zend_Locale_Format - Lokalisierung von Zahlen(-formaten).

  • Zend_Locale_Data - Beziehen von lokalisierten Standard-Strings, wie Ländernamen, Sprachennamen und weiteren Daten vom CLDR .

  • TODO - Localization of collations

Jeder Benutzer nutzt Locales, auch wenn er es selber nicht weiss. Anwendungen die nicht explizit von der Lokalisierung gebrauch machen, nutzen dennoch eine Lokale, und zwar die des Autors. Wenn eine Klasse oder Funktion von der Lokalisierung gebrauch macht, dann sagen wir, sie ist locale-aware (Locale-bewusst). Aber wie kann man dem Code mitteilen, welche Lokalisierung er benutzen soll?

Ein Locale-String ermöglicht über Zend_Locale und dessen Unterklassen den Zugriff auf Informationen über die Sprache und die Region des Benutzers. Entsprechende Formate, Normen und Umwandlungsschemata können aus diesen Informationen abgeleitet werden.

18.1.3. Wie werden Locales dargestellt?

Locale-Strings bestehen aus zwei Teilen: Aus der Sprache des Benutzers und dessen Landes oder Region (z.B. Deutsch wird auch in Österreich gesprochen). Die vom Zend Framework benutzten Locale-Strings sind international standardisierte Abkürzungen der Sprache und der Region, die in der Form sprache_REGION notiert werden. Beide Teile, die Sprache und die Region, werden jeweils mit zwei Buchstaben (ASCII-Zeichen) abgekürzt.

Ein Benutzer aus Deutschland würde die Sprache Deutsch und die Region Deutschland erwarten, was durch den Locale-String "de_DE" repräsentiert werden kann. Ein Benutzer aus den USA würde die Sprache Englisch mit der Region USA bevorzugen, was dem Locale-String "en_US" enspricht. Die Locales, die im Zend Framework verwenden werden können, sind unter anderem aus der Liste der vordefinierten Sparach- und Regionskombinationen zu entnehmen.

Beispiel 18.1. Bestimmte Locale festlegen

<?php
require_once 'Zend_Locale');
$locale = new Zend_Locale('de_DE'); // Deutsche Sprache _ Deutschland
?>

Ein Deutscher Benutzer in Amerika könnte die Sprache Deutsch und die Region USA erwarten. Solche nicht standardisierten Kombinationen werden nicht direkt unterstützt. Stattdessen wird bei einer ungültigen Zusammensetzung der Regions-Teil abgeschnitten und nur noch mit dem Sprach-Teil weitergearbeitet. So wird zum Beispiel aus "de_IS" nur noch "de" und aus "xh_RU" nur noch "xh". Die Gültigkeit von diesen Kombinationen ist zusätzlich davon abhängig, welche Daten verarbeitet werden. So kann es sein, dass eine Kombination für die Verarbeitung von Zeitangaben gültig ist, für die Verarbeitung von Währungsangaben aber beschnitten wird. Sollte der Sprach-Teil eine ungültige Bezeichnung haben (z.B. "zz_DE"), wird eine Standard-"root"-Locale verwendet. Die "root" Locale enthält international bekannte Standardformate für Uhrzeiten, Daten, Zahlen, Währungen usw.

Zu beachten ist, dass sich im Laufe der Zeit Änderungen in einzelnen Zeitzonen ergeben haben, die vom Zend Framework nicht beachtet werden können. Eine historische Auflistung zeigt z.B., dass in den USA Änderungen an der Sommerzeit vorgenommen wurden und sogar Regionen in andere Zeitzonen versetzt worden sind. Da nicht alle historischen Änderungen aller Länder der Welt beachtet werden können, werden mathemathische Datums- und Zeitoperationen vom Zend Framework immer korrekt nach den aktuellen Sommerzeit- und Zeitzonenzuordnungen berechnet.

18.1.4. Die richtige Locale auswählen

In den meisten Situationen wird mit new Zend_Locale() automatisch die korrekte Locale gewählt, die im Browser des Benutzers als bevorzugt eingestellt ist. Es ist aber auch möglich die bevorzugte Locale des Servers zu ermitteln, indem man die Instanz mit new Zend_Locale(Zend_Locale::ENVIRONMENT) bezieht.

Beispiel 18.2. Automatische Bestimmung der Locale

<?php
require_once 'Zend/Locale.php';
$locale  = new Zend_Locale();
$locale1 = new Zend_Locale(Zend_Locale::BROWSER);     // Standardverhalten, entspicht der vorherigen Zeile
$locale2 = new Zend_Locale(Zend_Locale::ENVIRONMENT); // Bevorzuge die Servereinstellung
$locale3 = new Zend_Locale(Zend_Locale::FRAMEWORK);   // Bevorzuge die Einstellung der Framework-Anwendung
?>

Der Suchalgorithmus zur automatischen Bestimmung der Locale von Zend_Locale benutzt drei Quellen:

  1. const Zend_Locale::BROWSER - Der Webbrowser des Benutzers liefert bei jeder Anfrage Informationen über bevorzugte Locales des Benutzers, die von PHP in der globalen Variable HTTP_ACCEPT_LANGUAGE zur Verfügung gestellt werden. Wird keine akzeptable Locale gefunden, so wird versucht über die ENVIRONMENT und letztlich über die FRAMEWORK Einstellung eine brauchbare Locale zu ermitteln.

  2. const Zend_Locale::ENVIRONMENT - PHP stellt die vom Server bevorzugte Locale durch die interne Funktion setlocale() zur Verfügung. Wird dort keine brauchbare Locale gefunden, so wird versucht über die FRAMEWORK und letztlich über die BROWSER Einstellung eine brauchbare Locale zu ermitteln.

  3. const Zend_Locale::FRAMEWORK - Sobald das Zend Framework einen standardisierten Weg bietet, Vorgabewerte für Komponenten zu setzen (derzeit noch in Arbeit), wird eine Locale anhand eines Vorgabewertes gewählt. Wird keine brauchbare Locale gefunden, so wird versucht über die ENVIRONMENT und letztlich über die BROWSER Einstellung eine brauchbare Locale zu ermitteln.

18.1.5. ZF Locale-Aware Klassen

Im Zend Framework, nutzen alle locale-aware Klassen Zend_Locale, um die benötigte Locale automatisch zu ermitteln, so wie es oben beschrieben wurde. Wird z.B. ein Datum mittels Zend_Date ohne die Angabe einer Locale erstellt, so wird das erstellte Objekt eine Locale benutzen, die der Browser des Benutzers als bevorzugt anzeigt.

Beispiel 18.3. Zend_Date benutzt standardmäßig die bevorzugte Locale des Benutzers

<?php
require_once 'Zend/Date.php';
$date = new Zend_Date('2006', Zend_Date::YEAR);
?>

Dieses Verhalten kann übergangen werden, indem man den locale-aware Klassen eine vorgegebene Locale als drittes Argument an den Konstruktor übergibt. In dem Fall wird dann die übergebene Locale benutzt und diese nicht mehr automatisch ermittelt.

Beispiel 18.4. Vorgeben einer Locale

<?php
require_once 'Zend/Date.php';
require_once 'Zend/Measure/Temperature.php';

$deLocale = new Zend_Locale('de_DE');
$date = new Zend_Date('2006', Zend_Date::YEAR, $deLocale);
$temp = new Zend_Measure_Temperature('37,7', Zend_Measure::TEMPERATURE, $deLocale);
?>

Wenn feststeht, dass viele Objekte eine gemeinsame Locale benutzen werden, so empfiehlt es sich diese explizit mit anzugeben, um den Overhead beim häufigen ermitteln der Standardlocale zu minimieren.

Beispiel 18.5. Performanceoptimierung durch das einmalige Setzen der verwendeten Locale

<?php
require_once 'Zend/Date.php';
require_once 'Zend/Measure/Temperature.php';

$locale = new Zend_Locale();
$date = new Zend_Date('2006', Zend_Date::YEAR, $locale);
$temp = new Zend_Measure_Temperature('100,10', Zend_Measure::TEMPERATURE, $locale);
?>

18.1.6. Zend_Locale_Format::setOptions(array $options)

The 'precision' option of a value is used to truncate or stretch extra digits. A value of '-1' disables modification of the number of digits in the fractional part of the value. The 'locale' option helps when parsing numbers and dates using separators and month names. The date format 'format_type' option selects between CLDR/ISO date format specifier tokens and PHP's date() tokens. The 'fix_date' option enables or disables heuristics that attempt to correct invalid dates. The 'number_format' option specifies a default number format for use with toNumber() (see Abschnitt 18.3.2, „Number localization“ ).

The 'date_format' option can be used to specify a default date format string, but beware of using getDate(), isDate(), getTime(), and isTime() after using setOptions() with a 'date_format'. To use these four methods with the default date format for a locale, use array('date_format' => null, 'locale' => $locale) for their options.

Beispiel 18.6. Dates default to correct locale of web users

<?php
require_once 'Zend/Locale.php';
Zend_Locale_Format::setOptions('locale' => 'en_US', 'fix_date' => true, 'format_type' => 'php');
?>