MySQL query with DATE_FORMAT() to Laravel Querybuilder (or Eloquent) - mysql

I'm trying to get records from a table on a specific day.
Dates's format: datetime (YYYY-MM-DD HH:II:SS)
I'm trying to translate a MySQL query to Laravel query builder. But I don't know how to deal with the DATE_FORMAT().
Here is MySQL query
SELECT * FROM events
JOIN customers ON events.id_customer = customers.id
WHERE start_date > DATE_FORMAT("2017-06-15", "%Y-%m-%d %H:%i:%s")
AND end_date < DATE_FORMAT("2017-06-16", "%Y-%m-%d %H:%i:%s")
;
In my controller I get a date (string) that I put into a DateTime
$date_datetime = new \DateTime(Input::get('date_string'));
And then change its format
$query_date = date_format($date_datetime, 'Y-m-d H:i:s');
I've tried the following code, but it is obviously not working
$pdf_events = DB::table('events')
->join('customers', 'events.id_customer', '=', 'customers.id')
->select(...)
->whereRaw("start_date > DATE_FORMAT($query_date, '%Y-%m-%d %H:%i:%s')")
->whereRaw("end_date < DATE_FORMAT($query_date, '%Y-%m-%d %H:%i:%s')+1")
->get();

I strongly recommend using Carbon for handling DateTime in Laravel since it has support out of the box.
Now, how to use it to resolve your problem?
First, you need to convert your input into Carbon object.
$start_date = Carbon::parse(Input::get('date_string'));
// Assuming you want the end date 1 day later at same time
$end_date = $start_date->addDay();
// You could change the format with format() but in this case we don't need to
Then in your Eloquent, you can use the Carbon Datetime object to query using where()
$pdf_events = DB::table('events')
->join('customers', 'events.id_customer', '=', 'customers.id')
->select(...)
->where("start_date", ">", $start_date)
->where("end_date", "<", $end_date)
->get();

You can pass Carbon (doc) objects to compare dates. For example:
->where('start_date', '=', Carbon::now())
You can build a custom Carbon object for a custom date-time to pass into the where clause.

You don't need DATE_FORMAT, Try this:
$query_start_date = \Carbon\Carbon::createFromFormat("Y-m-d H:i:s", request()->date_string);
// Add 1 day to the date
$query_end_date = $query_start_date->addDay();
$pdf_events = DB::table('events')
->join('customers', 'events.id_customer', '=', 'customers.id')
->where(
[
["start_date", ">", $query_start_date],
["end_date", "<", $query_end_date]
]
)->get();

use Datetime;
$end_date1 = $request->input('end_date');
$EndDateTime = DateTime::createFromFormat('d/m/Y H:i:s', $end_date1);
$end_date = $EndDateTime->format('Y-m-d H:i:s');
try like this its work for me

Related

Laravel - query the same column with two conditions

I want to get all the datas that were created 30-365 days ago. Tried following codes but it's not working.
Database:
id created_at
1 2022-05-09
2 2021-06-08
Here id 2 was created before 365 days from today(2022-06-10), so it should not be shown. However id 1 was created before 30 days but not more than 365 days. So only id 1 should be shown.
Code 1:
$today = Carbon::now();
$doubtfulLoan = Loan::select('*')
->where(function($query) use ($today) {
return $query
->where('created_at', '<', $today->subDays(30)->endOfDay())
->where('created_at', '>=', $today->subDays(365)->endOfDay());
})
->get();
Output: it gives empty array
P.S if the 2nd where clause is commented, it gives both the ids and if the 1st where clause is commented, it gives id 1 only. But keeping both the condition gives empty array. What am I doing wrong?
Code 2:
$today = Carbon::now();
$doubtfulLoan = Loan::select('*')
->where([
['created_at', '<', $today->subDays(30)->endOfDay()],
['created_at', '>=', $today->subDays(365)->endOfDay()]
])->get();
Output: it gives both the array.
Thanks in advance.
You need to get into the habit of using CarbonImmutable to prevent nasty surprises like this. Use this code:
$today = CarbonImmutable::now();
$doubtfulLoan = Loan::select('*')
->where(function($query) use ($today) {
return $query
->where('created_at', '<', $today->subDays(30)->endOfDay())
->where('created_at', '>=', $today->subDays(365)->endOfDay());
})
->get();
This is because you are doing $today->subDays(30)->endOfDay() which changes the instance value of the carbon instance and then doing $today->subDays(365)->endOfDay() which changes it again. This is however the same instance, so the query builder will do:
SELECT * FROM loans WHERE created_at < '395 days ago' and created_at >= '395 days ago'
since you have passed the same instance. This obviously is never satisfied.
Using the CarbonImmutable class makes all your Carbon objects immutable and any modifications will create a new instance and will not modify the existing instance.
use laravel between method here
$doubtfulLoan = Loan::select('*')
->whereBetween('created_at',[
today()->subDays(365)->startOfDay(),
today()->subDays(30)->endOfDay()
])->get();

PHP Mysql PDO retrieve records by date range

I'm retrieving a list of items from my database using the PDO approach and when I do:
$select['from'] = date('Y-m-d 00:00:00',strtotime("2016-02-01"));
$sql = "SELECT * FROM listings WHERE date_added >= :date AND date_added < DATE_ADD(:date, INTERVAL 30 DAY)";
$statement = $pdo->prepare($sql);
$statement->bindParam(":date", $select['from'], PDO::PARAM_STR);
$statement->execute();
var_dump of my result gives:
object(stdClass)#5 (2) { ["data"]=> array(0) { } ["rows"]=> int(0) }
Running the same query directly through PhpMyAdmin gives the desired result. date_added is data type DATETIME
This can be a problem of your date format.
You have to use the format 'Y-m-d H:i:s' in PHP.
$date = date('Y-m-d H:i:s', strtotime($yourdate));

