yii2 find values between two timestamps - php

What am trying is to query orders created between two dates
so i have
$maxdate = ; //timestamp value
$mindate = ; //timestamp value
$orders = Orders::find()->where(["created_at" ..]) //stuck hre
IN normal words would be
find where created_at is between $maxdate and $mindate
How do i go about this?

You may achieve your goal by this
$orders = Orders::find()->where(["between", "created_at", $mindate, $maxdate])
This is the fully reference about building various of Queries

Related

How to compare created_at timestamp with Carbon date In laravel?

I have orders table , I want to get orders that have been created at this month only (delivery process happens at the same day).
I want to compare between the carbon date which refers to this current month with the created_at field of type timestamps for orders.
This is my attempt:
$month = Carbon::today();
$currentMont = $month->month;
$thisMonthOrders = Order::where('place_id',$id)->where('stage',9)->whereDate('created_at',$currentMont)->get();
dd($thisMonthOrders);
The output that it gives me is an empty array.
You'll need to use the MONTH function in MySQL, along with a whereRaw:
$thisMonthOrders = Order::where('place_id',$id)
->where('stage',9)
->whereRaw('MONTH(created_at) = ?',[$currentMont])
->get();
However, you'll have issues when you have multiple years, unless you also add in a YEAR check. You might have better luck with whereBetween instead.
$start = Carbon::now()->startOfMonth();
$end = $start->copy()->endOfMonth();
$thisMonthOrders = Order::where('place_id',$id)
->where('stage',9)
->whereBetween('created_at',[$start, $end])
->get();

Adding DateTime intervals with foreach loop

I asked a question yesterday in adding together datetime intervals and was pointed to this thread - How we can add two date intervals in PHP
This is great and makes sense. However, when I try to do what the submitted answer says in a foreach loop, I'm ending up with an incorrect result.
This is a function I have made that gets all the clock in times and out times of staff, they are stored in the db and are created using PHP's date(H:i:s).
My function gets all the in and out times of any given employee, and my reporting feature I'm working on needs to display the total amount of hours they have worked.
I tried to achieve this by converting the times to datetime objects and using ->diff to get the intervals and thus calculating that days hours, I am then trying use a foreach loop to add the intervals together thus giving me a sum total of the hours worked in any given date range.
The whole function together is this:
function getTotalHours($staff_id,$from_date,$to_date){
$sql = "SELECT * FROM oc_staff_times WHERE date BETWEEN '$from_date' AND '$to_date' AND staff_id = '$staff_id'";
$result = $this->conn->query($sql);
if ($result->num_rows > 0) {
while ($row = mysqli_fetch_assoc($result)) {
$data[] = $row;
}
$base_time = new DateTime('00:00');
$total = new DateTime('00:00');
foreach ($data as $time) {
$in = new DateTime($time['clock_in_time']);
$out = new DateTime($time['clock_out_time']);
$interval = $in->diff($out);
$base_time->add($interval);
}
return $total->diff($base_time)->format("%H:%I");
}
}
I was hoping to get a monthly total, however it seems I'm only getting one days total as my final result. Here is a screen shot of the UI (the total hours are crudely circled) this also shows the time stamps my function should be adding together.
You can do this in a single query instead. Use TIMEDIFF() to get the difference for each row, then convert those to seconds by using TIME_TO_SEC(), SUM() those up and put it back into time-format with SEC_TO_TIME() - all in MySQL!
SELECT SEC_TO_TIME(SUM(TIME_TO_SEC(TIMEDIFF(`clock_out_time`, `clock_in_time`))))
FROM `oc_staff_times`
WHERE `staff_id` = ?
AND `date` BETWEEN ? AND ?
Making your function with a prepared statement..
function getTotalHours($staff_id, $from_date, $to_date){
$sql = "SELECT SEC_TO_TIME(SUM(TIME_TO_SEC(TIMEDIFF(`clock_out_time`, `clock_in_time`))))
FROM `oc_staff_times`
WHERE `staff_id` = ?
AND `date` BETWEEN ? AND ?";
$stmt = $this->conn->prepare($sql);
$stmt->bind_param("sss", $staff_id, $from_date, $to_date);
$stmt->execute();
$stmt->bind_result($totalTime);
$stmt->fetch();
$stmt->close();
return $totalTime;
}
SQL fiddle showing the query in action http://sqlfiddle.com/#!9/525b83/7
The answer from Qirel offers a nice way to do this in SQL, however if you want to understand why your code didn't work:
$base_time = new DateTime('00:00'); does not create an interval, it's a date. It means that if you add 24 hours to it and ask only the time part, it will show '00:00' because you end up the day after.
One solution would have been to declare $base_time as an interval, for example like this:
$base_time = new DateInterval('PT0S');
And at the end output directly like this:
$base_time->format("%H:%I");

How to check trip start-date and end-date with start-time and end-time in codeigniter

