На колко години месеци и дни си

dakata__92

Super Moderator
Нещо забих тотално. Търся си прост код с който да калкулирам някой на колко години е с точност месеци и дни. Примерно имам датата
2015 03 19 - 1993 02 17 = 22 01 02.
Искам да е възможно най-сбито и упростено но се сещам само за някакви така по-обемни функции а не са ми нужни. Не се сещам как точно да го направя в момента. :)
 
Fakeheal каза:
Използвай DateTime класа и diff метода на php:

Код:
$date = new DateTime('1995-03-13'); //или 13-03-1995
$now = new DateTime();
$interval = $now->diff($date);
echo $interval->y;

http://php.net/manual/en/datetime.diff.php
Няма ли друг варянт? Не ми се правят две напразни инстанции на класове само заради гъзарийката ми. Принципно става и е правилен варянта ти за което благодаря но процедурен код търся.
 
Справих се. Ако може да го скъсим някак ще съм благодарен.
PHP:
$ageY = date("Y")-intval($yyyy);
			$ageM = date("n")-intval($mm);
			$ageD = date("j")-intval($dd);
			if($ageD < 0){
				$ageD = $ageD += date("t");
				$ageM--;
			}
			if($ageM < 0){
				$ageM+=12;
				$ageY--;
			}
			$age = $ageY."/".$ageM."/".$ageD;
:)
 
Защо да правим нещо както трябва, щом можем да нацвъкаме някаква глупост :)
 
lamerko каза:
Защо да правим нещо както трябва, щом можем да нацвъкаме някаква глупост :)
Защото ако гониш производителност ще разбереш колко забавят инстанциите и зареждането в паметта при голям брой интерации в цикъл. Защотото ако имам 5000 интерации на цикъла горният код е по-бърз от създаването на две ненужни инстанции. Не е въпроса в писането на кода знам, че нейният варянт е правилен и то много повече спрямо моят но все пак е по-бавен заради зареждането на ненужни методи в паметта.
 
dakata__92 каза:
lamerko каза:
Защо да правим нещо както трябва, щом можем да нацвъкаме някаква глупост :)
Защото ако гониш производителност ще разбереш колко забавят инстанциите и зареждането в паметта при голям брой интерации в цикъл. Защотото ако имам 5000 интерации на цикъла горният код е по-бърз от създаването на две ненужни инстанции. Не е въпроса в писането на кода знам, че нейният варянт е правилен и то много повече спрямо моят но все пак е по-бавен заради зареждането на ненужни методи в паметта.

Искаш да кажеш, че всеки голям проект (те очевидно гонят производителност, иначе не им е на далаверка), не използват обекти и като цяло нямат взимане-даване с ООП, за да са бързи?

Относно примера ти:

"Защотото ако имам 5000 интерации на цикъла горният код е по-бърз от създаването на две ненужни инстанции."

Вкарай малко логика. Защо 5000 пъти ще създаваш new DateTime(); (за сегашната дата)? Смяташ години, не часове, не секунди. Цикъла ти и половин ден да върви (poor you), надали ще изкара нещо невярно.

Обектите не са нещо, което е измислено да ти твари кода и да ти се мотка само пред очите. ООП е нещо супер мощно, логично и добронамерено. :p
 
Нямам нищо против ООП. Кодът ми е обектно ориентиран просто в метода който съм създал искам да използвам процедурен код. С microtime виждам за какво време се зареждат нещата. Когато ползвам в логиката твоят код дори теста да е както казваш ти "Защо 5000 пъти ще създаваш new DateTime(); (за сегашната дата)? "пак се бави повече спрямо процедурното решение което съм задал. Извинявам се но ако търся производителност в точно определен метод съставляващ 75 - 80 процента от приложението на обектноориентиран код който бива викан от незнайно къде да обработва и изчислява количество информация на база даден ключ в моят случай това грубо решение което подадох е по-бързо спрямо интерационната промяна на датата и зареждането в паметта на още допълнителни методи при инициализацията. Тоест просто казано пълня паметта с http://bg2.php.net/manual/en/class.datetime.php ето тази ненужна логика когато ми трябват прости процедурни решения. Няма защо да влизаме в дълбочина аз съм привърженик на ООП! Просто случаят ми е такъв и търся процедурно решение на проблема. :) Ако е възможно горният код да бъде подобрен ще съм много благодарен и опростен. :) :?:
 
