покритикуйте код

Kirill

Новичок
покритикуйте код

При устройстве на работу попросили написать функцию - написал, не взяли, хотелось бы уяснить в чем косяк.
Задача:
Нужно написать функцию, которая получает входными параметрами две даты
(в формате YYYY-MM-DD), а на выходе дает число (может быть дробным)
месяцев между двумя этими датами.
Примеры работы этой функции:
dateDiffInMonths('2007-07-05', '2007-11-05')
5.00537634409
dateDiffInMonths('2007-07-05', '2008-07-25')
12.6451612903

Мое решение:

PHP:
<?php
function dateDiffInMonths($start, $end){
	$start_time = strtotime($start);
	$end_time = strtotime($end);
	
	if($start_time == -1 || $end_time == -1) return false;
	if($start_time > $end_time) return false;
	
	$day_time = 60*60*24;
	$out = 0;
	$counted_time = $start_time;
	
	while($counted_time < $end_time){
		$month_days = date("t", $counted_time);
		if(mktime(null,null,null,date('m',$counted_time),$month_days,date('Y',$counted_time)) > $end_time){
			$diff_time = $end_time-$counted_time;
		}
		else{
			$tmp_end = mktime(null,null,null,date('m',$counted_time),$month_days,date('Y',$counted_time));
			if(date("j", $tmp_end) == $month_days && date("j", $counted_time) == 1){
				$out += 1;
				$counted_time += $month_days*$day_time;

				$counted_time += CheckOnSummerTime($counted_time);
				
				continue;
			}
			else{
				$diff_time = $tmp_end-$counted_time;
			}
		}		
			
		$out += $diff_time/($month_days*$day_time);
		
		$counted_time += $diff_time + $day_time;		
	}
	
	return $out;
}

function CheckOnSummerTime($day){
	if(date("H", $day) == date("H", mktime(23,0,0))){		
		return 60*60;
	}
	elseif(date("H", $day) == date("H", mktime(1,0,0))){
		return -60*60;
	}
}
?>
 

Alexandre

PHPПенсионер
я бы задал числом $day_time = 86400; // 60*60*24;
так чтоб процессор лишних вычислений не делал.

по алгоритму грубая оценка:
число месяцев одного года:
- вычисляется день года первой даты
- вычисляется день года второй даты {в обоих случаях используется date()}
- разницу делим на 30

разных лет: вычисляем разницу между годами, год*365, разницу в дней_в_году прибавляем ко второй дате.
еще год можно проверить на высокостность.

более точная оценка:
переводим все даты в юникс-тайм
вычисляем разницу в юникстайм,
далее полученную разницу в юникстайм делим на 86400 (60*60*24) - получаем разницу в кол-во дней, далее делим на 30 получаем грубо в месяцах.
вообще можно юникстайм перевести в дату, то тогда если разница в пределах одного года, то номер полученного месяца будет указывать на разницу в месяцах. если год > 1970, то кол-во лет превышающее 1970г надо * на 12 и прибавить к текущему месяцу
вот самый точный ответ.
 

Kirill

Новичок
я вычислял точное число месяцев, не понимаю в чем ошибка :(
 

Alexandre

PHPПенсионер
не переживай так,
исходи из принципа:
"не ты недостоин такой работы, а тебя недостойна эта работа." c

что не делается, все делается к лучшему.

-~{}~ 27.03.08 18:56:

Один из вариантов: им мог не понравится
- стиль кодирования
- скорость
- не понравился стиль мышления
- взяли своего по звонку
- взяли на более мелкие деньги
 

Kirill

Новичок
я не переживаю, я спокоен как удав :)
я хотел бы узнать свои ошибки чтобы впредь их не допускать
 

Alexandre

PHPПенсионер
закинь резюме на jobs собака tradebox ру
если у нас не понравится, то меня некоторые друзья просят найти учеников
могу направить к ним

