How to differentiate days between a list of dates? PHP - php

I've been trying to make a list of days of when I went to school and when I didn't.
I'm looping the days here. Another array contains the days I didn't go to school.
<?php
$fecha1 = "2015-03-10";
$fecha2 = date("Y-m-d",strtotime($fecha1."+ 10 days"));
$fecha3 = array("2015-03-11","2015-03-14","2015-03-17");
$j=1;
for($i=$fecha1;$i<$fecha2;$i = date("Y-m-d", strtotime($i ."+ 1 days"))){
for ($n=0; $n <count($fecha3) ; $n++) {
if($i==$fecha3[$n]){
$obs="not there";
}else{
$obs="there";
}
}
echo "Day ".$j." ".$i."---".$obs."<br />";
$j++;
}
?>
and the output is
Day 1 2015-03-10---there
Day 2 2015-03-11---there
Day 3 2015-03-12---there
Day 4 2015-03-13---there
Day 5 2015-03-14---there
Day 6 2015-03-15---there
Day 7 2015-03-16---there
Day 8 2015-03-17---not there
Day 9 2015-03-18---there
Day 10 2015-03-19---there
I dont understand why it doesnt say "not there" on day 2 2015-03-11
and day 5 2015-03-14, someone help me please I've been with this for hours.

You should add a break once the needle is found:
if($i==$fecha3[$n]){
$obs="not there";
break; // this is important
}else{
$obs="there";
}
Another alternative is also in_array() for searching:
if(in_array($i, $fecha3)){
$obs="not there";
}else{
$obs="there";
}

It's because 2015-03-11 and 2015-03-14 are the first two values in the $fecha3 array, and $obs gets overwritten in that second for loop.
In this case I would recommend using in_array() instead of a second for loop:
$fecha1 = '2015-03-10';
$fecha2 = 10;
$fecha3 = array('2015-03-11', '2015-03-14', '2015-03-17');
for ($i = 0; $i < $fecha2; $i++) {
$date = date('Y-m-d', strtotime($fecha1 . ' + ' . $i . ' days'));
$obs = in_array($date, $fecha3) ? 'not there' : 'there';
echo 'Day ' . ($i + 1) . ' ' . $date . '---' . $obs . '<br />';
}

Related

PHP if date is older than X days

