I want to create a function that checks, if a specific time is between two timestamps that are stored in a MySQL database.
The function should be able to ignore the time ($fullday = true) or check the time as well.
My presence table has a row with start = 2021-11-01 10:00:00 and end = 2021-11-05 18:00:00.
is_available('2021-11-02', true); should give me a result, but is doesn't.
What I expect as well:
is_available('2021-11-01 09:30:00'); should not have a result, as 9:30 is before 10:00 but is_available('2021-11-01 10:01:00'); should give me a result. And so on.
The query, my function creates is:
SELECT *
FROM `presence`
WHERE DATE_FORMAT(start, "%Y-%m-%d") <= "2021-11-02"
AND DATE_FORMAT(end, "%Y-%m-%d") >= "2021-11-02"
And this my function so far:
function is_available($date, $fullday = false)
{
$presenceModel = new PresenceModel();
if ($fullday) {
$date = date('Y-m-d', strtotime($date));
$presences = $presenceModel
->where('DATE_FORMAT(start, "%Y-%m-%d") <= "' . $date . '"')
->where('DATE_FORMAT(end, "%Y-%m-%d") >= "' . $date . '"')
->findAll();
} else {
$date = date('Y-m-d H:i:s', strtotime($date));
$presences = $presenceModel
->where('DATE_FORMAT(start, "%Y-%m-%d %H:%i:%s") <= "' . $date . '"')
->where('DATE_FORMAT(end, "%Y-%m-%d %H:%i:%s") >= "' . $date . '"')
->findAll();
}
return count($presences) > 0 ? true : false;
}
You should be able to simplify this dramatically by getting MySQl to do more of the work. You don't need to format DATETIME columns to do comparisons on them, and BETWEEN will further reduce your PHP effort.
Based on your code above I think this will do the job:
function is_available($date, $fullDay = false) {
$presenceModel = new PresenceModel();
$date = date('Y-m-d H:i:s', strtotime($date));
if ($fullDay) {
$presences = $presenceModel
->where("'$date' between DATE(`start`) and DATE(`end`)" )
->findAll();
} else {
$presences = $presenceModel
->where("'$date' between `start` and `end`" )
->findAll();
}
return count($presences) > 0 ? true : false;
}
However, using SELECT * will return the entirety of all the matching rows, when all you really need is whether one exists. You should aim to get your query something close to this, which will return just a single value (1) if there's a matching row.:
SELECT 1 FROM `presence`
WHERE "2021-11-02" between start AND end
LIMIT 1
My approach would be to use strtotime() function to convert the date into an int and then convert the other date from the db and then compare those ints in php.
if($datenow > $dbstartdate && $datenow < $dbenddate){
return true;
}else{
return false;
}
Related
I need to be able to get the total amount spent either monthly or daily. To do that I do sum(tblaccounts.amountin) but the issue i'm having is I need to convert my date column to a different timezone fist. I've tried messing with convert_tz(date,"+00:00","+10:00") but not sure how to use it with LIKE.
How can I get records for monthly or daily based on the $period variable while first converting the timestamp?
Something like WHERE convert_tz(date) LIKE $date_to_check%
function check_limit($period='monthlylimit') {
if ($period == 'monthlylimit') {
$date_to_check = date("Y-m");
}
else { ### Day period
$date_to_check = date("Y-m-d");
}
$select = "SELECT
sum(tblaccounts.amountin) as amountin
FROM tblaccounts
WHERE date LIKE '" . $date_to_check . "%'";
}
Utilizing the timezone change inside mysql, this should work out:
if ($period == 'monthlylimit') {
$date = date('Ym');
$format = '%Y%m';
} else {
$date = date('Ymd');
$format = '%Y%m%d';
}
$sql = "SELECT SUM(t.amountin) as amountin FROM tblaccounts t WHERE
DATE_FORMAT(CONVERT_TZ(t.date,'+00:00','+10:00'),'". $format ."') = '". $date ."'";
The correct timezone numbers, will depend on what you have mysql defaulted too, and your desired result. You may have to twiddle with that number.
Or you can change the timezone for the date on php's side and skip mysql tz converting:
$dt = new DateTime("now", new DateTimeZone($tz));// $tz to equal what you are aiming for
$dt->setTimestamp(time());// might not be needed
if ($period == 'monthlylimit') {
$date = $dt->format('Ym');
$format = '%Y%m';
} else {
$date = $dt->format('Ymd');
$format = '%Y%m%d';
}
$sql = "SELECT SUM(t.amountin) as amountin FROM tblaccounts t WHERE
DATE_FORMAT(t.date,'". $format ."') = '". $date ."'";
Note: I did not use LIKE here, as that is why I introduced DATE_FORMAT to set it to a single value to compare on.
I have following format 2016-06-06 TO 2016-06-12
I want to know that whether my date i.e 2016-06-11 lies in between or not. How can I do this?
You can use PHP if condition for checking date range:
$compareDate = "2016-06-06 TO 2016-06-12";
$dateArr = explode(" TO ",$compareDate);
$starting_date = $dateArr[0];
$final_date = $dateArr[1];
$date = "2016-06-11";
if($date >= $starting_date && $date <= $final_date) {
...
}
if($date >= $fome_date && $date <= $to_date)
{
echo "yes";
}
else
{
echo "no";
}
https://3v4l.org/UdIgq
i hope it will be helpful
Dates can be compared just as numbers can be
So using
date > starting_date && date < final_date
Will be just fine for an if clause. Also if you have I would recommend you do this in the database part as dbs have built in queries for such occasions.
i'm trying to add X month to a date taken from my database
$sql_batch = "SELECT * FROM mgm_subscription WHERE status = '1'"
$query_batch = mysql_query($sql_batch);
$row_batch = mysql_fetch_array($query_batch);
$addMonth = 3;
$startDate = $row_batch['start_month'];
$endDate = strtotime('+'.$addMonth.' month', $startMonth); // add number of days from form
$endDate = date('m/d/y H:i:s', $endDate );
$sql_date = "INSERT INTO user_subscription (user_id, start_month, end_month, sub_status) VALUES ('".$usercode2."','".$startDate."','".$endDate."', '')";
$query_date = mysql_query($sql_date);
NULL was inserted into the end_month.
start_month and end_month is DATE type in the mysql
how do i fix this? tq.
If I understood your question, your $endDate should be
$endDate = date('Y-m-d', strtotime($startDate.' +'.$addMonth.' months'));
So this will equate to:
$endDate = $startDate + 3 months /* in Y-m-d format */
EDIT: Just saw that your column datatype is Date. This would mean that you can't store timestamp in your date. It has to be Y-m-d format only as that is the valid mysql format supported.
You insert $endMonth a value(number of days from form) then you try to replace it ($endMonth) and you call back your replaced variable..
$endMonth = strtotime('+'.$addMonth.' month', $startMonth); // add number of days from form
$endMonth = date('m/d/y H:i:s', $endMonth);
It will return null value.. My suggestion, try to put other variable to prevent duplicate value or missing data
You only mention adding X months. Maybe I misunderstood your question, but if all you care about is the month, I would do the following:
if ($startMonth === 'January') {
$monthNumber = 1;
} else if ($startMonth === 'February') {
$monthNumber = 2;
} //Up to November then finish with {
else {
$monthNumber = 12;//December
}
$newMonthNumber = $monthNumber + $addMonth;
if ($newMonthNumber % 12 == 1) {
$endMonth = 'January';
} else if ($newMonthNumber % 12 == 1) {
$endMonth = 'February';
} //Up to November then finish with {
else {
$endMonth = 'December';
}
$sql_date = "INSERT INTO user_subscription (user_id, start_month, end_month, sub_status) VALUES ('".$usercode2."','".$startMonth."','".$endMonth."', '')";
$query_date = mysql_query($sql_date);
I am trying to compare two date strings of type d/m/y, but it seems that something with the comparison of that type of dates doesn't work. I thought to use DateTime PHP's function, but at first I want to learn why the script above doesn't work.
Here is the code:
public function listActiveNews(){
$today = strtotime(date('d/m/Y'));
$db = mysql_init();
$sql = "SELECT * FROM ph_news WHERE newActive = 1";
$prq = $db->prepare($sql);
$prq->execute();
foreach($prq->fetchAll(PDO::FETCH_ASSOC) as $fetch){
$dateFrom = strtotime($fetch['newsDateFrom']);
$dateUntil = strtotime($fetch['newsDateUntil']);
if ( ($today >= $dateFrom) && ($today <= $dateUntil) ){
print date('d/m/Y') . " >= " . $fetch['newsDateFrom'] .
" && " . date('d/m/Y') . " <= " .
$fetch['newsDateUntil'] ."<br>" ;
print $fetch['Title'];
}
}
}
I am getting this result and I cannot understand why the comparison of these dates returns TRUE in the if clause.
Output:
28/02/2014 >= 20/03/2014 && 28/02/2014 <= 27/02/2014
Title
Here are the dates values:
date('d/m/Y') = 28/02/2014
$newsDateFrom = 20/03/2014
$dateUntil = 27/02/2014
Really... stop abusing the date system. $today = strtotime(date('d/m/Y')); is utterly pointless. $today = time() is the less convoluted and far more efficient version.
Plus, why are you doing the time filtering in PHP when you could simply do it in MySQL?
SELECT *
FROM ph_news
WHERE (newActive = 1) AND (curdate() BETWEEN newsDateFrom AND newsDateUntil)
will fetch only the records you actually want. Right now you're fetching pretty much the entire table, and then throwing away most everything except the few records you really did want.
I have fields in my table for date, but they contain everything - day, year and month. Can I write a query to get only the records, which has month equal to the current month? I can do this:
$today = new \DateTime();
$month = $today->format('m');
$cat = $em->getRepository('EMBudgetTrackerBundle:Expense')->find(1);
$ex_date = $cat->getDate();
and compare $month and $ex_date, but can I write some kind of query? Something like this:
public function getExpensesByMonth($month)
{
$q = $this->createQueryBuilder('e');
$q->select('e')
->where('e.date = :date')
->setParameter('date', $month);
return $q->getQuery()->getResult();
}
Thank you in advance! :)
If you database column is in DateTime format you can use the DateTime object in your query. As far as I know you can only query for time ranges though.
public function getExpensesByMonth($beginning, $end)
{
$q = $this->createQueryBuilder('e');
$q->select('e')
->where('e.date > :beginning')
->andWhere('e.date < :end')
->setParameter('beginning', $beginning)
->setParameter('end', $end);
return $q->getQuery()->getResult();
}