Laravel - where >= not working

I'm trying to get a database entry with this lines of code:
$hoy = date('YYYY-MM-DD');
$stay = Stay::where('guest', '=', $id )
->where('indate', '<=', $hoy )
->where('outdate', '>=', $hoy )
->get( array( 'id', 'room', 'bed', 'guest', 'booking', 'indate', 'outdate' ) );
The thing is, if I remove the outdate >= $hoy line, it works. But with it, it doesn't.
The line i'm trying to retrieve has it's outdate set to 2015-12-02, so it should return it.
Any ideas?
Looks like this is your problem:
$hoy = date('YYYY-MM-DD');
If you want to generate a date like 2015-12-02, you should do this instead:
$hoy = date('Y-m-d');
Source: http://php.net/manual/en/function.date.php
This query expects both conditions to be true.
If you want to return when either one is true you should try ->orwhere.
If you are looking for both to be true you need to keep in mind that if there are timestamps on the date the query of <= will only find dates with a timestamp of 00:00:00 for the requested date.

Kohana ORM select records by date

I need to get all rows on the specified day, using Kohana ORM. Date field name is 'created_date', stored date format is '0000-00-00 00:00:00' ('Y-m-d H:i:s').
$day = '2015-07-17'; // for example
$items_filtered = ORM::factory($this->_object_name)
->where(DB::expr("DATE_FORMAT('created_date', '%Y-%M-%d')"), '=', $day)
->order_by('created_date', 'DESC')
->find_all();
Thanks in advance!
You would want to use a between query like below:
$dayst = '2015-07-17 00:00:00'
$dayen = '2015-07-17 23:59:59'
$items_filtered = ORM::factory($this->_object_name)
->where('created_date', 'between', array($dayst, $dayen))
->order_by('created_date', 'DESC')
->find_all();

Make Zend\Db (zf2) between clause inclusive

I'm currently using Zend Framework 2 and a query with date ranges to obtain data out of a MySQL DB, and I came across the between clause that was previously not available in ZF1.
However, my code which looks something like this is not working correctly:
$dateStart = '2012-12-20';
$dateEnd = '2012-12-31';
$sql = new Sql($_db);
$select = $sql->select()
->from(array("t" => $table))
->columns(array("col1" => "col_as_1", "col2" => "col_as_2"));
$select->where->between("date", $dateStart, $dateEnd);
$stmt = $sql->prepareStatementForSqlObject($select);
$result = $stmt->execute()->getResource()->fetchAll(\PDO::FETCH_ASSOC);
Apparently the between clause is not inclusive, I can only get results until 2012-12-30, is there a way to make it inclusive? I've been taking a look at the ZF2 docs but they are not very helpful and running the same query on MySQL query browser returns all of the data I need.
So you can try lessThanOrEqualTo and greaterThanOrEqualTo.
Between doesn't seem to provide this functionality: between($identifier, $minValue, $maxValue)
If you trace out your query with $select->__toString() you can see the query as string.
I don't have ZF2 on my computer but I could imagine that between in ZF2 will output date > '2012-12-20' AND date < '2012-12-31'.
NOTE THIS : WHEN USING between on Mysql
date_column_name between 'startDate' AND 'endDate'
NOTE : you should want to insert +1 date to endDate . Because of when you insert 2015-05-18 date to endDate.you can not get data of 2015-05-18.So you need to plus one date to endDate.
You can do it using this
$plusToDate = date('Y-m-d H:i:s', strtotime($toDate . ' + 1 day'));
The BETWEEN should be inclusive, are you sure there are no hours, minutes and seconds after the date, that would cause it not to select dates on 2012-12-31 since 2012-12-31 00:00:01 would technically be > 2012-12-31
Format must be same, use mysql DATE function
$select->where->between("DATE(date)", DATE('.$dateStart.'), DATE('.$dateEnd.'));
$from_date = date('Y-m-d', strtotime($AppCleaner->from_date ));
$to_date = date('Y-m-d', strtotime($AppCleaner->to_date ));
$select->where->between('appointment_date', $from_date . ' 00:00:00', $to_date . ' 23:59:59');
also, Use the between clause as below:
$sql = new Sql($this->adapter);
$select = $sql->select();
$select->from('app_posts');
$select->where->NEST->between( 'id', 30,40);
$select->group('app_posts.id');
// echo $select->getSqlString($this->adapter->getPlatform());
// exit;
$statement = $sql->prepareStatementForSqlObject($select);
$result = $statement->execute();
$resultSet = new ResultSet();
$resultSet->initialize($result);
$posts = $resultSet->buffer()->toArray();
return $resultSet;
Try this:
//I have a static function to make conversion Data Format
public static function convertBrazilianDate2MySQLDatabase($dataBrazil) {
$array = explode("/", $dataBrazil);
$array = array_reverse($array);
$str = implode($array, "/");
return date("Y-m-d", strtotime($str));
}
//In My Service I built my sentence
$dtStart = \Estrutura\Helpers\Data::convertBrazilianDate2MySQLDatabase($dt_start) . ' 00:00:01';
$dtEnd = \Estrutura\Helpers\Data::convertBrazilianDate2MySQLDatabase($dt_end) . ' 23:59:59';
$select->where->between('field name in table', $dtStart, $dtEnd);
[...]