select menu with current date - php

How do you create a select with the option of 2 days ahead from today picked as the default option (i.e. a 48 hour window) in PHP? This is the code I'm using so far but it doesn't work unfortunately!
<?php
$weekday = array('Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday');
$days = range (1, 31);
$currentDay = date('F');
echo "<select name='weekday'>";
foreach ($days as $value) {
$default = ($value == $currentDay)?'selected="selected"':'';
echo '<option '.$default.' value="'.$value.'">'.$value."</option>\n";
}
echo '</select> ';
?>

I'm confused as to what your code does.
As far as I can tell $weekday is not used after being instantiated, and you are setting $currentDay to the text representation of the current month (e.g. September).
But if you want to get the day of month of the day 48 hours from now:
$two_days_ahead = date('j', strtotime('+ 48 hours'));

Related

PHP - Populate select options with 15 min time intervals

Hi I am creating a website for a restaurant delivery service. Basically when the customer is checking out, he/she can choose when they want the food to be delivered. I want the select box to contain time intervals of 15 mins ranging from the current time until the close time. The restaurant is open for deliveries between 11:00 to 23:00. The first option I want is to be "As soon as possible", and then the next option is an hour later (rounded to nearest 15mins), and then 15 mins each time. So basically something like this:
(Suppose current time is 13:55)
As soon as possible
15:00
15:15
15:30
15:45
...and so on until close time (23:00)
If the restaurant is closed (after 23:00) then I just want the select box to have an option that says "CLOSED".
Here is what I have tried so far but it is not working:
<select>
<?php
$timenow = date("H:i");
if($timenow >"23:00" || $timenow < "11:00"){
echo '<option value="Closed">CLOSED</option>';
echo "</select>";
}
else{
$deliverytime = date("H:i", strtotime('+15 minutes', $timenow));
echo '<option value="asap">As soon as possible</option>';
while($deliverytime < "23:00" && $deliverytime > "11:00"){
echo '<option value="'. $deliverytime.'">' . $deliverytime . '</option>';
$deliverytime = date("H:i", strtotime('+15 minutes', $deliverytime));
}
echo "</select>";
}
?>
strtotime('+15 minutes', $timenow) is not correct. The second argument should be a timestamp, not a string. You want something like strtotime('+15 minutes', time()) or just leave off the second argument (current time is the default).
A better approach is to always work with the timestamps until you output. That makes rounding and comparisons much easier.
<select>
<?php
$timenow = time();
$opentime = strtotime('11:00');
$closetime = strtotime('23:00');
if($timenow > $closetime || $timenow <= $opentime){
echo '<option value="Closed">CLOSED</option>';
echo "</select>";
}
else{
// you said you wanted the time to start in 1 hour, but had +15 minutes...
$deliverytime = strtotime('+1 hour', $timenow);
// round to next 15 minutes (15 * 60 seconds)
$deliverytime = ceil($deliverytime / (15*60)) * (15*60);
echo '<option value="asap">As soon as possible</option>';
while($deliverytime <= $closetime && $deliverytime >= $opentime) {
echo '<option value="'. date('H:i', $deliverytime) .'">' . date('H:i', $deliverytime) . '</option>'."\n";
$deliverytime = strtotime('+15 minutes', $deliverytime);
}
echo "</select>";
}
I can't provide a complete solution but can point you in the right direction.
This code will handle the 15 minute interval parts for you:
$start = new DateTime();
$end = new DateTime('11PM');
$interval = new DateInterval('PT15M');
$period = new DatePeriod($start, $interval, $end);
foreach ($period as $dt)
{
echo $dt->format("l Y-m-d") . PHP_EOL;
}
The accepted answer in this Stack Overflow question shows how to get to the nearest 15 minute interval: PHP DateTime round up to nearest 10 minutes
Combine the two and you should have a complete solution to your problem.

How many of a certain week day has passed this month

