MySQL searching through time interval - php

The system is as such. Tutors provide their availability (Monday - Sunday) and the time frame they are available on that day (0700 - 1400) (ie: 7am - 2pm).
I am trying to figure out the best way to store and search through this information to find available tutors. Searching only needs to be done on a daily system (ie: day of the week - mon, tues, wed, etc).
My planned infrastructure:
//Tutor Availability
---------------------------------------------------------------------------
tutorID | monday | tuesday | wednesday | thursday | friday |
---------------------------------------------------------------------------
27 | 0700-1200 | NULL | 1400-1800 | NULL | NULL |
---------------------------------------------------------------------------
35 | NULL | 1400-1600 | NULL | NULL | 1100-1900 |
//Scheduled tutor sessions
------------------------------------
tutorID | day | time |
------------------------------------
27 | monday | 0700-0900 |
------------------------------------
35 | friday | 1300-1500 |
Query: SELECT tutorid FROM tutoravailability WHERE 'monday'=... is available between 0900-1100 and is not in scheduled tutor session.
I have been searching forever about how I can search through (and store) these time intervals in MySQL. Is this the best way to store the time intervals of a 24 hours day? Will it even be possible to search between these intervals? Am I approaching this from the wrong way? Any insight is appreciated.
Updated Infrastructure
//Tutor Availability
-----------------------------------------------------
tutorID | day | start_time | end_time | PK |
-----------------------------------------------------
27 | mon | 0700 | 1200 | 1 |
-----------------------------------------------------
27 | fri | 1400 | 1800 | 2 |
-----------------------------------------------------
35 | tue | 1100 | 1600 | 3 |
//Scheduled tutor sessions
--------------------------------------------------------
tutorID | day | start_time | end_time | PK |
--------------------------------------------------------
27 | mon | 0800 | 1000 | 1 |
--------------------------------------------------------
27 | fri | 1600 | 1800 | 2 |
So with this system it will be much simpler to search for available times. However I am still at a loss as to how to compare the availability against the scheduled lessons to ensure no overlap.
SELECT tutorID
FROM tutoravailability WHERE day = 'fri'
AND start_time <= '1400'
AND end_time >= '1530'
Now I don't understand how I would compare this query against the Scheduled tutor sessions table to avoid duplicate bookings.
Final Update
To ensure their are no overlapping of the Scheduled Tutors sessions I will use the MySQL BETWEEN clause to search for the start and end time.

If you store the time interval using two columns it will be much easier for you to perform a search using sql query.
i.e. tutorID, day, startTime, endTime

You can use a bit flag to indicate the availability (24 bit) and scheduled time (24 bit). Then you can use 24 bit to represent the available hours and scheduled hours for each day.
In the Tutor Availability table, let's say '1' stands for Available in and '0' stands for unavailable. In the Scheduled table, '0' stands for Scheduled, '1' stands for Unscheduled.
So the available interval 0900-1100 can be stored as POW(2,9) | POW(2,10) | POW(2,11); the scheduled 1000-1200 can be stored as ^(POW(2,10) | POW(2,12))
Then the following query can give your the availability of on tutor - available on Monday between 09 am to 11 am:
SELECT ta.tutorid FROM tutoravailability ta, tutorscheduled ts
WHERE ta.tutorid = ts.tutorid AND ts.day = 'monday'
AND (ta.monday & ts.time & (POW(2,9) | POW(2,10) | POW(2,11))) = (POW(2,9) | POW(2,10) | POW(2,11))

Related

Event reservation system php mysql

I want to build a small event-registration tool.
Users should be able to book multiple events at different times.
Example
Event1
Time1 09:00 - 10:00 | Max Participants 12
Time2 11:00 - 12:00 | Max Participants 9
Event2
Time1 09:00 - 10:00 | Max Participants 6
Time2 11:00 - 12:00 | Max Participants 9
I think I need the tables "events", "reservation" and "reservation-in-progress".
But I'm not sure how to structure these.
My Idea:
events
event_id | host_id | date_of_event | title | description | time_1 | max_participants_1 | time_2 | max_participants_2
reservation
reservation_id | user_id | date_of_reservation | event_1 | time_1 | event_2| time_2
reservation-in-progress
reservation-in-progress_id | user_id | date_of_reservation | event_1 | time_1 | event_2| time_2 | time_end_of_blocked_reservation
your idea is right but no need to take second table reservation-in-progress you can simply add status field in the events or reservation table so you can mark status as in progress.
Thanks

Best way to handle business opening time in a year PHP and MySQL

