Date Query with Doctrine - php

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();
}

Related

Laravel - Sum values on the same date query builder then "combine" all same date into only 1 row

Consider:
$tglA = $request->tglA;
$tglB = $request->tglB;
$group = $request->group;
$barangId = $request->barangId;
$kodeMerk = $request->kodeMerk;
$interval = DateInterval::createFromDateString('1 day');
$tglTotal = new DatePeriod($tglA, $interval, $tglB);
if($group == 'true') {
if(empty($request->departemenId)) {
$scoreboard = HistoryPenjualan::select('kodeSales', 'departemenId', DB::raw('SUM(score) as totalScore'))
->whereBetween('tgl', [$tglA, $tglB])
->groupBy('departemenId')
->orderBy('totalScore', 'desc')
->get();
}
How can I sum the score value of the same date of whereBetween date range and then not show the duplicated date?
You can try to GROUP BY DATE(tgl):
$scoreboard = HistoryPenjualan::select('kodeSales', 'departemenId', DB::raw('SUM(score) as totalScore'))
->whereBetween('tgl', [$tglA, $tglB])
->groupBy('departemenId', DB::raw('DATE(tgl)'))
->orderBy('totalScore', 'desc')
->get();

Date & time comparison operators >= not showing dates that are equal

I am trying to show events that occur either today or on a later date where today is specifically the problem.
public function getInspirationsMeetingIds()
{
$ids = [];
if (($inspirationMeetings = $this->getCustomField('meetings'))) {
foreach ($inspirationMeetings as $meeting) {
$row = new Inspiration($meeting['meeting']);
$dateFrom = $row->getCustomField('date');
if (strtotime($dateFrom) >= time()) {
$ids[] = $row->getId();
}
}
}
return $ids;
}
For some reason this will only show events that are greater than time() and not the events that are today, but then when i try this:
if (strtotime($dateFrom) <= time()) {
$ids[] = $row->getId();
}
Today's and older events are shown.
I think you need to add a timestamp to your datefrom.
Strtotime will add noon if time is omitted.
See this example https://3v4l.org/cYKO4
if (strtotime($dateFrom ) >= strtotime(date("Y-m-d 00:00"))) {
Will make it show all of datefrom
Edit added the 00:00 at the wrong side
Use the DateTime class http://php.net/manual/en/class.datetime.php
time() gives seconds since Jan 1st 1970. The chance that you hit the exact second is very small, so it will hardly ever match.
Instead, create a date with the time.
$date = new DateTime($dateFrom); // or DateTime::createFromFormat($format, $dateFrom);
$today = new DateTime();
if ($date >= $today) {
// should work
}

Laravel: Compare two dates against today with Eloquent

So I have events table which has start date and end date.
What I want to do is a comparison between today and start date + end date so if today is between start and end, return that collection which will be displayed on page, if it isn't ignore that event.
Problem is that when I retrieve an event I cannot access it as it is return that it doesn't exist in the collection, but it does after view is returned.
Here's my controller:
public function show($id)
{
$today = date("Y-m-d");
$today_dt = new DateTime($today);
$event = Event::with('businesses')
->get();
$test = $event->startdate;
$test2 = $event->enddate;
//something like if $today is not less that start date and not higher than end date, return that collection?
dd($test);
return view('events.showEvent', compact('event'));
}
use where date function like this
$today = Carbon::now();
$event = Event::with('businesses')
->whereDate('startdate', '<', $today->format('Y-m-d'))
->whereDate('enddate', '>', $today->format('Y-m-d'))
->get();
If I understood your problem correctly, I think this should suffice:
$today = Carbon::today();
$event = Event::whereDate('startdate', '>', $today->format('Y-m-d'))
->whereDate('enddate', '<', $today->format('Y-m-d'))
->with('businesses')
->get();
I hope you did search the internet for this problem in the first place
in Model
public function scopeOfToday($query){
$today = \Carbon\Carbon::today()->format('Y-m-d');
return $query->whereRaw("? BETWEEN startdate and enddate",$today);
}
in Controller
public function show($id)
{
$event = Event::ofToday()->with('businesses')->get();
$test = $event->startdate;
$test2 = $event->enddate;
//something like if $today is not less that start date and not higher than end date, return that collection?
dd($test);
return view('events.showEvent', compact('event'));
}

Calculate from exist table

I want to count data from exist table which the date is today. And everyday it counts automaticaly.
I have pembayaran table that include 'tanggal' column as date and 'total' column as number that i will count.
I've tried this code. But it always give me '0'. Did i forget something?
Controller
public function index(){
$today = date('Y-m-d');
$where = array('tanggal' => $today);
$getpem = $this->aruskas_m->selectX('pembayaran',$where)->result();
$jumlah =0;
foreach ($getpem as $row) {
$jumlah += $row->total;
}
$data['kasmasuk'] = $jumlah;
$this->load->view('laporan/aruskas_v', $data);
}
Change
$where = array('tanggal' => $today);
to
$where = array('date(tanggal)='. $today);
Please make sure your date field's format is exactly like this Y-m-d format. Otherwise you have to change the date format of $today perfectly matching with tanggal field in your condition $where = array('tanggal' => $today);

How to include today when iterating a DatePeriod?

Why is today excluded from the returned values?
SELECT DATE(created) AS reg_date,
COUNT(*) AS user_reg_per_day
FROM users
WHERE created > (NOW() - INTERVAL 30 DAY)
GROUP BY reg_date
My query seems to be fine, but I use following PHP to fill in the gaps:
function generate_calendar_days() {
$end = date("Y-m-d");
$today = strtotime($end);
$start = strtotime("-30 day", $today);
$start = date('Y-m-d', $start);
$range = new DatePeriod(
DateTime::createFromFormat('Y-m-d', $start),
new DateInterval('P1D'),
DateTime::createFromFormat('Y-m-d', $end));
$filler = array();
foreach($range as $date) {
$d = $date->format('Y-m-d');
$filler[$d] = 0;
}
return $filler;
}
My guess is $today is not correct.
There is no reason your query should exclude data from the current day unless there is something odd with the way you are writing data to this table. Are you maybe not seeing it because you are not ordering your results (i.e. it is at bottom of result set)?
It would be giving partial day results for the day 30 days ago. As such, you might consider modifying the WHERE condition a bit:
SELECT DATE(created) AS reg_date,
COUNT(*) AS user_reg_per_day
FROM users
WHERE created >= DATE(DATE_SUB(NOW(),INTERVAL 30 DAY))
GROUP BY reg_date
ORDER BY reg_date DESC
The following is comments on update question, since it seems problem is in PHP code.
I do not fully understand why you would mix strtotime functionality with DateTime, DateInterval, DatePeriod. It is good to see that you are using those though as those are drastically underused by many developers.
That being said I might rewrite that function as:
function generate_calendar_days($start = 'today', $days = 30, $days_in_past = true) {
$dates = array();
try {
$current_day = new DateTime($start); // time set to 00:00:00
} catch (Exception $e) {
echo ('Failed with: ' . $e->getMessage());
return false;
}
$interval = new DateInterval('P1D');
if (true === $days_in_past) {
$interval->invert = 1; // make days step back in time
}
$range = new DatePeriod($current_day, $interval, $days);
foreach($range as $date) {
$dates[] = $date->format('Y-m-d');
}
return $dates;
}
Note that here I have added parameters to make your function more flexible. I also only return an array of date strings so as to make the the function more general purpose. You can leave how to work with the array of dates as an implementation detail outside the scope of this function.
Your zero-filled array can easily be constructed outside the function call like this:
$calendar = array_fill_keys(generate_calendar_days(), 0);
Your sentence is perfect, in fact SELECT (NOW() - INTERVAL 30 DAY) returns 2013-12-18 22:33:30. I experimented similar odd problems, and it was because our DDBB server had a different time configuration than our Apache Server, and it gaves us weird results.
Check your servers time configuration, (http://dev.mysql.com/doc/refman/5.5/en/time-zone-support.html)
You can see from the comments in the PHP manual that people have had the trouble including the end date when iterating a DatePeriod. There are various modifications suggested there that can help with that, but for what you're doing you don't really need the end date, since you're always just going back a set number of days from the current date.
You can include the end date by using the "recurrences" form of the DatePeriod constructor.
function generate_calendar_days(int $n): array
{
$range = new DatePeriod(new DateTime("-$n day"), new DateInterval('P1D'), $n);
foreach($range as $date) {
$filler[$date->format('Y-m-d')] = 0;
}
return $filler;
}
$days = generate_calendar_days(30);

Categories