Обходное решение кодировки Charset для strftime () в Windows?

Я подумал, что нашел лучшее решение для обхода PHP strftime () в Windows, а затем пользователь сообщил о проблеме.

Windows имеет некоторые ограничения для strftime () и, кроме того, она не поддерживает UTF-8. Поэтому я написал обходной путь для обеих этих проблем, но наткнулся на проблемы с кодировкой.

Вот как выглядит мой код:

function strftimefixed($format, $timestamp=null) {

if ($timestamp === null) $timestamp = time();

if (strtoupper(substr(PHP_OS, 0, 3)) == 'WIN') {
$format = preg_replace('#(?<!%)((?:%%)*)%e#', '\1%#d', $format); // Don't mind this line
}

return mb_convert_encoding(strftime($format, $timestamp), 'UTF-8', 'auto'); // Charset is the problem
}

Сообщение об ошибке

Предупреждение: mb_convert_encoding (): невозможно определить кодировку символов

Как видите, «auto» не может определить кодировку. Пользователь находится на чешской установке Windows, но я не могу жестко закодировать его в «ISO-8859-2», поскольку это поможет только чешским пользователям, а не другим конечным пользователям, которые не имеют ни малейшего представления, что такое языковой стандарт Windows. или какой кодировкой.

Так что же является наилучшим возможным решением для универсального крутого решения?

Примечание: формат не является проблемой здесь. Это может быть что угодно, например,% b% e% Y% H:% M. Идентификация кодировки — это проблема.

1

Решение

В соответствии с руководство, проблемы, которые strftime () имеет в Windows, включают:

Не все спецификаторы преобразования могут поддерживаться вашей C-библиотекой, в
в этом случае они не будут поддерживаться PHP strftime ().
Кроме того, не все платформы поддерживают отрицательные временные метки, поэтому ваш
диапазон дат может быть ограничен не ранее эпохи Unix
. это
означает, что% e,% T,% R и,% D (и, возможно, другие) — а также даты
до 1 января 1970 года — не будет работать на Windows, некоторые Linux
дистрибутивы и несколько других операционных систем.

Ваш код использует нераскрытые параметры ($format а также $timestamp) так что вас беспокоит довольно непонятно.

Однако полученное сообщение об ошибке связано с кодировка текста, не дата обработки per se. Просто невозможно правильно обрабатывать текст для неизвестных кодировок, но вы можете выбирать кодировка производится strftime() выбрав подходящий язык:

strftime — Форматировать местное время / дату в соответствии с настройками локали

Отформатируйте время и / или дату в соответствии с настройками локали. Названия месяцев и дней недели и другие зависящие от языка строки соответствуют текущая локаль установлена ​​с Setlocale ().

Однако следует помнить, что обработка локали ненадежна на некоторых платформах, таких как поточно-ориентированные сборки в Windows. Если это так, вам может понадобиться сбросить strftime() целиком и выберите подходящий инструмент локализации.

Конечно, вы всегда можете оставить локаль по умолчанию и просто попытаться угадать кодировку, но вам, вероятно, потребуется поддерживать базу данных.

0

Другие решения

Лучшее решение, которое я мог придумать, — это определить кодировку локали Windows и решить ее оттуда.

function strftimefixed($format, $timestamp=null) {

if ($timestamp === null) $timestamp = time();

if (strtoupper(substr(PHP_OS, 0, 3)) == 'WIN') {
$format = preg_replace('#(?<!%)((?:%%)*)%e#', '\1%#d', $format);

$locale = setlocale(LC_TIME, 0);

switch(true) {
case (preg_match('#\.(874|1256)$#', $locale, $matches)):
return iconv('UTF-8', "$locale_charset", strftime($format, $timestamp));

case (preg_match('#\.1250$#', $locale)):
return mb_convert_encoding(strftime($format, $timestamp), 'UTF-8', 'ISO-8859-2');

case (preg_match('#\.(1251|1252|1254)$#', $locale, $matches)):
return mb_convert_encoding(strftime($format, $timestamp), 'UTF-8', 'Windows-'.$matches[1]);

case (preg_match('#\.(1255|1256)$#', $locale, $matches)):
return iconv('UTF-8', "Windows-{$matches[1]}", strftime($format, $timestamp));

case (preg_match('#\.1257$#', $locale)):
return mb_convert_encoding(strftime($format, $timestamp), 'UTF-8', 'ISO-8859-13');

case (preg_match('#\.(932|936|950)$#', $locale)):
return mb_convert_encoding(strftime($format, $timestamp), 'UTF-8', 'CP'.$matches[1]);

case (preg_match('#\.(949)$#', $locale)):
return mb_convert_encoding(strftime($format, $timestamp), 'UTF-8', 'EUC-KR');

default:
trigger_error("Unknown charset for system locale ($locale)", E_USER_NOTICE);
return mb_convert_encoding(strftime($format, $timestamp), 'UTF-8', 'auto');
}
}

return strftime($format, $timestamp);
}
0

По вопросам рекламы [email protected]