Меню Рубрики

Установка времени php ini

Установка временнОй зоны в PHP

Иногда возникает такая ситуация, что текущее время на сервере не соответствует вашему текущему часовому поясу или часовому поясу региона, на который ориентирован ваш сайт.

Чтобы было понятно, напомню: территориально Россия очень большая, и далеко не всем нужно, чтобы их сайты «жили» по московскому времени. Например, Урал, Сибирь, Дальний восток и т.д.

Серверы большинства популярных российских хостинг-провайдеров размещены на технологических площадках Москвы и Санкт-Петербурга и по-умолочанию настроены, естественно, на московскую временну́ю зону. Сервер не может автоматически подстраиваться под ваше текущее местоположение и переводить системные часы. В связи с чем, работа функций даты и времени на сайте может быть не совсем корректной. Естественно, сейчас речь не идёт о CMS, в которых поправка часового пояса обычно присутствует прямо в интерфейсе администратора.

В первую очередь проверьте текущее состояние с помощью PHP-кода:

Хорошо, если у вас свой сервер и имеется доступ к php.ini, где можно задать нужную временну́ю зону и забыть. Например, таким образом:

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

Установка временной зоны на виртуальном хостинге

На виртуальном хостинге, доступа к конфигам сервера чаще всего нет. Поэтому, в первую очередь попробуйте задать временну́ю зону с помощью .htaccess. Просто найдите или создайте в корне своего сайта файл .htaccess и добавьте в него такую строку:

Если способ не сработает, тогда воспользуемся функцией date_default_timezone_set(), которая устанавливает временную зону по умолчанию для всех функций даты и времени. Для этого нужно где-нибудь в начале скрипта просто добавьте такую строку:

Естественно, Europe/Moscow меняется на необходимый вам часовой пояс. Для территории РФ в PHP поддерживаются следующие временные зоны:

  • Europe/Moscow
  • Europe/Samara
  • Europe/Kaliningrad
  • Europe/Volgograd
  • Asia/Anadyr
  • Asia/Kamchatka
  • Asia/Krasnoyarsk
  • Asia/Magadan
  • Asia/Novokuznetsk
  • Asia/Novosibirsk
  • Asia/Omsk
  • Asia/Sakhalin
  • Asia/Vladivostok
  • Asia/Yakutsk
  • Asia/Yekaterinburg

Со списком всех доступных временных зон можно ознакомиться по ссылке или выполнить команду, которая возвратит вам список временных зон, доступных на вашем сервере.

Подпишитесь на мой телеграм и первыми получайте новые материалы, в том числе которых нет на сайте.

200 бесплатных наборов кистей для Фотошопа
731

Как в Фотошопе сменить русский язык на английский
485

Как отправить большое видео в Ватсап
453

Топ 12 Вордпресс шаблонов для сайта доставки еды
262

Как скачать приватное видео из фейсбука
196

25 лучших шаблонов для создания интернет-магазина на OpenCart
194

5 лучших книг по Вордпресс на русском языке
149

Как быстро наполнить сайт на WordPress с помощью плагина WP All Import
145

Как использовать Media Query в JavaScript
144

Как импортировать большую базу данных MySQL в обход ограничений phpMyAdmin
137

Как быстро удалить все исходящие заявки в друзья во Вконтакте
118

Установка временнОй зоны в PHP
96

Как посмотреть, кто кого лайкает в Инстаграм
90

10 рекомендуемых книг-бестселлеров по PHP
83

Как включить мультисайт и создать сеть сайтов на Вордпресс
83

20 лучших шаблонов Вордпресс для сферы услуг
82

FontAwesome и ещё 25 бесплатных иконочных шрифтов
80

Как открыть *.CDR в Adobe Illustrator
74

10 бесплатных шаблонов лендингов в PSD
72

20 лучших Вордпресс шаблонов для блога
66

Практикующий веб-разработчик, специализируюсь на платформе Вордпресс.

источник

date_default_timezone_set

date_default_timezone_set — Устанавливает временную зону по умолчанию для всех функций даты/времени в скрипте

Описание

date_default_timezone_set() устанавливает временную зону по умолчанию для всех функций даты/времени в скрипте.