We have developed a website for pharmacies in which we show the opened pharmacies in a specific city.
I handle this with a field named "timestamps" in wich it is stored all timestamps of opening hour every 15 minutes for a period of about 3 months.
For example if every days the farmacy is open from 8:00 to 19:00 there is a range of timestamps from one time to another, with an interval of 15 minutes.
While in the frontend we have a list of opened pharmacies and I could show opened ones by querying the database with for example:
"WHERE timestamps LIKE('%1449820800%')" where the timestamp is the current time rounded to the nearest quarter hour.
The question is: considering the time ranges are different from week to week, is there a better way to handle this situation? Also because we have 25.000 users and the website is slow if we have large amount of timestamps.
Thank you in advance!
You could just have a database with each day of openning for every store :
-----------------------------------------
| StoreId | Day | HourOpen | HourClose |
=========================================
| 1 | 1 | 8:30 | 21:15 |
-----------------------------------------
| 1 | 2 | 9:00 | 17:00 |
-----------------------------------------
| 2 | 1 | 10:00 | 12:30 |
-----------------------------------------
| 2 | 1 | 14:00 | 19:00 |
=========================================
In this table, the day represent the day of the week (1 for monday, 2 for tuesday for example) and then you just have to parameter the openniong hours for each store only once.
You can then query this table to see if a store is open for a day of the week at the very moment.
If a pharmacy has an exceptionnal closure or openning hours for a day, i suggest an ovveride table like this one
----------------------------------------------------------
| StoreId | Date | isOpen | HourOpen | HourClose |
==========================================================
| 1 | 2015-12-20 | true | 10:00 | 16:00 |
----------------------------------------------------------
| 2 | 2015-12-20 | false | null | null |
==========================================================
This way, you can check first if an pharmacy has any record in this table for the current day (not depending of the time) if it does, you check if there is an opening. If there is not any entry in the override table, you check with the first table.
You also can ahve a hour model table with opening and closing time, a day table, and an associative table that creates relations between stores, hours and days.

How to schedule events in PHP

I am creating a processing system in PHP, I read tons of tutorials over the internet but nothing
seems to satisfy what I need for my system.
I have table SCHEDULE in SQL..
+----+------+---------------------+
| ID | Name | Description |
+----+------+---------------------+
| | | |
| 1 | D | Daily |
| 2 | W | Weekends |
| 3 | EOM | End Of the month |
| 4 | 11d | 11 day of the month |
| 5 | M | Monday |
+----+------+---------------------+
And Table PROCESS..
+----+---------------+-----------+
| ID | Schedule_id | Name |
+----+---------------+-----------+
| 1 | 1 | Process 1 |
| 2 | 2 | Process 2 |
| 3 | 3 | Process 3 |
+----+---------------+-----------+
What I want is to automatically show the process on each days base on their schedule.
Meaning:
if Process1 = D RUN Process1 everyday
if Process2 = W RUN ONLY Process2 on weekends
if Process3 = 11d RUN ONLY Process3 on the 11th day of the month
I also want them to store on my calendar and also how about holidays?
All answers will be appreciated thanks.
I understand that activities don't have an associated schedule, so you can be at any given time. Taking that as a starting point, you can run a cronjob, every day, through a script in PHP which being entrusted to compare the tasks that the day should be made and there using shell_exec() php function to run the process in bash or in what you have defined.
That is:
For each record in "sheduled" you compare the date (If today, tomorrow or the weekend) and if there is a match, run the associated process.

MySQL - selecting the correct data within the correct week using week beginnings

