From ea832e21600192815e6380e53848226229dc7ec5 Mon Sep 17 00:00:00 2001 From: Joshua Ramon Enslin Date: Sat, 10 Sep 2022 02:13:35 +0200 Subject: [PATCH] Remove use of deprecated strfttime, use enums instead of class constants for many parts of NodaTimeAutotranslater --- src/NodaTimeAutotranslater.php | 318 ++++------- src/enums/NodaTimeAutotranslaterLocales.php | 494 ++++++++++++++++++ src/enums/NodaTimeAutotranslaterStatus.php | 20 + .../NodaTimeAutotranslaterSuffixMode.php | 13 + src/enums/NodaTimeAutotranslaterUseCase.php | 12 + src/inc/datesByCountry.php | 138 ----- tests/NodaTimeAutotranslaterTest.php | 5 + 7 files changed, 652 insertions(+), 348 deletions(-) create mode 100644 src/enums/NodaTimeAutotranslaterLocales.php create mode 100644 src/enums/NodaTimeAutotranslaterStatus.php create mode 100644 src/enums/NodaTimeAutotranslaterSuffixMode.php create mode 100644 src/enums/NodaTimeAutotranslaterUseCase.php diff --git a/src/NodaTimeAutotranslater.php b/src/NodaTimeAutotranslater.php index 07a4f49..0ded8b8 100644 --- a/src/NodaTimeAutotranslater.php +++ b/src/NodaTimeAutotranslater.php @@ -12,144 +12,7 @@ require_once __DIR__ . '/inc/datesByCountry.php'; */ 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 TRANSLATABLE_SINCE_START = 3; - const TRANSLATABLE_UNTIL_END = 4; - const TRANSLATABLE_ONLY_YEAR = 5; - const TRANSLATABLE_CENTURY = 6; - const TRANSLATABLE_DECADE = 7; - const TRANSLATABLE_TIMESPAN_YEARS = 8; - const TRANSLATABLE_TIMESPAN_DATES = 9; - - const LANGS_TO_LOCALES = [ - 'ar' => 'ar_SY.utf8', - 'de' => 'de_DE.utf8', - 'en' => 'en_US.utf8', - 'es' => 'es_ES.utf8', - 'fa' => 'fa_IR.UTF-8', - 'fr' => 'fr_FR.utf8', - 'hu' => 'hu_HU.utf8', - 'id' => 'id_ID.utf8', - 'it' => 'it_IT.utf8', - 'ka' => 'ka_GE.UTF-8', - 'ko' => 'ko_KR.UTF-8', - 'pl' => 'pl_PL.utf8', - 'pt' => 'pt_BR.utf8', - 'ro' => 'ro_RO.UTF-8', - 'ru' => 'ru_RU.UTF-8', - 'ta' => 'ta_IN.UTF-8', - 'tl' => 'tl_PH.utf8', - 'tr' => 'tr_TR.utf8', - - // Languages that don't really need a specific locale - 'ja' => 'en_US.utf8', - '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', - ]; + // TODO: Move these to NodaTimeAutotranslaterLocales const LANGS_SINCE_START_FORMAT_YEAR = [ 'ar' => '%s-', @@ -360,6 +223,12 @@ final class NodaTimeAutotranslater { /** @var MDMysqliStmt */ private MDMysqliStmt $_insertStmt; + /** + * Formats a time according to a specified format. + * + * @return string + */ + /** * Checks if a time is translatable. * Translatable times have either a counting time day and month or at least a month. @@ -368,48 +237,48 @@ final class NodaTimeAutotranslater { * @param string $zeit_ende End year. * @param string $zeit_zaehlzeit_monat Counting time month. * - * @return integer + * @return NodaTimeAutotranslaterStatus */ - public static function check_translatability(string $zeit_beginn, string $zeit_ende, string $zeit_zaehlzeit_monat):int { + public static function check_translatability(string $zeit_beginn, string $zeit_ende, string $zeit_zaehlzeit_monat):NodaTimeAutotranslaterStatus { if ($zeit_ende === "?") { - return self::TRANSLATABLE_SINCE_START; + return NodaTimeAutotranslaterStatus::SINCE_START; } if ($zeit_beginn === "?") { - return self::TRANSLATABLE_UNTIL_END; + return NodaTimeAutotranslaterStatus::UNTIL_END; } if (\intval($zeit_ende) >= 0 && \intval($zeit_beginn) < 0) { - return self::TRANSLATABLE_NOT; + return NodaTimeAutotranslaterStatus::NOT; } if (($zeit_ende > 0 && \intval($zeit_ende) % 100 === 0 and (\intval($zeit_beginn) - 1) % 100 === 0) || (\intval($zeit_beginn) < 0 && \intval($zeit_beginn) % 100 === 0 and (\intval($zeit_ende) + 1) % 100 === 0) ) { - return self::TRANSLATABLE_CENTURY; + return NodaTimeAutotranslaterStatus::CENTURY; } if ((\intval($zeit_ende) + 1) % 10 === 0 and \intval($zeit_beginn) % 10 === 0 and \intval($zeit_beginn) > 1000) { - return self::TRANSLATABLE_DECADE; + return NodaTimeAutotranslaterStatus::DECADE; } if (\intval($zeit_ende) < 0 && \intval($zeit_beginn) < 0 || (\intval($zeit_ende) < 1000 and \trim($zeit_zaehlzeit_monat, ", .0") === "") ) { - return self::TRANSLATABLE_AS_YEAR_WITH_SUFFIX; + return NodaTimeAutotranslaterStatus::AS_YEAR_WITH_SUFFIX; } if ($zeit_ende === $zeit_beginn and \trim($zeit_zaehlzeit_monat, ", .0") === "") { - return self::TRANSLATABLE_ONLY_YEAR; + return NodaTimeAutotranslaterStatus::ONLY_YEAR; } if ($zeit_ende !== $zeit_beginn and \trim($zeit_zaehlzeit_monat, ", .0") === "") { - return self::TRANSLATABLE_TIMESPAN_YEARS; + return NodaTimeAutotranslaterStatus::TIMESPAN_YEARS; } // Conditions speaking against translatability. if (\trim($zeit_zaehlzeit_monat, ", .0") === "") { - return self::TRANSLATABLE_NOT; + return NodaTimeAutotranslaterStatus::NOT; } - return self::TRANSLATABLE_AS_MONTH_DAY; + return NodaTimeAutotranslaterStatus::AS_MONTH_DAY; } @@ -419,17 +288,17 @@ final class NodaTimeAutotranslater { * @param integer $start Start year. * @param integer $end End year. * - * @return integer + * @return NodaTimeAutotranslaterSuffixMode */ - public static function getSuffixModeForYearsWSuffix(int $start, int $end):int { + public static function getSuffixModeForYearsWSuffix(int $start, int $end):NodaTimeAutotranslaterSuffixMode { if ($start < 0 && $end < 0) { - $suffixMode = 2; // 2; // " v. Chr."; + $suffixMode = NodaTimeAutotranslaterSuffixMode::BCE; // 2; // " v. Chr."; } else if ($end < 1000) { - $suffixMode = 1; // " n. Chr."; + $suffixMode = NodaTimeAutotranslaterSuffixMode::CE; // " n. Chr."; } - else $suffixMode = 0; // Times larger than 1000 n. Chr. + else $suffixMode = NodaTimeAutotranslaterSuffixMode::ANY; // Times larger than 1000 n. Chr. return $suffixMode; @@ -438,21 +307,21 @@ final class NodaTimeAutotranslater { /** * Applies suffix format to a time string. * - * @param string $tLang Two digit ANSI language code. - * @param string $timeName Time name. - * @param integer $suffixMode Suffix mode. + * @param string $tLang Two digit ANSI language code. + * @param string $timeName Time name. + * @param NodaTimeAutotranslaterSuffixMode $suffixMode Suffix mode. * * @return string */ - public static function applyBcBceFormat(string $tLang, string $timeName, int $suffixMode):string { + public static function applyBcBceFormat(string $tLang, string $timeName, NodaTimeAutotranslaterSuffixMode $suffixMode):string { switch ($suffixMode) { - case 0: + case NodaTimeAutotranslaterSuffixMode::ANY: return $timeName; - case 1: - return \sprintf(self::LANGS_TO_CE_FORMAT[$tLang], $timeName); - case 2: - return \sprintf(self::LANGS_TO_BCE_FORMAT[$tLang], $timeName); + case NodaTimeAutotranslaterSuffixMode::CE: + return \sprintf(NodaTimeAutotranslaterLocales::fromString($tLang)->eraFormatCeForSprintf(), $timeName); + case NodaTimeAutotranslaterSuffixMode::BCE: + return \sprintf(NodaTimeAutotranslaterLocales::fromString($tLang)->eraFormatBceForSprintf(), $timeName); default: throw new Exception("Unknown case encountered for time translations."); } @@ -464,7 +333,7 @@ final class NodaTimeAutotranslater { * * @param array $timeInfo Time information. * - * @return array + * @return array */ public static function translateYearsWithSuffix(array $timeInfo):array { @@ -474,34 +343,35 @@ final class NodaTimeAutotranslater { $suffixMode = self::getSuffixModeForYearsWSuffix($start, $end); // Time info to pass - if ($suffixMode === 2) { + if ($suffixMode === NodaTimeAutotranslaterSuffixMode::BCE) { $timeInfoToCopy = $timeInfo; $timeInfoToCopy["zeit_beginn"] = \abs($start); $timeInfoToCopy["zeit_ende"] = \abs($end); } $output = []; - foreach (self::LANGS_TO_CE_FORMAT as $tLang => $ceFormat) { + $cases = NodaTimeAutotranslaterLocales::cases(); + foreach ($cases as $tLang) { - if ($suffixMode === 2) { + if ($suffixMode === NodaTimeAutotranslaterSuffixMode::BCE) { if (empty($timeInfoToCopy)) { throw new Exception("No time information to copy existent"); } - $ceIndicatorsToRemove = explode("%s", self::LANGS_TO_CE_FORMAT[$tLang]); - $year = self::getTranslations($timeInfoToCopy)[$tLang]; + $ceIndicatorsToRemove = explode("%s", $tLang->eraFormatCeForSprintf()); + $year = self::getTranslations($timeInfoToCopy)[$tLang->name]; foreach ($ceIndicatorsToRemove as $ceIndicatorToRemove) { $year = str_replace($ceIndicatorToRemove, "", $year); } } else { if ($start === $end) { - $year = \sprintf(self::LANGS_SINGLE_YEAR_FORMAT[$tLang], (string)\abs($start)); + $year = \sprintf($tLang->formatSingleYearForSprintf(), (string)\abs($start)); } - else $year = \sprintf(self::LANGS_YEARSPAN_FORMAT[$tLang], (string)\abs($start), (string)\abs($end)); + else $year = \sprintf($tLang->formatYearspanForSprintf(), (string)\abs($start), (string)\abs($end)); } - $output[$tLang] = self::applyBcBceFormat($tLang, $year, $suffixMode); + $output[$tLang->name] = self::applyBcBceFormat($tLang->name, $year, $suffixMode); } return $output; @@ -513,15 +383,17 @@ final class NodaTimeAutotranslater { * * @param array $timeInfo Time information. * - * @return array + * @return array */ public static function translateYearOnly(array $timeInfo):array { $start = \intval($timeInfo['zeit_beginn']); $output = []; - foreach (self::LANGS_SINGLE_YEAR_FORMAT as $tLang => $format) { - $output[$tLang] = \sprintf($format, (string)\abs($start)); + $cases = NodaTimeAutotranslaterLocales::cases(); + foreach ($cases as $tLang) { + $format = $tLang->formatSingleYearForSprintf(); + $output[$tLang->name] = \sprintf($format, (string)\abs($start)); } return $output; @@ -532,7 +404,7 @@ final class NodaTimeAutotranslater { * * @param array $timeInfo Time information. * - * @return array + * @return array */ public static function translateTimespanYears(array $timeInfo):array { @@ -540,9 +412,9 @@ final class NodaTimeAutotranslater { $end = \intval($timeInfo['zeit_ende']); $output = []; - if (\abs($start) === 1102) throw new Exception(var_export($timeInfo, true)); - foreach (self::LANGS_YEARSPAN_FORMAT as $tLang => $format) { - $output[$tLang] = \sprintf($format, (string)\abs($start), (string)\abs($end)); + $cases = NodaTimeAutotranslaterLocales::cases(); + foreach ($cases as $tLang) { + $output[$tLang->name] = \sprintf($tLang->formatYearspanForSprintf(), (string)\abs($start), (string)\abs($end)); } return $output; @@ -553,7 +425,7 @@ final class NodaTimeAutotranslater { * * @param array $timeInfo Time information. * - * @return array + * @return array */ public static function translateYearsAsCentury(array $timeInfo):array { @@ -595,7 +467,7 @@ final class NodaTimeAutotranslater { * * @param array $timeInfo Time information. * - * @return array + * @return array */ public static function translateYearsAsDecade(array $timeInfo):array { @@ -631,7 +503,7 @@ final class NodaTimeAutotranslater { * * @param array $timeInfo Time information. * - * @return array + * @return array */ public static function translateYearsAfterStart(array $timeInfo):array { @@ -660,7 +532,7 @@ final class NodaTimeAutotranslater { * * @param array $timeInfo Time information. * - * @return array + * @return array */ public static function translateYearsSinceStart(array $timeInfo):array { @@ -691,7 +563,7 @@ final class NodaTimeAutotranslater { * * @param array $timeInfo Time information. * - * @return array + * @return array */ public static function translateYearsBeforeEnd(array $timeInfo):array { @@ -720,7 +592,7 @@ final class NodaTimeAutotranslater { * * @param array $timeInfo Time information. * - * @return array + * @return array */ public static function translateYearsUntilEnd(array $timeInfo):array { @@ -781,71 +653,97 @@ final class NodaTimeAutotranslater { ]; $output = []; - foreach (self::LANGS_YEARSPAN_FORMAT as $tLang => $format) { - $start_term = self::getTranslations($startTimeInfo)[$tLang]; - $end_term = self::getTranslations($endTimeInfo)[$tLang]; + $cases = NodaTimeAutotranslaterLocales::cases(); + foreach ($cases as $tLang) { + $start_term = self::getTranslations($startTimeInfo)[$tLang->name]; + $end_term = self::getTranslations($endTimeInfo)[$tLang->name]; - $output[$tLang] = \sprintf($format, $start_term, $end_term); + $output[$tLang->name] = \sprintf($tLang->formatYearspanForSprintf(), $start_term, $end_term); } return $output; } - if (!($translation_type = self::check_translatability((string)$timeInfo['zeit_beginn'], (string)$timeInfo['zeit_ende'], (string)$timeInfo['zeit_zaehlzeit_monat']))) { + if (($translation_type = self::check_translatability((string)$timeInfo['zeit_beginn'], (string)$timeInfo['zeit_ende'], (string)$timeInfo['zeit_zaehlzeit_monat'])) === NodaTimeAutotranslaterStatus::NOT) { throw new MDgenericInvalidInputsException("Non-translatable date: {$timeInfo['zeit_beginn']} - {$timeInfo['zeit_ende']}"); } - if ($translation_type === self::TRANSLATABLE_ONLY_YEAR) { + if ($translation_type === NodaTimeAutotranslaterStatus::ONLY_YEAR) { return self::translateYearOnly($timeInfo); } - if ($translation_type === self::TRANSLATABLE_SINCE_START) { + if ($translation_type === NodaTimeAutotranslaterStatus::SINCE_START) { return self::translateYearsSinceStart($timeInfo); } - if ($translation_type === self::TRANSLATABLE_UNTIL_END) { + if ($translation_type === NodaTimeAutotranslaterStatus::UNTIL_END) { return self::translateYearsUntilEnd($timeInfo); } - if ($translation_type === self::TRANSLATABLE_CENTURY) { + if ($translation_type === NodaTimeAutotranslaterStatus::CENTURY) { return self::translateYearsAsCentury($timeInfo); } - if ($translation_type === self::TRANSLATABLE_DECADE) { + if ($translation_type === NodaTimeAutotranslaterStatus::DECADE) { return self::translateYearsAsDecade($timeInfo); } - if ($translation_type === self::TRANSLATABLE_TIMESPAN_YEARS) { + if ($translation_type === NodaTimeAutotranslaterStatus::TIMESPAN_YEARS) { return self::translateTimespanYears($timeInfo); } - if ($translation_type === self::TRANSLATABLE_AS_YEAR_WITH_SUFFIX) { + if ($translation_type === NodaTimeAutotranslaterStatus::AS_YEAR_WITH_SUFFIX) { return self::translateYearsWithSuffix($timeInfo); } $suffixMode = self::getSuffixModeForYearsWSuffix(\intval($timeInfo['zeit_beginn']) - 1, \intval($timeInfo['zeit_ende'])); 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; + $dateStr = "{$timeInfo['zeit_zaehlzeit_jahr']}-{$timeInfo['zeit_zaehlzeit_monat']}-05 12:00:01"; + $usecase = NodaTimeAutotranslaterUseCase::MONTH; } else { - $dateStr = "{$timeInfo['zeit_zaehlzeit_jahr']}-{$timeInfo['zeit_zaehlzeit_monat']}-{$timeInfo['zeit_zaehlzeit_tag']} 00:00:01"; - $usecase = self::USECASE_DAY; + $dateStr = "{$timeInfo['zeit_zaehlzeit_jahr']}-{$timeInfo['zeit_zaehlzeit_monat']}-{$timeInfo['zeit_zaehlzeit_tag']} 12:00:01"; + $usecase = NodaTimeAutotranslaterUseCase::DAY; } - $dateGeneral = \strtotime($dateStr); + $dateGeneral = new DateTimeImmutable($dateStr); $output = []; - foreach (self::LANGS_TO_LOCALES as $tLang => $locale) { + $cases = NodaTimeAutotranslaterLocales::cases(); + foreach ($cases as $tLang) { - \setlocale(LC_TIME, $locale); - if ($locale !== \setlocale(LC_TIME, "0")) continue; - if ($usecase === self::USECASE_MONTH) $tLangValue = \strftime(getMonthFormatByLang($tLang), $dateGeneral ?: 0); - else { # if ($usecase === self::USECASE_DAY) - $tLangValue = \strftime(getDateFormatByLang($tLang), $dateGeneral ?: 0); + $locale = $tLang->localeIntlDateFormatter(); + + $dateGeneral = IntlCalendar::createInstance(locale: $locale); + $dateGeneral->set(IntlCalendar::FIELD_YEAR, (int)$timeInfo['zeit_zaehlzeit_jahr']); + $dateGeneral->set(IntlCalendar::FIELD_MONTH, (int)$timeInfo['zeit_zaehlzeit_monat'] - 1); + if ($usecase === NodaTimeAutotranslaterUseCase::DAY) { + $dateGeneral->set(IntlCalendar::FIELD_DAY_OF_MONTH, (int)$timeInfo['zeit_zaehlzeit_tag']); } - $output[$tLang] = self::applyBcBceFormat($tLang, $tLangValue, $suffixMode); + $format = match($usecase) { + NodaTimeAutotranslaterUseCase::MONTH => $tLang->formatYearMonthForIntlDateFormatter(), + default => $tLang->formatFullDateForIntlDateFormatter(), + }; + + /* + \setlocale(LC_TIME, $locale); + $tLangValue = self::_formatTimeName($locale, $tLangValue, $dateGeneral); + if ($locale !== \setlocale(LC_TIME, "0")) continue; + */ + + # \setlocale(LC_TIME, $locale); + # if ($locale !== \setlocale(LC_TIME, "0")) continue; + # $tLangValue = \strftime($format, $dateGeneral ?: 0); + + $fmt = new IntlDateFormatter( + $locale, + timezone: new DateTimeZone("GMT"), + pattern: $format, + ); + if (($tLangValue = $fmt->format($dateGeneral)) === false) continue; + + $output[$tLang->name] = self::applyBcBceFormat($tLang->name, $tLangValue, $suffixMode); } diff --git a/src/enums/NodaTimeAutotranslaterLocales.php b/src/enums/NodaTimeAutotranslaterLocales.php new file mode 100644 index 0000000..8b02486 --- /dev/null +++ b/src/enums/NodaTimeAutotranslaterLocales.php @@ -0,0 +1,494 @@ + + */ + declare(strict_types = 1); + +enum NodaTimeAutotranslaterLocales { + case ar; + case de; + case en; + case es; + case fa; + case fr; + case hu; + case id; + case it; + case ja; + case ka; + case ko; + case pl; + case pt; + case ro; + case ru; + case ta; + case tl; + case tr; + case zh; + + /** + * Returns an instance of this from a string. + * + * @param string $lang Language code to create enum from. + * + * @return static + */ + public static function fromString(string $lang):static { + + return match($lang) { + 'ar' => static::ar, + 'de' => static::de, + 'en' => static::en, + 'es' => static::es, + 'fa' => static::fa, + 'fr' => static::fr, + 'hu' => static::hu, + 'id' => static::id, + 'it' => static::it, + 'ka' => static::ka, + 'ko' => static::ko, + 'pl' => static::pl, + 'pt' => static::pt, + 'ro' => static::ro, + 'ru' => static::ru, + 'ta' => static::ta, + 'tl' => static::tl, + 'tr' => static::tr, + 'ja' => static::ja, + 'zh' => static::zh, + }; + + } + + /** + * Returns the locale as used by strftime. + * + * @return string + */ + public function localeStrftime():string { + + return match($this) { + self::ar => 'ar_SY.utf8', + self::de => 'de_DE.utf8', + self::en => 'en_US.utf8', + self::es => 'es_ES.utf8', + self::fa => 'fa_IR.UTF-8', + self::fr => 'fr_FR.utf8', + self::hu => 'hu_HU.utf8', + self::id => 'id_ID.utf8', + self::it => 'it_IT.utf8', + self::ka => 'ka_GE.UTF-8', + self::ko => 'ko_KR.UTF-8', + self::pl => 'pl_PL.utf8', + self::pt => 'pt_BR.utf8', + self::ro => 'ro_RO.UTF-8', + self::ru => 'ru_RU.UTF-8', + self::ta => 'ta_IN.UTF-8', + self::tl => 'tl_PH.utf8', + self::tr => 'tr_TR.utf8', + + // Languages that don't really need a specific locale + self::ja => 'en_US.utf8', + self::zh => 'en_US.utf8', + }; + + } + + /** + * Returns the locale as used by IntlDateFormatter. + * + * @return string + */ + public function localeIntlDateFormatter():string { + + return match($this) { + self::ar => 'ar-SY', + self::de => 'de-DE', + self::en => 'en-US', + self::es => 'es-ES', + self::fa => 'fa-IR', + self::fr => 'fr-FR', + self::hu => 'hu-HU', + self::id => 'id-ID', + self::it => 'it-IT', + self::ka => 'ka-GE', + self::ko => 'ko-KR', + self::pl => 'pl-PL', + self::pt => 'pt-BR', + self::ro => 'ro-RO', + self::ru => 'ru-RU', + self::ta => 'ta-IN', + self::tl => 'tl-PH', + self::tr => 'tr-TR', + + // Languages that don't really need a specific locale + self::ja => 'en-US', + self::zh => 'en-US', + }; + + } + + /** + * Returns the common era format for a given language. + * + * @return string + */ + public function eraFormatCeForSprintf():string { + + return match($this) { + self::ar => '%s', + self::de => '%s n. Chr.', + self::en => '%s CE', + self::es => '%s d.C.', + self::fa => '%s', + self::fr => '%s ap. J.-C.', + self::hu => '%s', + self::id => '%s M.', + self::it => '%s d.C.', + self::ka => '%s წ', + self::ko => '%s', + self::pl => '%s n.e.', + self::pt => '%s dC', + self::ro => '%s', + self::ru => '%s', + self::ta => '%s பொ.ச.', + self::tl => '%s AD', + self::tr => '%s', + self::ja => '西暦%s', + self::zh => '%s', + }; + + } + + /** + * Returns the before common era format for a given language. + * + * @return string + */ + public function eraFormatBceForSprintf():string { + + return match($this) { + self::ar => '-%s', + self::de => '%s v. Chr.', + self::en => '%s BC', + self::es => '%s a.C.', + self::fa => '-%s', + self::fr => '%s av. J.-C.', + self::hu => 'Kr. e. %s', + self::id => '%s SM', + self::it => '%s a.C.', + self::ka => 'ძვ. წ. %s წ', + self::ko => '기원전%s', + self::pl => '%s pne', + self::pt => '%s AC', + self::ro => '%s î.Hr.', + self::ru => '%s г. до н.э.', + self::ta => 'கிமு %s', + self::tl => '%s BC', + self::tr => 'MÖ %s', + + // Languges that don't really need a specific locale + self::ja => '紀元前%s', + self::zh => '公元前%s', + }; + + } + + /** + * Returns the appropriate format for a single year in the current language. + * + * @return string + */ + public function formatSingleYearForSprintf():string { + + return match($this) { + self::ar => '%s', + self::de => '%s', + self::en => '%s', + self::es => '%s', + self::fa => '%s', + self::fr => '%s', + self::hu => '%s', + self::id => '%s', + self::it => '%s', + self::ka => '%s', + self::ko => '%s년', + self::pl => '%s', + self::pt => '%s', + self::ro => '%s', + self::ru => '%s', + self::ta => '%s', + self::tl => '%s', + self::tr => '%s', + self::ja => '%s年', + self::zh => '%s年', + }; + + } + + /** + * Returns the appropriate format for a timespan of several years in the current language. + * + * @return string + */ + public function formatYearspanForSprintf():string { + + return match($this) { + self::ar => '%s-%s', + self::de => '%s-%s', + self::en => '%s-%s', + self::es => '%s-%s', + self::fa => '%s-%s', + self::fr => '%s-%s', + self::hu => '%s-%s', + self::id => '%s-%s', + self::it => '%s-%s', + self::ka => '%s-%s', + self::ko => '%s년-%s년', + self::pl => '%s-%s', + self::pt => '%s-%s', + self::ro => '%s-%s', + self::ru => '%s-%s', + self::ta => '%s-%s', + self::tl => '%s-%s', + self::tr => '%s-%s', + self::ja => '%s年から%s年', + self::zh => '%s年至%s年', + }; + + } + + /** + * Returns the appropriate format for formatting a full date (Y-m-d) in a given language + * using strftime. + * + * @return string + */ + public function formatFullDateForStrfttime():string { + + return match($this) { + self::ar => '%d/%m/%Y', + # self::be => '%d.%B.%Y', + # self::bg => '%Y-%B-%d', + # self::ca => '%d/%m/%Y', + # self::cs => '%d.%B.%Y', + # self::da => '%d-%m-%Y', + self::de => '%d.%m.%Y', + # self::el => '%d/%B/%Y', + self::en => '%B %d, %Y', + self::es => '%d/%m/%Y', + # self::et => '%d.%m.%Y', + self::fa => '%d/%m/%Y', + # self::fi => '%d.%B.%Y', + self::fr => '%d/%m/%Y', + # self::ga => '%d/%m/%Y', + # self::hr => '%d.%m.%Y', + self::hu => '%Y. %B %d.', + self::id => '%d %B %Y', + # self::in => '%d/%m/%Y', + # self::is => '%d.%B.%Y', + self::it => '%d/%m/%Y', + # self::iw => '%d/%m/%Y', + self::ja => '%Y年%m月%d日', + self::ka => '%d.%m.%Y', + self::ko => '%Y년 %m월 %d일', + # self::lt => '%Y.%B.%d', + # self::lv => '%Y.%d.%B', + # self::mk => '%d.%B.%Y', + # self::ms => '%d/%m/%Y', + # self::mt => '%d/%m/%Y', + # self::nl => '%d-%B-%Y', + # self::no => '%d.%m.%Y', + self::pl => '%d.%m.%Y', + self::pt => '%d/%m/%Y', + self::ro => '%d.%m.%Y', + self::ru => '%d.%m.%Y', + # self::sk => '%d.%B.%Y', + # self::sl => '%d.%B.%Y', + # self::sq => '%Y-%m-%d', + # self::sr => '%d.%B.%Y.', + # self::sv => '%Y-%m-%d', + self::ta => '%d-%m-%Y', + self::tl => '%Y-%m-%d', + self::tr => '%d.%m.%Y', + # self::uk => '%d.%m.%Y', + # self::vi => '%d/%m/%Y', + self::zh => '%Y年%m月%d日', + }; + + } + + /** + * Returns the appropriate format for formatting a full date (Y-m-d) in a given language + * using IntlDateFormatter. + * + * @return string + */ + public function formatFullDateForIntlDateFormatter():string { + + return match($this) { + self::ar => 'dd/MM/Y', + # self::be => '%d.%B.%Y', + # self::bg => '%Y-%B-%d', + # self::ca => '%d/%m/%Y', + # self::cs => '%d.%B.%Y', + # self::da => '%d-%m-%Y', + self::de => 'dd.MM.Y', + # self::el => '%d/%B/%Y', + self::en => 'MMMM d, Y', + self::es => 'dd/MM/Y', + # self::et => '%d.%m.%Y', + self::fa => 'dd/MM/Y', + # self::fi => '%d.%B.%Y', + self::fr => 'dd/MM/Y', + # self::ga => '%d/%m/%Y', + # self::hr => '%d.%m.%Y', + self::hu => 'Y. MMMM dd.', + self::id => 'dd MMMM dd', + # self::in => '%d/%m/%Y', + # self::is => '%d.%B.%Y', + self::it => 'dd/MM/Y', + # self::iw => '%d/%m/%Y', + self::ja => 'Y年MM月dd日', + self::ka => 'dd.MM.Y', + self::ko => 'Y년 MM월 dd일', + # self::lt => '%Y.%B.%d', + # self::lv => '%Y.%d.%B', + # self::mk => '%d.%B.%Y', + # self::ms => '%d/%m/%Y', + # self::mt => '%d/%m/%Y', + # self::nl => '%d-%B-%Y', + # self::no => '%d.%m.%Y', + self::pl => 'dd.MM.Y', + self::pt => 'dd.MM.Y', + self::ro => 'dd.MM.Y', + self::ru => 'dd.MM.Y', + # self::sk => '%d.%B.%Y', + # self::sl => '%d.%B.%Y', + # self::sq => '%Y-%m-%d', + # self::sr => '%d.%B.%Y.', + # self::sv => '%Y-%m-%d', + self::ta => 'dd-MM-Y', + self::tl => 'Y-MM-dd', + self::tr => 'dd.MM.Y', + # self::uk => '%d.%m.%Y', + # self::vi => '%d/%m/%Y', + self::zh => 'Y年MM月dd日', + }; + + } + + /** + * Returns the appropriate format for formatting a year and month (Y-m-d) in a given language + * using strftime. + * + * @return string + */ + public function formatYearMonthForStrfttime():string { + + return match($this) { + self::ar => '%m/%Y', + # self::be => '%B %Y', + # self::bg => '%Y-%B', + # self::ca => '%m/%Y', + # self::cs => '%B.%Y', + # self::da => '%m-%Y', + self::de => '%B %Y', + # self::el => '%B %Y', + self::en => '%B %Y', + self::es => '%B %Y', + self::fa => '%B %Y', + self::fr => '%B %Y', + self::hu => '%Y. %B', + # self::in => '%m/%Y', + # self::is => '%B %Y', + self::id => '%B %Y', + self::it => '%B %Y', + # self::iw => '%m %Y', + self::ja => '%Y年%m月', + self::ka => '%B %Y', + self::ko => '%Y년 %m월', + # self::lt => '%Y. %B.', + # self::lv => '%Y. %B', + # self::mk => '%B %Y', + # self::ms => '%m %Y', + # self::mt => '%m %Y', + # self::nl => '%B %Y', + # self::no => '%B %Y', + self::pl => '%B %Y', + self::pt => '%B %Y', + self::ro => '%B %Y', + self::ru => '%B %Y', + # self::sk => '%B %Y', + # self::sl => '%B %Y', + # self::sq => '%B %Y', + # self::sr => '%B %Y', + # self::sv => '%Y-%m', + self::ta => '%B %Y', + self::tr => '%B %Y', + self::tl => '%B %Y', + # self::uk => '%m %Y', + # self::vi => '%m %Y', + self::zh => '%Y年%m月', + }; + + } + + /** + * Returns the appropriate format for formatting a year and month (Y-m-d) in a given language + * using IntlDateFormatter. + * + * @return string + */ + public function formatYearMonthForIntlDateFormatter():string { + + return match($this) { + self::ar => 'MM/Y', + # self::be => 'MMMM Y', + # self::bg => 'Y-MMMM', + # self::ca => 'MM/Y', + # self::cs => 'MMMM.Y', + # self::da => 'MM-Y', + self::de => 'MMMM Y', + # self::el => 'MMMM Y', + self::en => 'MMMM Y', + self::es => 'MMMM Y', + self::fa => 'MMMM Y', + self::fr => 'MMMM Y', + self::hu => 'Y. MMMM', + # self::in => 'MM/Y', + # self::is => 'MMMM Y', + self::id => 'MMMM Y', + self::it => 'MMMM Y', + # self::iw => 'MM Y', + self::ja => 'Y年MM月', + self::ka => 'MMMM Y', + self::ko => 'Y년 MM월', + # self::lt => 'Y. MMMM.', + # self::lv => 'Y. MMMM', + # self::mk => 'MMMM Y', + # self::ms => 'MM Y', + # self::mt => 'MM Y', + # self::nl => 'MMMM Y', + # self::no => 'MMMM Y', + self::pl => 'MMMM Y', + self::pt => 'MMMM Y', + self::ro => 'MMMM Y', + self::ru => 'MMMM Y', + # self::sk => 'MMMM Y', + # self::sl => 'MMMM Y', + # self::sq => 'MMMM Y', + # self::sr => 'MMMM Y', + # self::sv => 'Y-MM', + self::ta => 'MMMM Y', + self::tr => 'MMMM Y', + self::tl => 'MMMM Y', + # self::uk => 'MM Y', + # self::vi => 'MM Y', + self::zh => 'Y年MM月', + }; + + } +} diff --git a/src/enums/NodaTimeAutotranslaterStatus.php b/src/enums/NodaTimeAutotranslaterStatus.php new file mode 100644 index 0000000..c3ace89 --- /dev/null +++ b/src/enums/NodaTimeAutotranslaterStatus.php @@ -0,0 +1,20 @@ + + */ + declare(strict_types = 1); + +enum NodaTimeAutotranslaterStatus { + case NOT; + case AS_MONTH_DAY; + case AS_YEAR_WITH_SUFFIX; + case SINCE_START; + case UNTIL_END; + case ONLY_YEAR; + case CENTURY; + case DECADE; + case TIMESPAN_YEARS; + case TIMESPAN_DATES; +} diff --git a/src/enums/NodaTimeAutotranslaterSuffixMode.php b/src/enums/NodaTimeAutotranslaterSuffixMode.php new file mode 100644 index 0000000..13bab26 --- /dev/null +++ b/src/enums/NodaTimeAutotranslaterSuffixMode.php @@ -0,0 +1,13 @@ + + */ + declare(strict_types = 1); + +enum NodaTimeAutotranslaterSuffixMode { + case BCE; + case ANY; + case CE; +} diff --git a/src/enums/NodaTimeAutotranslaterUseCase.php b/src/enums/NodaTimeAutotranslaterUseCase.php new file mode 100644 index 0000000..e002af0 --- /dev/null +++ b/src/enums/NodaTimeAutotranslaterUseCase.php @@ -0,0 +1,12 @@ + + */ + declare(strict_types = 1); + +enum NodaTimeAutotranslaterUseCase { + case DAY; + case MONTH; +} diff --git a/src/inc/datesByCountry.php b/src/inc/datesByCountry.php index 517a5de..e69de29 100644 --- a/src/inc/datesByCountry.php +++ b/src/inc/datesByCountry.php @@ -1,138 +0,0 @@ - - */ -declare(strict_types = 1); - -/** - * Function getDateFormatByLang returns the common date format in a given - * country / language. - * - * @param string $lang Language code to check. - * - * @thanks Michael Connor (https://gist.github.com/mlconnor/1887156) for - * compiling the underlying array. - * - * @return string - */ -function getDateFormatByLang(string $lang):string { - - $datesByCountry = [ - 'ar' => '%d/%m/%Y', - 'be' => '%d.%B.%Y', - 'bg' => '%Y-%B-%d', - 'ca' => '%d/%m/%Y', - 'cs' => '%d.%B.%Y', - 'da' => '%d-%m-%Y', - 'de' => '%d.%m.%Y', - 'el' => '%d/%B/%Y', - 'en' => '%B %d, %Y', - 'es' => '%d/%m/%Y', - 'et' => '%d.%m.%Y', - 'fa' => '%d/%m/%Y', - 'fi' => '%d.%B.%Y', - 'fr' => '%d/%m/%Y', - 'ga' => '%d/%m/%Y', - 'hr' => '%d.%m.%Y', - 'hu' => '%Y. %B %d.', - 'id' => '%d %B %Y', - 'in' => '%d/%m/%Y', - 'is' => '%d.%B.%Y', - 'it' => '%d/%m/%Y', - 'iw' => '%d/%m/%Y', - 'ja' => '%Y年%m月%d日', - 'ka' => '%d.%m.%Y', - 'ko' => '%Y년 %m월 %d일', - 'lt' => '%Y.%B.%d', - 'lv' => '%Y.%d.%B', - 'mk' => '%d.%B.%Y', - 'ms' => '%d/%m/%Y', - 'mt' => '%d/%m/%Y', - 'nl' => '%d-%B-%Y', - 'no' => '%d.%m.%Y', - 'pl' => '%d.%m.%Y', - 'pt' => '%d/%m/%Y', - 'ro' => '%d.%m.%Y', - 'ru' => '%d.%m.%Y', - 'sk' => '%d.%B.%Y', - 'sl' => '%d.%B.%Y', - 'sq' => '%Y-%m-%d', - 'sr' => '%d.%B.%Y.', - 'sv' => '%Y-%m-%d', - 'ta' => '%d-%m-%Y', - 'tr' => '%d.%m.%Y', - 'uk' => '%d.%m.%Y', - 'vi' => '%d/%m/%Y', - 'zh' => '%Y年%m月%d日', - ]; - if (!isset($datesByCountry[$lang])) return $datesByCountry["en"]; - - return $datesByCountry[$lang]; - -} - -/** - * Function getDateFormatByLang returns the common date format in a given - * country / language. - * - * @param string $lang Language code to check. - * - * @thanks Michael Connor (https://gist.github.com/mlconnor/1887156) for - * compiling the underlying array. - * - * @return string - */ -function getMonthFormatByLang(string $lang):string { - - $datesByCountry = [ - 'ar' => '%m/%Y', - 'be' => '%B %Y', - 'bg' => '%Y-%B', - 'ca' => '%m/%Y', - 'cs' => '%B.%Y', - 'da' => '%m-%Y', - 'de' => '%B %Y', - 'el' => '%B %Y', - 'en' => '%B %Y', - 'es' => '%B %Y', - 'fa' => '%B %Y', - 'fr' => '%B %Y', - 'hu' => '%Y. %B', - 'in' => '%m/%Y', - 'is' => '%B %Y', - 'it' => '%B %Y', - 'iw' => '%m %Y', - 'ja' => '%Y年%m月', - 'ka' => '%B %Y', - 'ko' => '%Y년 %m월', - 'lt' => '%Y. %B.', - 'lv' => '%Y. %B', - 'mk' => '%B %Y', - 'ms' => '%m %Y', - 'mt' => '%m %Y', - 'nl' => '%B %Y', - 'no' => '%B %Y', - 'pl' => '%B %Y', - 'pt' => '%B %Y', - 'ro' => '%B %Y', - 'ru' => '%B %Y', - 'sk' => '%B %Y', - 'sl' => '%B %Y', - 'sq' => '%B %Y', - 'sr' => '%B %Y', - 'sv' => '%Y-%m', - 'ta' => '%B %Y', - 'tr' => '%B %Y', - 'tl' => '%B %Y', - 'uk' => '%m %Y', - 'vi' => '%m %Y', - 'zh' => '%Y年%m月', - ]; - if (!isset($datesByCountry[$lang])) return $datesByCountry["en"]; - - return $datesByCountry[$lang]; - -} diff --git a/tests/NodaTimeAutotranslaterTest.php b/tests/NodaTimeAutotranslaterTest.php index 268d971..c3756cb 100644 --- a/tests/NodaTimeAutotranslaterTest.php +++ b/tests/NodaTimeAutotranslaterTest.php @@ -6,7 +6,12 @@ */ declare(strict_types = 1); use PHPUnit\Framework\TestCase; +require __DIR__ . "/../src/NodaTimeSplitter.php"; require __DIR__ . "/../src/NodaTimeAutotranslater.php"; +require __DIR__ . "/../src/enums/NodaTimeAutotranslaterStatus.php"; +require __DIR__ . "/../src/enums/NodaTimeAutotranslaterSuffixMode.php"; +require __DIR__ . "/../src/enums/NodaTimeAutotranslaterUseCase.php"; +require __DIR__ . "/../src/enums/NodaTimeAutotranslaterLocales.php"; /** * This script contains tests for the automatic translation class for time names.