Find Earliest Date - PHP - php

I use PHP to perform SQL to pull out some data from my database between a date range. The dates are stored as date in the relation:
$from = "2011-08-11";
$to = "2011 - 08- 25";
$query = mysql_query("SELECT date FROM `entries` WHERE date BETWEEN '$from' AND '$to' ORDER BY date ASC");
I would like to find the earliest date pulled from the relation.
If the query is successful, I store the 'date' attribute in a php array called $dates. I thought I could iterate over this $dates and compare the $date values after converting them into dates.
if($query){
$dates = array();
while($row = mysql_fetch_array($query)){
$dates[] = $row['date'];
}
$min = strftime("%Y-%m-%d", strtotime($dates[0]));
for($i = 1; $i < count($dates); $i++){
if($dates[i] < $min){
$min = $dates[i];
}
}
This does not work however...It prints random values....Perhaps there is a much simpler way to do this and I am overcomplicating matters...
HEEEELLLP!!

If you order your query, then it will be the first (or the last) row in you're query. So you wouldn't need to find it.

Instead of
$min = strftime("%Y-%m-%d", strtotime($dates[0]));
you should use
$min = date("%Y-%m-%d", strtotime($dates[0]));

The simplest way is to use the first date since you know it is already the earliest due to ASC in your SQL statement. After you read the rows into your array, just use the first element.
while($row = mysql_fetch_array($query)){
$dates[] = $row['date'];
}
$earliest_date = $dates[0];

If all you want to do is find just the earliest date, and you don't care about the rest, you could use the aggregate function min() in your query like so:
SELECT MIN(date) AS earliest FROM `entries` WHERE date BETWEEN '$from' AND '$to'
Then just grab the earliest column from the result set in your php code.

Convert the dates to numbers and sort the array?
Take what you have (lines 1-5),
foreach ($dates as $date) {
// convert each date from "YYYY-MM-DD" to "YYYYMMMDD" and turn it into an int
$date = intval(str_replace("-", "", $date));
}
// sort the array from lowest to highest
asort($dates);
// the minimum is the first item in the array
$minint = $date[0];
// convert back into "YYYY-MM-DD" format
$min = substr($minint, 0, 4) . "-" . substr($minint, 4, 6) . "-" . substr($minint, 6);

Related

get average of given dates in php

I try to get an average of given dates but I failed when dates are from two different years. I need something like this
given dates:
2017-06-1
2017-06-3
2017-06-4
2017-06-3
2017-06-5
output : 2017-06-4
this is my code:
$total = 0;
foreach ($dates as $date) {
$total+= date('z', strtotime($date))+1;
}
$avg_day = $total/sizeof($dates);
$date = DateTime::createFromFormat('z Y', $avg_day . ' ' . date("Y"));
but my code is not working for
given dates:
2016-12-29
2016-12-31
2017-01-1
2017-01-5
2017-01-3
You can work with timestamp of the date and use avg() method of the Illuminate\Support\Collection
$dates = [
'2016-12-29', '2016-12-31', '2017-01-1', '2017-01-5', '2017-01-3'
];
$dateCollection = collect();
foreach($dates as $date){
$dateCollection->push((new \DateTime($date))->getTimestamp());
}
$averageTimestamp = $dateCollection->avg(); //timestamp value
$averageDate = date('Y-m-d', $average);
Or using Carbon package:
$dateCollection->push(Carbon::parse($date)->timestamp);
...
$averageDate = Carbon::createFromTimestamp($average)->toDateString();
Your code is not working for your base dates. The correct output for
2017-06-1 2017-06-3 2017-06-4 2017-06-3 2017-06-5
is
2017-06-03
According to OpenOffice calc, and overall logic (a date is represented by epoch number)
Check out this script
$dates = ['2017-06-1 ', '2017-06-3', '2017-06-4', '2017-06-3', '2017-06-5'];
$dates = array_map('strtotime', $dates);
$average = date('Y-m-d', array_sum($dates) / count($dates)); // 2017-06-03 (1496490480)
echo $average;
Keep simple tasks simple
I think you have problem with averaging year. So, You can do this to get average.
Just an algorithm:
Find smallest date among your dates at first as $smallest
Initiate a variable $total = 0;
Add difference of each date in days with smallest date.
Find average from total.
Add this total to smallest date.
Here, You have smallest as $smallest = '2016-12-29'
$total = 0;
$dates = ['2016-12-29', '2016-12-31', '2017-01-1', '2017-01-5', '2017-01-3'];
$smallest = min($dates);
$smallest = Carbon::parse($smallest);
foreach($dates as $date){
$d = Carbon::parse($date);
$total = $total+$smallest->diffInDays($d);
}
$average_day = $total/sizeof($dates);
$average_date = $smallest->addDays($average_day);
Hope, This might help you.

CONCAT date issue

My database has y m d fields with no leading zeros in the month and day. I am trying to compare a records y-m-d against today's date. Greater than or equal show a greenlight image else red light. It's not working! HELP!
$q = "SELECT * FROM pec_mbbtmssgs WHERE activity='bike' AND CONCAT(`y`,'-','m','-','d') >= date('Y-n-j')";
$r = mysql_query($q);
$row = mysql_fetch_assoc($r);
$activity = $row['activity'];
if($activity == "bike") {
$image = "greenlight25";
}
else {
$image = "redlight25";
}
echo '<img src=http://img/' . $image . '.gif />';
?>
Your usage of CONCAT() is a bit off, as database-columns should either be wrapped in backticks or nothing at all, and strings/separators in singlequotes '.
You can also just do DATE(NOW()) to get the current date, and compare against this. Then you use the DATE() with the result of your CONCAT(), so it becomes like this
SELECT *
FROM pec_mbbtmssgs
WHERE activity='bike'
AND DATE(CONCAT(y, '-', m, '-', d)) >= DATE(NOW())
The simpler approach would be to just store your date in a DATE type column, instead of 3 separate ones. You can always extract the specific information you want (e.g. you can extract the month, even if your value is 2016-11-30).
$q = "SELECT * FROM pec_mbbtmssgs WHERE activity='bike' AND unix_timestamp(CONCAT(`y`,'-',`m`,'-',`d`)) >= unix_timestamp(CURDATE())";

php/mysql ordered random dates

I found this great function on SO whilst looking for a way to generate random dates between two fixed timestamps:
function randomDate($start_date, $end_date)
{
// Convert to timestamps
$min = strtotime($start_date);
$max = strtotime($end_date);
// Generate random number using above bounds
$val = rand($min, $max);
// Convert back to desired date format
return date('Y-m-d H:i:s', $val);
}
Source and credit
but I am looking for a way for the dates to be generated in order (start date to end date) as I have used it to generate dates to insert into a database.
The problem is my posts are ORDER BY id DESC and using the function "as is" being that they are random the dates end up out of sync.
ie:
post id 4 - date = 2010-07-11 14:14:10
post id 3 - date = 2012-02-22 18:23:21
post id 2 - date = 2011-03-17 13:52:47
post id 1 - date = 2011-08-14 15:33:50
and I need them to be in sync with the post id.
Now your thinking why not change the query to ORDER BY date DESC instead? ...well that would mess up 99% of code I have already written as there are other columns/rows dependent on it being ORDER BY id DESC and so ordering the dates when being inserted into the database is the only solution.
update:
this is what I tried using madfriend code but all dates are the same where have I gone wrong?
function randomDate($startdate, $enddate){
$min = strtotime($startdate);
$max = strtotime($enddate);
$val = rand($min, $max);
return date('Y-m-d H:i:s', $val);
}
$query = "SELECT * FROM foo";
$num = mysql_num_rows(mysql_query($query));
$randate = randomDate('2010-07-12 09:13:40', '2012-06-12 09:13:40');
$dates = array($randate);
for ($i = 0; $i < $num; $i++) {
$dates[] = randomDate($startdate, $enddate);
}
sort($dates);
while($date = array_shift($dates)) {
$update = "UPDATE foo SET date='{$date}'";
mysql_query($update);
}
plus getting
Notice: Undefined variable: startdate
I'm not quite sure whether you are talking about creation or modification of existing rows.
Updates: basic idea here is quite simple. First, count number of posts with SELECT COUNT(*) FROM your_posts_table query. After that:
// $num is number of posts
$dates = array();
for ($i = 0; $i < $num; $i++) {
$dates[] = randomDate($startdate, $enddate);
}
sort($dates); // Sort dates in ascending order
while($date = array_shift($dates)) {
// now $date won't be lower than it was in previous iterations.
// use it to update your table
}
Insertions: If you are talking about insertions and want to make latest post date random but biggest, here's what you do:
First, select last added post date.
Second, call randomDate with $startdate set to the date of last added post.
Last, insert new row with this date.
function randomDate($startdate, $enddate){
$min = strtotime($startdate);
$max = strtotime($enddate);
$val = rand($min, $max);
return date('Y-m-d H:i:s', $val);
}
$query = "SELECT * FROM foo";
$num = mysql_num_rows(mysql_query($query));
$randate = randomDate('2010-07-12 09:13:40', '2012-06-12 09:13:40');
$dates = array($randate);
for ($i = 0; $i < $num; $i++) {
$dates[] = randomDate($startdate, $enddate);
}
sort($dates);
while($date = array_shift($dates)) {
This query updates all rows in one go:
$update = "UPDATE foo SET date='{$date}' ";
mysql_query($update);
}
Probably were wanting to use
$update = "update foo set date='{$date}' where id = (select id from foo where date is not null order by id limit 1)";
(for that to work you need to set each date in the db to null before you start updating: update foo set date=null)
Also you shouldn't be using myslq_query..

convert MySQL date result to monthname and create variables

I have a MySQL database with a date column.
I create a variable of the value in PHP like this:
$query = mysql_query ("SELECT customer_date FROM customers WHERE customer_id = {$_SESSION['session_id']}");
while ($result = mysql_fetch_object($query)) {
$date = $result->customer_date;
}
I need to convert the $datefrom YYYY-MM-DD to three variables
$yearvalue (for example 2012)
$monthname (for example August)
$dayvalue (for example 10)
And I need to be able to echo out anywhere in my code... How would I do this in a fancy way? I'm pretty new to coding...
Here:
while ($result = mysql_fetch_object($query)) {
$date = $result->customer_date;
$yearvalue = date("Y", strtotime($date) );
$monthname = date("F", strtotime($date) );
$dayvalue = date("d", strtotime($date) );
}
It'll only work/store the value of these values for the last row outputted from the $result.
how about this?
while ($result = mysql_fetch_object($query)) {
$date = $result->customer_date;
list($year,$month,$day,$hour,$minute,$second)=
explode('-',date('Y-F-d-h-i-s',strtotime($date)));
}
Also read this. You will need to play with Y-F-d-h-i-s as per your requirement.

Trouble inserting two values with array_push() in a while loop

I am trying to count the occurrences of certain dates in my MySQL table using a PHP while loop and place the date and number of repetitions in an array. I am able to properly add the date to the array, but I cannot seem to add the number of repetitions to it.
Example:
function counter() {
//The 'timestamp' column uses the MySQL timestamp type
$query = mysql_query("SELECT timestamp FROM table1 ORDER BY timestamp DESC");
$date_c;
$counter = 0;
$date_array();
while($row = mysql_fetch_array($query)) {
//gets the year, month, and day from the timestamp
$year = substr($row['timestamp'], 0, 4);
$month = substr($row['timestamp'], 5, 2);
$day = substr($row['timestamp'], 8, 2);
$date = $month.'/'.$day.'/'.$year;
if($date == $date_c) {
$counter += 1;
} else {
array_push($date_array, $date, $counter);
$counter = 0;
}
$date_c = $date;
However, when I echo part of the array the counter does not update. Here is an example using the first repeated date in table1:
>>> echo $date;
06/15/2012
>>> echo $counter;
25
>>> echo $date_array[0];
06/15/2012
>>> echo $date_array[1];
0
I have played around with this for a while but I can't seem to find my error. Does anyone know what I am doing wrong?
Is there anything else you want to do with those rows? Because this seems easier to me:
SELECT DATE_FORMAT(timestamp,'%m/%d/%Y') as 'date', COUNT(*) as 'count'
FROM table1
GROUP BY DATE_FORMAT(timestamp,'%m/%d/%Y')
ORDER BY timestamp DESC
... and the problem in the php code might be the last date / count isn't pushed to $date_array (the array_push will have to run once more after the while loop is finished, if the last iteration did NOT push a counter on the array.....)
Agreed with Wrikken that you can get the count of unique dates in SQL, rather than needing to do it in PHP.
However, if you do want to count the instances of each date, I would use the associative array feature of arrays in PHP. So something like:
$query = mysql_query("SELECT timestamp FROM table1");
$date_array = array();
while($row = mysql_fetch_array($query)) {
$year = substr($row['timestamp'], 0, 4);
$month = substr($row['timestamp'], 5, 2);
$day = substr($row['timestamp'], 8, 2);
$date = $month.'/'.$day.'/'.$year;
// Using the # symbol to suppress warnings for missing index
# $date_array[$date]++;
}
print_r($date_array);
At the end of that loop, $date_array is an associative array with the date as the key, and the number of occurrences as the value.

Categories