From 974fe39cde758e52bb119a7ed107c6eb8986c904 Mon Sep 17 00:00:00 2001 From: Joshua Ramon Enslin Date: Sun, 20 Sep 2020 17:13:42 +0200 Subject: [PATCH] Allow translations of times before 1000 CE --- src/NodaTimeAutotranslater.php | 178 +++++++++++++++++++++++++++++++-- 1 file changed, 172 insertions(+), 6 deletions(-) diff --git a/src/NodaTimeAutotranslater.php b/src/NodaTimeAutotranslater.php index 0f4d416..d1fbd4a 100644 --- a/src/NodaTimeAutotranslater.php +++ b/src/NodaTimeAutotranslater.php @@ -15,6 +15,10 @@ final class NodaTimeAutotranslater { const USECASE_MONTH = 1; const USECASE_DAY = 2; + const TRANSLATABLE_NOT = 0; + const TRANSLATABLE_AS_MONTH_DAY = 1; + const TRANSLATABLE_AS_YEAR_WITH_SUFFIX = 2; + const LANGS_TO_LOCALES = [ 'ar' => 'ar_SY.utf8', 'de' => 'de_DE.utf8', @@ -40,6 +44,106 @@ final class NodaTimeAutotranslater { 'zh' => 'en_US.utf8', ]; + const LANGS_SINGLE_YEAR_FORMAT = [ + 'ar' => '%s', + 'de' => '%s', + 'en' => '%s', + 'es' => '%s', + 'fa' => '%s', + 'fr' => '%s', + 'hu' => '%s', + 'id' => '%s', + 'it' => '%s', + 'ka' => '%s', + 'ko' => '%s년', + 'pl' => '%s', + 'pt' => '%s', + 'ro' => '%s', + 'ru' => '%s', + 'ta' => '%s', + 'tl' => '%s', + 'tr' => '%s', + + // Languages that don't really need a specific locale + 'ja' => '%s年', + 'zh' => '%s年', + ]; + + const LANGS_YEARSPAN_FORMAT = [ + 'ar' => '%s-%s', + 'de' => '%s-%s', + 'en' => '%s-%s', + 'es' => '%s-%s', + 'fa' => '%s-%s', + 'fr' => '%s-%s', + 'hu' => '%s-%s', + 'id' => '%s-%s', + 'it' => '%s-%s', + 'ka' => '%s-%s', + 'ko' => '%s년-%s년', + 'pl' => '%s-%s', + 'pt' => '%s-%s', + 'ro' => '%s-%s', + 'ru' => '%s-%s', + 'ta' => '%s-%s', + 'tl' => '%s-%s', + 'tr' => '%s-%s', + + // Languages that don't really need a specific locale + 'ja' => '%s年から%s年', + 'zh' => '%s年至%s年', + ]; + + const LANGS_TO_BCE_FORMAT = [ + 'ar' => '-%s', + 'de' => '%s v. Chr.', + 'en' => '%s BC', + 'es' => '%s a.C.', + 'fa' => '-%s', + 'fr' => '%s av. J.-C.', + 'hu' => 'Kr. e. %s', + 'id' => '%s SM', + 'it' => '%s a.C.', + 'ka' => 'ძვ. წ. %s წ', + 'ko' => '기원전%s', + 'pl' => '%s pne', + 'pt' => '%s AC', + 'ro' => '%s î.Hr.', + 'ru' => '%s г. до н.э.', + 'ta' => 'கிமு %s', + 'tl' => '%s BC', + 'tr' => 'MÖ %s', + + // Languages that don't really need a specific locale + 'ja' => '紀元前%s', + 'zh' => '公元前%s', + ]; + + const LANGS_TO_CE_FORMAT = [ + 'ar' => '%s', + 'de' => '%s n. Chr.', + 'en' => '%s CE', + 'es' => '%s d.C.', + 'fa' => '%s', + 'fr' => '%s ap. J.-C.', + 'hu' => '%s', + 'id' => '%s M.', + 'it' => '%s d.C.', + 'ka' => '%s წ', + 'ko' => '%s', + 'pl' => '%s n.e.', + 'pt' => '%s dC', + 'ro' => '%s', + 'ru' => '%s', + 'ta' => '%s பொ.ச.', + 'tl' => '%s AD', + 'tr' => '%s', + + // Languages that don't really need a specific locale + 'ja' => '西暦%s', + 'zh' => '%s', + ]; + /** @var MDMysqli */ private MDMysqli $_mysqli_noda; /** @var integer */ @@ -51,17 +155,74 @@ final class NodaTimeAutotranslater { * Checks if a time is translatable. * Translatable times have either a counting time day and month or at least a month. * + * @param string $zeit_beginn Beginn year. + * @param string $zeit_ende End year. * @param string $zeit_zaehlzeit_monat Counting time month. * - * @return boolean + * @return integer */ - public static function check_translatability(string $zeit_zaehlzeit_monat) { + public static function check_translatability(string $zeit_beginn, string $zeit_ende, string $zeit_zaehlzeit_monat):int { - if (trim($zeit_zaehlzeit_monat, ", .0") === "") { - return false; + if (intval($zeit_ende) >= 0 && intval($zeit_beginn) < 0) { + return self::TRANSLATABLE_NOT; + } + if (intval($zeit_ende) < 1000 || intval($zeit_ende) < 0 && intval($zeit_beginn) < 0) { + return self::TRANSLATABLE_AS_YEAR_WITH_SUFFIX; + } + // Conditions speaking against translatability. + else if (trim($zeit_zaehlzeit_monat, ", .0") === "") { + $output = self::TRANSLATABLE_NOT; } - return true; + return self::TRANSLATABLE_AS_MONTH_DAY; + + } + + /** + * Translated years or timespans below 1000 CE. + * + * @param array $timeInfo Time information. + * + * @return void + */ + public function translateYearsWithSuffix(array $timeInfo):void { + + $start = intval($timeInfo['zeit_beginn']); + $end = intval($timeInfo['zeit_ende']); + + if ($start < 0 && $end < 0) { + $suffixMode = 2; // 2; // " v. Chr."; + } + else if ($end < 1000) { + $suffixMode = 1; // " n. Chr."; + } + else $suffixMode = 0; + + foreach (self::LANGS_TO_CE_FORMAT as $tLang => $ceFormat) { + + if ($start === $end) { + $year = sprintf(self::LANGS_SINGLE_YEAR_FORMAT[$tLang], (string)abs($start)); + } + else $year = sprintf(self::LANGS_YEARSPAN_FORMAT[$tLang], (string)abs($start), (string)abs($end)); + + switch ($suffixMode) { + case 0: + $timeName = $year; + break; + case 1: + $timeName = sprintf($ceFormat, $year); + break; + case 2: + $timeName = sprintf(self::LANGS_TO_BCE_FORMAT[$tLang], $year); + break; + default: + throw new Exception("Unknown case encountered for time translations."); + } + + $this->_insertStmt->bind_param("iss", $this->_znum, $tLang, $timeName); + $this->_insertStmt->execute(); + + } } @@ -74,10 +235,15 @@ final class NodaTimeAutotranslater { */ public function translate(array $timeInfo):void { - if (!self::check_translatability((string)$timeInfo['zeit_zaehlzeit_monat'])) { + if (!($translation_type = self::check_translatability($timeInfo['zeit_beginn'], $timeInfo['zeit_ende'], (string)$timeInfo['zeit_zaehlzeit_monat']))) { throw new MDgenericInvalidInputsException("Non-translatable date"); } + if ($translation_type === self::TRANSLATABLE_AS_YEAR_WITH_SUFFIX) { + $this->translateYearsWithSuffix($timeInfo); + return; + } + if (trim((string)$timeInfo['zeit_zaehlzeit_tag'], ", .0") === "") { $dateStr = "{$timeInfo['zeit_zaehlzeit_jahr']}-{$timeInfo['zeit_zaehlzeit_monat']}-05 00:00:01"; $usecase = self::USECASE_MONTH;