Jump to content

Вывод даты в PHP


Veseloff
 Share

Recommended Posts

Так порой случается, что необходимо в PHP сформировать «человекопонятную» дату. То есть что-то в виде «4 февраля 2010 14:35:48». Представим, что у нас есть какие-то новости на сайте и у этих новостей должна быть дата, когда новость была добавлена. Новости хранятся в БД MySQL. Наиболее подходящий, как я раньше считал, для преобразования даты вариант хранениея: UNIX_TIMESTAMP в поле типа INT, так как, если бы это был DATETIME, то перед преобразованием даты при помощи функции PHP date(), нам бы приходилось делать strtotime(). Однажды оказалось, что следующая конструкция отнимает слишком много времени:

$months=array('01'=>'января', '02'=>'февраля', '03'=>'марта', '04'=>'апреля', '05'=>'мая', '06'=>'июня', '07'=>'июля', '08'=>'августа', '09'=>'сентября', '10'=>'октября', '11'=>'ноября', '12'=>'декабря');
$t=date('j '.$months[date('m', $date)].' Y H:i:s', $date);

Были разные предположения, даже такое, что date «спотыкается» на незнакомых функции русских символах, но следующий вариант только ухудшил ситуацию:

$t=date('j ', $date).$months[date('m', $date)].date(' Y H:i:s', $date);

В принципе, логично — функция date используется не два, а три раза. Но зато стало понятно, что функция никак не реагирует на незнакомые символы — она просто медленная сама по себе. После длительного раздумья и перебора всех возможных и невозможных вариантов, пришёл к несколько нестандартному решению, которое оказалось очень даже хорошим. Вместо UNIX_TIMESTAMP используем тип поля DATETIME и NOW() для заполнения, а для формирования даты делаем так:

$months=array('01'=>'января', '02'=>'февраля', '03'=>'марта', '04'=>'апреля', '05'=>'мая', '06'=>'июня', '07'=>'июля', '08'=>'августа', '09'=>'сентября', '10'=>'октября', '11'=>'ноября', '12'=>'декабря');
$t=preg_replace('~(\d{4})-(\d{2})-(0(\d)|([^0]\d)) (\d{2}):(\d{2}):(\d{2})~e', '"\\4\\5 ".$months["\\2"]." \\1 \\6:\\7:\\8"', $date);

Вот такое вот интересное решение. Пользуйтесь.

Link to comment
Share on other sites

Я вот на днях накалякал код.

Задача была такой (сам придумал) , выводить если опубликовано сегодня, то вывод сегодня в 21:00;

если вчера, то вчера в 21:00

если в этом году, то 31 января в 21:00

если не в этом году, то 31 января 2010 в 21:00

// сперва надо, что б отображался месяц на русском и в родительном падеже
// для этого создаём массив

$mese[0]="";
$mese[1]="Января";
$mese[2]="Февраля";
$mese[3]="Марта";
$mese[4]="Апреля";
$mese[5]="Мая";
$mese[6]="Июня";
$mese[7]="Июля";
$mese[8]="Августа";
$mese[9]="Семпября";
$mese[10]="Октября";
$mese[11]="Ноября";
$mese[12]="Декабря";

$mesyac = (int)date("m");

$date = date("j")." ".$mese[$mesyac]; // дата, которая пойдёт в БД, выглядеть должна "31 января"
$time = date("G:i", (time()+2000)); // время, 21:00
$year = date("Y"); // год, 2010

$today = date("j", (time()+2000))." ".$mese[$mesyac]; // "сегодня"
$yesterday = date("j", (time()-3600*24+2000))." ".$mese[$mesyac]; // "вчера"
$thisyear = date("Y"); // "этот год"

//из базы данных уже всё извлечено

$d = $ro['data'];
$t = $ro['vremya'];
$y = $ro['year'];
if($d == $today){$time = "сегодня в ".$t;} // если дата из БД совпадает с сегодняшней, то будет писаться "сегодня в 21:00"
if($d == $yesterday){$time = "вчера в ".$t;} // аналогично строчке выше
if($d != $today && $d != $yesterday && $y == $thisyear){$time = $d." в ".$t;} // если в этом году, будет писаться "31 января в 21:00"
if($d != $today && $d != $yesterday && $y != $thisyear){$time = $d." ".$y." в ".$t;} // если и не в этом году, то полным "31 января 2010 в 21:00"

и в нужном месте вставляем

".$time."

И вот мне интересно, на сколько хороший говнокод я придумал?=)

Link to comment
Share on other sites