I have some problems with dates. I need make if like --->
if your activity is less than 1 day do somethink
else if your activity is more than 1 day and less than 3 do moething else
else if your activity is more than 3 do moething else
I need this in PHP. My actual code is:
if (strtotime(strtotime($last_log)) < strtotime('-1 day') ) {
$prom .= "" . json_encode('last_activity') . ": " . json_encode("inactive less than 1 day") . ",";
} else if (strtotime($last_log) > strtotime('-1 day') && strtotime($last_log) < strtotime('-3 day')) {
$prom .= "" . json_encode('last_activity') . ": " . json_encode("inactive more than 1 day and less than 3 days") . ",";
} else if (strtotime($last_log) > strtotime('-3 day')) {
$prom .= "" . json_encode('last_activity') . ": " . json_encode("inactive more than 3") . ",";
}
I think I really don't understand date calculations.
Date_diff is much easier in this case:
$datetime1 = date_create(); // now
$datetime2 = date_create($last_log);
$interval = date_diff($datetime1, $datetime2);
$days = $interval->format('%d'); // the time between your last login and now in days
see: http://php.net/manual/en/function.date-diff.php
Or in your way:
if(strtotime($last_log) < strtotime('-1 day')){
// it's been longer than one day
}
If you want to do it with strtotime, do it like this:
date_default_timezone_set('SOMETHING FOR YOU');
$last_log = '-0.5 day';
$last_log_time = strtotime($last_log);
$minus1day_time = strtotime('-1 day');
$minus3day_time = strtotime('-3 day');
echo $last_log_time . "<br>";
echo $minus1day_time . "<br>";
echo $minus3day_time . "<br>";
if ($last_log_time < $minus3day_time)
{
echo "inactive more than 3";
}
elseif ( ($last_log_time <= $minus1day_time) && ($last_log_time >= $minus3day_time) )
{
echo "inactive more than 1 day and less than 3 days";
}
elseif ($last_log_time > $minus1day_time)
{
echo "inactive less than 1";
}
Couple things I changed from your code:
remove the strtotime(strtotime()). Do not do it twice!
For your second if, I added parentheses to ensure correct evaluation of conditions.
I reversed the order of your if. First check if it is very old (so < -3). Then check if it is between -3 and -1. Then check between -1 and now.
Added <= and >=. The = cases were missing from your code. So if the last_log was == -1, it was not processed ever.
I replace "else if" by "elseif".
I used variables because recalculating strtotime all over is wasteful. And it makes the code less readable IMHO.
Then apply the json_encode comment.
To explain why the logic was reversed:
the last login of a user will always be before now.
lets say that the user's last_login is 5 days ago. strtotime($last_login) will be smaller than strtotime('-1 days'), so the if will be true. But that is not what the OP wants! He wants here the case where the last login is older than 3 days.
Remember that we are comparing numbers in the past, so the smaller, the older.
$dateLog = new DateTime($last_log); // format if needed
$tomorrow = new DateTime("tomorrow");
$yesterday = new DateTime("yesterday");
$threeDaysAgo = new DateTime("-3 days");
if ($dateLog < $yesterday) {
// Do what you want
} else if ($dateLog > $yesterday && $dateLog < $threeDaysAgo) {
// Do another thing
} else if ($dateLog > $threeDaysAgo) {
// ...
}
The doc is here : http://php.net/manual/en/datetime.diff.php

Checking for the 5th recurrence regarding to startdate. Recurring on specific weekday in the month

I have got a script that repeats activitities.
When the repeat settings are:
repeat "the 2nd tuesday every 2 months, stop at 5 instances" (like google calendar would do).
I can accomplish "the 2nd tuesday every 2 months" with the script below:
<?php
$pubDay = 19;
$pubMonth = 7;
$pubYear = 2017;
$repeatMonths = 2;
$newMonth = $pubMonth;
$newYear = $pubYear;
$raisedMonth = $pubMonth + $repeatMonths;
if ( $raisedMonth > 12 ) {
$newMonth = ($raisedMonth) % 12; // off 12 at starts at 1
$newYear = $pubYear + 1;
} else {
$newMonth = $raisedMonth;
}
$occurenceInMonth = ceil($pubDay / 7); // determine the weekday occurence in the month (b.e. the "2nd thursday")
$dates = array();
foreach (getWeekDayDates($pubDow, $newYear, $newMonth) as $weekdaydate) {
$dates[] = $weekdaydate->format("Y-m-d");
}
// we need the x occurence (-1)
$newPubDate = isset($dates[$occurenceInMonth -1]) ? $dates[$occurenceInMonth -1] . " " . $pubHour . ":" . $pubMin : "";
echo $newPubDate;
function getWeekDayDates($weekday, $y, $m) {
return new DatePeriod(
new DateTime("first " . $weekday . " of $y-$m"),
DateInterval::createFromDateString('next ' . $weekday),
new DateTime("next month $y-$m-01")
);
}
?>
This works like a charm.
But now i need to check wether it is the 5th instance, starting at 17-9-2016.
My script is now like this:
// get the end date
$startdate = "2016-09-17";
$repeatMonths = 2;
$endTime = strtotime($startdate . " +" . ($repeatMonths * $reps) . " months");
if ( $endTime >= strtotime($newPubDate) ) {
$doRepeat = true;
}
But this can go wrong!
By example when the repetitons starts (startddate) at saturday 4-7 and it repeats every first sunday.
When the sunday in the last repetition is on the 6th of the month. The script above returns false, but it shouldnt't.
How can i check on a simple way if it is the 5th occurence?
I would create an array which holds DateTime objects of the next 5 "2nd tuesdays of the month":
$startdate = new \DateTime('second tue of february 2017');
$dates = array();
$repetitions = 5;
for ($i=0; $i<$repetitions; $i++) {
$dates[] = clone $date->modify('+1 month');
}
Using this array it should be easy to check, whether the date is reached or not yet.

