Add automatic translation of times since and until another time
This commit is contained in:
parent
4f1e65934a
commit
308e11b4f8
|
@ -18,6 +18,9 @@ final class NodaTimeAutotranslater {
|
||||||
const TRANSLATABLE_NOT = 0;
|
const TRANSLATABLE_NOT = 0;
|
||||||
const TRANSLATABLE_AS_MONTH_DAY = 1;
|
const TRANSLATABLE_AS_MONTH_DAY = 1;
|
||||||
const TRANSLATABLE_AS_YEAR_WITH_SUFFIX = 2;
|
const TRANSLATABLE_AS_YEAR_WITH_SUFFIX = 2;
|
||||||
|
const TRANSLATABLE_SINCE_START = 3;
|
||||||
|
const TRANSLATABLE_UNTIL_END = 4;
|
||||||
|
const TRANSLATABLE_ONLY_YEAR = 5;
|
||||||
|
|
||||||
const LANGS_TO_LOCALES = [
|
const LANGS_TO_LOCALES = [
|
||||||
'ar' => 'ar_SY.utf8',
|
'ar' => 'ar_SY.utf8',
|
||||||
|
@ -144,6 +147,56 @@ final class NodaTimeAutotranslater {
|
||||||
'zh' => '%s',
|
'zh' => '%s',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const LANGS_SINCE_START_FORMAT_YEAR = [
|
||||||
|
'ar' => '%s-',
|
||||||
|
'de' => 'Seit %s',
|
||||||
|
'en' => 'Since %s',
|
||||||
|
'es' => 'Desde %s',
|
||||||
|
'fa' => '%s-',
|
||||||
|
'fr' => 'Depuis %s',
|
||||||
|
'hu' => '%s-től',
|
||||||
|
'id' => 'Sejak %s',
|
||||||
|
'it' => 'Dal %s',
|
||||||
|
'ka' => '%s წლიდან',
|
||||||
|
'ko' => '%s부터',
|
||||||
|
'pl' => 'Desde %s',
|
||||||
|
'pt' => '%s dC',
|
||||||
|
'ro' => 'Din %s',
|
||||||
|
'ru' => 'С %s г.',
|
||||||
|
'ta' => '%s முதல்',
|
||||||
|
'tl' => 'Mula noong %s',
|
||||||
|
'tr' => '%s-',
|
||||||
|
|
||||||
|
// Languages that don't really need a specific locale
|
||||||
|
'ja' => '%s以来',
|
||||||
|
'zh' => '自%s以來',
|
||||||
|
];
|
||||||
|
|
||||||
|
const LANGS_UNTIL_START_FORMAT_YEAR = [
|
||||||
|
'ar' => '-%s',
|
||||||
|
'de' => 'Bis %s',
|
||||||
|
'en' => 'Until %s',
|
||||||
|
'es' => 'Hasta %s',
|
||||||
|
'fa' => '-%s',
|
||||||
|
'fr' => 'Jusqu\'en %s',
|
||||||
|
'hu' => '%s-ig',
|
||||||
|
'id' => 'Sampai %s',
|
||||||
|
'it' => 'Fino al %s',
|
||||||
|
'ka' => '%s წლამდე',
|
||||||
|
'ko' => '%s까지',
|
||||||
|
'pl' => 'do %s roku',
|
||||||
|
'pt' => 'até %s',
|
||||||
|
'ro' => 'până în %s',
|
||||||
|
'ru' => 'до %s г.',
|
||||||
|
'ta' => '%s வரை',
|
||||||
|
'tl' => 'Hanggang %s',
|
||||||
|
'tr' => '%s-',
|
||||||
|
|
||||||
|
// Languages that don't really need a specific locale
|
||||||
|
'ja' => '%sまで',
|
||||||
|
'zh' => '直到%s',
|
||||||
|
];
|
||||||
|
|
||||||
/** @var MDMysqli */
|
/** @var MDMysqli */
|
||||||
private MDMysqli $_mysqli_noda;
|
private MDMysqli $_mysqli_noda;
|
||||||
/** @var integer */
|
/** @var integer */
|
||||||
|
@ -163,12 +216,21 @@ final class NodaTimeAutotranslater {
|
||||||
*/
|
*/
|
||||||
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):int {
|
||||||
|
|
||||||
|
if (intval($zeit_beginn) > 1000 and $zeit_ende === "?") {
|
||||||
|
return self::TRANSLATABLE_SINCE_START;
|
||||||
|
}
|
||||||
|
if (intval($zeit_ende) > 1000 and $zeit_beginn === "?") {
|
||||||
|
return self::TRANSLATABLE_UNTIL_END;
|
||||||
|
}
|
||||||
if (intval($zeit_ende) >= 0 && intval($zeit_beginn) < 0) {
|
if (intval($zeit_ende) >= 0 && intval($zeit_beginn) < 0) {
|
||||||
return self::TRANSLATABLE_NOT;
|
return self::TRANSLATABLE_NOT;
|
||||||
}
|
}
|
||||||
if (intval($zeit_ende) < 0 && intval($zeit_beginn) < 0 || intval($zeit_ende) < 1000) {
|
if (intval($zeit_ende) < 0 && intval($zeit_beginn) < 0 || intval($zeit_ende) < 1000) {
|
||||||
return self::TRANSLATABLE_AS_YEAR_WITH_SUFFIX;
|
return self::TRANSLATABLE_AS_YEAR_WITH_SUFFIX;
|
||||||
}
|
}
|
||||||
|
if ($zeit_ende === $zeit_beginn and trim($zeit_zaehlzeit_monat, ", .0") === "") {
|
||||||
|
return self::TRANSLATABLE_ONLY_YEAR;
|
||||||
|
}
|
||||||
// Conditions speaking against translatability.
|
// Conditions speaking against translatability.
|
||||||
if (trim($zeit_zaehlzeit_monat, ", .0") === "") {
|
if (trim($zeit_zaehlzeit_monat, ", .0") === "") {
|
||||||
return self::TRANSLATABLE_NOT;
|
return self::TRANSLATABLE_NOT;
|
||||||
|
@ -179,16 +241,14 @@ final class NodaTimeAutotranslater {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Translated years or timespans below 1000 CE.
|
* Gets suffix mode for years with suffix.
|
||||||
*
|
*
|
||||||
* @param array<integer|string> $timeInfo Time information.
|
* @param integer $start Start year.
|
||||||
|
* @param integer $end End year.
|
||||||
*
|
*
|
||||||
* @return void
|
* @return integer
|
||||||
*/
|
*/
|
||||||
public function translateYearsWithSuffix(array $timeInfo):void {
|
public static function getSuffixModeForYearsWSuffix(int $start, int $end):int {
|
||||||
|
|
||||||
$start = intval($timeInfo['zeit_beginn']);
|
|
||||||
$end = intval($timeInfo['zeit_ende']);
|
|
||||||
|
|
||||||
if ($start < 0 && $end < 0) {
|
if ($start < 0 && $end < 0) {
|
||||||
$suffixMode = 2; // 2; // " v. Chr.";
|
$suffixMode = 2; // 2; // " v. Chr.";
|
||||||
|
@ -196,8 +256,51 @@ final class NodaTimeAutotranslater {
|
||||||
else if ($end < 1000) {
|
else if ($end < 1000) {
|
||||||
$suffixMode = 1; // " n. Chr.";
|
$suffixMode = 1; // " n. Chr.";
|
||||||
}
|
}
|
||||||
else $suffixMode = 0;
|
else $suffixMode = 0; // Times larger than 1000 n. Chr.
|
||||||
|
|
||||||
|
return $suffixMode;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public static function applyBcBceFormat(string $tLang, string $timeName, int $suffixMode):string {
|
||||||
|
|
||||||
|
switch ($suffixMode) {
|
||||||
|
case 0:
|
||||||
|
return $timeName;
|
||||||
|
case 1:
|
||||||
|
return sprintf(self::LANGS_TO_CE_FORMAT[$tLang], $timeName);
|
||||||
|
case 2:
|
||||||
|
return sprintf(self::LANGS_TO_BCE_FORMAT[$tLang], $timeName);
|
||||||
|
default:
|
||||||
|
throw new Exception("Unknown case encountered for time translations.");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Translated years or timespans below 1000 CE.
|
||||||
|
*
|
||||||
|
* @param array<integer|string> $timeInfo Time information.
|
||||||
|
*
|
||||||
|
* @return array<string>
|
||||||
|
*/
|
||||||
|
public function translateYearsWithSuffix(array $timeInfo):array {
|
||||||
|
|
||||||
|
$start = intval($timeInfo['zeit_beginn']);
|
||||||
|
$end = intval($timeInfo['zeit_ende']);
|
||||||
|
|
||||||
|
$suffixMode = self::getSuffixModeForYearsWSuffix($start, $end);
|
||||||
|
|
||||||
|
$output = [];
|
||||||
foreach (self::LANGS_TO_CE_FORMAT as $tLang => $ceFormat) {
|
foreach (self::LANGS_TO_CE_FORMAT as $tLang => $ceFormat) {
|
||||||
|
|
||||||
if ($start === $end) {
|
if ($start === $end) {
|
||||||
|
@ -205,43 +308,112 @@ final class NodaTimeAutotranslater {
|
||||||
}
|
}
|
||||||
else $year = sprintf(self::LANGS_YEARSPAN_FORMAT[$tLang], (string)abs($start), (string)abs($end));
|
else $year = sprintf(self::LANGS_YEARSPAN_FORMAT[$tLang], (string)abs($start), (string)abs($end));
|
||||||
|
|
||||||
switch ($suffixMode) {
|
$output[$tLang] = self::applyBcBceFormat($tLang, $year, $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();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
return $output;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Runs autotranslater.
|
* Translated only years: 1994.
|
||||||
*
|
*
|
||||||
* @param array<integer|string> $timeInfo Time information.
|
* @param array<integer|string> $timeInfo Time information.
|
||||||
*
|
*
|
||||||
* @return void
|
* @return array<string>
|
||||||
*/
|
*/
|
||||||
public function translate(array $timeInfo):void {
|
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));
|
||||||
|
}
|
||||||
|
return $output;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Translated years or timespans below 1000 CE.
|
||||||
|
*
|
||||||
|
* @param array<integer|string> $timeInfo Time information.
|
||||||
|
*
|
||||||
|
* @return array<string>
|
||||||
|
*/
|
||||||
|
public static function translateYearsSinceStart(array $timeInfo):array {
|
||||||
|
|
||||||
|
$start = intval($timeInfo['zeit_beginn']);
|
||||||
|
|
||||||
|
$innerTimeInfo = $timeInfo;
|
||||||
|
$innerTimeInfo['zeit_ende'] = $timeInfo['zeit_beginn'];
|
||||||
|
$output = [];
|
||||||
|
|
||||||
|
foreach (self::LANGS_SINCE_START_FORMAT_YEAR as $tLang => $format) {
|
||||||
|
|
||||||
|
$dateAlone = self::getTranslations($innerTimeInfo)[$tLang];
|
||||||
|
|
||||||
|
$timeName = sprintf($format, $dateAlone);
|
||||||
|
$output[$tLang] = $timeName;
|
||||||
|
|
||||||
|
}
|
||||||
|
return $output;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Translated years or timespans below 1000 CE.
|
||||||
|
*
|
||||||
|
* @param array<integer|string> $timeInfo Time information.
|
||||||
|
*
|
||||||
|
* @return array<string>
|
||||||
|
*/
|
||||||
|
public static function translateYearsUntilEnd(array $timeInfo):array {
|
||||||
|
|
||||||
|
$end = intval($timeInfo['zeit_ende']);
|
||||||
|
|
||||||
|
$innerTimeInfo = $timeInfo;
|
||||||
|
$innerTimeInfo['zeit_beginn'] = $timeInfo['zeit_ende'];
|
||||||
|
|
||||||
|
$output = [];
|
||||||
|
foreach (self::LANGS_UNTIL_START_FORMAT_YEAR as $tLang => $format) {
|
||||||
|
|
||||||
|
$dateAlone = self::getTranslations($innerTimeInfo)[$tLang];
|
||||||
|
|
||||||
|
$timeName = sprintf($format, $dateAlone);
|
||||||
|
$output[$tLang] = $timeName;
|
||||||
|
}
|
||||||
|
return $output;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets translations for a given entry type.
|
||||||
|
*
|
||||||
|
* @param array<integer|string> $timeInfo Time information.
|
||||||
|
*
|
||||||
|
* @return array<string>
|
||||||
|
*/
|
||||||
|
public static function getTranslations(array $timeInfo):array {
|
||||||
|
|
||||||
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']))) {
|
||||||
throw new MDgenericInvalidInputsException("Non-translatable date");
|
throw new MDgenericInvalidInputsException("Non-translatable date");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($translation_type === self::TRANSLATABLE_ONLY_YEAR) {
|
||||||
|
return self::translateYearOnly($timeInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($translation_type === self::TRANSLATABLE_SINCE_START) {
|
||||||
|
return self::translateYearsSinceStart($timeInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($translation_type === self::TRANSLATABLE_UNTIL_END) {
|
||||||
|
return self::translateYearsUntilEnd($timeInfo);
|
||||||
|
}
|
||||||
|
|
||||||
if ($translation_type === self::TRANSLATABLE_AS_YEAR_WITH_SUFFIX) {
|
if ($translation_type === self::TRANSLATABLE_AS_YEAR_WITH_SUFFIX) {
|
||||||
$this->translateYearsWithSuffix($timeInfo);
|
return self::translateYearsWithSuffix($timeInfo);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (trim((string)$timeInfo['zeit_zaehlzeit_tag'], ", .0") === "") {
|
if (trim((string)$timeInfo['zeit_zaehlzeit_tag'], ", .0") === "") {
|
||||||
|
@ -255,6 +427,7 @@ final class NodaTimeAutotranslater {
|
||||||
|
|
||||||
$dateGeneral = strtotime($dateStr);
|
$dateGeneral = strtotime($dateStr);
|
||||||
|
|
||||||
|
$output = [];
|
||||||
foreach (self::LANGS_TO_LOCALES as $tLang => $locale) {
|
foreach (self::LANGS_TO_LOCALES as $tLang => $locale) {
|
||||||
|
|
||||||
setlocale(LC_TIME, $locale);
|
setlocale(LC_TIME, $locale);
|
||||||
|
@ -264,9 +437,28 @@ final class NodaTimeAutotranslater {
|
||||||
$tLangValue = strftime(getDateFormatByLang($tLang), $dateGeneral ?: 0);
|
$tLangValue = strftime(getDateFormatByLang($tLang), $dateGeneral ?: 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$output[$tLang] = $tLangValue;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return $output;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Runs autotranslater.
|
||||||
|
*
|
||||||
|
* @param array<integer|string> $timeInfo Time information.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function translate(array $timeInfo):void {
|
||||||
|
|
||||||
|
$translations = self::getTranslations($timeInfo);
|
||||||
|
|
||||||
|
foreach ($translations as $tLang => $tLangValue) {
|
||||||
$this->_insertStmt->bind_param("iss", $this->_znum, $tLang, $tLangValue);
|
$this->_insertStmt->bind_param("iss", $this->_znum, $tLang, $tLangValue);
|
||||||
$this->_insertStmt->execute();
|
$this->_insertStmt->execute();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -545,6 +545,26 @@ final class NodaTimeSplitter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Endings beginning with a space
|
||||||
|
if (preg_match("/ (\(bis\))$/", $datum)) {
|
||||||
|
if (($spacePos = strrpos($datum, " ")) === false) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
if ($output = self::attempt_splitting(substr($datum, 0, $spacePos))) {
|
||||||
|
$output[0] = "?";
|
||||||
|
return $output;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (preg_match("/\-ig$/", $datum)) {
|
||||||
|
if (($spacePos = strrpos($datum, "-")) === false) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
if ($output = self::attempt_splitting(substr($datum, 0, $spacePos))) {
|
||||||
|
$output[0] = "?";
|
||||||
|
return $output;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return [];
|
return [];
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user