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

Форум PHP

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

 

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

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

тема: Работа с датами, периоды дат
 
 автор: Zilog   (06.05.2009 в 00:51)   письмо автору
 
 

Возникла задача, есть:
1. ряд периодов дат, например с 12.07 по 29.08 - и таких несколько, охватывающих весь год. То есть, весь год поделен на сектора с такого-то по такое-то;
2. юзером назначенные даты, которые он выбирает самостоятельно;

Нужно отследить, какие заранее заданные периоды охватил выбор юзверя. Например, если он выбрал с 25.07 по 05.08, то получается он своим выбором охватил два заранее заданных периода.

Вопросы возниккли такие:
А. Как и в каком формате хранить периоды, что бы удобнее ими было пользоваться?
Б. С какого боку подойти к алгоритму проверки дат - тут, я понимаю, всё зависит от пункта А.

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

  Ответить  
 
 автор: Trianon   (06.05.2009 в 01:09)   письмо автору
 
   для: Zilog   (06.05.2009 в 00:51)
 

Сразу посоветую хранить интервалы времени в виде открытых справа отрезков.
То есть не с даты DА по дату DB , а с момента MA до момента MB, включая MA и не включая MB.
При таком подходе проверка на пересечение, операции вычисления пересечения, объединения интервалов записываются достаточно просто.

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

  Ответить  
 
 автор: Zilog   (06.05.2009 в 01:17)   письмо автору
 
   для: Trianon   (06.05.2009 в 01:09)
 

>Сразу посоветую хранить интервалы времени в виде открытых справа отрезков.
>То есть не с даты DА по дату DB , а с момента MA до момента MB, включая MA и не включая MB.

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


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

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

  Ответить  
 
 автор: Trianon   (06.05.2009 в 01:22)   письмо автору
 
   для: Zilog   (06.05.2009 в 01:17)
 

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

Определить само понятие "момент времени", извините, не возьмусь.

>Поясню, на всякий, своё представление. Допустим год может выглядеть так.
>ааааааббббббббвввввввввгггггггггддд ддддддд
>т.е. он поделен на пять секторов. Каждый сектор - это период с такого-то числа по такое-то, и храниться в виде интервалов (DA-DB, как понял).

Вы как, всерьез полагаете, что у Вас яснее, чем у меня?

  Ответить  
 
 автор: DJ Paltus   (06.05.2009 в 09:54)   письмо автору
 
   для: Trianon   (06.05.2009 в 01:22)
 

ИМХО, что-то наподобие гороскопа. Год бьется на промежутки, потом в нем выбирается отрезок времени и смотрится, какие "знаки зодиака" он задел.
Если так, то проще всего хранить границы "знаков" в обычном unix-формате в массиве.
Юзер дает верхнюю планку, мы обходим массив и находим минимальное значение границы "знака", большее заданного. Затем он дает нижнюю планку, и мы таким же образом находим максимальное значение границы, но уже меньшее заданного. Тут важно не спутать.:)
Затем, имея "верх" и "низ", соответствующие границам "знаков" из нашего массива (соответственно, индексы элементов-то мы имеем тоже), можно использовать эти сведения против юзера. Или для чего там надо.

  Ответить  
 
 автор: Trianon   (06.05.2009 в 10:08)   письмо автору
 
   для: DJ Paltus   (06.05.2009 в 09:54)
 

Сомнительно мне, что это гороскоп... Скорее список постов какой-нибудь...
Мы влезаем в область догадок....

  Ответить  
 
 автор: DJ Paltus   (06.05.2009 в 10:45)   письмо автору
 
   для: Trianon   (06.05.2009 в 10:08)
 

Список постов - это было бы просто по дате, по времени. А тут по промежуткам, да еще и несимметричным. Гороскопом я это приблизительно назвал, чтобы более вещественно себе представлять промежутки.

  Ответить  
 
 автор: Zilog   (07.06.2009 в 15:48)   письмо автору
 
   для: DJ Paltus   (06.05.2009 в 09:54)
 

Возвращаюсь к теме - так пока и не сделал. Гороскоп - пример неплохой, однако у меня несколько посложнее, можно рассмотреть на примере любого торгового предприятия, у которого стоимость услуг может колебаться в зависимости от времени года.

Напрмер.
Есть гостиница, у неё несколько номеров, цены на каждый номер зависят от времени года. Получая от пользователя две даты ОТ и ДО, нам надо вывести стоимость номера(ов) на указанный период.

Как я вижу решение по структуре. Есть несклько таблиц:
1. ГОСТИНИЦЫ. hotelID, hotelCaption и тд.
2. НОМЕРА roomID, hotelID, roomCaption и тд.
3. СЕЗОНЫ seasonID, hotelID, seasonFrom, seasonTo и тд.
4. ЦЕНЫ rateID, hotelID(??), roomID, seasonID, rate и тд.

Начало и концец периода храним в формате timestamp (спасибо за совет, так уобнее будет делать сравнения).

Если со структурой всё более менее ясно, то с механизмом, с логикой работы не очень.
Вроде всё просто: зная даты ОТ и ДО (и, возможно тип НОМЕРА) лезем сперва в СЕЗОНЫ и собираем все Сезоны, которые задел наш выбор.

Зная Сезоны, мы можем из таблицы ЦЕНЫ достать информацию по выбранной гостинице/омеру или вообще всё подряд.

Технически представлю себе это следующим образом. Допустим у нас есть четыре сезона. Назовём их для удобства A,B,C и D. Есть, так же выбанный юзером период user select, котоый задевает три периода частично B и D, а C - включает полностью.

||--------A---------||-----------B---------||-----------C-----------||------------D----------||
.............................................. {Uf------------ user select --------------Ut} ............

Собираем урожай:
SELECT * FROM seasons WHERE userFrom <= seasonTo AND userTo >= seasonFrom


Далее, имея на руках сезоны, попадающие под выбор пользователя, мы можем определить кол-во "задетых" дней в каждом, и слазив в таблицу ЦЕНЫ - получить окончательный результат.

Всё ли так? Верная ли реализация?

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

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