Working dates between two given dates in Php

Please, i need assistance in this code.I have checked others in Stakeoverflow, but it is not combatible, hence this question. I want to generate all working /weekdays between two dates.I have found a code, but it is generating all days, including weekend. How do i eliminate the weekend from the list or ensure the list generated is ONLY for weekdays?
<?php
$start_Date = date('Y-m-d');
$end_Date = date('Y-m-d', strtotime('30 weekdays'));
//echo $start_Date."<br/>";
//echo $end_Date."<br/>";
// Specify the start date. This date can be any English textual format
$date_from = $start_Date;
$date_from = strtotime($date_from); // Convert date to a UNIX timestamp
// Specify the end date. This date can be any English textual format
$date_to = $end_Date;
$date_to = strtotime($date_to); // Convert date to a UNIX timestamp
// Loop from the start date to end date and output all dates inbetween
$c = 0;
for ($i = $date_from; $i <= $date_to; $i += 86400) {
$c++;
echo $c . "=> " . date("Y-m-d", $i) . '<br />';
}
I expect 30days to be generated but with this code, I am getting 42days . Weekend has been added,instead of weekdays ONLY .
Just add this to your loop:
$w = date('w',$i);// day of week - Sunday == 0, Saturday == 6
if($w == 0 || $w == 6){
continue;
}
DEMO
Your code is almost working only have to add a if checking in your code
your code
for ($i = $date_from; $i <= $date_to; $i += 86400) {
$c++;
echo $c . "=> " . date("Y-m-d", $i) . '<br />';
}
please replace with that one
for ($i = $date_from; $i <= $date_to; $i += 86400) {
$day = date("w", $i);
if($day != 0 && $day!= 6){ // will continue if not Sunday or Saturday
$c++;
echo $c . "=> " . date("Y-m-d", $i) . '<br />';
}
}
You also can take help from php.net
Thanks
You may need to get the day of the week, like date("D"), then use it in your for loop to check..something like this?:
$Weekends = array("Sat","Sun");
for....
$DayOfWeek = date("D",$i);
if(!in_array($DayOfWeek, $Weekend)){
// increment...
}

Calculate season prices

I want to calculate season prices.
The beginning and ending dates of the seasons should be 'the last Saturday of this month' instead of '2016-31-12'.
The only problem for me is that I don't know how to loop trough the array called 'period' when there is a period booked with a different year number.
To clear things up, 'the last Saturday of this month' changes in the next year.
Example:
$beginseason1 = new DateTime('December');
$beginseason1->modify('last saturday of this month');
My code:
<?php
// declare season dates
$startdate = new DateTime('2016-12-31');
$enddate = new DateTime('2018-04-30');
$beginseason1 = new DateTime('2016-01-01');
$endseason1 = new DateTime('2016-03-30');
$beginseason2 = new DateTime('2016-03-31');
$endseason2 = new DateTime('2016-04-30');
$beginseason3 = new DateTime('2016-05-01');
$endseason3 = new DateTime('2016-12-31');
// get period of booked dates and put them in a array
$period = new DatePeriod(
new DateTime($startdate->format('Y-m-d')),
new DateInterval('P1D'),
new DateTime($enddate->format('Y-m-d'))
);
//declare variables below
$price = 0;
$daysinseason1 = 0;
$daysinseason2 = 0;
$daysinseason3 = 0;
// loop trough array and check every date with season prices
foreach($period as $date)
{
if($date->format('m-d') >= $beginseason1->format('m-d') && $date- >format('m-d') <= $endseason1->format('m-d')){
echo $date->format('m-d') . "<br/>";
$price = $price + 25;
$daysinseason1++;
}
if($date->format('m-d') >= $beginseason2->format('m-d') && $date->format('m-d') <= $endseason2->format('m-d')){
echo $date->format('m-d') . "<br/>";
$price = $price + 25;
$daysinseason2++;
}
if($date->format('m-d') >= $beginseason3->format('m-d') && $date->format('m-d') <= $endseason3->format('m-d')){
echo $date->format('m-d') . "<br/>";
$price = $price + 25;
$daysinseason3++;
}
}
echo "season 1: " . $daysinseason1 . "<br/>";
echo "season 2: " . $daysinseason2 . "<br/>";
echo "season 3: " . $daysinseason3 . "<br/>";
?>
My code does the trick but it doesn't matter if the year is 2016 or 2018 31-12 is alway the last Saturday of December.
And also the beginning of season 1 occur in 2016 but the ending in 2017.
How can I program this the right way?

