Проблема с часовым поясом по умолчанию в php 7.1/7.0

я немного запутался, исследуя определение часового пояса по умолчанию в php 7.1/7.0: у нас есть простой код php CLI:

 php -r "var_dump(ini_get('date.timezone'),date_default_timezone_get());"

и согласно документации php.net (http://php.net/manual/en/function.date-default-timezone-get.php) мы должны иметь «UTC» в результате функции date_default_timezone_get, потому что мы не устанавливаем часовой пояс в php.ini. А вот вывод этого кода:

Command line code:1:
string(0) ""
Command line code:1:
string(16) "America/Anguilla"

здесь мы видим, что ini_get('date.timezone') равно пустой строке, но date_default_timezone_get равно America/Anguilla

я использую: PHP 7.1.12-3+ubuntu14.04.1+deb.sury.org+1 (cli) (built: Dec 14 2017 15:58:40) ( NTS ).

php -i показывает нам:

свидание

date/time support => enabled
timelib version => 2016.05
"Olson" Timezone Database Version => 0.system
Timezone Database => internal
Default timezone => America/Anguilla

Кстати, часовой пояс на этом сервере: Asia/Qatar (AST, +0300), но насколько я знаю, он не должен браться php из php 5.4.

Не могли бы вы помочь мне узнать, где было установлено это значение для этого часового пояса?

ОБНОВЛЕНО: это исходный код php 7.1 функции определения часового пояса:

       static char* guess_timezone(const timelib_tzdb *tzdb)
    {
        /* Checking configure timezone */
        if (DATEG(timezone) && (strlen(DATEG(timezone))) > 0) {
            return DATEG(timezone);
        }
        /* Check config setting for default timezone */
        if (!DATEG(default_timezone)) {
            /* Special case: ext/date wasn't initialized yet */
            zval *ztz;

            if (NULL != (ztz = cfg_get_entry("date.timezone", 

sizeof("date.timezone")))
            && Z_TYPE_P(ztz) == IS_STRING && Z_STRLEN_P(ztz) > 0 && timelib_timezone_id_is_valid(Z_STRVAL_P(ztz), tzdb)) {
            return Z_STRVAL_P(ztz);
        }
    } else if (*DATEG(default_timezone)) {
        if (DATEG(timezone_valid) == 1) {
            return DATEG(default_timezone);
        }

        if (!timelib_timezone_id_is_valid(DATEG(default_timezone), tzdb)) {
            php_error_docref(NULL, E_WARNING, "Invalid date.timezone value '%s', we selected the timezone 'UTC' for now.", DATEG(default_timezone));
            return "UTC";
        }

        DATEG(timezone_valid) = 1;
        return DATEG(default_timezone);
    }
    /* Fallback to UTC */
    return "UTC";
}

В php 5.6 и ниже я вижу, что php генерирует предупреждение, если часовой пояс не установлен:

 /* Fallback to UTC */
    php_error_docref(NULL TSRMLS_CC, E_WARNING, DATE_TZ_ERRMSG "We selected the timezone 'UTC' for now, but please set date.timezone to select your timezone.");
    return "UTC";

Заранее спасибо,

С уважением,

Дмитрий


person programmer    schedule 26.07.2018    source источник
comment
Если бы вы включили error_reporting, вы, вероятно, увидели бы большое предупреждение о том, что date.timezone не установлено, и о том, как вам на самом деле нужно его установить.   -  person Sammitch    schedule 26.07.2018
comment
@Sammitch, я пытался включить отчеты об ошибках, используя php -r "error_reporting(E_ALL); var_dump(ini_get('date.timezone'),date_default_timezone_get());", но все равно не вижу предупреждения, кстати, я обновил свой пост и поделился исходным кодом php функции определения часового пояса   -  person programmer    schedule 26.07.2018
comment
Хорошо, но в вашем примере кода по-прежнему отображается неустановленная или иным образом недопустимая настройка для date.timezone, и никакая дополнительная информация не указывает на то, что вы ее исправили.   -  person Sammitch    schedule 26.07.2018
comment
@Sammitch в php.ini у меня есть закомментированная строка ;date.timezone = , а ini_get('date.timezone') показывает пустую строку. я просто пытаюсь понять, почему php имеет часовой пояс по умолчанию Америка/Ангилья   -  person programmer    schedule 26.07.2018
comment
Будьте ???? причиной ???? вы ???? пришлось ???? ???? установить ???? это.   -  person Sammitch    schedule 27.07.2018
comment
да. наверняка он работает, если я установил его в php.ini и нет проблем. Но для меня интересен вопрос, почему php берет Америку/Ангилью, но не берет «UTC», если он не установлен в php.ini   -  person programmer    schedule 27.07.2018


Ответы (1)


Весьма вероятно, что часовой пояс по умолчанию устанавливается через date_default_timezone_set [https://www.php.net/manual/en/function.date-default-timezone-set.php] либо в коде поставщика инициализации, либо во время сборки.

Я бы сказал, что это то, что системные упаковщики should делают вместо того, чтобы оставлять это неопределенным. Если аргумент PHP состоит в том, что начиная с версии 5.4, поскольку значение не может быть правильно угадано во всех системах, то он не должен угадывать все, он должен оставить на усмотрение упаковщиков и установщиков определение правильного значения для системы.

Я также слышал, что причина, по которой разработчики PHP сделали это, заключается в том, что некоторые разработчики PHP использовали локальную дату и время для представления времени конечного пользователя, что, конечно, должно определяться настройками или конфигурацией браузера пользователя. Date-timezone следует использовать только для таких вещей, как журналы и географически ограниченные установки. Но в таком случае зачем удалять полезное угадывание по умолчанию, даже если оно иногда ошибочно?

В любом случае, PHP решил, что гораздо лучше обеспечить, чтобы все установки PHP сообщали неправильное время по умолчанию, чем это было проклятием немногих.

person Otheus    schedule 22.03.2021