обещаю интересные проекты, где действительно можно набраться знаний
а не тирожирование бизнесс-сайтов, чем занимается большинство студий

главное, чтоб было желание в изучении PHP/OOP/BD/Unix/Ajax/jQuery etc

вакансия
 

alexv

Новичок
к коду два замечания:

1. что получим для dateDiffInMonths('1960-07-05', '2007-11-05') ?
2. зачем цикл?
вычитаем года, * 12
вычитаем месяцы
вычитаем дни, /31
все суммируем
 

tashkentchi

Новичок
а если так:
PHP:
$start = '2007-07-05';
$end = '2007-11-05';

$start_date = new DateTime($start);
$date = new DateTime($end);
$date->modify($start_date->format('-Y \y\e\a\r -m \m\o\n\t\h -d \d\a\y'));
echo 12*$date->format('Y') + $date->format('m') + $date->format('d')/30;
-~{}~ 27.03.08 21:15:

хотя, дробное число месяцев - уротство имхо

-~{}~ 27.03.08 21:18:

Kirill, они еще 10 кандидатов посмотрят, устанут и наймут предпоследнего :)
 

alexcrown

Новичок
Потому, что вы неправильно поняли их задачу. При решении нужно исходить из предпосылки, что между одинаковыми числами двух месяцев целое число месяцев, т.е. между '2007-07-05' и '2007-11-05' ровно 4 месяца, а между '2007-07-05' и '2008-07-25' 12 месяцев и еще (25-5)/31= 0,64 месяца.
Алгоритм в общем виде должен определять номера годов Г1 и Г2, номера месяцев М1 и М2, номера дней Д1 и Д2 и количество дней в месяце последней даты ДД. Тогда число месяцев определяется по формуле:
(Г2-Г1)*12+(М2-М1)+(Д2-Д1)/ДД

Сорри, не заметил сообщения alexv. Тоже самое написал
 

StUV

Rotaredom
Kirill
просили написать на личном собеседовании или тестовое задание на дом?

-~{}~ 27.03.08 20:24:

если на личном - за сколько времени написал ?
 

Духовность™

Продвинутый новичок
а зачем нужна такая функция? похоже они просто тебя использовали, ибо при трудоустройстве давать такое задание - бред.
 

Alexandre

PHPПенсионер
они еще 10 кандидатов посмотрят, устанут и наймут предпоследнего
да, у последнего есть преимущество...
но можно и опоздать, короче как фортуна...

но у этой медали есть оборотная сторона:
мы вот тоже искали программиста, просмотрели пяток программистов, пока выбирали, тот кто нам больше всего понравился - уже устроился. А остальные на его фоне - слабенькие... вот и не знаем -кого теперь выбрать.
 

berkut

Новичок
triumvirat ыы) почему-же бред? по хорошему на 5-10мин задание, и не на такую простыню кода - они узнали, что хотели. в тоже время, такая хрень в вряд-ли могла понадобиться в реале, а если собеседование в офисе или он-лайн - для них дороже, тратить время. отличный тест
 

StUV

Rotaredom
berkut
+1
скорее всего хотели 3 строки кода за минуту
искали "кодера" - а это "архитекторский подход" ;)
 

berkut

Новичок
StUV в корне не согласен. как раз кодера и не искали. по мне так топикстартер с таким решением - как раз и кодер. решение - говно.

-~{}~ 27.03.08 23:02:

triumvirat
я не считаю это локальным случаем, потому-что всё очень просто - по сути задача на логику.
 

kode

never knows best
Re: покритикуйте код

PHP:
function diffTimes($from,$to){
	$from = strtotime($from);$to = strtotime($to);
//2592000 = 60 * 60 * 24 * 30 - секунд в одном месяце
	return (abs($to - $from) / 2592000);
}
-~{}~ 28.03.08 01:15:

правда результат с небольшой погрешностью (изза 28/29/30/31, взято 30 как самое частое)
 
Сверху