Evenly spread results set over a number of days PHP

I am trying to disperse the results of 3 queries in a very specific manner across any number of days. Each result from each array represents 1 phone call, and I want a total of 18 phone calls per day.
I need a total of 18 total results per day broken down by:
8 $active_costco results
4 $inactive_costso results
3 $bashas results
3 $afs results
$active_costco returns 321 total results
$inactive_costco returns 119 total results
$bashas returns 64 total results
$afs returns 47 results
I need the total number of results to be 18 per day, so if there are no more $afs or $inactive_costco's, fill in to 18 with $active_costcos.
Here is the php I have currently (it only divides the active_costcos across 8 per day)
$active_costco = sql::results($query);
$inactive_costco = sql::results();
$bashas = sql::results("");
$afs = sql::results("");
$date = date('Y-m-d');
$str = 'INSERT pharmacy.dbo.hotlist (employee_id, store_id, follow_up_date, created_at, status, urgency)VALUES';
for ($i = 0; $i < count($active_costco); $i++)
{
if ($i%8 == 0)
{
$date = date('Y-m-d', strtotime($date . '+1 Weekday'));
}
$str .= "('0CS',". $active_costco[$i]['id'] . ", '$date', '". date('Y-m-d H:m.s') . "', 1, 3)";
$str .= ($i == count($active_costco)-1)? '': ',';
$str .= '<br />';
}
echo $str;
Any help would be appreciated.
Thanks,
Mike
After spending a little time on this, here is the solution I came up with:
$str = 'INSERT pharmacy.dbo.hotlist (employee_id, store_id, follow_up_date, created_at, status, urgency)VALUES';
do
{
$date = date('Y-m-d', strtotime($date . " +1 Weekday"));
$today = array();
for ($i = 0; $i < 3; $i ++)
{
$basha = array_pop($bashas);
$associated = array_pop($afs);
if (!empty($basha))
$today[] = $basha;
if (!empty($associated))
$today[] = $associated;
}
for ($i = 0; $i < 4; $i++)
{
$inactive = array_pop($inactive_costco);
if (!empty($inactive))
$today[] = $inactive;
}
$count = 18 - count($today);
for ($i = 0; $i < $count; $i++)
{
$active = array_pop($active_costco);
if (!empty($active))
$today[] = $active;
}
$calls_left = count($active_costco) + count($inactive_costco) + count($bashas) + count($afs);
foreach ($today as $v)
{
echo "Store ID = " . $v['id'] . " Date = " . $date . "<br />";
}
}while ($calls_left > 0);
It goes through and pops elements off each of the arrays (the number that was specified). If it the array is empty (there is nothing to pop) it doesn't add anything. Then it counts the number of calls in the today array, subtracts that from 18, and grabs the remaining calls from $active_costsco.
Thanks to everyone that put in input.

Categories