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..
Related
I'm getting records from a MySQL database with this PHP function:
function someFunction($date){
// all distinct records
$query = "select count(distinct column_name) as alias from table_name where DATE(date_column) = '$date'";
$result = $connection->query($query);
$row = $result->fetch_assoc();
return $row['alias'];
// end of all distinct records
}
Now what the below PHP code does is, get the day in the date, compute the week of the month it belongs to and stores it an an array.
//while fetch_assoc returns records
//$result1 query: "select * from table_name where DATE(date) between '$first_date' and date_add('$end_date',interval 1 day)"
while ($row1 = $result1->fetch_assoc()) {
$date = $row1['date'];
$start = 1;
$end = 7;
for ($i = 1; $i <= 5; $i++) {
if ((int) date('d', strtotime($date)) >= $start && (int) date('d', strtotime($date)) <= $end) {
if (!isset($arr1[$i]) || !isset($arr2[$i])) {
$arr1[$i] = 0;
$arr2[$i] = 0;
}
++$arr1[$i];
$arr2[$i] = someFunction(date('Y-m-d', strtotime($date)));
}
$start += 7;
$end += 7;
}
}
Consider 1st, 2nd and 3rd belong to the same week, 1st has 3 records, 2nd has 4 and 3rd has 1. The while loop will iterate 7 times, each value returned by the someFunction() overwriting the value in $arr2[$i].
So my question is, how will I be able to check if the previous iteration date value is equal to the current date value?
So my question is, how will I be able to check if the previous iteration date value is equal to the current date value?
Pseudocode:
$lastValue = …; // initialization with a value that does not occur in the actual values,
// such as NULL, empty string, …
while(…) {
if($currentValue == $lastValue) {
// do something
}
else {
// do something else
}
// …
$lastValue = $currentValue; // set current value for next loop interation
}
Starting with the number 9 and using php, I would like to be able to count up from there, and echo out the next number in increments of 1.
So, number 9, then after 1 month the number would change to 10, then another month 11, then 12 etc., with no maximum number/stop point.
How can I accomplish this? So far I have the below code.
$number = 9;
$output = $number + 1;
echo $output;
Is there a way to set this to increase once a month?
You can do this with the PHP date()-function. This is one example of doing it if you are not dependent on the day of the month, but adding day functionality is possible and should be quit easy.
$startNumber = 9;
$startYear = 2015;
$startMonth = 9;
$currentYear = intval( date( "Y" ) );
$currentMonth = intval( date( "n" ) );
$monthsToAdd = ( ( $currentYear - $startYear ) * 12 )
+ ( $currentMonth - $startMonth );
echo $startNumber + $monthsToAdd;
From your question, I'd say:
$number = 9;
$output = date('n') + $number;
echo $output;
But that depends on what you are trying to accomplish. You can also wrap the number around the date() with a modulo.
However this is nothing random. If you want to create a random number every month like your topic suggests, use the month as the random seed.
srand(date('n'));
$number = rand();
a very inefficient way would be
<?php
function increm($duration){
while ($i<$duration) {
$i++;
}
return true;
}
$number = 9;
$start = time();
$i = 0;
while (1){
increm(3600*24*30);
$i++;
// Do your code
}
?>
this script would have to be run continuously for months.
A better way would be
<?php
$number = 9;
if(!file_exists('date.txt')){
$date=date('n');
file_put_contents( (string)time());
$date = 0;
}
else{
$date= file_get_contents('date.txt');
$date= date()-(int)$date;
$date= floor($date/(24*3600*30));
}
// do whatever you may
?>
But this script would increase it whenever called as the first open date would be stored. Will work forever (till UNIX can timestamp).
for this purpose you have to store the number in the database, compare with current unix timestamp and update it when the new month is reached.
2 database columns: count_month int(10) and next_month int(10) where next_month will contain the unix timestamp of the first day of the next month. you can run it with cronjobs or on production.
<?php
$now = strtotime("now");
$next_month = strtotime("first day of next month");
if ($query = $dbconnect->prepare("SELECT next_month FROM table1")) {
$query->execute();
$query->bind_result($compare_time);
$query->store_result();
$row_count = $query->num_rows;
if ($row_count > 0) {
while ($query->fetch()) {
if ($compare_time < $now) { // you reached the 1th of the next month time to update
if ($query2 = $dbconnect->prepare("UPDATE table1 SET count_month=count_month +1, next_month=?")) {
$query2->bind_param('i', $next_month);
$query2->execute();
$query2->close();
}
}
}
}
$query->free_result();
$query->close();
}
?>
I have a table xeon_users_rented, with: clicks0, clicks1, clicks2, clicks3, clicks4, clicks5, clicks6
Each day, clicks0 will increase, and every day at midnight, a cronjob will run, making clicks0 = clicks1 (setting todays clicks, to yesterday clicks), and then set clicks0 to zero.
What I am trying to achieve is I want to make a graph, that shows the sum of clicks0, clicks1 etc., where clicks0 is todays date.
I have the query below:
$data = array();
for ($x = 0; $x <= 6; $x++) {
$date = date("Y/m/d", time() - ($x * 86400));
$queryE = $dbh->prepare("SELECT SUM(clicks$x) FROM xeon_users_rented WHERE user_by=:username");
$queryE->bindParam(":username", $userdata['username']);
$queryE->execute();
$row = $queryE->fetch(PDO::FETCH_ASSOC);
$dates[] = date("Y/m/d", time() - ($x * 86400));
$data[] = ($row['clicks'.$x.''] > 0 ? $row['clicks'.$x.''] : 0);
}
$days = array('Today');
for ($i = 0; $i < 6; $i++) {
$days[$i] = date('d-m', strtotime('-'.($i + 0).' day'));
}
The $days is working perfectly - it will print out today, and the last couple of days.
The $data is not working. It is just printing out:
0,0,0,0,0,0,0
Can someone please help me out here.
The column from your SUM isn't going to be named clicks$x. It will be named something like SUM(clicks1).
Provide an explicit name in the SQL, like
SELECT SUM(clicks$x) as clickSum ...
Then reference it in row as
$row['clickSum']
Is there a query to run in php that would let you insert all dates in between two dates?
For example, entering 03/20/2012 and 03/20/2013 and populating mysql with all the dates in between the two?
I was making a ticketing system for an airline and they have 13 flights daily from 20+ locations and inserting them manually was getting tedious.
I wanted to insert the dates as well as the values for each day
EG.
FROM TO Date_From Date_To
Dar Es Salaam Zanzibar 03/20/2012 03/21/2012
Dar Es Salaam Zanzibar 03/21/2012 03/22/2012
Note
I do not want to GENERATE this list (the questions I've researched only answered how to generate a list) I want to POPULATE a MySQL DB
Any help would be greatly appreciated
You could use this function to generate an array of dates
function dateRange( $first, $last, $step = '+1 day', $format = 'd/m/Y' ) {
$dates = array();
$current = strtotime( $first );
$last = strtotime( $last );
while( $current <= $last ) {
$dates[] = date( $format, $current );
$current = strtotime( $step, $current );
}
return $dates;
}
$dateRange = dateRange("03/20/2012", "03/20/2013);
and then iterato over the array to insert the data
$stmt = $dbh->prepare("INSERT INTO table (from, to, date_from, date_to) VALUES (:from, :to, :datefrom, :dateto)");
$stmt->bindParam(':from', "Dar Es Salaam");
$stmt->bindParam(':to', "zanzibar");
$stmt->bindParam(':from', $datefrom);
$stmt->bindParam(':to', $dateto);
for ($i = 0; $i < count($dateRange); $i++){
$datefrom = strototime($dateRange[$i]);
$dateto = strototime($dateRange[$i+1]);
$stmt->execute();
}
The simplest way to populate a DB is to generate a list of SQL insert queries.
So if you can GENERATE a list of queries that do something like insert into table (... , date_from, date_to, ... ) values ( ..., val1, val2, ...) you can then run these queries and POPULATE the table.
$int_date_from = strtotime($str_date_from); // Will be used often
$int_days = (strtotime($str_date_to) - $int_date_from); // Calculate difference in seconds
$int_days /= floor(60 * 60 * 24); // Seconds to days
$arr_values = array();
for($i = 0; $i < $int_days; $i++) {
$str_new_date_from = date('m/d/Y', strtotime("+{$i} Days", $int_date_from));
$str_new_date_to = date('m/d/Y', strtotime('+'.($i + 1).' Days', $int_date_from));
$arr_values[] = "('{$str_from}', '{$str_to}', '{$str_new_date_from}', '{$str_date_to}')";
}
$str_values = implode(', ', $arr_values);
mysql_query("
INSERT INTO table
VALUES {$str_values}
");
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);