I am building a chart and for that extracting data from the past 24 hours, 48 hours, 1 week and 2 weeks.
I used INTERVAL statements for this purpose but they are not working as expected. I am using Laravel. Here is the function to extract the data:
public function range($range)
{
$data = new Main();
$data0 = $data->whereRaw('updated_at >= DATE_SUB(NOW(), INTERVAL '.$range.')')->whereRaw('MINUTE(updated_at)>54')->orwhereRaw('MINUTE(updated_at)<6')->where('server_short_name', '=', 'FiveRP')->get();
$data1 = $data->whereRaw('updated_at >= DATE_SUB(NOW(), INTERVAL '.$range.')')->whereRaw('MINUTE(updated_at)>54')->orwhereRaw('MINUTE(updated_at)<6')->where('server_short_name', '=', 'GTALife')->get();
$data2 = $data->whereRaw('updated_at >= DATE_SUB(NOW(), INTERVAL '.$range.')')->whereRaw('MINUTE(updated_at)>54')->orwhereRaw('MINUTE(updated_at)<6')->where('server_short_name', '=', 'GermanV')->get();
return compact('data0', 'data1', 'data2');
}
Here is the function that calls the view:
public function hours24()
{
$t = $this::range('24 HOUR');
return view('chart', $t);
}
But in the chart, I am getting results from 22nd of May as well which is the earliest date on DB. Which means that the code isnt working as expected although it is correct according to me. Is there something I am missing out?
I have found the solution. Actually in my code I am using an 'orwhereRaw' which means that I am implying an OR between all the where statements which is sadly not what I want.
Related
Am trying to perform a query and get items where created_at is not greater that 24 hrs
I have tried
$trucks = Orders::find()
->where(["created_at"=>not more than 24 hrs ]) //stuck here
->orderBy(['created_at' => SORT_DESC])->all();
Nb:Created_at is in unix timestamp.
in usual php it would be the equivalent of
$created_at= 1500373706; // time order was created
if ((time() - $created_at) > 86400) {
//Dont get these
} else {
//Get these
}
How do i go about this?
I found this answer and made some very slight modifications to fit your situation: How to compare Dates from database in Yii2
$yesterday = strtotime("-24 hours");
$trucks = Orders::find()->where(['<=', 'created_at', $yesterday])
->orderBy('created_at DESC')->all();
I currently get the last 30 days results like this.
public function commission_month(){
$status = 'A';
$this->db->select_sum('LenderCommission');
$this->db->where(['Status' => $status ]) ;
$this->db->where('CompletedDate >= DATE_SUB(CURDATE(), INTERVAL 30 DAY) ');
$query = $this->db->get('toutcome');
$result = $query->result();
return $result[0]->LenderCommission;
}
What i am really trying to do is get results for this current month.
And then when its the next month , its should do the same.
You can use a "like" query to get the information you need, assuming the dates are stored in a manner you can easily apply a like to.
Basically, the query will be something along the lines of ... AND CompletedDate LIKE 'YYYY-MM-%'... where YYYY and MM are valid year and months. This can be done in CodeIgniter by using the $this->db->like() builder:
$this->db->like('CompletedDate', date('Y-m'));
Your code then being:
public function commission_month(){
$status = 'A';
$this->db->select_sum('LenderCommission');
$this->db->where(['Status' => $status ]) ;
$this->db->like('CompletedDate', date('Y-m'));
$query = $this->db->get('toutcome');
$result = $query->result();
return $result[0]->LenderCommission;
}
I have to make a notification after 30 days.
foreach ($pdo->query($sql) as $row) {
$date = date_create($row['data']);
$laikotarpas = date_diff(new DateTime("now"), $date);
// var_dump($liko);
$liko = 30 - $laikotarpas->d;
I want correct result in days.
I have added a row at 2014.03.19 and this shows that left 3days to 30.
My goal is to achieve:
I add record at 2014.03.19 and get result how many days have passed from today. I thought that $laikotarpas->d gives a duration in days, but, when i do calculations to set the limit for 30days.
So my main problem is to get correct $liko, but I have no idea how.
I am adding my time using this code (using PDO):
$q->execute(array($name,
date("Y-m-d H:i:s", time())
);
In my database I use DATETIME. And i print that date from SQL using this php:
<?php echo date_format(date_create($data['data']), 'Y-m-d'); ?>
Is my way good? How to improve this?
-----edit-----
I have to use php5.2
Just got an idea, it takes only days and ignores months passed count. How to update that to count duration only in days?
If you want to find the difference between now and a date in the past, try something like this:
PHP >= 5.2.0
$then = '2014-03-19';
$date = new DateTime($then);
$now = new DateTime('now');
$diff = $date->diff($now);
echo $diff->days . ' days since ' . $then . PHP_EOL; // 58 days since 2014-03-19
PHP < 5.2.0
$date = strtotime($then);
$now = time();
$diff = $now - $date;
$days = round($diff / 60 / 60 / 24); // convert seconds to days and round off
Note: after understanding more about your problem, I highly suggest you filter your results based on date ranges in MySQL rather than PHP - it'll be easier and more economic and will reduce your potential risk for affecting data you didn't mean to. See Cull Larson's answer.
You could just use a query like this:
SELECT * FROM myTable WHERE DATE(signupDate) = DATE_SUB(NOW(), INTERVAL 25 DAY);
That will give you all results with a signup date that is 25 days old. If you have a flag in the table telling you whether you've notified them, you can pass that along too:
SELECT * FROM myTable WHERE notified=false AND DATE(signupDate) = DATE_SUB(NOW(), INTERVAL 25 DAY);
If you want to get every record 25 days or older, that hasn't been notified:
SELECT * FROM myTable WHERE notified=false AND DATE(signupDate) <= DATE_SUB(NOW(), INTERVAL 25 DAY);
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);
I have this function in my model the purpose of it is to get the stats of the past 30 days starting from the actual day, it was working fine before i reach 30th day then I found out it is counting from the oldest date, so I flipped the order_by from "ase" to "desc" but it seems still going back and counting before the oldest day and not giving me that data I want, so I'm wondering if there any way using codeigniter and give a starting point for the "limit" which should be the actual date.
function graph_data($id_person)
{
$this->db->limit(30); // get data for the last 30 days including the curent day
$this->db->where('personid',$id_person);
$this->db->order_by('date', 'ase');
$query = $this->db->get('stats');
foreach($query-> result_array() as $row)
{
$data[] = $row;
}
return $data;
}
limit returns in your case the last 30 rows. It has nothing to do with dates, unless you only add a row each day.
try using mysql Between
SELECT DATE_FORMAT(create_date, '%m/%d/%Y')
FROM mytable
WHERE create_date BETWEEN SYSDATE() - INTERVAL 30 DAY AND SYSDATE()
ORDER BY create_date ASC
Source -- https://stackoverflow.com/a/2041619/337055
I finally found the solution by giving a range or days, 29 days before the actual day without using BETWEEN and that works fine
<?php
function graph_data($id_person)
{
$today = date('Y-m-d');
$lastdate = date('Y-m-d', strtotime('-29 days', strtotime($today)));// 30 days ago
$this->db->where('personid',$id_person);
$this->db->where("date <= '$today'");
$this->db->where("date >= '$lastdate'");
$this->db->order_by('date', 'ase');
$query = $this->db->get('stats');
$data = array();
foreach($query-> result_array() as $row)
{
$data[] = $row;
}
return $data;
}