Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
Программирование. Ступени успешной карьеры. Авторы: Кузнецов М.В., Симдянов И.В. PHP 5/6. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В. PHP 5. На примерах. Авторы: Кузнецов М.В., Симдянов И.В., Голышев С.В. PHP Puzzles. Авторы: Кузнецов М.В., Симдянов И.В. MySQL 5. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум PHP

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: timestamp - помогите разобраться
 
 автор: Zilog   (30.11.2009 в 16:30)   письмо автору
 
 

timestamp - помогите разобраться.

Есть массив, который описывает год в промежутках разной длины.
даты в массиве представлены в виде timestamp.
Например:
01.01.2009 - 28.02.2009
01.03.2009 - 31.08.2009
01.09.2009 - 31.10.2009
01.11.2009 - 31.12.2009

Есть две даты заданные пользователем. Бегаю по массиву, и выясняю, сколько дней из каждого периода задевает отрезок, заданный пользователем, получаю кол-во "задетых" дней в периоде, складываю, и на выходе имею общее кол-во дней (ночей).

Делаю это вот так (это внутри цикла):

if ($userFrom >= $Base->From)
{
    if ($userTo <= $Base->To) $nights = (($userTo - $userFrom)/86400);
    if ($userTo > $Base->To) $nights = (($Base->To - $userFrom)/86400);
}
    if ($userFrom <= $Base->From)
{
    if ($userTo < $Base->To) $nights = ($userTo - $Base->From)/86400;
    if ($userTo >= $Base->To) $nights = ($Base->To - $Base->From)/86400;
}


Вот здесь начинается интересное.
В самом конце, для проверки правильности расчётов, полученное значение (сумму всех ночей) сравниваю с разницей заданных ользователем дат ($controlNights = round(($userTo-$userFrom)/86400);)

Пока же в цикле я складываю отдельно значение переменной $nights;

$nights - дробное число. Если я просто складываю все значения, то на выходе результат заведомо больше реального ($controlNights - накапливается дробная часть).

Если брать целую часть - то всё работает пучком, но при некоторых значениях заданных пользователем дат - наблюдается ошибка: общее кол-во $nights выходит на 1 меньше или больше, чем $controlNights.

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


Буду очень признателен за помощь.

  Ответить  
 
 автор: sim5   (30.11.2009 в 16:34)   письмо автору
 
   для: Zilog   (30.11.2009 в 16:30)
 

Если у вас даты именно так, то для начала сделайте "реверс" датам - год вперед, день в конец.

  Ответить  
 
 автор: Zilog   (30.11.2009 в 16:39)   письмо автору
 
   для: sim5   (30.11.2009 в 16:34)
 

>Если у вас даты именно так, то для начала сделайте "реверс" датам - год вперед, день в конец.

даты в массиве представлены как unix timestamp (и далее везде) . Здесь я их так описал для удобства восприятия.

  Ответить  
 
 автор: sim5   (30.11.2009 в 16:51)   письмо автору
 
   для: Zilog   (30.11.2009 в 16:39)
 

Ясно. А зачем такие сложности, ведь день года можно узнать функцией date для начальной и конечной меток, ну соответственно их разница даст период.

  Ответить  
 
 автор: Zilog   (30.11.2009 в 16:56)   письмо автору
 
   для: sim5   (30.11.2009 в 16:51)
 

>Ясно. А зачем такие сложности,

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


Пример глюка:
Если период описан как 02.03.2009 - 31.05.2009,
а заданные пользователем даты: 26.03.2009 и 31.03.2009,
то результат будет 4 ночи (4.9583333333333 если не брать только целую часть - округлять до бОльшего смысла нет, т.к. ошибка плавает в обе стороны).

  Ответить  
 
 автор: Zilog   (30.11.2009 в 17:39)   письмо автору
 
   для: Zilog   (30.11.2009 в 16:56)
 

вопрос всё ещё актуален

  Ответить  
 
 автор: Trianon   (30.11.2009 в 18:20)   письмо автору
 
   для: Zilog   (30.11.2009 в 16:30)
 

В постановке задачи очень много неопределенности.
Пересечение интервалов вычисляется значительно проще.

  Ответить  
 
 автор: Zilog   (30.11.2009 в 18:26)   письмо автору
 
   для: Trianon   (30.11.2009 в 18:20)
 

>В постановке задачи очень много неопределенности.
да. главная - что периоды, да и все расчёты (функции работы с временем) в БД надо было перевести в ГМТ. Всё заработало

>Пересечение интервалов вычисляется значительно проще.
как?

  Ответить  
 
 автор: Trianon   (30.11.2009 в 19:37)   письмо автору
 
   для: Zilog   (30.11.2009 в 18:26)
 


[PQ) = [AB) & [CD)

p = max(a, c) 
q = min(b, d)

A*-----------------oB
       C*---------------------oD
       P*----------oQ

  Ответить  
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования