Date comparison working as long as time is 00:00:00 - php

this is my events script that pulls out appointments for the next 7 days, it appears to work ok, but only under one condition........The dates and times are held in the mysql db in datetime format so 2013-12-23 08:30:00 . My script prints out each day and finds appointments for that day for customers that are dropping off or picking up things. The mysql looks through the db and matches the customers with the dropping off or picking up fields to the date being printed and adds them in the div below the date.
The problem I am having is that if the time is set to anything other than 00:00:00 it doesn't pickup that customer for that day. How do I get the comparison to ignore the time and only use the date ?.
// Date box container
echo '<div class="dateboxcontainer">';
// Loop through and create a date for the next 7 days
$days = new DatePeriod(new DateTime, new DateInterval('P1D'), 7);
foreach ($days as $day) {
echo '<div class="datebox">';
echo '<div class="topdate">';
echo strtoupper($day->format('D d')) . PHP_EOL;
echo '</div>';
// Get the names for each day
$theday = strtoupper($day->format('Y-m-d'));
$sqldate = <<<SQL
SELECT *
FROM `jobdetails`
WHERE datedroppingoff = '$theday' OR datepickingup = '$theday'
SQL;
if(!$resultdate = $db->query($sqldate)){
die('There was an error running the query [' . $db->error . ']');
}
while($rowdate = $resultdate->fetch_assoc()){
echo $rowdate['name'];
}
//
echo '</div>';
}
echo '</div>';
//

What you are doing right now is comparing date/time values to just date values. This comparison would fail if the time part is anything other than midnight.
You can fix the comparison by using the DATE() MySql function to compare apples with apples:
WHERE DATE(datedroppingoff) = '$theday' OR DATE(datepickingup) = '$theday'
There are other ways to do the same, for example
WHERE DATEDIFF(datedroppingoff, '$theday') = 0 OR ...
If you had a $nextday value at hand you could also do
WHERE (datedroppingoff >= '$theday' AND datedroppingoff < '$nextday') OR ...

You are storing a specific time and day in mySQL, but only search for a date in your SQL query. As mySQL does not understand the difference between you wanting to search for a complete day or a specific point in time, mySQL assumes you are looking for the day at time 0:00:00.
You have a few options, you could search for a time period (pseudo code, check the borders yourself):
WHERE datedroppingoff > '$theday' AND datedroppingoff < '$theday'+1
another option is to store the date and time in separate db fields. That way you can keep your SQL queries simpler.
Good luck.

Related

PHP count time and divide in daytime/nighttime

I have been trying to figure this out for a week now. My wife has started a new taxi-company and she asked me to code a simple webpage for here where she could press a button to save a timestamp, then the press is again when she gets off work, it then creates a second timestamp
I have an MYSQL database with rows containing the start time and stop time. I have managed to use the diff function to see how much time it is between the two timestamps but now comes the tricky part.
Since it's different payments at different times of the day I need to divide the time at a shortened time.
Up to 19:00 she works "daytime" and after that, she works "nighttime" until 06:00 the other day, then there is "weekend daytime" and "weekend nighttime" as well.
So if she creates a timestamp whit the date and time: 2018-08-08 06:30 and then another timestamp at 2018-08-08 21:00, then I need a script that puts these data in ex "$daytimehours = 12" "$daytimeminutes = 30" and "$nighttimehours = 3" "$nighttimeminutes = 0"
I have managed to create a script that almost works, but it is several pages long, and it contains one if-statement for each different scenario daytime-nighttime, nighttime-daytime etc.
So do anyone has a good idea on how to solve this? or maybe just point me in the right direction. I would be happy to pay some money to get this to work.
My solution is
<?php
date_default_timezone_set('Asia/Almaty');
$endDate = '2018-08-08 21:00';
$startDate = '2018-08-08 06:30';
$nightmare = date('Y-m-d 19:00');
$startDay = date('Y-m-d 06:00');
$diffMorning = strtotime($nightmare) - strtotime($startDate);
$diffNight = strtotime($endDate) - strtotime($nightmare);
echo gmdate('H:i', $diffMorning) . "\n"; // this is the difference from start day till 19:00
echo gmdate('H:i', $diffNight); // this is the difference on nightmare
$total = $diffMorning + $diffNight;
echo intval($total/3600) . " hours \n";
echo $total%3600/60 . " minutes \n";
echo $total%3600%60 . ' seconds';
You can check via online compiler
given two dates stated as:
$endDate = '2018-08-08 21:00';
$startDate = '2018-08-08 06:30';
you can use the PHP Date extension to achieve the difference like this:
$start = date_create($startDate);
$end = date_create($endDate);
$boundnight = clone($end);
$boundnight->setTime(19,00);
$total_duration = date_diff($end,$start);//total duration from start to end
$day_duration = date_diff($boundnight,$start);//daytime duration
$night_duration = date_diff($end,$boundnight);// nighttime duration
you can use the format method to print a human readable string this way:
$total_duration=$total_duration->format('%H:%I');
$day_duration=$day_duration->format('%H:%I');
$night_duration=$night_duration->format('%H:%I');
At this step there is nothing left but you say you want to convert each duration in minutes.So let's build a function :
function toMinute($duration){
return (count($x=explode(':',$duration))==2?($x[0]*60+$x[1]):false);
}
Then you can use it this way:
$total_duration = toMinute($total_duration);
$day_duration = toMinute($day_duration);
$night_duration = toMinute($night_duration);
The output of
var_dump($total_duration,$day_duration,$night_duration) at this step is:
int(870)
int(750)
int(120)

Repeat insert query with a different date given by a frequency

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.

Why is the date "2012-12-01" causing printed table to repeat it over and over?

I know this one is strange. I have a table called schedule with a column called Date with the column type being DATE. I have dates (in YYYY-MM-DD format) from 2012-11-01 to 2013-01-02 in this column. What's happening is if I enter a date, any date, that has 2012-12-01 anywhere in between, it restarts the loop. So if I select 2012-11-15 to 2012-12-15 it will print from Novemeber 15th to December 1st, but then after December 1st it starts printing again at November 15th. If I select 2012-11-15 to 2012-11-30 or 2012-12-02 to 2012-12-30 everything works fine, it's just when that particular date is involved that it causes problems. Here is my code:
<?php
////////////////////////////////////////////////////////
//////First set the date range that we want to use//////
////////////////////////////////////////////////////////
if(isset($_POST['from']) && ($_POST['from'] != NULL))
{
$startDate = $_POST['from'];
echo "<script>alert (\"startDate: " . $startDate . "\")</script>";
}
else
{
//Default date is Today
$startDate = date("Y-m-d");
echo "<script>alert (\"startDate: " . $startDate . "\")</script>";
}
if(isset($_POST['to']) && ($_POST['to'] != NULL))
{
$endDate = $_POST['to'];
echo "<script>alert (\"endDate: " . $endDate . "\")</script>";
}
else
{
//Default day is one month from today
$endDate = date("Y-m-d", strtotime("+1 month"));
echo "<script>alert (\"endDate: " . $endDate . "\")</script>";
}
//////////////////////////////////////////////////////////////////////////////////////
//////Next calculate the total amount of days selected above to use as a limiter//////
//////////////////////////////////////////////////////////////////////////////////////
$dayStart = strtotime($startDate);
$dayEnd = strtotime($endDate);
$total_days = abs($dayEnd - $dayStart) / 86400 +1;
echo "<script>alert (\"Total Days: " . $total_days . "\")</script>";
//////////////////////////////////////////////////////////////////////////////////////////////////////////
//////Then we're going to get the date range specified from the schedule table and print the results//////
//////////////////////////////////////////////////////////////////////////////////////////////////////////
//Select the dates from the schedule table, limited to the total amount days.
$sql = ("SELECT Date FROM schedule WHERE Date BETWEEN '$startDate' AND '$endDate' LIMIT $total_days");
//Run a check on the query to make sure it worked. If it failed then print the error.
if(!$result_date_query = $mysqli->query($sql))
{
die('There was an error getting the date from the schedule table [' . $mysqli->error . ']');
}
//Loop through the results while a result is being returned.
while($row = $result_date_query->fetch_assoc())
{
//First format and then print the all the dates selected.
echo "<td class=\"schedule_date_cell\">" . date('M j', strtotime($row['Date'])) . "</td>";
}
//Free the result.
$result_date_query->free();
?>
I am at a loss. I've added in some echo statements to show what's going on and everything is as expected. I just don't understand how all dates before and all dates after work perfectly, but anything that has Dec 1st in it makes it restart the loop. I'm not sure if it's relevant, but there are multiples of the same dates in the column, which is why I have set LIMIT in the query.
I'm hoping someone can crack this case wide open as I'm dying to know the answer!
**EDIT: **I tried this same query from within PHPmyadmin as suggested in the comments, and it produces the same results. I also tried removing the LIMIT as well as changing from single quotes '2012-11-01' to double quotes "2012-11-01" with still the same results.
**EDIT2: **For each date in the Date column, there are 92 instances of each date. So, for example, there are 92 records of 2012-12-01 and 92 records of 2012-12-02 and so on. The interesting thing is, when I remove LIMIT from the query and use the date range of 2012-11-30 to 2012-12-15 (Nov 30th to Dec 15th) is prints Nov 29th, Nov 30th, Dec 1st then repeats those three dates again and again, 92 times! Then after that it starts to print the rest of the days Dec 2nd, Dec 3rd, Dec 4th ...Dec 15th and then repeats THOSE dates again and again, 92 times! This just proves that for some reason the loop is restarting at Dec 1st because if I enter a date range of Nov 1st to Nov 3rd it prints all dates in the range before repeating itself 92 times. The reason for the LIMIT was so to stop it from returning all instances of each date, so I would only get Nov 1st to Nov 3rd one time and not 92 times, but when the limit is removed we can see that Dec 1st is causing some weird issues.
**EDIT3: **I created a new table schedule2 identical to schedule and entered the same date range of 2012-11-01 to 2013-01-02, but this time with only one instance of each. Then I ran my query again and it works perfectly, in any date combination. So obviously the problem is that there is more than one instance of this date in the schedule table, but I can't figure out WHY it's a problem. I don't understand what this date is having an affect on the while loop. And before you suggest it, yes, I do need to have multiple instances of the same date in the table ;)
There's no need to use a LIMIT clause. Instead, change your query to make sure it does not return any dates more than once:
SELECT DISTINCT(Date) FROM schedule WHERE Date BETWEEN '$startDate' AND '$endDate'
That will give you each date just once.
You probably have an index on the Date column (which is good), and the index sorts all dates in November before dates in December (at least for the same year). And you would have the same issue for date ranges that start in December and end in January.
The fact that it loops at Dec 1st is for the most part just a coincidence. I don't know the specifics of how MySQL works internally, but if you don't give it an order, then it will apply whatever order it feels like to the data when you request it.
Combine this with the fact that you have duplicate dates, and then you end up with the situation have you described spontaneously happening for no apparent reason.
Since you want each date exactly once, and you want them to appear in order chronologically, then you need to tell MySQL you want those two things when you make the query. As such, add DISTINCT AND ORDER BY commands:
SELECT DISTINCT(Date) FROM schedule WHERE Date BETWEEN '$startDate' AND '$endDate' ORDER BY Date ASC
You could have prevented the duplication by adding a UNIQUE index on the columns that define an entry for a particular date.
This is pretty easy to add after the fact if you've cleaned up your data to remove duplicates:
ALTER TABLE schedule ADD UNIQUE INDEX index_on_date (date)
The alternative is to select only one row per date, which usually amounts to appending GROUP BY date at the end of your query.