Начиная с версии PHP 5.1.0 (когда функции даты/времени были переписаны), вызов любой функции даты/времени генерирует E_NOTICE , если временная зона имеет неверное значение, и/или E_WARNING , если используются системные параметры или переменная окружения TZ .

Вместо использования этой функции, вы можете воспользоваться INI-настройкой date.timezone для установки временной зоны по умолчанию.

Список параметров

Идентификатор временной зоны, как например UTC или Europe/Lisbon. Список допустимых идентификаторов временной зоны можно найти в разделе Список поддерживаемых временных зон.

Возвращаемые значения

Функция возвращает FALSE , если timezone_identifier имеет неверное значение, в остальных случаях TRUE .

Примеры

Пример #1 Получение временной зоны по умолчанию

if ( strcmp ( $script_tz , ini_get ( ‘date.timezone’ ))) <
echo ‘Временная зона скрипта отличается от заданной в INI-файле.’ ;
> else <
echo ‘Временные зоны скрипта и настройки INI-файла совпадают.’ ;
>
?>

Список изменений

Версия Описание
5.3.0 Теперь выбрасывает E_WARNING вместо E_STRICT .
5.1.2 Функция начала проверять timezone_identifier .

Смотрите также

  • date_default_timezone_get() — Возвращает временную зону, используемой по умолчанию всеми функциями даты/времени в скрипте
  • Список поддерживаемых временных зон

User Contributed Notes 22 notes

I’m sure I’m not the only one who is distressed by the recent default behavior change to E_NOTICE when the timezone isn’t explicitly set in the program or in .ini. I insure that the clock on the server IS correct, and I don’t want to have to set it in two places (the system AND PHP). So I want to read it from the system. But PHP won’t accept that answer, and insists on a call to this function. So, here’s my answer:

function setTimezone ( $default ) <
$timezone = «» ;

// On many systems (Mac, for instance) «/etc/localtime» is a symlink
// to the file with the timezone info
if ( is_link ( «/etc/localtime» )) <

// If it is, that file’s name is actually the «Olsen» format timezone
$filename = readlink ( «/etc/localtime» );

$pos = strpos ( $filename , «zoneinfo» );
if ( $pos ) <
// When it is, it’s in the «/usr/share/zoneinfo/» folder
$timezone = substr ( $filename , $pos + strlen ( «zoneinfo/» ));
> else <
// If not, bail
$timezone = $default ;
>
>
else <
// On other systems, like Ubuntu, there’s file with the Olsen time
// right inside it.
$timezone = file_get_contents ( «/etc/timezone» );
if (! strlen ( $timezone )) <
$timezone = $default ;
>
>
date_default_timezone_set ( $timezone );
>
?>

Use it by calling it with a fallback default answer.

Yes, I know it doesn’t work on Windows. Neither do I 🙂 Perhaps someone wants to add that functionality.

This creates a huge problem for downloadable programs, which obviously cannot be hardcoded as this suggests, since the coder has no idea where they will be run.

Seems to me that if the server’s timezone cannot be relied on, then THAT is the the problem which needs fixed. Not, cause the coder’s syntactically-correct work to generate bogus error messages.

As Christopher Kramer said 9 years ago, not setting default timezone has performance impacts on PHP 5.6, and on PHP 7.1

It hasn’t on php 7.2 anymore.

As I set error_reporting to 0 in my script, it doesn’t seem linked to the fact it is logging the error.

I ran its benchmark script (modified) on Linux multiple times, alternating ‘on’ and ‘off’ setting :

$tz = ( $argc > 1 && ( $argv [ 1 ] == ‘on’ )) ? ‘on’ : ‘off’ ;
if ( $tz == ‘on’ ) date_default_timezone_set (@ date_default_timezone_get ());

$start = mktime ( 0 , 0 , 0 , 1 , 1 , 2005 );
$end = mktime ( 0 , 0 , 0 , 1 , 1 , 2020 );

$t0 = microtime ( true );
for ( $i = 0 ; $i 50000 ; $i ++) date ( «H:i:s d.m.Y» , rand ( $start , $end ));

echo «Time ( $tz ): » .(( microtime ( true ) — $t0 )* 100 ). «\n» ;

I avoid using strings as arguments when a constant or other kind of reference should be used. For example, to set the default timezone to UTC, the recommended code is:

( ‘UTC’ ); // Potential for mistakes
?>

However, using the string «UTC» here opens up the possibility for mistakes. For example, if the string «UTX» were entered accidentally,
most PHP editors PHP won’t flag that as an error. When run, the interpreter will show the common warning about a misspelled timezone and using «UTC» by default.

PHP should define constants to represent the major timezones. Actually it does, but «DateTimeZone::UTC» inconveniently contains the integer value 1024, not a string. However, «DateTimeZone::listIdentifiers()» can turn a timezone integer into an array of timezone identifier strings. So, I use this code:

( DateTimeZone :: listIdentifiers ( DateTimeZone :: UTC )[ 0 ]); // Foolproof
?>

It’s longer, but if I make a mistake specifying the timezone (which I won’t because I use code completion), my editor would highlight the problem. If I ran the program with an invalid timezone reference anyway, PHP would give the more helpful error, «Fatal error: Undefined class constant ‘UTX’ in /tmp/tarfu.php on line 24».

I experienced that using this function highly increases performance of functions like getdate() or date() using PHP 5.2.6 on Windows.
I experienced similar results on Linux servers with PHP 5.2.6 and 5.2.10, although the difference was not that significant on these servers: The PHP 5.2.10 server did run with date_default_timezone_set («only») twice as fast as without. The 5.2.6 server did 5 times faster with date_default_timezone_set. As you can see below, the 5.2.6-Windows machine did a LOT faster.
Of course these machines have completely different hardware and can not really be compared, but all show improved performance.

I checked PHP 4.4.9 on Windows (without date_default_timezone_set of course) and noticed that its as fast as PHP 5.2.6 with date_default_timezone_set.

The following script shows this:

# uncomment to see difference
# date_default_timezone_set(date_default_timezone_get());

function getmicrotime ()
<
list( $usec , $sec ) = explode ( ‘ ‘ , microtime ());
return ( $sec . substr ( $usec , 1 , 7 ));
>

$start = mktime ( 0 , 0 , 0 , 1 , 1 , 2005 );
$end = mktime ( 0 , 0 , 0 , 1 , 1 , 2020 );
$nr = 50000 ;

$start_time = getmicrotime ();
for( $i = 0 ; $i $nr ; $i ++) <
# $value=getdate(rand($start,$end));
date ( «H:i:s d.m.Y» , rand ( $start , $end ));
>
$end_time = getmicrotime ();

echo «Time: » .( $end_time — $start_time );

// With date_default_timezone_set(): «Time: 0.379343986511»
// Without date_default_timezone_set(): «Time: 7.4971370697»

?>

Note that the timezone is not changed, it is only set again. I really wonder why this makes such a big performance difference, but its good to know.

It’s really a hassle that there is no way to set the timezone offset. I attempted to use the code that searched for the correct timezone name by offset from below. I found it didn’t work reliably since various cities may have different rules about time DST etc. My solution is to actually search the array and do a test to insure the offset is what I expect it to be. It seems very kludgey (if thats a word) but it works.

function setTimezoneByOffset ( $offset )
<
$testTimestamp = time ();
date_default_timezone_set ( ‘UTC’ );
$testLocaltime = localtime ( $testTimestamp , true );
$testHour = $testLocaltime [ ‘tm_hour’ ];

$abbrarray = timezone_abbreviations_list ();
foreach ( $abbrarray as $abbr )
<
//echo $abbr.»
«;
foreach ( $abbr as $city )
<
date_default_timezone_set ( $city [ ‘timezone_id’ ]);
$testLocaltime = localtime ( $testTimestamp , true );
$hour = $testLocaltime [ ‘tm_hour’ ];
$testOffset = $hour — $testHour ;
if( $testOffset == $offset )
<
return true ;
>
>
>
return false ;
>
?>

If you want users to choose their own timezones, here’s some code that gets all available timezones but only uses one city for each possible value:

$cities = array();
foreach( $timezones as $key => $zones )
<
foreach( $zones as $id => $zone )
<
/**
* Only get timezones explicitely not part of «Others».
* @see http://www.php.net/manual/en/timezones.others.php
*/
if ( preg_match ( ‘/^(America|Antartica|Arctic|Asia|Atlantic|Europe|Indian|Pacific)\//’ , $zone [ ‘timezone_id’ ] ) )
$cities [ $zone [ ‘timezone_id’ ]][] = $key ;
>
>

// For each city, have a comma separated list of all possible timezones for that city.
foreach( $cities as $key => $value )
$cities [ $key ] = join ( ‘, ‘ , $value );

// Only keep one city (the first and also most important) for each set of possibilities.
$cities = array_unique ( $cities );

// Sort by area/city name.
ksort ( $cities );

I was having major issues with the date.timezone setting after I updated from 5.3.3 to 5.4.29. I still need to update further, and perhaps it’s a bug in this version that will be fixed when I update..

But to fix the issue of php not being about to find my time zone, I added a .htaccess file to the root of my web directory. All I have in it is this one line (without quotes)

«php_value date.timezone America/Denver»

And now the timezone is set in any directory I browse in. Very strange, and I still haven’t figured out why It wont work from the php.ini file. But here’s how to overcome the frustration.

After poundering and knocking my head on the table, I finally got a proper fix for Windows and PHP timezone handling.

Since Windows applies the DST to ActiveTimeBias in the registry, you only need this to apply.
The only problem is, that it cant use the timezone_set command.

You can request a response back in any date-format you wish, or use the default one given in the function itself.

// Return proper time
function time_zone_fix ( $timeGiven = «H:i:s» )
<
$shell = new COM ( «WScript.Shell» ) or die( «Requires Windows Scripting Host» );
$time_bias = -( $shell -> RegRead ( «HKEY_LOCAL_MACHINE\\SYSTEM\\
CurrentControlSet\\Control\\TimeZoneInformation\\
ActiveTimeBias» )) / 60 ;
$timestamp_bias = 60 * 60 * $time_bias ;
echo $time_bias . «
» ;
return gmdate ( $timeGiven , strtotime ( $timestamp_bias . » seconds» ));
>
?>

I found a need to change the timezone based on a DB record, so it would display properly for each record. So I wrapped some of the other posts into this small class:

class TZStack
<
private $stack = array();
public function __construct ()<>
public function push ( $newTZ )
<
array_push ( $this -> stack , date_default_timezone_get ());
if (isset( $newTZ ) && ( «» != $newTZ ))
<
date_default_timezone_set ( $newTZ );
>
>
public function pop ()
<
if ( count ( $this -> stack ) > 0 )
<
date_default_timezone_set ( array_pop ( $this -> stack ));
>
>
>
// the global TZ stack for the rest of the code to use.
$tzStack = new TZStack ();
// In case I need to know the TZ at the web server. 🙂
$script_tz = date_default_timezone_get ();
?>

Then in my per-record code:

foreach( $records as $item )
<
$tzStack -> push ( $item [ ‘TZ’ ]);
$TZ = date ( «T» , time ());
// code that displays this record, using $TZ.
$tzStack -> pop ();
>
?>

date() [function.date]: It is not safe to rely on the system’s timezone settings. Please use the date.timezone setting, the TZ environment variable or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected ‘America/Los_Angeles’ for ‘PST/-8.0/no DST’ instead

Of course this is a problem that recently surfaced since PHP5. Quick fix is to set your time zone, add this line to your php code:

Most of the scripts here depend on PHP identifying the correct zone when one is not set, but that does not always happen.

For example PHP 5.3.3 gives a ‘UTC’ result for a detected ‘8.0/no DST’. Not much help.

So for those of us who for very good reasons really cannot set time zones in scripts of in .ini files, here is a function
for use in a Windows environment that sets the default time zone to the OS time zone and returns the detected and set texts.

function date_system_timezone_set () <
$shell = new COM ( «WScript.Shell» ) or die( «Requires Windows Scripting Host» );
$time_bias = -( $shell -> RegRead (
«HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control
\\TimeZoneInformation\\Bias» ))/ 60 ;
$ab = -( $shell -> RegRead (
«HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control
\\TimeZoneInformation\\ActiveTimeBias» ))/ 60 ;
$sc = $shell -> RegRead (
«HKEY_USERS\\.DEFAULT\\Control Panel\\International\\sCountry» );
foreach( timezone_abbreviations_list () as $tza ) foreach( $tza as $entry ) <
$country = strtok ( $entry [ ‘timezone_id’ ], ‘/’ );
$locale = strtok ( ‘|’ );
if( $country == $sc && $ab ==( $entry [ ‘offset’ ]/ 60 / 60 ) && ( $ds = $time_bias != $ab )== $entry [ ‘dst’ ]) <
date_default_timezone_set ( $timezone_identifier = $country . «/» . $locale );
return sprintf ( ‘%.1f’ , $ab ). «/» .( $ds ? » : ‘no ‘ ). ‘DST’ . » » . $timezone_identifier ;
>
>
return false ;
>
?>

Regarding my post 3 years before:
The performance impact seems to be caused by the fact that a log message is written if you do not set a timezone. And writing a log message to disk can take significantly longer than actually calculating date() or getdate() — esp. on systems with slow IO like the Windows machine I used 3 years ago.

PHP 4 did not produce any log messages, and therefore was as fast as PHP5 with a timezone set.

So if you run date() or getdate() a lot of times, this will cause a lot of log messages to be written to disk (if you did not disable them in your php.ini settings), which will take its time.

So either use this function or set the ini-setting «date.timezone» to make things faster.
(And have a look into your logfiles! Solving all those warnings will not only save you disk space but will also speed up your web application.)

> I’m sure I’m not the only one who is distressed by the recent default behavior change to E_NOTICE when the timezone isn’t explicitly set in the program or in .ini.

You should always turn on notices and have a customer error handler that converts notices or indeed any PHP message to exceptions.

I’ve been doing this for years and it looks like expanding the use of exceptions in PHP itself is an ongoing process. It’s almost certainly stuck with notices from legacy patterns prior to PHP possessing exception capability with the reason it’s not been thoroughly applied being BC breakage.

Even in my extensions I redirect notices and warnings to exceptions. I’m certain the whole pressure for the ?? operator was to facilitate errors to exceptions as the only real drawback of that is needing to use isset a fair bit more.

Similar for asserts, json, etc, etc it all to use exceptions.

Another note. I profiled my PHP script and it reported that calling this function took half the time. Anyone else got this? Is it really that expensive? Am I doubling init time not having it in php.ini and possibly setting to the timezone it’s already on? Or is it messing with time and breaking the time measurement? One day I’ll bother to wrap it in microtime to try to see.

Note that there may be some unexpected s >
[red. That is only true for the putenv() hack — Derick]

This does indeed include the web server’s logs and other output files and reports which by default usually do not include any indication of timezone. This has a further side-effect on log processing and analysis, obviously.

While it’s easy to change timezones based on names or abbreviations, I haven’t found any straightforward way of doing so using an offset integer. This situation comes up if you’re using AJAX to get information about a user’s timezone; javascript’s getTimezoneOffset() method just sends you an offset number. So, here’s my clunky solution: an adaptation of chris’ function at http://us.php.net/manual/en/function.timezone-name-from-abbr.php.

function set_tz_by_offset ( $offset ) <
$offset = $offset * 60 * 60 ;
$abbrarray = timezone_abbreviations_list ();
foreach ( $abbrarray as $abbr ) <
//echo $abbr.»
«;
foreach ( $abbr as $city ) <
//echo $city[‘offset’].» $offset
«;
if ( $city [ ‘offset’ ] == $offset ) < // remember to multiply $offset by -1 if you're getting it from js
date_default_timezone_set ( $city [ ‘timezone_id’ ]);
return true ;
>
>
>
date_default_timezone_set ( «ust» );
return false ;
>

?>

[EDIT BY thiago AT php DOT net: This code has contributions from iateadonut at gmail dot com]

This is a good script if you know or control your system so that you know that the local TZ in your OS is correct. Unfortunately, this script still creates an warning message under BSD UNIX.

To fix this, just add an «@» in front of «localtime» as:

A simple method for conversation between two time zone.

= new DateTime ( «2012-07-05 16:43:21» , new DateTimeZone ( ‘Europe/Paris’ ));

echo date ( «Y-m-d h:iA» , $date -> format ( ‘U’ ));

источник

Читайте также:  Установка заборов из профлиста бетонирование

Добавить комментарий

Adblock
detector