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();
}
?>
Related
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']
I need to find date x such that it is n working days prior to date y.
I could use something like date("Y-m-d",$def_date." -5 days");, but in that case it wont take into consideration the weekend or off-date. Let's assume my working days would be Monday to Saturday, any idea how I can accomplish this?
Try this
<?php
function businessdays($begin, $end) {
$rbegin = is_string($begin) ? strtotime(strval($begin)) : $begin;
$rend = is_string($end) ? strtotime(strval($end)) : $end;
if ($rbegin < 0 || $rend < 0)
return 0;
$begin = workday($rbegin, TRUE);
$end = workday($rend, FALSE);
if ($end < $begin) {
$end = $begin;
$begin = $end;
}
$difftime = $end - $begin;
$diffdays = floor($difftime / (24 * 60 * 60)) + 1;
if ($diffdays < 7) {
$abegin = getdate($rbegin);
$aend = getdate($rend);
if ($diffdays == 1 && ($astart['wday'] == 0 || $astart['wday'] == 6) && ($aend['wday'] == 0 || $aend['wday'] == 6))
return 0;
$abegin = getdate($begin);
$aend = getdate($end);
$weekends = ($aend['wday'] < $abegin['wday']) ? 1 : 0;
} else
$weekends = floor($diffdays / 7);
return $diffdays - ($weekends * 2);
}
function workday($date, $begindate = TRUE) {
$adate = getdate($date);
$day = 24 * 60 * 60;
if ($adate['wday'] == 0) // Sunday
$date += $begindate ? $day : -($day * 2);
return $date;
}
$def_date="";//define your date here
$preDay='5 days';//no of previous days
date_sub($date, date_interval_create_from_date_string($preDay));
echo businessdays($date, $def_date); //date prior to another date
?>
Modified from PHP.net
Thanks for the help guys, but to solve this particular problem I wrote a simple code:
$sh_padding = 5; //No of working days to count backwards
$temp_sh_padding = 1; //A temporary holder
$end_stamp = strtotime(date("Y-m-d", strtotime($date_format)) . " -1 day"); //The date(timestamp) from which to count backwards
$start_stamp = $end_stamp; //start from same as end day
while($temp_sh_padding<$sh_padding)
{
$sh_day = date('w',$start_stamp);
if($sh_day==0){ //Skip if sunday
}
else
{
$temp_sh_padding++;
}
$start_stamp = strtotime(date("Y-m-d",$start_stamp)." -1 day");
}
$sh_st_dte = date("Y-m-d",$start_stamp); //The required start day
A quick bit of googling got me to this page, which includes a function for calculating the number of working days between two dates.
It should be fairly trivial to adjust that concept to suit your needs.
Your problem, however, is that the concept of "working days" being monday to friday is not universal. If your software is only ever being used in-house, then it's okay to make some assumptions, but if it's intended for use by third parties, then you can't assume that they'll have the same working week as you.
In addition, public holidays will throw a big spanner in the works, by removing arbitrary dates from various working weeks throughout the year.
If you want to cater for these, then the only sensible way of doing it is to store the dates of the year in a calendar (ie a big array), and mark them individually as working or non-working days. And if you're going to do that, then you may as well use the same mechanism for weekends too.
The down-side, of course, is that this would need to be kept up-to-date. But for weekends, at least, that would be trivial (loop through the calendar in advance and mark weekend days where date('w')==0 or date('w')==6).
I have this function that gives me a set of options in a select input.
The options give me times with 5 minute interval.
The problem is when the time is like 23:45, the options will start from 00:10 and loops based on the $j variable.
This is what I want to do in words:
Give me a list of options in 5 minutes interval from $open_time till $close_time.
If the current Time ($timeNow) is greater than the $open_time, set the $open_time to the $timeNow to be shown as first option.
Do this loop only until the $close_time.
I hope this is clear.
Appreciate your help :)
Here is the code:
function selectTimesofDay(){
$output = "";
$now = date('G:i ', time()); // time now
$timeNow = strtotime($now); // strtotime now
$next_five = ceil($timeNow / 300) * 300; // get next 5 minute
// time now rounded to next 10 minute
$round5minNow = date('G:i', strtotime('+15 minutes',$next_five));
$open_time = strtotime('17:00');
$close_time = strtotime('23:59');
// in the middle of working hours, time sets to current
if($timeNow >= $open_time && $timeNow < $close_time){
$open_time = strtotime($round5minNow);
}
$time_diff = round(($close_time - $open_time)/60) ;
if(date('l') == 'Friday'){
$j = ($time_diff/5)+11; // working hours extended untill 1:00 AM
} else{
$j = ($time_diff/5)-1; // working hours untill 12:00 AM
}
for($i = 0; $i <= $j; $i++){
$b = $i*5;
$data = date('l')." - ".date("H:i", strtotime('+'.$b.' minutes', $open_time));
$output .= "<option value=\"{$data}\">";
$output .= $data;
$output .= "</option>";
}
return $output;
}
What you really need is:
function selectTimesOfDay() {
$open_time = strtotime("17:00");
$close_time = strtotime("23:59");
$now = time();
$output = "";
for( $i=$open_time; $i<$close_time; $i+=300) {
if( $i < $now) continue;
$output .= "<option>".date("l - H:i",$i)."</option>";
}
return $output;
}
So what this does is run a loop checking every five-minute interval between opening and closing. Skip it if it is before the curent time, and otherwise add an option.
It's much more efficient than what you were trying to do, and probably easier to understand too.
You can even put this after the loop:
if( $output == "") return "<option disabled>Sorry, we're closed for today</option>";
Also, notice how I left out the value attribute all the time. That's because in the absence of a value, the option's text is used as a value. Thus this solution avoids needless duplication.
Consider taking the hard-coded open and close times out of the function body. The goal with functions is to write code that you can reuse, so if your hours change then you don't have to change with your function, but rather the arguments that are passed to it.
// sample usage: print '<select>'.selectTimesofDay('17:00', '23:59').'</select>';
function selectTimesofDay($start=false, $end=false, $interval='5 minutes'){
$interval = DateInterval::createFromDateString($interval);
$rounding_interval = $interval->i * 60;
$date = new DateTime(
date('Y-m-d H:i', round(strtotime($start) / $rounding_interval) * $rounding_interval)
);
$end = new DateTime(
date('Y-m-d H:i', round(strtotime($end) / $rounding_interval) * $rounding_interval)
);
$opts = array();
while ($date < $end) {
if ($date->getTimestamp() < time()) {
$date->add($interval);
continue;
}
$data = $date->format('l').' - '.$date->format('H:i');
//$opts[] = '<option value="'.$date->getTimestamp().'">'.$data.'</option>'; // < -- pass the timestamp instead of a string?
$opts[] = '<option>'.$data.'</option>';
$date->add($interval);
}
return count($opts) < 1 ?
'<option value="-1">- closed -</option>' :
implode("\n", $opts);
}
Documentation
PHP's DateTime object - http://www.php.net/manual/en/class.datetime.php
PHP's DateInterval object - http://www.php.net/manual/en/dateinterval.format.php
PHP functions - http://www.php.net/manual/en/functions.user-defined.php
PHP function tutorial - http://www.tizag.com/phpT/phpfunctions.php
I've been reading about problems in php with strtotime and "next month" issues. What i want to make is counter of months between two dates.
For example if I have start date 01.02.2012 and stop date 07.04.2012 I'd like to get return value - 3 months. Also 3 months would be the result if start date i 28.02.2012 and 07.04.2012. I am not counting exact number of days/months, just a number of months I have between two dates. It's not a big deal to make it with some strange date, mktime and strtotime usage, but unfortunatelly start and stop dates might be in two different years so
mktime(0,0,0,date('m')+1,1,date('Y');
isnt going to work (i do not now the year and if it changes between start and stop date. i can calculate it but it is not nice solution). Perfect solution would be to use:
$stat = Array('02.01.2012', '07.04.2012')
$cursor = strtotime($stat[0]);
$stop = strtotime($stat[1]);
$counter = 0;
while ( $cursor < $stop ) {
$cursor = strtotime("first day of next month", $cursor);
echo $cursor . '<br>';
$counter++;
if ( $counter > 100) { break; } // safety break;
}
echo $counter . '<br>';
Unfortunatelly strtotime isnt returning proper values. If I use it is returning empty string.
Any ideas how to get timestamp of the first day of next month?
SOLUTION
$stat = Array('02.01.2012', '01.04.2012');
$start = new DateTime( $stat[0] );
$stop = new DateTime( $stat[1] );
while ( $start->format( 'U') <= $stop->format( 'U' ) ) {
$counter ++;
echo $start->format('d:m:Y') . '<br>';
$start->modify( 'first day of next month' );
}
echo '::' . $counter . '..<br>';
<?php
$stat = Array('02.01.2012', '07.04.2012');
$stop = strtotime($stat[1]);
list($d, $m, $y) = explode('.', $stat[0]);
$count = 0;
while (true) {
$m++;
$cursor = mktime(0, 0, 0, $m, $d, $y);
if ($cursor < $stop) $count ++; else exit;
}
echo $count;
?>
the easy way :D
How do I go about getting all the work days (mon-fri) in a given time period (let's say, today till the end of the next month) ?
If you're using PHP 5.2+ you can use the library I wrote in order to handle date recursion in PHP called When.
With the library, the code would be something like:
$r = new When();
$r->recur(<start date here>, 'weekly')
->until(<end date here>)
->wkst('SU')
->byday(array('MO', 'TU', 'WE', 'TH', 'FR'));
while($result = $r->next())
{
echo $result->format('c') . '<br />';
}
This sample does exactly what you need, in an quick and efficient way.
It doesn't do nested loops and uses the totally awesome DateTime object.
$oDateTime = new DateTime();
$oDayIncrease = new DateInterval("P1D");
$aWeekDays = array();
$sStart = $oDateTime->format("m-Y");
while($oDateTime->format("m-Y") == $sStart) {
$iDayInWeek = $oDateTime->format("w");
if ($iDayInWeek > 0 && $iDayInWeek < 6) {
$aWeekDays[] = clone $oDateTime;
}
$oDateTime->add($oDayIncrease);
}
Try it here: http://codepad.org/wuAyAqnF
To use it, simply pass a timestamp to get_weekdays. You'll get back an array of all the weekdays, as timestamps, for the rest of the current month. Optionally, you can pass a $to argument - you will get all weekdays between $from and $to.
function get_weekdays ($from, $to=false) {
if ($to == false)
$to = last_day_of_month($from);
$days = array();
for ($x = $from; $x < $to; $x+=86400 ) {
if (date('w', $x) > 0 && date('w', $x) < 6)
$days[] = $x;
}
return $days;
}
function last_day_of_month($ts=false) {
$m = date('m', $ts);
$y = date('y', $ts);
return mktime(23, 59, 59, ($m+1), 0, $y);
}
I suppose you could loop through the dates and check the day for each one, and increment a counter.
Can't think of anything else off the top of my head.
Pseudocode coming your way:
Calculate the number of days between now and the last day of the month
Get the current day of the week (i.e. Wednesday)
Based on the current day of the week, and the number of days left in the month, it's simple calculation to figure out how many weekend days are left in the month - it's going to be the number of days remaining in the month, minus the number of Sundays/Saturdays left in the month.
I would write a function, something like:
daysLeftInMonth(daysLeftInMonth, startingDayOfWeek, dayOfWeekToCalculate)
where:
daysLeftInMonth is last day of the month (30), minus the current date (15)
startingDayOfWeek is the day of the week you want to start on (for today it would be Wednesday)
dayOfWeekToCalculate is the day of the week you want to count, e.g. Saturday or Sunday. June 2011 currently has 2 Sunday, and 2 Saturdays left 'til the end of the month
So, your algorithm becomes something like:
getWeekdaysLeft(todaysDate)
...getWeekdaysLeft is something like:
sundaysLeft = daysLeftInMonth(lastDayOfMonth - todaysDate, "Wednesday", "Sunday");
saturdaysLeft = daysLeftInMonth(lastDayOfMonth - todaysDate, "Wednesday", "Saturday");
return ((lastDayOfMonth - todaysDate) - (sundaysLeft + saturdaysLeft));
This code does at least one part you ask for. Instead of "end of next month" it simply works with a given number of days.
$dfrom = time();
$fourweeks = 7 * 4;
for ($i = 0; $i < $fourweeks; $i ++) {
$stamp = $dfrom + ($i * 24 * 60 * 60);
$weekday = date("D", $stamp);
if (in_array($weekday, array("Mon", "Tue", "Wed", "Thu", "Fri"))) {
print date(DATE_RSS, $stamp) . "\n";
}
}
// Find today's day of the month (i.e. 15)
$today = intval(date('d'));
// Define the array that will hold the work days.
$work_days = array()
// Find this month's last day. (i.e. 30)
$last = intval(date('d', strtotime('last day of this month')));
// Loop through all of the days between today and the last day of the month (i.e. 15 through 30)
for ( $i = $today; $i <= $last; $i++ )
{
// Create a timestamp.
$timestamp = mktime(null, null, null, null, $i);
// If the day of the week is greater than Sunday (0) but less than Saturday (6), add the timestamp to an array.
if ( intval(date('w', $timestamp)) > 0 && intval(date('w', $timestamp)) < 6 )
$work_days[] = mktime($timestamp);
}
The $work_days array will contain timestamps which you could use this way:
echo date('Y-m-d', $work_days[0]);
The code above with work in PHP 4 as well as PHP 5. It does not rely on the functionality of the DateTime class which was not available until PHP 5.2 and does not require the use of "libraries" created by other people.