Отвратительно. Начиная с заполнения массива (зачем лишний элемент, да и как-то неаккуратненько), заканчивая логикой. У меня был задача избвится от функции date, так как она медленная, а тут она используется СЕМЬ раз. Жуть какая-то. Переделать однозначно.

Link to comment
Share on other sites

Не знаю даже. Возможно, что и так. Надо по ситуации смотреть — насколько быстро strtotime работает, как именно будем считать сегодня-завтра ну и так далее

Link to comment
Share on other sites

У меня был задача избвится от функции date, так как она медленная

медленная в каком смысле? медленно синхронизируется с системным временем? или медленно делает запрос?

Link to comment
Share on other sites

медленная в каком смысле? медленно синхронизируется с системным временем? или медленно делает запрос?

Медленно работает. Первый вариант медленнее последнего примерно в 4 раза.

Link to comment
Share on other sites

какое-то не нужное "решение", то что хранить в int это удобно и экономно вы можете преобразовывать дату как хотите , то есть у вас есть гибкость настроек (можно показывать дату в зависимости от часового полюса и т.д.).А если вам это не нужно, зачем тогда в таком виде хранить не легче и быстрей будет тупо при добавлении этой новости в базу вбивать 21 января 2010 11:03

Edited by gradus
Link to comment
Share on other sites

да и кстати откуда вы такую информацию взяли что ваш вариант быстрей работает чем date не понятно:

$months=array('01'=>'января', '02'=>'февраля', '03'=>'марта', '04'=>'апреля', '05'=>'мая', '06'=>'июня', '07'=>'июля', '08'=>'августа', '09'=>'сентября', '10'=>'октября', '11'=>'ноября', '12'=>'декабря');
$date=date('Y-m-d H:i:s');
$date2=time();
$m = microtime(1);

$t=preg_replace('~(\d{4})-(\d{2})-(0(\d)|([^0]\d)) (\d{2}):(\d{2}):(\d{2})~e', '"\\4\\5 ".$months["\\2"]." \\1 \\6:\\7:\\8"', $date);

print (microtime(1) - $m.'<br>');

$m = microtime(1);

$t=date('j '.$months[date('m', $date2)].' Y H:i:s', $date2);

print (microtime(1) - $m.'<br>');

результат:

7.5101852417E-5 //время затраченное на выполнение вашего варианта

0.000249862670898 // время затраченное на выполнение варианта от date

Edited by gradus
Link to comment
Share on other sites

$a=7.5101852417E-5;
$b=0.000249862670898;
echo $b/$a; // 3.326984126978

Не понял, в чём вопрос. Действительно быстрее. В данном случае в 3 с лишним раза.

скорей в 30' 000 раз быстрей :)

на сколько надо умножить $b что бы получить результат $a = во сколько раз $b быстрей $a

$b*30000 $a

Edited by gradus
Link to comment
Share on other sites

скорей в 30' 000 раз быстрей :)

на сколько надо умножить $b что бы получить результат $a = во сколько раз $b быстрей $a

$b*30000 $a

E-5 - это умножить на 10 в минус пятой степени

и того: $a = 7.5101852417E-5 = 0.000075101852417;

$b=0.000249862670898;

Считать где учились ?

Link to comment
Share on other sites

скорей в 30' 000 раз быстрей :)

на сколько надо умножить $b что бы получить результат $a = во сколько раз $b быстрей $a

$b*30000 $a

http://ru.wikipedia.org/wiki/%D0%A7%D0%B8%...%82%D0%BE%D0%B9

Кстати, для чистоты эксперимента надо такие вещи проверять на большем количестве итераций. Хотя бы на миллионе. А то разница чрезвычайно мала и даже вызов microtime может создать очень большую погрешность. Например, у меня на рабочей машине ваш код выдаёт соотношение примерно 1/1.3, что не совсем верно.

Link to comment
Share on other sites

хех не усмотрел E-5, зрением основывался на первые целые числа :)

что ж сразу грязью то...

p.s. ну на моей машине всегда date выдаёт меньшее число даже если местами поменять с preg

Edited by gradus
Link to comment
Share on other sites

хех не усмотрел E-5, зрением основывался на первые целые числа :)

что ж сразу грязью то...

Для любого программиста это epic fail, после которого стоит задуматься о смене професии :)

p.s. ну на моей машине всегда date выдаёт меньшее число даже если местами поменять с preg

Да ладно? А что выдаст вам вот такой код:

#!/usr/bin/php
<?php
system('clear');
$dat1='2011-02-09 20:08:11';
$dat2=1297264091;