I am working on Booking system where a user can book their cars, before adding any trip inside the database/table I want to check the trip already exist between the dates and times.
Here is my query inside my model.
$this->db->select('trId')
->from('trips')
->where('carId',$data['carId'])//car Id
->where('tripStart <=',$data['tripStart'])//trip start date
->where('tripEnd >= ',$data['tripEnd'])//trip end date
->where('tripStartTime <= ',$data['tripStartTime'])//trip start time
->where('tripStartEnd >=',$data['tripStartEnd'])//trip end time
->get();
I have stored the values in my trips table is
tripStart = '2018-03-01'
tripEnd = '2018-03-03'
tripStartTime = '09:00:00'
tripStartEnd = '13:00:00'
select trId from trips
where carId = value AND
(Between tripStart = "value" AND tripEnd = "value") AND
(Between tripsStartTime = "value" AND tripStartEnd = "value");
This that What you want
Yes you can but before that you have to concate sql columns for comparing
Know SQL CONCAT
Also you need to combine your variables using into datetime using strtotime PHP function
<?php
$tripStart = '2018-03-01';
$tripEnd = '2018-03-03';
$tripStartTime = '09:00:00';
$tripStartEnd = '13:00:00';
$from = date('Y-m-d H:i:s',strtotime($tripStart.$tripStartTime));
$to = date('Y-m-d H:i:s',strtotime($tripEnd.$tripStartEnd));
$this->db->select('trId')
->from('trips')
->where('carId',1)//car Id
->where("CONCAT(tripStart,'',tripStartTime) > ",$from)
->where("CONCAT(tripEnd,'',tripStartEnd) < ",$to)
->get();
?>

Laravel get most out of the database

I'm having a tracker in Laravel 4 and I was wondering, how can I get the 'most' from my table.
So want I want is to have the day that had the most visitors.
My table structure looks like this:
So, my controller looks like this:
public function index()
{
$begin = date('Y-m-01');
$end = date('Y-m-t');
$visits = Tracker::selectRaw('date, count(ip)')->groupBy('date')->whereRaw("date between '$begin' and '$end'")->get();
//get total visits per month
$get_visits = Visitor::whereRaw("date between '$begin' and '$end'")->count();
// get average visits
// transform dates to DateTime objects (we need the number of days between $begin and $end)
$begin = new \DateTime($begin);
$end = new \DateTime('now');
$diff = $end->diff($begin); // creates a DateInterval object
$days = (int)$diff->format('%a'); // %a --> days
$average_visits = $get_visits / $days;
return View::make('admin.home.index')->with('stats', $visits)
->with('get_visits', $get_visits)
->with('average_visits', $average_visits);
}
What I want as an output:
We had the most visitors on 18/06/2015 (542 visitors)
For example.
Thanks!
You can SELECT the date ORDER BY the amount of visitors DESCENDING and LIMIT by 1. This is basic mysql. How to use this in laravel, is in the documentation.
Order by desc:
->orderBy('visits', 'desc')
Limit:
->take(1)
My example query is based on a system that has a column which counts the visits(which your structure doesn't have). So let me help you with your structure.
You want to have it by date so you basically GROUP BY date:
->groupBy('date')
From this query you want to have the amount of rows that belong to that date. So you use COUNT:
->count()
This is all based on that you know stuff about queries. This is all according to the query builder.

MySQL Query with Idiorm and Date Issue

I want to use a chart on some of my data and generate the values based on selected dates (with a date picker). I've stolen most of the stuff on the web and might have only a simple questions.
Here is the Idiorm query:
if (isset($_GET['start']) AND isset($_GET['end'])) {
$start = $_GET['start'];
$end = $_GET['end'];
$data = array();
// Select the results with Idiorm
$results = ORM::for_table('tbl_data')
->where_gte('date', $start)
->where_lte('date', $end)
->order_by_desc('date')
->find_array();
// Build a new array with the data
foreach ($results as $key => $value) {
$data[$key]['label'] = $value['date'];
$data[$key]['value'] = $value['rev'];
}
echo json_encode($data);
}
The $start and $end are from my datepicker and in yyyy-mm-dd format. The only thing I don't know how to do is how to change the ->where_gte statement. As you can see it's querying the db for the field date. In my db I have three fields, year, month and day.
Is there a way to combing the three fields year, month and day into one expression i.e. maybe ->where_gte('year'&'month'&'day', $start)???
I tried searching and searching but maybe have the wrong keywords or to less knowledge.
Thanks in advance for any help!
Since you have three fields in the DB, you need three where_gte clauses:
...
->where_gte('year', substr($start, 0, 4) // or most suitable date_format
->where_gte('month', substr($start, 5, 2) // or most suitable date_format
...
Hope it helps.
You can manage date format using MySql DATE_FORMAT() Function. E. G.:
// Select the results with Idiorm
$results = ORM::for_table('tbl_data')
->where_gte('date', "DATE_FORMAT($start, '%Y-%m-%d')")
->where_lte('date', "DATE_FORMAT($end, '%Y-%m-%d')")
->order_by_desc('date')
->find_array();

Categories