За время моей работы я достаточно часто занимался инспекцией чужого кода, занимался его поддержкой и модификациями.
В данной статье я решил проанализировать такую вещь, как проверку переменной на непустость
Из всех наблюдаемых мною конструкций можно выделить 3
1) empty($a)
2) $a==' '
3) !$a
Интересно, какой из этих методов более быстрый.
Ниже я привожу код теста, предполагается, что переменная $a существует, а функция gettime возвращает текущее время с точностью функции microtime
define ('Count',10000000);
$v=gettime();
for($i=0;$i[=Count;++$i)
if (empty($a))
{
}
echo ((gettime()-$v))."\n";
$v=gettime();
for($i=0;$i[=Count;++$i)
if ($a==''))
{
}
echo ((gettime()-$v))."\n";
$v=gettime();
for($i=0;$i[=Count;++$i)
if (!$a)
{
}
echo ((gettime()-$v))."\n";
Результат вполне ожидаемый.
1) 4,39
2) 4,87
3) 3,79
Операция логического отрицания быстрее, чем вызов встроенной функции проверки на пустоту и операции сравнения.
Однако не стоит забывать, что такое расхождение на 10 млн. итераций.
11 May 2008
08 May 2008
UTF и fgetcsv
Разбирая на досуге очередной csv-файл с данными в кодировке UTF-8, я столкнулся с проблемой. При нахождении в строке русских букв, мне выдавалось пустое значение, в тоже время для английских букв было все нормально.
Так как я раньше работал с csv-файлами, исключительно для рабочих нужд и на Windows-платформе, я никогда с таким поведением не сталкивался.
Ответ на данный вопрос был в самом конце описания функции fgetcsv.Функция принимает во внимание настройки локали
Однако как правильно установить локаль для целей разбора файла, если в csv-файле может быть символы из разных алфавитов, я использовал en_US.UTF-8 и все заработало
Так как я раньше работал с csv-файлами, исключительно для рабочих нужд и на Windows-платформе, я никогда с таким поведением не сталкивался.
Ответ на данный вопрос был в самом конце описания функции fgetcsv.Функция принимает во внимание настройки локали
Однако как правильно установить локаль для целей разбора файла, если в csv-файле может быть символы из разных алфавитов, я использовал en_US.UTF-8 и все заработало
Работа с временными зонами в PHP
Как только проект перестает быть завязан на ограниченное количество потребителей и растет география его применения, встает вопрос о применении временных зон. Когда я работал в одной известной интернет компании внедрение в работу временных зон (как в интерфейс отображения статистики, так и в программу анализа) было достаточно серьезным шагом. Поэтому я думаю всем будет интересно узнать, как же внедрить поддержку временных зон в свой проект.
Далее следует перевод статьи одного из разработчиков языка PHP Derick Rethans. Оригинал статьи может быть найден по следующей ссылке http://www.derickrethans.nl/talks.php
Содержание
Проблемы временных зон
Проблемы перевода времени
Другие проблемы временных зон и «перевода стрелок»
Проблемы в наименовании временных зон
Проблемы в представлении даты и времени
Функции в php 4 и php 5 для работы с временем и датами
Ограничения работы с датами
Улучшения работы с датами в php 5.1 и выше
Форматы данных в php 5.1 и выше
Американский формат: 9/11;4:08 pm;12/22/78; 8:51:00 am
Комбинированный формат: Sat, 24 Apr 2004 21:48:40 +0200; 2001-11-29T13:20:01.123-05:00
Описательный формат: tomorrow; four months ago; last saturday; +20 days 2 hours
Текстовый формат: December 22. 1978; 22-december-1978
Все ISO 8601 форматы: 1978/12/22; 13:03:12.45678; 13:03:12.45678 +0100; 15:57-8; 1978-12-22; 15:57:41 pdt; 13:03:12.45678 CEST; 231431 CEST; 70-4-25; 13:03 CEST; 04:05 -0930; 23:41F
Форматы баз данных: 1999-Jan-08; 1999.238
Поддержка временных зон в php 5.1 и выше
Поддержка временных зон. Как использовать?
Изменение информации по временным зонам
Разбор дат (прошлое)
Разбор строки с информации о дате и времени используя функцию strtotime
Использование инициализации таймстампом
Возвращаемое значение представляет собой 32-битное целое
Разбор дат (будущее)
Разбор строки, содержащей информацию о дате и времени, используя функцию date_create
«$ts=date_create("1978-12-22 09:15:50");»
В качестве альтернативы можно сосздать объект типа DateTime
Эти функции уже не используют 32-битное целое, они возвращают объект класса DateTime, который является оберткой над 64-битным целым, для доступа к которому следует использовать следующую конструкцию
Формат дат
Все модификаторы форматов, поддерживаемые функцией date, поддерживаются тоже
Предопределенные форматы:
Локали в php6
Обновление даты и времени
Изменение даты и времени
Использование временных зон
Установка сокращенного названия временной зоны при разборе даты
Использование аббревиатур временных зон признано устаревшим, необходимо установить временную зону по умолчанию или полный идентификатор временной зоны
Временная зона по умолчанию
Установка временной зоны по умолчанию
Получение временной зоны по умолчанию
Временная зона по умолчанию определяется в соответствии с
Использование временных зон. Объект временная зона
Создание временной зоны
Использование временной зоны при разборе строкового представления
Использование временной зоны в качестве аргумента функций не перекрывает временную зону, указанную в разбираемой строке
Получение названия временной зоны
Получение текущего смещения от Гринвича
Использование временных зон. Изменение временной зоны
Использование временной зоны при разборе строкового представления
Таблицы перевода времени
Аббревиатуры и идентификаторы
Получение всех поддерживаемыех идентификаторов
Получение всех поддерживаемых аббревиатур
Перевод стрелок. Когда будет следующий?
Когда появится данная функциональность
В php 5.1 необходимо скомпилировать, используя флаг CFLAGS=-DEXPERIMENTAL_DATE_SUPPORT=1
В php 5.2 и выше по умолчанию
Далее следует перевод статьи одного из разработчиков языка PHP Derick Rethans. Оригинал статьи может быть найден по следующей ссылке http://www.derickrethans.nl/talks.php
Содержание
- Проблемы временных зон
- Проблемы перевода времени
- Другие проблемы временных зон и «перевода стрелок»
- Проблемы в наименовании временных зон
- Проблемы в представлении даты и времени
- Функции в php 4 и php 5 для работы с временем и датами
- Ограничения работы с датами
- Улучшения работы с датами в php 5.1 и выше
- Форматы данных в php 5.1 и выше
- Поддержка временных зон в php 5.1 и выше
- Поддержка временных зон. Как использовать?
- Изменение информации по временным зонам
- Разбор дат (прошлое)
- Разбор дат (будущее)
- Разбор строки, используя функцию date_parse
- Формат дат
- Локали в php6
- Обновление даты и времени
- Изменение даты и времени
- Использование временных зон
- Временная зона по умолчанию
- Использование временных зон. Объект временная зона
- Использование временных зон. Изменение временной зоны
- Таблицы перевода времени
- Аббревиатуры и идентификаторы
- Перевод стрелок. Когда будет следующий?
- Когда появится данная функциональность
Проблемы временных зон
- Большинство мест на земле имеют часовое смещение
- Некоторые места имеют получасовое или пятнадцати-минутное временное смещение
- В некоторых местах временная зона меняется в течении года
Проблемы перевода времени
- Множество стран переводит время дабы увеличить продолжительность светлой части суток
- Это делают не во всех странах
- Перевод часов происходит в разное время
- Существует большое количество исключений
Другие проблемы временных зон и «перевода стрелок»
- В Австралии зоны строго вертикальные
- В Бразилии дата, когда переводят срелки, меняется каждый год
- На остров Lord Howe (Австралия) переводят стрелки только на почаса
- Непал переводит стрелки на 15 минут
Проблемы в наименовании временных зон
- Одно именование может означать разные временные зоны:
Например:PST - Pacific Standart Time и Pakistan Standart Time
EST - Easten Standart Time (США), Easten Standart Time (Австралия) и Easten Brazil Standart Time - Одна зона может иметь несколько наименований Например:Central Europe Standart Time - CEST или CETDST
Проблемы в представлении даты и времени
- Двусмысленность
06/08/04
6 Августа 2004 года
8 Июня 2004 года
4 Августа 2006 - Нечитаемость
20040425010541
25 Апреля 2004 года 01:05:41 - Другие «магические» форматы
third saturday
2004-03-10 16:33:17.11403+1
2001-11-29T13:20:01.123-05:00
23:41:00.0Z
04:05:07.789 +0930
1999.238
Функции в php 4 и php 5 для работы с временем и датами
- checkdate - Проверяет правильность даты по грегорианскому календарю
- date(gmdate) - Форматирует системную дату/время (по Гринвичу)
- getdate - Возвращает информацию о дате/времени
- gettimeofday - Возвращает текущее время
- localtime - Возвращает системное время
- mktime(gmmktime) - Возвращает метку времени для заданной даты (по Гринвичу)
- strftime(gmstrftime) - Форматирует дату/время с учетом текущей локали (по Гринвичу)
- strtotime — Преобразует текстовое представление даты на английском языке в метку времени Unix
Ограничения работы с датами
- Использование Unix-таймстампа в качестве базы (количество секунд, прошедшее с 1 января 1970 года по Гринвичу)
- Таймстамп представляется ввиде 32-битного целого, что ограничивает использование данного представления диапазоном 1902-2038 годами
- На многих операционных системах данный тип может быть только положительным, ограничение диапазона 1970-2038
- strtotime - достачно сложная функция, реализация которой подвержена большим количеством ошибок
- Нет вариантов корректной работы с временными зонами
- Некоторые функции являются зависимыми от операционной системы
Улучшения работы с датами в php 5.1 и выше
- Использование 64-битного типа для хранения даты. Теперь граница интервала использования данного типа 4 Декабря 292277026596 год
- Функция strtorime была переписана
- Больше нет зависимости в реализации от операционной системы
- Полная поддержка временных зон, перевода часов и модификаторов дат
- Новый формат модификаторов временных зон
- Более продвинутые функции для работы с датами
Форматы данных в php 5.1 и выше
Американский формат: 9/11;4:08 pm;12/22/78; 8:51:00 am
Комбинированный формат: Sat, 24 Apr 2004 21:48:40 +0200; 2001-11-29T13:20:01.123-05:00
Описательный формат: tomorrow; four months ago; last saturday; +20 days 2 hours
Текстовый формат: December 22. 1978; 22-december-1978
Все ISO 8601 форматы: 1978/12/22; 13:03:12.45678; 13:03:12.45678 +0100; 15:57-8; 1978-12-22; 15:57:41 pdt; 13:03:12.45678 CEST; 231431 CEST; 70-4-25; 13:03 CEST; 04:05 -0930; 23:41F
Форматы баз данных: 1999-Jan-08; 1999.238
Поддержка временных зон в php 5.1 и выше
- Встроенная база на 551 временную зону
- Нет зависимости от аббревиатуры временной зоны
- Названия временных зон имеют формат - Continent/Location или Continent/Location/Sublocation
Поддержка временных зон. Как использовать?
- Каждая временная зона идентифицируется городом с наибольшим населением на данной территории
- Зоны разделены на 10 больших групп: Африка, Америка, Антарктика, Арктика, Азия,Европа,Индия,Тихий океан
- Существует также группа Другие, состоящая из вышедших из употребления названий и служащая для обеспечения обратной совместимости
- Больше информации по аббревиатурам временных зон по указанному адресу
Изменение информации по временным зонам
- Обновления информации по временным зонам происходят около 20 раз в год
- Большинство обновлений происходят неожиданно
- Чтобы не потерять актуальность, релизы php должны быть достаточно часты
- Расширение pecl, которое исправляет данные недостатки, называется timezonedb (pecl install timezonedb)
Разбор дат (прошлое)
Разбор строки с информации о дате и времени используя функцию strtotime
$ts=strtotime("2005-07-11 22:16:50 CEST");
Использование инициализации таймстампом
$date=strtotime("2005-07-11 22:16:50 CEST");
$ts=strtotime("next week",$date);
Возвращаемое значение представляет собой 32-битное целое
Разбор дат (будущее)
Разбор строки, содержащей информацию о дате и времени, используя функцию date_create
«$ts=date_create("1978-12-22 09:15:50");»
В качестве альтернативы можно сосздать объект типа DateTime
$ts=new DateTime("1978-12-22 09:15:50");
Эти функции уже не используют 32-битное целое, они возвращают объект класса DateTime, который является оберткой над 64-битным целым, для доступа к которому следует использовать следующую конструкцию
$ts=new DateTime("1978-12-22 09:15:50");Разбор строки, используя функцию date_parse
echo $ts->format('U');
$date="22apr2006 8:36:14.43 #^ Europe/Oslo CEST";
$t=date_parse($date);
echo $t['year'].'-'.$t['month'].'-'.$t['date'].' ';
echo $t['hour'].':'.$t['minute'].':'.$t['second'].' ';
echo $t['tz_id']."\n";
Формат дат
date_default_timezone_set("Europe/Oslo");
$ts=date_create("1979-12-31 09:15");
echo date_format($ts,"D Y-m-d H:i:s -\I\S\O \W/\Y: W/o");
Все модификаторы форматов, поддерживаемые функцией date, поддерживаются тоже
Предопределенные форматы:
date_default_timezone_set("Europe/Oslo");
$ts=date_create("December 22nd, 2005 15:41");
echo date_format($ts, DATE_ISO8601);
echo date_format($ts, DateTime::RFC1036);
echo date_format($ts, DATE_RSS);
Локали в php6
date_default_timezone_set("Europe/Oslo");
$ts=date_create("December 22nd, 2005 15:41");
$locales=array('en_US','fr_CA','nb_NO','ru_RU','ar_SA','ja_JP');
foreach($locales as $locale)
{
locale_set_default($locale);
echo date_format_locale($ts,DATE_RFC2822)."\n";
}
Обновление даты и времени
$date=new DateTime('now');
echo $date->format(DateTime::ISO8601)."\n";
$date->setTime(15,0,7);
echo $date->format(DateTime::ISO8601)."\n";
$date->setDate(2006,12,22);
echo $date->format(DateTime::ISO8601)."\n";
$date->setIsoDate(2006,45,2);
echo $date->format(DateTime::ISO8601)."\n";
Изменение даты и времени
date_default_timezone_set("Europe/Oslo");
$date=new DateTime('now');
echo $ts->format(DATE_RFC2822)."\n";
$ts->modify("+2 days");
echo $ts->format(DATE_RFC2822)."\n";
$ts->modify("fifth month");
echo $ts->format(DATE_RFC2822)."\n";
$ts->modify("Friday +3 weeks");
echo $ts->format(DATE_RFC2822)."\n";
$ts->modify("next friday");
echo $ts->format(DATE_RFC2822)."\n";
Использование временных зон
Установка сокращенного названия временной зоны при разборе даты
$ts=date_create("1978-12-22 09:15 CEST");
Использование аббревиатур временных зон признано устаревшим, необходимо установить временную зону по умолчанию или полный идентификатор временной зоны
$ts=date_create("1978-12-22 09:15 Europe/Oslo")
Временная зона по умолчанию
Установка временной зоны по умолчанию
date_default_timezone_set("Europe/Oslo");
$ts=date_create("1978-12-22 09:15");
echo $ts->format('e');
Получение временной зоны по умолчанию
echo date_default_timezone_get();
Временная зона по умолчанию определяется в соответствии с
- значением установленным функцией date_default_timezone_set()
- переменной окружения TZ
- значением date.timezone в php.ini
- системным отображением сокращения имени временной зоны
Использование временных зон. Объект временная зона
Создание временной зоны
$tz=timezone_open('Asia/Singapore');
Использование временной зоны при разборе строкового представления
$tz=timezone_open('Pacific/Honolulu');
$ts=date_create("1978-12-22 09:15',$tz);
Использование временной зоны в качестве аргумента функций не перекрывает временную зону, указанную в разбираемой строке
$tz=new DateTimeZone('Pacific/Honolulu');
$ts1=new DateTime('1978-12-22 09:15 CEST',$tz);
$ts2=new DateTime('1978-12-22 09:15 Europe/Amsterdam',$tz);
echo $ts2->format(DateTime::RFC2822);
Получение названия временной зоны
$tz=timezone_open('Asia/Singapore');
echo timezone_name_get($tz);
$tz=timezone_open('CEST');
echo timezone_name_get($tz);
Получение текущего смещения от Гринвича
$tz=new DateTimeZone("Europe/Amsterdam");
$d=new DateTime("2005-01-22 09:15");
echo $tz->getOffset($d);
$d->modify("+6 months");
echo $tz->getOffset($d);
Использование временных зон. Изменение временной зоны
Использование временной зоны при разборе строкового представления
$tz1=timezone_open('Pacisic/Honolulu');
$tz2=timezone_open('Europe/Amsterdam');
$tz3=timezone_open('Australia/Melbourne');
$ts=date_create("1978-12-22 09:15",$tz1);
echo $ts->getTimezone()->getName().':'.$ts->format(DATE_RFC822)."\n";
$ts->setTimezone($tz2);
echo $ts->getTimezone()->getName().':'.$ts->format(DATE_RFC822)."\n";
$ts->setTimezone($tz3);
echo $ts->getTimezone()->getName().':'.$ts->format(DATE_RFC822)."\n";
Таблицы перевода времени
$tz=timezone_open('Europe/Amsterdam');
$trs=timezone_transitions_get($tz); // или $trs=$tz->getTransitions();
foreach($trs as $ts)
printf("%20s %7d %d %s\n",$tr['time'],$tr['offset'],$tr['isdst'],$tr['abbr']);
Аббревиатуры и идентификаторы
Получение всех поддерживаемыех идентификаторов
$ids = timezone_identifiers_list();
echo "Number of identifiers: ".count($ids)."\n";
echo implode(", ", array_slice($ids, 0, 5)).'...'.implode(", ", array_slice($ids, -5));
Получение всех поддерживаемых аббревиатур
$abbrs = timezone_abbreviations_list();
foreach ($abbrs as $abbr => $ids)
foreach ($ids as $id)
printf("%-6s %6d %d %s\n", strtoupper($abbr),$id['offset'],$id['dst'], $id['timezone_id']);
Перевод стрелок. Когда будет следующий?
date_default_timezone_set("America/New_york");
$tz = new DateTimeZone("America/New_york");
foreach (timezone_transitions_get($tz) as $tr)
if ($tr['ts'] > time()) break;
$d = new DateTime( "@{$tr['ts']}" );
printf("The timezone %s switches to %s on %s.\nThe new GMT offset will be: %d (%s)\n", $tz->getName(), $tr['isdst'] ? "DST" : "standard time", $d->format('d M Y @ H:i T'), $tr['offset'], $tr['abbr']);
Когда появится данная функциональность
В php 5.1 необходимо скомпилировать, используя флаг CFLAGS=-DEXPERIMENTAL_DATE_SUPPORT=1
В php 5.2 и выше по умолчанию
Subscribe to:
Posts (Atom)