I am trying to figure out the best approach for designing a "7 day calendar" that will consist of an HTML table with the columns "Name, Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday". The HTML table rows will be filled with data from my database, ie. Name will have a persons Name, Sunday will show what that person needs to do on Sunday, ie "Brush teeth", etc etc. It's very similar to event calendars, except what I am looking to accomplish doesn't require the hourly view, just a simple 7 day, Sunday to Saturday view.
My database currently consists of "Name, EventDetails, and EventDate".
My HTML table columns consists of the columns "Name - Sunday - Monday - Tuesday - ..."
My Logic: Each time the page loads, the script will query the database and see if there are any EventDate entries that equal one of the 7 days of the week currently being viewed. If an EventDate matches, it will list itself in a row that matches the corresponding HTML table column of that date. Clicking "Previous Week" or "Next Week" would change to another week and should restart the script, but this time it will be using a different list of days to check against.
Anyone care to share some examples of what they can come up with to accomplish this?
Here is what I came up with so far... The problem with it is that if there are more than one event under a person, it makes a new row for each event whereas I'm working on getting it to list each event in one row.
<table border='1'>
<tr>
<th>Name</th>
<th>Sunday</th>
<th>Monday</th>
<th>Tuesday</th>
<th>Wednesday</th>
<th>Thursday</th>
<th>Friday</th>
<th>Saturday</th>
</tr>
<?php
function getCurrentWeek()
{
$weekArray = array();
// set the current date
$date = date("m/d/Y"); //'03/08/2011';
$ts = strtotime( $date );
// calculate the number of days since Monday
$dow = date('w', $ts);
$offset = $dow - 0;
if ($offset < 0) $offset = 6;
// calculate timestamp for the Monday
$ts = $ts - $offset*86400;
// loop from Monday till Sunday
for ($i=0; $i<7; $i++, $ts+=86400){
$temp_date = date("Y-m-d", $ts); // Reformat the dates to match the database
array_push( $weekArray, $temp_date );
}
return($weekArray);
}
$currentWeek = getCurrentWeek();
// Loop through the data array
while($row = mysql_fetch_array($result)){
$eventDate= $row['EventDate'];
// Loop through the currentWeek array to match a date from the database from a date in the current week
foreach ($currentWeek as $weekDay){
// If there is a matching date...
if ($eventDate == $weekDay) {
echo "<tr><td>".$row['Name']."</td>";
foreach ($currentWeek as $weekDay2){
if ($eventDate == $weekDay2)
echo "<td>".$row['EventName']."</td>";
else
echo "<td></td>";
}
echo "</tr>";
}
}
}
?>
</table>
To select a week you could do something like
set #weekday:= dayofweek(#adate);
set #StartOfWeek:= date_sub(#adate,INTERVAL #weekday DAY);
set #EndOfWeel:= date_add(#adate,INTERVAL (7- #weekday) DAY);
Then to select the week I'd do
SELECT * FROM TableWithEvents
WHERE TableWithEvents.EventDate
BETWEEN date_sub(#adate,interval #weekday day)
AND date_add(#date,INTERVAL (7-#weekday) DAY);
Note that using
#adate - #weekday will not work, you must use date_sub/date_add with the silly interval syntax.
It does work rather nice when adding months, where it correctly adds the number of days in a month or with years where it knows about leap years (but I digress).
For the pagination you can use the above SELECT with limit start, end; like so:
SELECT * FROM sometable WHERE some_where_thingy LIMIT 0,20;
O and don't forget to add an index to the EventDate field.
And I would recommend adding an autoincrement primary key named id to the table with events.
That way you can uniquely link to that particular event in some other table, like so:
Table FavEvents:
- id: integer (autoinc primary)
- Event_id: integer (link to your event)
- FanName: varchar(x) (name of user you loves event or what ever)
Then you can select "bill"s fav events like so:
SELECT * FROM FavEvents
INNER JOIN Events ON (FavEvents.Event_id = Event.id)
WHERE FavEvents.FanName = "bill"
I never use PHP so can't help you there, good luck.
Related
I'm building a system where an user can register activities. However the activities registered can repeat over the course of the year.
In order to prevent having the need that the user has to fill in the form to create an activity multiple times for each different date, I had the idea to add a textbox and a dropdown to the form to allow the user to fill in a frequency. The user can fill in a number in the textbox (for example "2") and select a value from the dropdown (for example "week"). So from that selection the activity has to be added to the database for the next 2 weeks on the same day.
However I have no idea how to let PHP adjust the date and add exactly 7 days to the selected date and repeat the same insert query with the new date, for every week/month/year selected from the given frequency.
EDIT 1:
I've tried this so far:
while ($i> 0)
{
$query2 = $this->db->connection->prepare("INSERT INTO activity(Act_Startdate) values (?)");
$query2->bind_param("s", $Startdate);
$query2->execute();
$Dates = date('d-m-Y', strtotime($Startdate . '+ 1 days'));
$Startdate = date('d-m-Y', strtotime($Dates));
$i--;
}
The first date insertion works, but the second one results 0000-00-00.
Read more about :
Date Time in PHP.
Date Interval in PHP
$numberPostedByUser = $_POST['your_input_name_in_form'];
$currentDate = new \DateTime(); // Getting current date
$iterator = 1;
while ($iterator <= $numberPostedByUser) {
$currentDate->add(new \DateInterval('P1D')); // Adding interval of one day in current date
$startDate = $currentDate->format('Y-m-d H:i:s'); // converting that day in convenient format we required
$query2 = $this->db->connection->prepare("INSERT INTO activity(Act_Startdate) values (?)");
$query2->bind_param("s", $startDate);
$query2->execute();
$iterator++; // increasing iterator for next loop
}
Hope may this code will help you.
I'm running into a coder's block with PHP dates. Let me first paint the picture of what I want to happen. ex:
$user_join_date = new DateTime('2015-01-31');
$today_date = new DateTime('2015-04-30');
Every day a cron will be run and for this example, on every 31st (or 30th - 28th depending on the month) the system will calculate commission for this user based on orders and volume from the past month BETWEEN '2015-03-31' AND '2015-04-29'.
So what I need is two fold. First, I need to make sure I'm calculating the commission on the correct day ie: the monthly anniversary of their join date OR that same month's equivalent. Second, I need to find the time frame in between which I'll calculate commissions as demonstrated in the mysql snippit above.
For obvious reasons I can't just say:
if ($user_join_date->format('d') == $today_date->format('d')){
calc_commission();
}
Because this wouldn't get run every month. Let me know if I'm unclear on anything.
I think you're saying you want to credit each user on an integral number of months since her signup date. There's an aspect of MySQL's date arithmetic you will find very convenient -- INTERVAL n MONTH addition.
DATE('2015-01-30') + INTERVAL 1 MONTH ==> '2016-02-28'
DATE('2016-01-30') + INTERVAL 1 MONTH ==> '2016-02-29'
This feature deals with all the oddball Gregorian Calendar trouble around weekdays, quite nicely. I'm going to call the date the renewal date.
Now, let us say that the column signup contains the date/time stamp for when the user signed up. This expression determines the most recent monthly renewal date. In particular, if it is equal to CURDATE(), today is the renewal date.
DATE(signup) + INTERVAL TIMESTAMPDIFF(MONTH, DATE(signup), CURDATE()) MONTH
Next: This closely related (duh!) expression is equal to the previous month's renewal date.
DATE(signup) + INTERVAL TIMESTAMPDIFF(MONTH, DATE(signup), CURDATE())-1 MONTH
You could just take CURDATE() - INTERVAL 1 MONTH but this is much more accurate around Gregorian month-end monkey business. Try it: it works right even at the end of February 2016 (leap year day).
Now, you'll want to use transactions that happened beginning on the previous renewal date >=, up until the end of the day before < the present renewal date, in your computation. In MySQL filtering by that date range looks like this.
WHERE transdate >= DATE(signup) +
INTERVAL TIMESTAMPDIFF(MONTH, DATE(signup), CURDATE())-1 MONTH
AND transdate < DATE(signup) +
INTERVAL TIMESTAMPDIFF(MONTH, DATE(signup), CURDATE()) MONTH
$base_dt is your joining date. So If you pass it to checkIt function It will provide you true or false accordingly today's day is billing day or not.
$base_dt = new DateTime('2015-04-30', new DateTimeZone("America/Chicago"));
if(checkIt($base_dt)) {
echo "true";
//this is the day.
} else {
echo "false";
//this is not the day.
}
So the check it function should be like this .....
function checkIt($base_dt) {
$base_d = $base_dt->format('j'); //without zeroes
echo $base_d;
$today = new DateTime('now');
$d = $today->format('j');
echo $d;
if($base_d == $d) {
return true;
} else if($base_d>28) {
$base_dt->modify('last day of this month');
$dif_base = $base_dt->format('j') - $base_d;
//echo $dif_base;
$today->modify('last day of this month');
$diff_today = $today->format('j') - $d;
//echo $diff_today;
if(($base_d==31 && $diff_today==0)||($base_d==30 && $diff_today==0 && $d<30)||($base_d==29 && $diff_today==0 && $d<29)) {
return true;
}
if($dif_base==0 && $diff_today==0) {
return true;
}
}
return false;
}
Im currently trying to calculate the amount of periods (each period is 1 week, after a certain date or day). Lets say first period start on 01-01-2013 (tuesday) until 29-01-2013 (tuesday)(4 periods in total).
I have a table that looks like:
id | startDate (datetime) | endDate (datetime)
I have two input fields where a user can fill in a start date and end date. I would like to fill any date between 01-01-2013 and 29-01-2013 and decide how many times it passes a tuesday (the date the period starts) again.
So if I would select 01-01-2013 until 07-01-2013 would result in: 1, but if i would select 06-01-2013 till 09-01-2013 this would result in 2 and 06-01-2013 till 16-01-2013 would result in 3 etc.
To be clear, I dont want to know the amount of weeks between the two dates, only the amount of times it 'crosses' the same day (tuesday) that was given in the database. Every period is 1 week. Is there anyone that could help me out?
Use PHP's date() function.
$startday = strtotime($start_date_from_db);//date from db;
$endday = strtotime($end_date_from_db);//date from db;
$counter = 0;
for($i=$startday; $i<=$endday; $i+=86400) {
$current_day = date('w', $i);
if($current_day == 2) { //0 for sunday, 1 for monday, 2 for tuesday
$counter++;
}
}
When comparing dates a good method is:
1- transform the dates to timestamps:
$timestamp1 = strtotime($date1);
$timestamp2 = strtotime($date2);
2- do the desired operation, in this case:
$timebetween = $timestamp2 - $timestamp1;
3- Transform result (number of seconds) to desired value, in this case:
$weeks= $timebetween / 604800;
I have a function that is accepting the date and time, and number of occurrences of an episode. I'm using a while loop to try and insert and episode every week on the same day and time. For example if the episode is monday at 7PM, i want to insert in for every monday at 7PM for the number of occurrences given.
Here's my code and while loop:
$sEpsAirDate = strtotime($aVars['air_date'].' '.$aVars['air_time'].$aVars['air_ampm']);
$i = 1;
while ($i <= $aVars['repeat_count']) {
$sEpsAirDate = // How can I alter this variable to change the date to every week?
db_res(
"INSERT INTO `hm_episodes_main` SET
`show_id` = '{$aVars['show_id']}',
`title` = '{$sEpsTitle}.{$i}',
`season` = '{$aVars['eps_season']}',
`uri` = '{$sUri}.{$i}',
`desc` = '{$sEpsDesc}',
`air_date` = '{$sEpsAirDate}'
");
$i++
}
How would I alter the $sEpsAirDate variable to be entered accurately on every day of the week on the given time?
Use mktime():
$next_ep_timestamp = mktime ($hour,$min,$sec, $first_ep_month, $first_ep_day + 7 * $weekcount, $first_ep_year);
"Init" this by setting the respective variables for the date, month and year of the first episode, then you can create new dates for following weeks by adding increments of 7 to the day-parameter in mktime (like shown above).
Then format for output to SQL like this:
$datetime_str = date("Y-m-d H:i:s", $next_ep_timestamp);
//gives a date-str like '2011-10-16 12:59:01'
The first idea that comes to my mind is just adding the seconds in a week to the sEpsAirDate with every iteration in the loop:
$sEpsAirDate += 604800;
If you needed to preserve the first air date you could copy it out into a separate variable and then do something like this (change the LCV $i to start at 0):
$sEpsAirDate = $sEpsFirstAirDate+(604800*$i);
But this method has the potential to create problems with Daylight Savings Time... so it might be safer to break the date into year, month and day variables and then recreate the $sEpsAirDate with every loop iteration by adding ($i*7) to day. ... So something like (again change the LCV $i to start at 0):
$sEpsAirDate = mktime($sEpsAirDateHour, $sEpsAirDateMinute, 0, $sEpsAirDateMonth, $sEpsAirDateDay+($i*7), $sEpsAirDateYear);
Please help a newbee. I have a table named event_calendar with fields named ec_start_date, ec_end_date and ec_event_name. The first two fields are date fields. It is a small table, with less than 100 entries. I want to list events with a start or end date in the current month, then I want to follow with a list of events with a start or end date in the next month. The two list will be headed by the month name. I would like the dates displayed in the list to be in the format dd/mm.
This is the code I've found to identify the months for the list headers.
$thismonth = mktime(0,0,0,date("n"));
$nextmonth = mktime(0,0,0,date("n")+1);
echo "<h2 class='caps'>";
echo date("n", $thismonth);
echo "</h2>";
echo "<h2 class='caps'>";
echo date("m", $nextmonth);
echo "</h2>";
This is the code I use to pull the entries for this month's (August) activities
$query = "SELECT ec_display,ec_event_name,ec_start_date,ec_end_date FROM event_calendar WHERE month(ec_start_date) = 8 OR month(ec_end_date) = 8 ORDER BY ec_start_date";
The problem is, if I replace the number 8 with the variable $thismonth, it fails.
Finally, how can I display only the dd/mm from ec_start_date and ec_end_date?
I greatly appreciate any guidance, but please be specific as I am very new to this! Thank you!
$thismonth contains a UNIX timestamp returned by mktime. The timestamp for hour 0, minute 0, second 0 of month 8 of this year is 1312862400. That's not 8.
Don't put that in your query, put date('n') (8) in it... or just let MySQL do it
$query = "SELECT ec_display,ec_event_name,ec_start_date,ec_end_date FROM event_calendar WHERE month(ec_start_date) = MONTH(CURRENT_DATE) OR month(ec_end_date) = MONTH(CURRENT_DATE) ORDER BY ec_start_date";