I have a calendar that I want to allow events to be repeated on a week day of the month. Some examples would be:
Repeat every 4th Tuesday of the month
Repeat every 2nd Friday of the month
And so on...
What I need is the ability to find out how many week days (for example Tuesday's) have passed this month so far.
I found some code that returns how many Monday's have passed.
$now=time() + 86400;
if (($dow = date('w', $now)) == 0) $dow = 7;
$begin = $now - (86400 * ($dow-1));
echo "Mondays: ".ceil(date('d', $begin) / 7)."<br/>";
This works well but how do I make it so that I can determine any week day? I cannot seem to get my head around the code to make this work.
strtotime is really useful for this kind of thing. Here are lists of the supported syntax. Using your example of repeat every 2nd Friday of the month I wrote the following simple snippet for you:
<?php
$noOfMonthsFromNow=12;
$dayCondition="Second Friday of";
$months = array();
$years = array();
$currentMonth = (int)date('m');
for($i = $currentMonth; $i < $currentMonth+$noOfMonthsFromNow; $i++) {
$months[] = date('F', mktime(0, 0, 0, $i, 1));
$years[] = date('Y', mktime(0, 0, 0, $i, 1));
}
for ($i=0;$i<count($months);$i++){
$d = date_create($dayCondition.' '.$months[$i].' '.$years[$i]);
if($d instanceof DateTime) echo $d->format('l F d Y H:i:s').'<br>';
}
?>
This can be tested at: http://www.phpfiddle.org/lite/
$beginningOfMonth = strtotime(date('Y-m-01')); // this will give you the timestamp of the beginning of the month
$numTuesdaysPassed = 0;
for ($i = 0; $i <= date('d'); $i ++) { // 'd' == current day of month might need to change to = from <= depending on your needs
if (date('w', $beginningOfMonth + 3600 * $i) == 2) $numTuesdaysPassed ++; // 3600 being seconds in a day, 2 being tuesday from the 'w' (sunday == 0)
}
Not sure if this will work, and there's probably a better way to do it; don't have the means to test it right now but hopefully this puts you on the right track! (I get tripped up on date math a bit too, especially with timezones)

Getting the next date of a day in MySQL database (PHP)

I have a series of weekly events in a database along with the day they happen on (in full form, so: 'Monday', 'Tuesday' etc). I've successfully printed the events in a while loop ordered by today, tomorrow, etc, but I'd like to put the date in brackets next to each one.
I thought it might be a case of (mock code):
$today = date("l");
$todays_date = date("j M");
if (day == $today) {
$date = $todays_date;
}
else if (day == $today + 1) {
$date = $todays_date + 1;
}
else if (day == $today + 2) {
$date = $todays_date + 2;
}
etc...
But I'm not so sure. It'd be ideal if I could just have the date in the database, but this seems to go against the grain of what MySQL is about.
Also, I'd like to ideally format the date as: 11 Jun.
EDIT
Presumably it's also got to fit into my while loop somehow:
if($result && mysql_num_rows($result) > 0) {
while ($row = mysql_fetch_array($result)) {
$items[] = array($row[0]);
echo "<option>" . $row[0] . "</option>";
}
}
You can use strtotime?
echo "Today: ".date("j M");
echo "Tomorrow: ".date("j M", strotime("+1 day"));
You can use strtotime:
echo strtotime("+1 day");

Finding all weekdays in a month

How do I go about getting all the work days (mon-fri) in a given time period (let's say, today till the end of the next month) ?
If you're using PHP 5.2+ you can use the library I wrote in order to handle date recursion in PHP called When.
With the library, the code would be something like:
$r = new When();
$r->recur(<start date here>, 'weekly')
->until(<end date here>)
->wkst('SU')
->byday(array('MO', 'TU', 'WE', 'TH', 'FR'));
while($result = $r->next())
{
echo $result->format('c') . '<br />';
}
This sample does exactly what you need, in an quick and efficient way.
It doesn't do nested loops and uses the totally awesome DateTime object.
$oDateTime = new DateTime();
$oDayIncrease = new DateInterval("P1D");
$aWeekDays = array();
$sStart = $oDateTime->format("m-Y");
while($oDateTime->format("m-Y") == $sStart) {
$iDayInWeek = $oDateTime->format("w");
if ($iDayInWeek > 0 && $iDayInWeek < 6) {
$aWeekDays[] = clone $oDateTime;
}
$oDateTime->add($oDayIncrease);
}
Try it here: http://codepad.org/wuAyAqnF
To use it, simply pass a timestamp to get_weekdays. You'll get back an array of all the weekdays, as timestamps, for the rest of the current month. Optionally, you can pass a $to argument - you will get all weekdays between $from and $to.
function get_weekdays ($from, $to=false) {
if ($to == false)
$to = last_day_of_month($from);
$days = array();
for ($x = $from; $x < $to; $x+=86400 ) {
if (date('w', $x) > 0 && date('w', $x) < 6)
$days[] = $x;
}
return $days;
}
function last_day_of_month($ts=false) {
$m = date('m', $ts);
$y = date('y', $ts);
return mktime(23, 59, 59, ($m+1), 0, $y);
}
I suppose you could loop through the dates and check the day for each one, and increment a counter.
Can't think of anything else off the top of my head.
Pseudocode coming your way:
Calculate the number of days between now and the last day of the month
Get the current day of the week (i.e. Wednesday)
Based on the current day of the week, and the number of days left in the month, it's simple calculation to figure out how many weekend days are left in the month - it's going to be the number of days remaining in the month, minus the number of Sundays/Saturdays left in the month.
I would write a function, something like:
daysLeftInMonth(daysLeftInMonth, startingDayOfWeek, dayOfWeekToCalculate)
where:
daysLeftInMonth is last day of the month (30), minus the current date (15)
startingDayOfWeek is the day of the week you want to start on (for today it would be Wednesday)
dayOfWeekToCalculate is the day of the week you want to count, e.g. Saturday or Sunday. June 2011 currently has 2 Sunday, and 2 Saturdays left 'til the end of the month
So, your algorithm becomes something like:
getWeekdaysLeft(todaysDate)
...getWeekdaysLeft is something like:
sundaysLeft = daysLeftInMonth(lastDayOfMonth - todaysDate, "Wednesday", "Sunday");
saturdaysLeft = daysLeftInMonth(lastDayOfMonth - todaysDate, "Wednesday", "Saturday");
return ((lastDayOfMonth - todaysDate) - (sundaysLeft + saturdaysLeft));
This code does at least one part you ask for. Instead of "end of next month" it simply works with a given number of days.
$dfrom = time();
$fourweeks = 7 * 4;
for ($i = 0; $i < $fourweeks; $i ++) {
$stamp = $dfrom + ($i * 24 * 60 * 60);
$weekday = date("D", $stamp);
if (in_array($weekday, array("Mon", "Tue", "Wed", "Thu", "Fri"))) {
print date(DATE_RSS, $stamp) . "\n";
}
}
// Find today's day of the month (i.e. 15)
$today = intval(date('d'));
// Define the array that will hold the work days.
$work_days = array()
// Find this month's last day. (i.e. 30)
$last = intval(date('d', strtotime('last day of this month')));
// Loop through all of the days between today and the last day of the month (i.e. 15 through 30)
for ( $i = $today; $i <= $last; $i++ )
{
// Create a timestamp.
$timestamp = mktime(null, null, null, null, $i);
// If the day of the week is greater than Sunday (0) but less than Saturday (6), add the timestamp to an array.
if ( intval(date('w', $timestamp)) > 0 && intval(date('w', $timestamp)) < 6 )
$work_days[] = mktime($timestamp);
}
The $work_days array will contain timestamps which you could use this way:
echo date('Y-m-d', $work_days[0]);
The code above with work in PHP 4 as well as PHP 5. It does not rely on the functionality of the DateTime class which was not available until PHP 5.2 and does not require the use of "libraries" created by other people.

how can i make any numbers above the month's total days appear as new month day numbers?

I have a php calendar at http://idea-palette.com/aleventcal/calendar.php.
I want the days that are not part of the current month to show up grayed out(which it does now), and I want it to appear as those are the days of the previous and next month.
As it is now, the days that appear before the first day of the month appear as negative numbers(-1,-2,-3, and so on) and the days that appear after the last day of the month just continue on, so if a month ends on the 31st, then it would read 32, 33, 34, and so on.
I'm trying to figure out a conditional statement with some sort of loop where I could see if it is greater than the total days and then do something else. The problem I see is that the table cell that is being created is being looped, so if I do just $day+1, then instead of 32, it will just read 33.
Here's my code:
for($i=0; $i< $total_rows; $i++)
{
for($j=0; $j<7;$j++)
{
$day++;
//if the current day is less or equal to the total days in the month
if($day>0 && $day<=$total_days_of_current_month)
{
$date_form = "$current_year/$current_month/$day";
echo '<div class="date_has_event" href="#"><td';
//If the date is today then give the td cell the 'today' class
if($date_form == $today)
{
echo ' class="today"';
}
//check if any event stored for the date
if(array_key_exists($day,$events))
{
//adding the date_has_event class to the <td> and close it
echo ' class="date_has_event">'.$day;
//adding the eventTitle and eventContent wrapped inside <span> & <li> to <ul>
echo '<div class="events"><ul>'.$events[$day].'</ul></div>';
}
}
else //if the current day is less or more than the total days in the month
{
//then create a table cell with the current day of the mont
echo '<td class="padding">' . $day . ' </td>'; h
}
}
}
just subtract the number of days in the current month of the day is positive:
else //if the current day is less or more than the total days in the month
{
if($day > 1){
echo '<td class="padding">' . ($day - $total_days_of_current_month) . ' </td>'; // the next month
} else {
echo '<td class="padding">' . $day . ' </td>'; //then create a table cell with the current day of the month
}
}
Here's part of a calendar function I recently wrote, you can hopefully get some ideas from it.
// $month is a UNIX timestamp
// resetting to 1st of the month
$date = getdate(mktime(0, 0, 0, date('n', $month), 1, date('Y', $month)));
// resetting to first day in grid
$date = getdate(strtotime("-$date[wday] days", $date[0]));
$out = array();
$lastDay = mktime(0, 0, 0, date('n', $month), date('t', $month), date('Y', $month));
while ($date[0] <= $lastDay) {
$row = array();
for ($x = 0; $x <= 6; $x++) {
$attr = array('class' => 'weekday '.low(date('D', $date[0])));
if (date('n', $month) != $date['mon']) {
$attr['class'].= ' prevNextMonth';
}
if (date('Y-m-d') == date('Y-m-d', $date[0])) {
$attr['class'].= ' today';
}
$row[] = array($date['mday'], $attr);
$date = getdate(strtotime("+1 day", $date[0]));
}
$out[] = $row;
}
// makes table rows out of the array, considers the $attr array as well
$out = $this->Html->tableCells($out);
$out = sprintf('<table><tbody>%s</tbody></table>', $out);
You don't need Steve's conditional: instead use
echo '<td class="padding">' . date("j",mktime(12,0,0,$current_month,$day,$current_year)) . ' </td>';
mktime handles out-of-range dates my moving them into the next or previous month, which is exactly what you want.

Categories