Using PHP to select table entries using two date fields and current month

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";

Looping through dates until a free one is found

I have a function which checks my database to see if a date exists, if it does exist, i want to display the next date which isnt in the database.
Is this possible?
My function returns 1 if there is a date in the database and 0 if there isnt, im using codeigniter, but not using any built in functions.
Its basically an availability checker, it allows us to input many different dates in the database, so calling my function i use
$availcheck = $ci->availability->check_availability_by_date(date('d/m/Y'));
The i use a if statement to check if the first time it runs it returns a value, this is how i have it
if($availcheck > 0){
// loop through the next dates and run the function again to see if it returns 0
} else {
echo 'available now';
}
I guess i would add 1 to the current date, check that one, then add another 1 and check that and so on.
Im just not sure how.
Cheers,
if i understand you correct , your problem is adding the day ?
if so i would suggest using the epoch or unix time
so convert the date to unix time using mktime than just add 1 day in seconds (24*60*60)
and then convert back to d/m/y format.
you can use the date function.
$date = time(); // get current timestamp
while ($availcheck) // while date IS found in database
{
$availcheck = $ci->availability->check_availability_by_date(date('d/m/Y',$date));
$date = $date + (24*60*60); // add one day
}
$date = $date - (24*60*60); // reduce one day
echo date('d/m/Y',$date); // prints the first date that is not in the DB
This SQL code could work for me.
$today = date("Y-m-d"); //today
$sql = "SELECT date FROM calendar WHERE date>'{$today}' AND date<='2100-12-31' AND date='0000-00-00' LIMIT 1";
Since you can't determine the ending date, 2100 could be for testing.

Categories