I am trying to select data, when inserting the data it has an auto insert of the date when submitting. So when data is inserted it inserts the current date.
However, in my table I have week beginnings, so I am trying to select the data inside of that week:
mysql> select * from week;
+---------+------+------------+
| week_id | week | date |
+---------+------+------------+
| 1 | 1 | 2014-12-29 |
| 2 | 2 | 2015-01-05 |
| 3 | 3 | 2015-01-12 |
| 4 | 4 | 2015-01-19 |
| 5 | 5 | 2015-01-26 |
| 6 | 6 | 2015-02-02 |
| 7 | 7 | 2015-02-09 |
| 8 | 8 | 2015-02-16 |
| 9 | 9 | 2015-02-23 |
| 10 | 10 | 2015-03-02 |
| 11 | 11 | 2015-03-09 |
| 12 | 12 | 2015-03-16 |
| 13 | 13 | 2015-03-23 |
| 14 | 14 | 2015-03-30 |
| 15 | 15 | 2015-04-06 |
| 16 | 16 | 2015-04-13 |
| 17 | 17 | 2015-04-20 |
e.g.
select * from table where date='2015-04-06';
However the data will not be selected and presented because the inserted date was 2015-04-10. The only way to retrieve that data is by doing this:
select * from table where date='2015-04-10'; < when the data was inserted
So my question is, is it possible to select that data from that week beginning?
So if I select data from 2015-04-06 it should show data from the range of 2015-04-06 to 2015-04-12, is that possible?
Hopefully I have explained correctly, been a bit tricky to explain let alone try to implement. I can add any more info if needed.
NOTE: I am trying to use this inside of PHP so where the date is I would just use a variable, just thought I would say.
As the week will always end 6 days from the beginning you can use the between operator and the date_add function like this:
(for your specific example):
select *
from table
where date between '2015-04-06' and date_add('2015-04-06', interval 6 day)
And using a php variable:
select *
from table
where date between '$name_of_dt_var' and date_add('$name_of_dt_var', interval 6 day)
You could also compare the week of the date the data was entered with the weeks in the week table using WEEK() function.
Assuming that week is the same value as week(), the:
select t.*
from table t
where week = week('2015-04-10');
Even if the numbers do not match, then presumably you have some base date (such as 2015-01-01 and simple arithmetic would accomplish something very similar).
I have found that the most robust way to do this sort of week processing is to truncate each date in the table (in your example 2015-04-10) to the preceding Monday at midnight. That way you can compute the week of each item by assigning it to the first day of that week.
This little formula returns the preceding Monday given any DATE or DATETIME value.
FROM_DAYS(TO_DAYS(datestamp) -MOD(TO_DAYS(datestamp) -2, 7))
For example,
set #datestamp := '2015-04-10'
SELECT FROM_DAYS(TO_DAYS(#datestamp) -MOD(TO_DAYS(#datestamp) -2, 7))
yields the value 2015-04-06.
So, if you have a table called sale you can add up sales by week like this:
SELECT SUM(amount) weekly_amount,
FROM_DAYS(TO_DAYS(datestamp) -MOD(TO_DAYS(datestamp) -2, 7)) week_beginning
FROM sale
GROUP BY FROM_DAYS(TO_DAYS(datestamp) -MOD(TO_DAYS(datestamp) -2, 7))
This is a very convenient way to handle things, because it's robust over end-of-year transitions. The WEEK() function doesn't work quite as well.
If your business rules say that your weeks begin on Sunday rather than Monday, use -1 rather than -2, as follows.
FROM_DAYS(TO_DAYS(datestamp) -MOD(TO_DAYS(datestamp) -1, 7))

PHP / MySQL select by DATETIME field across DST change

Please forgive me if this unclear, but I am having a tough time trying to get what is in my mind down on paper.
Scenario:
We store a variety of jobs in a table. These are all timestamped using DATETIME set to UTC time zone.
Our users may have their timezones set in their preferences, so that we can transcribe system times to the users local times.
Now, assume that a user goes to select all jobs that were entered on October 25, 2012 (local user time):
+--------------------------------------+------------+---------+---------------------+
| id | project_id | amount | created |
+--------------------------------------+------------+---------+---------------------+
| 50889ba5-77b4-41e1-a942-1dea0ab761f6 | 15076850 | 50.00 | 2012-10-25 01:53:41 |
| 5088b9a3-8110-446e-81c8-75da341f3f95 | 15076850 | 2000.00 | 2012-10-25 04:01:39 |
| 5088c852-d434-41e6-ba5d-27560ab761f6 | 15076850 | 100.00 | 2012-10-25 05:04:18 |
| 50892a3b-ad9c-4a32-aebf-384c0ab761f6 | 15076850 | 500.00 | 2012-10-25 12:02:03 |
| 50893098-6b9c-4028-9a87-3eb20ab761f6 | 15076850 | 25.00 | 2012-10-25 12:29:12 |
| 50894b10-d260-4f61-8eb9-1d190ab761f6 | 15076850 | 25.00 | 2012-10-25 14:22:08 |
| 50895129-48c8-4bb4-928f-483b341f3f95 | 15076850 | 25.00 | 2012-10-25 14:48:09 |
| 50896019-7144-4e74-8037-4160341f3f95 | 15076850 | 50.00 | 2012-10-25 15:51:53 |
+--------------------------------------+------------+---------+---------------------+
8 rows in set (0.00 sec)
If this user is in the Eastern United States (EST), and the times in this table are UTC, the results are going to come across as October 24th for the first two rows in the table results. Basically, I want to exclude those first two rows if the user is EST.
I have been experimenting with the use of DateTime(), however - I am stuck because this spans DST end (November 4, 2012). When I select the date on October 25th, DST is active, so it shows the users local time as UTC -0400. When the job ends, it is after (UTC -0500).
I am completely stuck on how to make this work.
Get the UTC timestamp for what is the user's midnight (which is 4am UTC in the below example):
$start = new DateTime('2012-10-25 00:00:00', new DateTimeZone('America/New_York'));
$start->setTimeZone(new DateTimeZone('UTC'));
$start = $start->format('Y-m-d H:i:s');
// do the same with $end
SELECT ... WHERE `created` BETWEEN $start AND $end
The final query should select WHERE BETWEEN 2012-10-25 04:00:00 AND 2012-10-26 03:59:59, which is the day of October 25th in America/New York.
This should also work during DST changes. On November 4th, the query would be BETWEEN 2012-11-04 04:00:00 AND 2012-11-05 04:59:59, encompassing one more hour.

Categories