I really need help to display a month list view in which deposit received month should be green in color and no-deposit month should be in red color.
I have stuck in comparing the array values. and I am using codeigniter.
I have a table with start-date and end-date by using this I have created an array to display all months in between these dates. Please find the code which I have used to do it below:
$datefrom = strtotime($showrangecalendar['chitdate_start']);
$dateto = strtotime($showrangecalendar['chitdate_end']);
$start_date = date('Y-m-d', $datefrom);
$end_date = date('Y-m-d', $dateto);
$day = 2.628e+6; // Day in Months
$format = 'Y-F'; // Output format (see PHP date funciton)
$sTime = strtotime($start_date); // Start as time
$eTime = strtotime($end_date); // End as time
$numDays = round(($eTime - $sTime) / $day) + 1;
$days = array();
for ($d = 0; $d < $numDays; $d++) {
$days[] = date($format, ($sTime + ($d * $day)));
}
This code got me the Days list and I have displayed this using foreach statement to a table.
Now I have another table (accounts) with columns such as ID, Book_number, Deposit_Amount and Deposit_Month. Here the problem starts I have fetched data from "accounts" and loaded to my view using the below code from controller
$data['show_account']= $this->Accounts_model->get_all_accounts($sess_data);
My Model (Accounts_Model) is as shown below:
public function get_all_accounts($id)
{
$this->db->select("*");
$this->db->order_by('book_id','desc');
$this->db->from("accounts");
$this->db->where('bh_id',$id);
$query = $this->db->get();
return $query->result();
}
If I run the belowcode:
foreach($show_account as $values){
echo $values->deposit_month;
}
Its getting me the array result of all deposit month. Suppose I have data as 2018-Sep and 2018-Oct, These 2 months column should turn green in the above mentioned $days array.
Hope I have explained my requirement clearly. Please help me with this as I am already spent long hours in this.
Thanks in Advance.
Updated:
Now could you please check my model as follows:
public function get_dep_month($bh_id)
{
$this->db->select('deposit_month');
$this->db->from('accounts');
$this->db->where('bh_id',$_SESSION['bh_id']);
$this->db->order_by('deposit_month','asc');
$query = $this->db->get();
return $query->result_array();
}
And My Controller is as follows:
$sess_data = $this->session->userdata('bh_id');
$data['depM_array'] = $this->Accounts_model->get_dep_month($sess_data);
Now please check my View as follows:
<?php
// option 2
foreach($days as $day) { // using your already exist $day for-loop for display
if (!in_array($day, $depM_array)){
$calhilight = "calgreen";
}
else{
$calhilight = "calred";
}
?>
<li class="<?php echo $calhilight; ?>"><?= $day ?></li>
<?php
}
?>
But as my doposit_month column having only 2 values ie: 2018-Sep and 2018-Oct, Instead of getting green color for those 2 values, I am getting Green for who li element. Not getting where I have done wrong.
This is the Current page view which I am getting, Actually I am expecting a calendar view with 2 green fields for 2018-Sep and 2018-Oct and all other fields in Red
Performed Var Dumb in arrays:
Pls check this screenshot
FYI:
Below is the code from where I am getting $days array.
<?php
$datefrom = strtotime($showrangecalendar['chitdate_start']);
$dateto = strtotime($showrangecalendar['chitdate_end']);
$start_date = date('Y-m-d', $datefrom);
$end_date = date('Y-m-d', $dateto);
$day = 2.628e+6; // Day in Months
$format = 'Y-F'; // Output format (see PHP date funciton)
$sTime = strtotime($start_date); // Start as time
$eTime = strtotime($end_date); // End as time
$numDays = round(($eTime - $sTime) / $day) + 1;
$days = array();
for ($d = 0; $d < $numDays; $d++) {
$days[] = date($format, ($sTime + ($d * $day)));
}
?>
Here $start_date & $end_date is fetching from another table named chitdate.
Thanks Again.
You can use array-diff or simple for-loop.
Consider the following simple example:
$days = array("2018-September", "2018-October", "2018-November", "2018-December");
$deposit_month = array("2018-September", "2018-October");
// option 1:
$diff = array_diff($days, $deposit_month);
// now $diff has: "2018-November" and "2018-December"
// option 2
foreach($days as $day) { // using your already exist $day for-loop for display
if (!in_array($day, $deposit_month))
// color in red as not found in "deposit_month"
else
// color in green
}
Nicer writing for that if can be as:
$color = in_array($day, $deposit_month) ? "Green" : "Red";
I've got a script that sets up a array of dates which form a dropdown. The array is set up by some variables about the current date and an fixed offset for the last date (two weeks). Stripped down this is what it looks like:
public function getDatesOptionArray()
{
$datesArray = array();
$displayDate = Mage::getModel('core/locale')->storeDate();
$displayDate->add($this->_startDaysOffset, Zend_Date::DAY);
$dayOffset = $this->_startDaysOffset;
do
{
$dayofweek = date('w', strtotime($displayDate->toString(Varien_Date::DATE_INTERNAL_FORMAT)));
$datesArray[$displayDate->toString(Varien_Date::DATE_INTERNAL_FORMAT)] = Mage::helper('core')->formatDate($displayDate, Mage_Core_Model_Locale::FORMAT_TYPE_FULL);
$displayDate->add('1', Zend_Date::DAY);
$dayOffset++;
} while ($dayOffset <= $this->_endDaysOffset);
return $datesArray;
}
The thing is I want to leave out all the 'Sunday' options, and I've got the $dayofweek variable for each, where sunday is 0. I've tried to wrap the whole thing inside the do function in an if-statement (if $dayofweek !== 0), set an if ($dayofweek == 0) { continue;} and every other trick I could think of, but I get only either of these results
1: Only the first date is shown
2: All dates until the first sunday are shown, none after that
3: All dates are shown
I think I might be missing the point on the do-while loop; how do I exclude if $dayofweek == 0?
For me is something like this, i use while because Do...While(...) the first time it will not check your condition you'll enter your loop at last 1 time, and when you use while(...){} every time your program will check your condition
public function getDatesOptionArray()
{
$datesArray = array();
$displayDate = Mage::getModel('core/locale')->storeDate();
$displayDate->add($this->_startDaysOffset, Zend_Date::DAY);
$dayOffset = $this->_startDaysOffset;
while ($dayOffset <= $this->_endDaysOffset)
{
$dayofweek = date('w', strtotime($displayDate->toString(Varien_Date::DATE_INTERNAL_FORMAT)));
if ($dayofweek != 0) {
$datesArray[$displayDate->toString(Varien_Date::DATE_INTERNAL_FORMAT)] = Mage::helper('core')->formatDate($displayDate, Mage_Core_Model_Locale::FORMAT_TYPE_FULL);
}
$displayDate->add('1', Zend_Date::DAY);
$dayOffset++;
}
return $datesArray;
}
Let say the array is
$date = array(
2017-10-12,
2017-10-13,
2017-10-14,
2017-10-15,
2017-10-16,
2017-10-17,
2017-10-18,
2017-10-19,
2017-10-20,
2017-10-21,
2017-10-22,
2017-10-23,
2017-10-24,
2017-10-25
);
Now do this for remove sunday's dates
$i=0;
do{
if(date('w',strtotime($date[$i]))>0) $dateArray[] = $date[$i];
$i++;
} while ($i<count($date));
echo "<pre>";print_r($dateArray);
return $datesArray;
$dateArray will give you dates without sundays.
I am trying to show results of each month.
Im having this for loop:
foreach ($overview as $day) {
$year = date("Y") - 1;
if ($day->user == $info->id) {
$startDate = new DateTime($day->Calendar_startdate);
$endDate = new DateTime($day->Calendar_enddate);
$s = $startDate->format('Y-m-d');
$e = $endDate->format('Y-m-d');
if ($s > $year) {
$workdays = number_of_working_days($s, $e);
$daysleft = $daysleft + $workdays;
} else {
}
}
}
This for loop is also in an if statement which echos the months.
Now I need to let it work for the months January, February etc...
I am able to not show results if in the previous year which works well.
If you want to compare $s with $year just change $year to :
$time = new DateTime('now');
/*** you can use `now` for today
/* or you can change to a fixed date exmp: 2016-01-01
*/
$year = $time->modify('-1 year')->format('Y-m-d');
Than you can compare $s > $year
I fixed by checking each month if it contained for example -01-
DB::table('Calendar')->where('Calendar_startdate', 'like','%' . $monthnumber . '%')->where('user', $info->id)->where('Calendar_type',2)->get();
I have some PHP code to calculate the number of days between two specific dates. The difference should not count Sundays and Saturdays. Also, I have an array of dates, which includes holidays, which also need to be skipped.
I gave the starting date as 01-05-2015 and ending date as 01-06-2015. I gave the entire days in the month of may as array. Thus the difference should be 1 day. But I am getting the output as 7. What is the problem? Here is the code.
function dateRange($first, $last) {
$dates = array();
$current = strtotime($first);
$now = $current;
$last = strtotime($last);
while( $current <= $last ) {
if (date('w', $current) != 0){
$dates[] = date('d-m-Y', $current);
}
$current = strtotime('+1 day', $current);
}
unset($dates[0]);
return $dates;
}
$datea = "01-05-2015";
$date = "01-06-2015";
$hdsarray = array("1-05-2015","2-05-2015","4-05-2015","5-05-2015","7-05-2015","8-05-2015","9-05-2015","11-05-2015","12-05-2015","14-05-2015","15-05-2015","16-05-2015","18-05-2015","19-05-2015","21-05-2015","22-05-2015","23-05-2015","25-05-2015","26-05-2015","28-05-2015","29-05-2015","30-05-2015");
$datesarray = dateRange($datea, $date);
$result = array_diff($hdsarray,$datesarray);
$date_diff = sizeof($result);
echo $date_diff;
The only problem I can see is in the usage of array_diff, It actually includes the sat and sun which is excluded by dateRange function, if not found in holidays list.
Instead, you can pass your holiday dates in dateRange function, and filter over there.
function dateRange($first, $last, $excludeDates) {
$dates = array();
$current = strtotime($first);
$now = $current;
$last = strtotime($last);
while( $current <= $last ) {
if (date('w', $current) != 0 && date('w', $current) != 6 && !in_array(date('j-m-Y', $current), $excludeDates)){
$dates[] = date('d-m-Y', $current);
}
$current = strtotime('+1 day', $current);
}
return $dates;
}
$datea = "01-05-2015";
$date = "01-06-2015";
$hdsarray = array("1-05-2015","2-05-2015","4-05-2015","5-05-2015","7-05-2015","8-05-2015","9-05-2015","11-05-2015","12-05-2015","14-05-2015","15-05-2015","16-05-2015","18-05-2015","19-05-2015","21-05-2015","22-05-2015","23-05-2015","25-05-2015","26-05-2015","28-05-2015","29-05-2015","30-05-2015");
$datesarray = dateRange($datea, $date, $hdsarray);print_r($datesarray);
Result:
Array
(
[0] => 06-05-2015
[1] => 13-05-2015
[2] => 20-05-2015
[3] => 27-05-2015
[4] => 01-06-2015
)
All the 5 dates come in the result, are not sat, sun, and also not there in holidays list.
It seems that there are several problems here. First, as pointed out by others the condition:
if (date('w', $current) != 0){
only checks for Sundays, if it should also include Saturday's it should be:
if (date('w', $current) != 0 && date('w', $current) != 6){
Secondly, it seems that the $hdsarray array does not contain all of the days in May. It seems that all of the Wednesdays are missing.
The third issue is that you are using array_diff on two arrays, one containing Dates and the other ones containing Strings. From the documentation:
Two elements are considered equal if and only if (string) $elem1 ===
(string) $elem2. In words: when the string representation is the same.
In your $hdsarray you are using "1-05-2015" to denote the first day of the month, while:
echo date('d-m-Y', strtotime("1-05-2015"));
results in "01-05-2015". You will need to add an additional 0 in $hdsarray for these dates or work with dates as well.
Last but not least, the current algorithm will not work correctly if the $hdsarray contains dates for a Saturday or Sunday, the result of array_diff will still contain these dates. Since you want to filter the result of daterange the array_filter function might be more suitable.
Despite an answer has already been provided, here is a little snippet with a class handling everything for you:
<?php
class dateRange {
protected $start, $end, $daysToExclude, $datesToExclude;
function __construct($dateStart, $dateEnd, $daysToExclude, $datesToExclude) {
$this->start = $dateStart;
$this->end = $dateEnd;
$this->daysToExclude = $daysToExclude;
$this->datesToExclude = $this->fixFormat($datesToExclude);
}
public function getRangeLength ($callback = null) {
$tmp = array();
$now = strtotime($this->start);
$to = strtotime($this->end);
while ( $now <= $to ) {
if (!in_array(date("w", $now), $this->daysToExclude)) {
$tmp[] = date('d-m-Y', $now);
}
$now = strtotime('+1 day', $now);
}
is_callable($callback) && call_user_func($callback, array_diff($tmp,$this->datesToExclude));
return count(array_diff($tmp,$this->datesToExclude));
}
private function fixFormat($el) {
if (!is_array($el)) {
return false;
}
else {
foreach ($el as &$value) {
$value = date("d-m-Y",strtotime($value));
}
return $el;
}
}
}
?>
I decided to keep your current logic (using date_diff), but I thought that, in the future, you may have your boss telling you "You know what? I don't want to have mondays aswell there" so, with the current system, you will have to edit your function manually and, perhaps, you won't remember anymore what you did.
The class above expects four parameters:
dateStart (d-m-Y format)
dateEnd (d-m-Y format)
daysToExclude (array with IDs of the days to exclude -> example array(0,6) to exclude saturdays and sundays).
datesToExclude (array with the dates to exclude, every format supported).
The class will automatically fix the datesToExclude array format in order to allow you to use date_diff.
Here is an example to use it, following your case:
<?php
$dateStart = "01-05-2015";
$dateEnd = "01-06-2015";
$daysToExclude = array(0,6);
$exclusions = array(
"1-05-2015",
"2-05-2015",
"4-05-2015",
"5-05-2015",
"7-05-2015",
"8-05-2015",
"9-05-2015",
"11-05-2015",
"12-05-2015",
"14-05-2015",
"15-05-2015",
"16-05-2015",
"18-05-2015",
"19-05-2015",
"21-05-2015",
"22-05-2015",
"23-05-2015",
"25-05-2015",
"26-05-2015",
"28-05-2015",
"29-05-2015",
"30-05-2015"
);
$dateRange = new dateRange($dateStart, $dateEnd, $daysToExclude, $exclusions);
echo $dateRange->getRangeLength();
?>
The code above outputs 5.
The function getRangeLength also accepts a callback and will return the array resulting of the date_diff operation, so you can also:
$dateRange->getRangeLength(function($res) {
echo "Literal output: <br />";
print_r($res);
echo "<br />count is: " . count($res);
});
The above outputs:
Literal output:
Array ( [3] => 06-05-2015 [8] => 13-05-2015 [13] => 20-05-2015 [18] => 27-05-2015 [21] => 01-06-2015 )
count is: 5
So if you later will need to remove mondays too, you will be able to easily do that by changing daysToExclude to array(0,1,6);
Hope this will be helpful to anyone else who will need this, despite a valid answer has already been posted.
Your original problem, in any case, was pretty much related to the array_diff function, which was NOT doing its job because of the fact that the date strings were not compatible, because "1-01-2015" is different from "01-01-2015", unless you first convert BOTH of them to times and then back to dates.
The code is fine (except that $nowis not used at all). The problem is the $hdsarray is wrong:
It should $hdsarray = array("01-05-2015", "02-05-2015", "04-05-2015", "05-05-2015", "07-05-2015", "08-05-2015", "09-05-2015",...);
date('d-m-Y', $current);will always return a leading 0 for all days between 1 and 9.
That's where the difference comes from.
This question already has answers here:
I have 2 dates in PHP, how can I run a foreach loop to go through all of those days?
(13 answers)
Closed 1 year ago.
I want to fill an array with values. The keys of this array should be readable dates in the format 'YEAR-MONTH-DAY'. Starting point is '2010-5-25'.
The process should abort on the current date. Obviously, all dates should be valid dates.
I thought about doing this loop. But it seems that PHP is not able to check the condition of more than one in a 'for' loop. It does not give me any warnings or errors, though.
for ($d = 25, $m = 5, $y = 2010,
$this_day = date('j'),
$this_month = date('n'),
$this_year = date('Y');
($y <= $this_year) && ($m <= $this_month) && ($d <= $this_day);
$d++)
{
$values[$y.'-'.$m.'-'.$d] = 0; //fill array
$d++;
if(!checkdate($m, $d, $y)){
$d = 1;
$m++;
if($m > 12) { $m = 1; $y++; }
}
}
Doing this with nested loops would be rather painful.
One solution would be to use integer times as keys and then convert them later in another loop into the readable dates.
Is there a more efficient way?
Here is code that does some error checking, for example, valid dates provided and start date cannot be bigger than end date:
function arrayKeyDates($start, $end='now') {
// can use DateTime::createFromFormat() instead
$startDate = new DateTime($start);
$endDate = new DateTime($end);
if ($startDate === false) {
// invalid start date.
return;
}
if ($endDate === false) {
// invalid end date.
return;
}
if ($startDate > $endDate) {
// start date cannot be greater than end date.
return;
}
$dates = array();
while($startDate <= $endDate) {
$dates[$startDate->format('Y-n-j')] = 0;
$startDate->modify('+1 day');
}
return $dates;
}
print_r(arrayKeyDate('2014-11-30'));
I get the following output:
Array
(
[2014-11-30] => 0
[2014-12-1] => 0
[2014-12-2] => 0
[2014-12-3] => 0
[2014-12-4] => 0
[2014-12-5] => 0
[2014-12-6] => 0
[2014-12-7] => 0
)
Error handling code is left to you.
UPDATE (DateTime::createFromFormat)
If you want to create the DateTime objects using a custom format you can, in my function, you can do something like this:
$startDate = DateTime::createFromFormat('Y-n-j', $start);
Where $start would have the value 2010-5-25.
For more information, see: http://php.net/manual/en/datetime.createfromformat.php
$startDate = new \DateTime('2010-05-25');
$endDate = new \DateTime();
$interval = new \DateInterval('P1D');
$period = new \DatePeriod ($startDate, $interval, $endDate);
$dates = array();
foreach ($period as $key => $date) {
$dates[$date->format('Y-m-d')] = null;
}
var_dump($dates);
Simply you can try using strtotime(). Example:
$values = array();
$oldDate = strtotime('2010-05-25');
while($oldDate <= time()){
$values[date('Y-m-d', $oldDate)] = 'Your value';
$oldDate += 86400;
//Other codes
}
I know this is an old question, but might be helpful for new viewers a shorter version
$dummyArray = array_fill(1, 7, 0);
$dates = array_flip(array_map(function($val, $idx) {
return date_create('2010-5-25')->modify('-' . $idx . ' days')->format('Y-m-d');
}, $dummyArray, array_keys($dummyArray)));
I'm basically generating a dummy array which is going to have the numbers of days I want to extract as index, and then converting those to dates with array_map, after which I just flip the array to have the dates as keys instead of values
I took the liberty to clean up your code a little to make it readable:
<?php
$this_day = date('j');
$this_month = date('n');
$this_year = date('Y');
echo sprintf("Today: d-m-y: %s-%s-%s\n", $this_day, $this_month, $this_year);
for ($d = 25, $m = 5, $y = 2010;
($y <= $this_year) && ($m <= $this_month) && ($d <= $this_day);
$d++) {
echo sprintf("Date: d-m-y: %s-%s-%s\n", $d, $m, $y);
$values[$y.'-'.$m.'-'.$d] = 0; //fill array
$d++;
if(!checkdate($m, $d, $y)){
$d = 1;
$m++;
if($m > 12) { $m = 1; $y++; }
}
}
This shows that the code works perfectly well. That is if you chose the correct condition!
Today is the 07th, but your initial values start with the 25th which falsifies the condition. To verify chose a start day of '02' and see the output...
I guess you want to re-check your condition. Most likely it is something else you want to express...
First of all; the loop doesn't execute because you are checking separately if year number is lower then current year number, etc. But today is the 7th, and you start at the 25th of may 2010:
$d = 25;
$this_day = date('j'); // today: 7
$loop = $d <= $this_day; // evaluates to false
Because the 'day-check' evaluates to false, the whole expression evaluates to false. So the loop will only start to run on december the 25th.
You can better use the DateTime object to construct the dates and perform modifications on the created object. This will also safe you a lot of sweat with stuff like leap years etc. Example:
for (
$start = new DateTime('2010-05-25'),
$today = new DateTime('now') ;
$start->diff($today)->format('%a') >= 0 ;
$start->modify('+1 day')
) {
$values[$start->format('Y-m-d')] = 0;
}
easy does it!