Просто сравни времената при 5000 интерации без голяма логика и се увери сама. Като цяло разликата е никаква но в приложението се усеща веднага.
PHP:
<meta http-equiv='Content-Type' content='text/html; charset= utf-8' />
<?php
$time_start = microtime(true);
for($i=0;$i<5000;$i++){
$ageY = date("Y")-1993;
$ageM = date("n")-11;
$ageD = date("j")-17;
if($ageD < 0){
    $ageD = $ageD += date("t");
    $ageM--;
}
if($ageM < 0){
    $ageM+=12;
    $ageY--;
}
$age = $ageY."/".$ageM."/".$ageD;

}
$time_end = microtime(true);
$time = $time_end - $time_start;
echo "<br><center>Време ".$time."</center>";
?>
сравни го с
PHP:
<meta http-equiv='Content-Type' content='text/html; charset= utf-8' />
<?php
$time_start = microtime(true);
$date = new DateTime('1993-11-17');
for($i=0;$i<5000;$i++){
	$now = new DateTime();
	$interval = $now->diff($date);
	$age = $interval->y.$interval->m.$interval->d;
}
$time_end = microtime(true);
$time = $time_end - $time_start;
echo "<br><center>Време ".$time."</center>";
?>
 
Твърдението ти много ме заинтригува и реших да пробвам кода, който си дал. Направих няколко промени:
Код:
$date = new DateTime('1993-11-17');
for($i=0;$i<5000;$i++){
	$now = new DateTime();

1.Предполагам че си разменил местата на $now и $date - няма смисъл да правиш now винаги (но дори и да не е така разлика няма - опитах)

2. 5000 е изключително малко за подобен тест, така не проверяваш скоростта на твоя код а на php, кешове, оптимизации и т.н. Направих го 50000

Код: http://pastebin.com/M6SbgP5E
Резултати с Xeon E3-1241 и PHP 5.3.10 (много стара версия!) без опкод кеш.

Код:
time classes: 0.39952707290649
time functions: 0.50110602378845
time classes no gc: 0.38848996162415

Никога не трябва да спираш gc в истински код, направих го от интерес - разликата е почти никаква. За около 20 рефреш-а разликата е минимална.

Опит с 500 000 итерации:
Код:
time classes: 3.8634009361267
time functions: 5.0189640522003
time classes no gc: 3.9263830184937

Разликата е никаква, но я има и е в полза на обектното решение при мен.
Лично аз никога не бих избрал процедурно мазало в сравнение с 2 реда код, който дори и работи по-бързо.
Отново, това няма никакъв начин да се усети, за разлика от много други неща в кода ти със сигурност. Ако трафика ти е толкова огромен че разлика от няколко наносекунди е проблем мисля че php е грешният инструмент за целта.
 
Не знам защо изпитвате такъв ужас от обектното програмиране. Вярно, че обектния модел е малко по-бавен спрямо процедурния модел, но разликата не е фатална. Всъщност лошия стил на писане и непознаването на езика са много по-страшни.

За примера: след лека оптимизация го сведох с разлика от 1 хилядна от секундата при хиляда итерации:

PHP:
<meta http-equiv='Content-Type' content='text/html; charset= utf-8' />
<?php
$time_start = microtime(true);

$date = new DateTime();
$now = clone $date;

for($i=0;$i<1000;$i++){
	$date->setDate(1993, 11, 17);
	$age = $now->diff($date)->format('%Y/%m/%d');
}
$time_end = microtime(true);
$time = $time_end - $time_start;
echo "<br><center>Време ".$time."</center>";
?>

В същото време инстанцията ни предоставя методи за цялостна работа с дата и час. Да не забравяме, че подобни действия с много итерации за смятане на нещо са нужни единствено, когато инициализираме някакви данни, което обекновенно се налага еднократно или в по-редки случаи на дадени интервали - например на 24 часа. Забавянето от 1 секунда за 1,000,000 итерации спрямо процедурния стил не е фатално.

Когато се разработва даден софтуер, той трябва да бъде:
1. Коректен;
2. Лесно разбран за други хора;
3. Добре организиран;
4. Позволяващ бъдещи разширявания без или с минимални промени;

Ако решиш да работиш в тази насока - навсякъде ще се сблъскаш с ООП.
 
Кодовете които дадох ги поставям в един документ. Тествам първият трия го и слагам дригият. При 50 000 интерации при мен на моята машина си дава, че процедурният код е по-бърз. Средно 0,9 на процедурния и 1,3 на обектно ориентираният. Говорим за доста сметки и интерации по принцип при мен достигат до към 10 000 и това е максимум за момента но имай в предвид, че имам проверки изчисления и от тук малко от там малко и се ускоряват нещата.
 
Добре де, защо трябва всеки път да създаваш нов обект? Това няма ли да увеличи бързодействието:

PHP:
$dateStart = new DateTime();
$dateEnd = new DateTime();
for ($i = 0; $i < 50000; $i++) {
    $dateStart->setDate(1970, 1, 1);
    $dateEnd->setDate(2015, 19, 3);
    echo $dateStart->diff($dateEnd)->format('Y-m-d');
}

По този начин създаваш веднъж два обекта и после работиш с тях без да заделяш нова памет.

Какво мислите? :idea:

http://php.net/manual/en/datetime.setdate.php
 
lamerko каза:
Не знам защо изпитвате такъв ужас от обектното програмиране. Вярно, че обектния модел е малко по-бавен спрямо процедурния модел, но разликата не е фатална. Всъщност лошия стил на писане и непознаването на езика са много по-страшни.

За примера: след лека оптимизация го сведох с разлика от 1 хилядна от секундата при хиляда итерации:

PHP:
<meta http-equiv='Content-Type' content='text/html; charset= utf-8' />
<?php
$time_start = microtime(true);

$date = new DateTime();
$now = clone $date;

for($i=0;$i<1000;$i++){
	$date->setDate(1993, 11, 17);
	$age = $now->diff($date)->format('%Y/%m/%d');
}
$time_end = microtime(true);
$time = $time_end - $time_start;
echo "<br><center>Време ".$time."</center>";
?>

В същото време инстанцията ни предоставя методи за цялостна работа с дата и час. Да не забравяме, че подобни действия с много итерации за смятане на нещо са нужни единствено, когато инициализираме някакви данни, което обекновенно се налага еднократно или в по-редки случаи на дадени интервали - например на 24 часа. Забавянето от 1 секунда за 1,000,000 итерации спрямо процедурния стил не е фатално.

Когато се разработва даден софтуер, той трябва да бъде:
1. Коректен;
2. Лесно разбран за други хора;
3. Добре организиран;
4. Позволяващ бъдещи разширявания без или с минимални промени;

Ако решиш да работиш в тази насока - навсякъде ще се сблъскаш с ООП.
Приятел, не си прочел, но ще ти го обясня отново. Кодът ми е обектно ориентиран просто методът в даденият клас който ползвам и викам е много тежък. Работя с ООП в момента просто търся решение на проблема в процедурен стил с цел бързина не само четимост на кода. Ако някой ми даде по-ускорен код от тези тук ще ползвам него а не просто защото ми е хрумнало да е процедурно решението. :shock:
 
anonimen каза:
Добре де, защо трябва всеки път да създаваш нов обект? Това няма ли да увеличи бързодействието:

PHP:
$dateStart = new DateTime();
$dateEnd = new DateTime();
for ($i = 0; $i < 50000; $i++) {
    $dateStart->setDate(1970, 1, 1);
    $dateEnd->setDate(2015, 19, 3);
    echo $dateStart->diff($dateEnd)->format('Y-m-d');
}

По този начин създаваш веднъж два обекта и после работиш с тях без да заделяш нова памет.

Какво мислите? :idea:

http://php.net/manual/en/datetime.setdate.php
Извинявам се, че си изтрих предният коментар просто тествах. Да ускорява нещата наистина спрямо ОО но отново процедурният е малко по-бърз. Сега от думите ти ще тествам нещо впрочем в моят код на обектно ориентираният трябва да тествате по логика така че не съм се осетил когато съм го поствал :
PHP:
<meta http-equiv='Content-Type' content='text/html; charset= utf-8' />
<?php
$time_start = microtime(true);
$now = new DateTime();
for($i=0;$i<50000;$i++){
	$date = new DateTime('1993-11-17');
	$interval = $now->diff($date);
	$age = $interval->y.$interval->m.$interval->d;
}
$time_end = microtime(true);
$time = $time_end - $time_start;
echo "<br><center>Време ".$time."</center>";
?>
 
Извинявам се, че продължавам темата но наистина ли това е максималното решение на проблема което дадох с процедурен код?
PHP:
<meta http-equiv='Content-Type' content='text/html; charset= utf-8' />
<?php
$time_start = microtime(true);
for($i=0;$i<50000;$i++){
	$ageY = date("Y")-1993;
	$ageM = date("n")-11;
	$ageD = date("j")-17;
	if($ageD < 0){
		$ageD += date("t");
		$ageM--;
	}
	if($ageM < 0){
		$ageM+=12;
		$ageY--;
	}
	$age = $ageY."/".$ageM."/".$ageD;
}
$time_end = microtime(true);
$time = $time_end - $time_start;
echo "<br><center>Време ".$time."</center>";
?>
Няма ли възможност да се опрости по някакъв начин и ускори? Било то със съкратен if else или нещо от сорта?
 
Изкарай си date("Y")/"n"/"j" извън цикъла - те са константа, няма смисъл на всяка итерация да ги взимаш отново. И пак казвам - този код ако се изпълнява често, то имаш грешен подход...
 
Код:
$now = date_create();
$birthdate = date_create("1995-03-13");
$diff = date_diff($now, $birthdate)->format("%y години"); // %m - за месеци и %d за дни
echo $diff;

:p funny, right?

Ето ти го на един ред, за да е "по-кратко" :D
Код:
echo date_diff(date_create(),date_create("1995-03-13"))->format("%y години"); // %m - за месеци и %d за дни
 
lamerko каза:
Изкарай си date("Y")/"n"/"j" извън цикъла - те са константа, няма смисъл на всяка итерация да ги взимаш отново. И пак казвам - този код ако се изпълнява често, то имаш грешен подход...
Хех браво! Товаааа като идея ускори мнооого нещата!
PHP:
<meta http-equiv='Content-Type' content='text/html; charset= utf-8' />
<?php
$time_start = microtime(true);
$ageY = date("Y");
$ageM = date("n");
$ageD = date("j");
$t = date("t");
for($i=0;$i<50000;$i++){
	$ageY -= 1993;
	$ageM -= 11;
	$ageD -= 17;
	if($ageD < 0){
		$ageD += $t;
		$ageM--;
	}
	if($ageM < 0){
		$ageM+=12;
		$ageY--;
	}
	$age = $ageY."/".$ageM."/".$ageD;
}
$time_end = microtime(true);
$time = $time_end - $time_start;
echo "<br><center>Време ".$time."</center>";
?>
Защо да е грешен подхода? Наложително е да се изпълнява заради изчислеията, които се трябвада бъдат правени на база него. Смисъл обработката на информацията трябва да е в цикъла заради сменящите се величини. Дори да го изнеса в метод пак трябва да се изпълнява в цикъл. Правя огромен статистически разбор и изчислително действие на база входна променлива спрямо която се правят всякакви шашми които няма да обяснявам и които оптимизирахме доста с приятели. Просто това е как да кажа частица която знам че може да бъде оптимизирана повече.
 
В момента на 50 000 интерации от 0.8 ~ 0.9 го свалихме на Време 0.26201486587524 тоест средно 0.26 ! Което е супер благодаря не се бях сетил за това! :) Още някоя подобна идея да слезне на 0.2 и го зарязвам :D
 

Горе