I am creating a wordpress widget. This will allow user to upload the image url of eight different picture. Now I want to change the image everty three days and start from begining after eight one for infinite time.
I manage to get the start of the first image. let sat that is : 2014/07/28
I have applied this logic:
$date = $start_date;
$date = strtotime($date);
$date = strtotime("+3 day", $date);
$end_date = date('Y-m-d', $date);
$begin = new DateTime( $start_date );
$end = new DateTime('');
$end = $end->modify( '+1 day' );
$interval = new DateInterval('P1D');
$daterange = new DatePeriod($begin, $interval ,$end);
if($start_date <= $end_date && $end_date > date('Y-m-d'))
{
$image_number = 1;
}else{
$i = 1;
$j = 1;
foreach($daterange as $date){
if($i%3 == 0){
echo $image_number = $j;
$j++;
if($j > 8){
$j = 1;
}
}
$i++;
}
}
?>
" alt="">
Can anybody tell me what is wrong with the code.
Thank you everybody in advance for your valuable time.
Alright so it seems you have 8 images named 1.jpg to 8.jpg
Every three days you want to change the image to the next, and when you are at 8, you want to go to 1.
I don't know if you have some kind of start date on which the images were uploaded, and I don't know if it matters to you.
Let's start out with an example in which viewing the image is tied to the date (and resets on the first of january)
##maybe you would like to set the timezone
##date_default_timezone_set('America/Los_Angeles');
$dayOfTheYear = date('z');
$iterationCount = ceil($dayOfTheYear / 3);
$numberForIteration = $iterationCount % 8;
echo '<img alt="" src="'.$numberForIteration.'.jpg" />';
## prints for example: <img alt="" src="6.jpg" />
We can build on this and have an option of a different start date, meaning that not january 1st, but another date is the start date.
## PHP Version should be above June 2012
$startDate = new DateTime("2014-07-01");
$currentDate = new DateTime();
$daysSinceStart = $startDate->diff($currentDate)->days;
$iterationCount = ceil($daysSinceStart / 3);
$numberForIteration = $iterationCount % 8;
echo '<img alt="" src="'.$numberForIteration.'.jpg" />';
Hope it helps.
David
Related
I have this function witch return an array of date. I need to jump on every seven days from now until last year.
$date[] = $lastDate = (new \DateTIme('NOW'))->format('Y-m-d');
for ($i = 1; $i < 54; ++$i) { // 54 -> number of weeks in a year
$date[] = $lastDate = date('Y-m-d', strtotime('-7 day', strtotime($lastDate)));
}
return array_reverse($date);
It works but I can do better.
I would like to change it because using 54 for the number of weeks in a year is not very good. (it can change)
So I want to use the DateInterval php class.
I can have the date of the last year with :
$lastYear = date('Y-m-d', strtotime('-1 year', strtotime($lastDate)));
But I don't know how I can have my array with all my dates with the DateInterval class.
Can someone help me? I'm very bad with date manipulation :( ...
Here is an example array about what I need:
["2015-07-06", "2015-07-13", "2015-07-20", "2015-07-27", "2015-08-03", "2015-08-10", "2015-08-17", "2015-08-24", "2015-08-31", "2015-09-07", "2015-09-14", "2015-09-21", "2015-09-28", "2015-10-05", "2015-10-12", "2015-10-19", "2015-10-26", "2015-11-02", "2015-11-09", "2015-11-16", "2015-11-23", "2015-11-30", "2015-12-07", "2015-12-14", "2015-12-21", "2015-12-28", "2016-01-04", "2016-01-11", "2016-01-18", "2016-01-25", "2016-02-01", "2016-02-08", "2016-02-15", "2016-02-22", "2016-02-29", "2016-03-07", "2016-03-14", "2016-03-21", "2016-03-28", "2016-04-04", "2016-04-11", "2016-04-18", "2016-04-25", "2016-05-02", "2016-05-09", "2016-05-16", "2016-05-23", "2016-05-30", "2016-06-06", "2016-06-13", "2016-06-20", "2016-06-27", "2016-07-04"]
PHP got it 's own native DateInterval object. Here 's a short example how to use it.
$oPeriodStart = new DateTime();
$oPeriodEnd = new DateTime('+12 months');
$oPeriod = new DatePeriod(
$oPeriodStart,
DateInterval::createFromDateString('7 days'),
$oPeriodEnd
);
foreach ($oPeriod as $oInterval) {
var_dump($oInterval->format('Y-m-d));
}
So what we 've done here? For a period of dates you need a start date, an end date and the interval. Just test it for yourself. Have fun.
Try this:
$timestamp = strtotime("last Sunday");
$sundays = array();
$last_year_timestamp = strtotime("-1 year ",$timestamp);
while($timestamp >= $last_year_timestamp) {
if (date("w", $timestamp) == 0) {
$sundays[] = date("Y-m-d", $timestamp);
$timestamp -= 86400*7;
continue;
}
$timestamp -= 86400;
}
I want to check between two user-specified times everyday and not run some function call (i.e. "Do Not Disturb").
For example, a user set a "Do Not Disturb" time block between 10:00pm to 6:00am (next day).
FYI, no days/dates are being specified by the end-user, ONLY times. This will run consistently everyday, 7 days a week.
So between 10pm-6am (next day), any function call is ignored. This is what I've written up so far:
$now = time(); // or $now = strtotime('11:00pm'); to simulate time to test
$start = strtotime('10:00pm');
$end = strtotime('6:00am +1 day');
// alternative time block
//$start = strtotime('10:00am');
//$end = strtotime('11:00am');
//debug
//echo date('r', $now) . '<br>' . date('r', $start) . '<br>' . date('r', $end) . '<br><br>';
if($start > $now || $now > $end) {
echo 'disturb';
} else {
echo 'do not disturb';
}
But this doesn't seem to work, because once you reach midnight, it's a new day, but the $end variable is already a day ahead.
I tried putting it a day behind, but then the issue is that the value of $end ends up being lower than the value of $start, which isn't correct.
I also tried adding a day to the $now variable whenever the time reaches midnight, but the issue w/ that is, what if the $start and $end times are within the same day?
What am I missing here?
Apparently you're trying to build some kind of calendar functionality here.
If you use strtotime('10:00pm'); this will change to the timestamp of the next day after midnight.
So you need to give the variable a date
$start = strtotime('2015-02-26 10:00pm');
$end = strtotime('2015-02-27 6:00am');
Not sure how you store these time blocks, but ideally they would be stored in a database table.
If it's every day the same you could do:
$now = time(); // or $now = strtotime('11:00pm'); to simulate time to test
$start = strtotime('10:00pm');
$end = strtotime('6:00am'); // without the +1 day
if($start > $end) {
if($start > $now && $now > $end) {
echo 'disturb';
} else {
echo 'do not disturb';
}
}else{
if($now < $start || $now > $end) {
echo 'disturb';
} else {
echo 'do not disturb';
}
}
That's a nice question actually,
You can use the the relatively new object oriented way of dealing with times.
I'll link you some info as I don't have time to write an entire example
http://php.net/manual/en/datetime.diff.php
http://php.net/manual/en/class.datetime.php
http://php.net/manual/en/class.dateinterval.php
specifically from the docs :
<?php
$datetime1 = new DateTime('2009-10-11');
$datetime2 = new DateTime('2009-10-13');
$interval = $datetime1->diff($datetime2);
echo $interval->format('%R%a days');
?>
Hope it helps
I would convert to DateTime() objects instead. Then you won't get any issues with days ending.
// obviously you'll need to feed in the date as well so
// that might involve some refactoring
$now = new DateTime();
$start = new DateTime('2015-02-26 10:00');
$end = new DateTime('2015-02-27 06:00');
Now you can compare as before.
If you don't know the date and your users are only specifying time, you might need to add the date dynamically. These are just for example.
Edit: to cope with unknown days, you could dynamically generate after grabbing today:
$today = new DateTime();
$start = new DateTime($today->format('Y-m-d') . ' 10:00');
$end = new DateTime($today->format('Y-m-d') . ' 06:00');
$end->add(new DateInterval('P1D'));
I am trying to create a dropbox that will display the last year, the current year and the next year using the php DateTime object.
In my current code I create three objects and have to call a method on 2 of them. This seems a bit heavy on the resources.
$today = new DateTime();
$last_year=new DateTime();
$last_year->sub(new DateInterval('P1Y'));
$next_year = new DateTime();
$next_year->add(new DateInterval('P1Y'));
echo date_format($last_year, 'Y').' '.date_format($today, 'Y').' '.date_format($next_year, 'Y');
another way I found to only use 1 object is
$today = new DateTime();
echo date_format($today->sub(new DateInterval('P1Y')), 'Y').' '.date_format($today->add(new DateInterval('P1Y')), 'Y').' '.date_format($today->add(new DateInterval('P1Y')), 'Y');
but that will become very confusing.
Can someone tell me a better way to do this using DateTime()? As I will need something similar for months ?
Depending upon your version of PHP (>= 5.4), you could tidy it up a bit like this:-
$today = new DateTime();
$last_year=(new DateTime())->sub(new DateInterval('P1Y'));
$next_year = (new DateTime())->add(new DateInterval('P1Y'));
echo $last_year->format('Y').' '.$today->format('Y').' '.$next_year->format('Y');
See it working.
A more readable and concise option may be to use \DateTimeImmutable.
$today = new DateTimeImmutable();
$one_year = new DateInterval('P1Y');
$last_year = $today->sub($one_year);
$next_year = $today->add($one_year);
echo $last_year->format('Y').' '.$today->format('Y').' '.$next_year->format('Y');
See it working.
Other than that, this all looks fine. Worry about optimisation when it is needed.
Try this. This quite efficient.
echo date("Y");
echo date("Y",strtotime("-1 year"));
echo date("Y",strtotime("+1 year"))
May be you can also limit the call of new DateInterval('P1Y') by creating one object and using it for all three calculations?
$interval = new DateInterval('P1Y');
$dateTime = new DateTime();
$lastYear = $dateTime->sub($interval)->format('Y');
$dateTime = new DateTime();
$nextYear = $dateTime->add($interval)->format('Y');
$dateTime = new DateTime();
$thisYear = $dateTime->format('Y');
echo $lastYear . ' ' . $thisYear . ' ' . $nextYear;
and by breaking the single string into multiple commands always helps me in reducing confusions.
<?php
$d = new DateTime('now');
$cy = $d->format('Y');
// Get previous year
$d->modify('-1 year');
$py = $d->format('Y');
//Next year : Since object has previous year, so +2 to get next year
$d->modify('+2 year');
$ny = $d->format('Y');
echo "Previous Year: ".$py."<br>";
echo "Current Year : ".$cy."<br>";
echo "Next Year : ".$ny."<br>";
$d = new DateTime('now');
$cm = $d->format('m');
$d->modify('-1 month');
$pm = $d->format('m');
$d->modify('+2 month');
$nm = $d->format('m');
echo "Previous Month: ".$pm."<br>";
echo "Current Month : ".$cm."<br>";
echo "Next Month : ".$nm."<br>";
?>
Output
Previous Year: 2013
Current Year : 2014
Next Year : 2015
Previous Month: 12
Current Month : 01
Next Month : 02
Just use basic math:
$current = date('Y');
$prev = $current - 1;
$next = $current + 1;
after reading all the answers I came up with this function to create a dropdown box for year.
$name is the name of the
$year_number is the number of years you want to display
this function starts with one year before the current year but you can easily modify it to start displaying from earlier years.
function drop_down_box_date_year(&$dbconn, $name, $year_number){
$today = new DateTime();
$interval = new DateInterval('P1Y');
$startyear = (new DateTime())->sub($interval);
echo '<select name="'.$name.'_year">';
for($i=0;$i<$year_number;$i++){
if($startyear->format('Y')==$today->format('Y')){
echo '<option value="'.$startyear->format('Y').'" selected>'.$startyear->format('Y').'</option>';
}else{
echo '<option value="'.$startyear->format('Y').'">'.$startyear->format('Y').'</option>';
}
$startyear->add($interval);
}
echo'</select>';
}
I have 2 dates. Lets say they look like this.
$start = 2010/12/24;
$end = 2012/01/05;
I query the database to look for visits between these two dates. I find some. I then populate an array called stats.
$stats['2010/12/25'] = 50;
$stats['2010/12/31'] = 25;
...
As you can see, there are days missing. I need to fill the missing dates with a value of zero. I was thinking something like this. (I have pulled day / month / year from start and end dates.
for($y=$start_year; $y <= $end_year; $y++) {
for($m=$start_month; $m <=$end_month; $m++) {
for($d=$start_day; $d <= $end_day; $d++) {
This would work fine for the year however the months and days wouldn't work. If the start day is the 15th. Days 1-14 of each subsequent month would be missed. I could have a solution like this then...
for($y=$start_year; $y <= $end_year; $y++) {
for($m=1; $m <13; $m++) {
$total_days = cal_days_in_month(CAL_GREGORIAN, $m, $y) + 1;
for($d=1; $d <= $total_days; $d++) {
I would then need a bunch of if statements making sure starting and end months and days are valid.
Is there a better way of doing this? Or could this even be done in my mysql query?
Just to demonstrate the power of some of PHP's newer interval handling method (mentioned by pgl in his answer):
$startDate = DateTime::createFromFormat("Y/m/d","2010/12/24",new DateTimeZone("Europe/London"));
$endDate = DateTime::createFromFormat("Y/m/d","2012/01/05",new DateTimeZone("Europe/London"));
$periodInterval = new DateInterval( "P1D" ); // 1-day, though can be more sophisticated rule
$period = new DatePeriod( $startDate, $periodInterval, $endDate );
foreach($period as $date){
echo $date->format("Y-m-d") , PHP_EOL;
}
Does require PHP >= 5.3.0
EDIT
If you need to include the actual end date, then you need to add a day to $endDate immediately before the foreach() loop:
$endDate->add( $periodInterval );
EDIT #2
$startDate = new DateTime("2010/12/24",new DateTimeZone("Europe/London"));
$endDate = new DateTime("2012/01/05",new DateTimeZone("Europe/London"));
do {
echo $startDate->format("Y-m-d") , PHP_EOL;
$startDate->modify("+1 day");
} while ($startDate <= $endDate);
For PHP 5.2.0 (or earlier if dateTime objects are enabled)
If you're using PHP5.3 then Mark Baker's answer is the one to use. If (as you say in your comment) you're still on PHP5.2 something like this should help you:
$startdate = strtotime( '2010/12/24' );
$enddate = strtotime( '2012/01/05' );
$loopdate = $startdate;
$datesArray = array();
while( $loopdate <= $enddate ) {
$datesArray[$loopdate] = 0;
$loopdate = strtotime( '+1 day', $loopdate );
}
It will create an array of the unix timestamp of every date between the start and end dates as the index and each value set to zero. You can then overwrite any actual results you have with the correct values.
$start_date = DateTime::createFromFormat('Y/m/d', '2010/12/24');
$end_date = DateTime::createFromFormat('Y/m/d', '2012/01/05');
$current_date = $start_date;
while($current_date <= $end_date) {
$current_date = $current_date->add(new DateInterval('P1D'));
// do your array work here.
}
See DateTime::add() for more information about this.
$i = 1;
while(date("Y/m/d", strtotime(date("Y/m/d", strtotime($start)) . "+ $i days")) < $end) {
... code here ...
$i++;
}
I would calculate the difference between start and end date in days, iterate on that adding a day to the timestamp on each iteration.
$start = strtotime("2010/12/24");
$end = strtotime("2012/01/05");
// start and end are seconds, so I convert it to days
$diff = ($end - $start) / 86400;
for ($i = 1; $i < $diff; $i++) {
// just multiply 86400 and add it to $start
// using strtotime('+1 day' ...) looks nice but is expensive.
// you could also have a cumulative value, but this was quicker
// to type
$date = $start + ($i * 86400);
echo date('r', $date);
}
I have this bit of horrible code saved:
while (($tmptime = strtotime('+' . (int) $d++ . ' days', strtotime($from))) && ($tmptime <= strtotime($to))) // this code makes baby jesus cry
$dates[strftime('%Y-%m-%d', $tmptime)] = 0;
(Set $from and $to to appropriate values.) It may well make you cry, too - but it sort of works.
The proper way to do it is to use DateInterval, of course.
I've got to write a loop that should start and end between two times. I know there are many ways to skin this cat, but I'd like to see a real programmers approach to this function.
Essentially I have Wednesday, for instance, that opens at 6:00pm and closes at 10:30pm.
I'm looking to write a loop that will give me a table with all of the times in between those two in 15 minute intervals.
So, I basically want to build a one column table where each row is
6:00pm
6:15pm
7:15pm
etc...
My two variables to feed this function will be the open time and the close time.
Now don't accuse me of "write my code for me" posting. I'll happily give you my hacked solution on request, I'd just like to see how someone with real experience would create this function.
Thanks :)
$start = new DateTime("2011-08-18 18:00:00");
$end = new DateTime("2011-08-18 22:30:00");
$current = clone $start;
while ($current <= $end) {
echo $current->format("g:ia"), "\n";
$current->modify("+15 minutes");
}
Try it on Codepad: http://codepad.org/JwBDOQQE
PHP 5.3 introduced a class precisely for this purpose, DatePeriod.
$start = new DateTime("6:00pm");
$end = new DateTime("10:30pm");
$interval = new DateInterval('PT15M');
$period = new DatePeriod($start, $interval, $end);
foreach ($period as $time) {
echo $time->format('g:ia'), PHP_EOL;
}
echo $end->format('g:ia'); // end time is not part of the period
$start = strtotime('2011-08-11 18:00:00');
for ($i = 0; $i < 20; $i++) {
echo date('g:ia', $start + ($i * (15 * 60))), '<br>';
}
I would go with the DateTime functions and increase the time by 15 minutes every loop-turn as long as the current time is lower then the end-time.
EDIT: as user576875 has posted
$start_date = '2019-07-30 08:00:00';
$end_date = '2019-09-31 08:00:00';
while (strtotime($start_date) <= strtotime($end_date)) {
echo "$start_date<br>";
$start_date = date ("Y-m-d H:i:s", strtotime("+1 hours", strtotime($start_date)));
}