$months=array('01'=>'января', '02'=>'февраля', '03'=>'марта', '04'=>'апреля', '05'=>'мая', '06'=>'июня', '07'=>'июля', '08'=>'августа', '09'=>'сентября', '10'=>'октября', '11'=>'ноября', '12'=>'декабря');

$time=microtime(1);

for($s=0; $s<=10000; $s++)
$t=date('j '.$months[date('m', $dat2)].' Y H:i:s', $dat2);

echo (microtime(1)-$time)."\r\n";

$time=microtime(1);

for($s=0; $s<=10000; $s++)
$t=preg_replace('~(\d{4})-(\d{2})-(0(\d)|([^0]\d)) (\d{2}):(\d{2}):(\d{2})~e', '"\\4\\5 ".$months["\\2"]." \\1 \\6:\\7:\\8"', $dat1);

echo (microtime(1)-$time)."\r\n";

Link to comment
Share on other sites

Для любого программиста это epic fail, после которого стоит задуматься о смене професии :)

ой не надо ладно, каждый ошибается особенно часто это делают программисты.Любой делал ошибки в программировании и куда хуже чем эта) тем более суть не изменилась, в работе я бы увидел этот не до чёт ,а тут не такой уж и внимательный :) да и профессия у меня другая :)

Да ладно? А что выдаст вам вот такой код:

странно, но сомневаюсь что ключом является погрешность microtime

Edited by gradus
Link to comment
Share on other sites

странно, но сомневаюсь что ключом является погрешность microtime

Зря сомневаетесь. Во-первых, microtime — функция и для её вызова, выполнения и принятия возвращаемого значения нужно время. Во-вторых, производится математическая операция «вычитание».

$t=microtime(1);
$a=microtime(1)-$t;
$b=microtime(1)-$t;
echo ($b-$a)*10000;

Вот этот код раз от раза будет выдавать вам разные результаты.

Link to comment
Share on other sites

Да не будет date быстрее. У меня хоть куда его ставь он всё равно медленнее работает: и на сервере, и на рабочем десктопе, и на домашнем, и на ноуте. Ну никак не быстрее. Да и те результаты, которые вы привели говорят о том, что я прав и date никак не быстрее. Не понимаю зачем спроить, если всё очевидно.

Link to comment
Share on other sites

Да и те результаты, которые вы привели говорят о том, что я прав и date никак не быстрее.

как-то вы противоречите себе

$a=7.5101852417E-5;

$b=0.000249862670898;

echo $b/$a; // 3.326984126978

Действительно быстрее. В данном случае в 3 с лишним раза.

Не понимаю зачем спроить, если всё очевидно.

разве это спор ? по моему щас ищем почему date быстрей в единичном использовании и уступает preg в цикле.Ну по крайней мере на моей машине так...

Link to comment
Share on other sites

Так ещё раз.

7.5101852417E-5 //время затраченное на выполнение вашего варианта

0.000249862670898 // время затраченное на выполнение варианта от date

Британскми учёными доказано, что 7.5101852417E-5 меньше, чем 0.000249862670898. То есть мой скрипт выполнился быстрее. Логика ясна? Меньше времени на выполнение означает, что скрипт работает быстрее. Вы сами написали, что мой скрипт выполнился быстрее. То, что я написал «действительно быстрее» означает, что мой вариант отработал быстрее. Я даже привёл доказательства. Я присвои переменной $a значение 7.5101852417E-5, а переменной $b значение 0.000249862670898. Потом я разделил $b на $a и у меня получился результат больше единицы. Это значит, что $b>$a. Ещё нужно объяснять, что мой вариант быстрее при любых раскладках?

Link to comment
Share on other sites

  • 9 months later...

как вывести блок, сделанный в views, в какой-нибудь ноде? Делаю так для теста:

<?php

block = module_invoke'views' ,'block', 'view', 'block_name';

print_rblock;

?>

Но ничего...

При чём тут вывод даты? Что это вообще?

Link to comment
Share on other sites

  • 5 weeks later...

Прочитал внимательно ФАК, но это подходит для выводимой даты в новостях. А у меня функция date находится в шаблоне. А параметры выводы 'l', 'd', 'S' и т.п. только для английских дней и мес.

Тоесть echo "<span>".date 'l'."</span>"; выводит день недели на английском

A - полное название дня недели в текущей локали

Если же поставить echo "<span>".date 'A'."</span>";

A - верхний регистр, выводит PM или AM, в зависимости от времени. "AM" или "PM"

Как быть?

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue. See more about our Guidelines and Privacy Policy