How to count array with the same month - php

$dates = array('2017-03-24 01:48:09', '2017-03-24 11:48:09', '2017-04-07 01:12:19', '2017-04-14 01:49:09', '2017-04-21 01:45:09', '2017-04-28 01:38:09');
if given array above..
i'm making a report to monitor user growth monthly.. i want to count the no. of entries per month
sample April 2 counts

$dates = array('2017-03-24 01:48:09', '2017-03-24 11:48:09', '2017-04-07 01:12:19', '2017-04-14 01:49:09', '2017-04-21 01:45:09', '2017-04-28 01:38:09');
$count = array();
foreach ($dates as $d) {
$count[date('m', strtotime($d))]++;
}
print_r($count);
Output will be:
Array ([03] => 2 [04] => 4 )
That is: 03 (March) has 2 values in given array.
If you need 03 as March, then use:
$count[date('F', strtotime($d))]++;
Then, output will be:
Array ([March] => 2 [April] => 4 )

<?php
$dates = array('2017-03-24 01:48:09', '2017-03-24 11:48:09', '2017-04-07 01:12:19', '2017-04-14 01:49:09', '2017-04-21 01:45:09', '2017-04-28 01:38:09');
foreach($dates as $date)
$year_months[] = date('Y-m', strtotime($date));
var_export($year_months);
var_export(array_count_values($year_months));
Output:
array (
0 => '2017-03',
1 => '2017-03',
2 => '2017-04',
3 => '2017-04',
4 => '2017-04',
5 => '2017-04',
)array (
'2017-03' => 2,
'2017-04' => 4,
)

Related

How to get only holiday date from date array

I'm trying to make a holiday array, it is based on work_day.
For example is if in 1 group there's only day 1-2 (sunday-monday), then the other day (tuesday-saturday) is holiday. And based on that days, I want to get a holiday date array from start of the year until now.
I have a table like this:
attendance_group_id | day
GROUP-001 | 1
GROUP-001 | 2
GROUP-002 | 1
GROUP-003 | 1
What I've done first is getting all data from work_day table using code bellow:
foreach ($group_work_hour as $hours) {
foreach ($hours as $hour){
$work_day = (object) array();
$work_day->group_id = $hour->attendance_group_id;
$work_day->day = $hour->day;
$work_day_arr[] = $work_day;
}
}
And the result from code above is like bellow, every group can have day up to 7 day (1-7). 1 for sunday and 7 for saturday.
Array work day
array (
0 =>
(object) array(
'group_id' => '854b5b57-f863-4e48-ba9b-617899c64750',
'day' => 2,
),
1 =>
(object) array(
'group_id' => '854b5b57-f863-4e48-ba9b-617899c64750',
'day' => 3,
),
2 =>
(object) array(
'group_id' => '854b5b57-f863-4e48-ba9b-617899c64750',
'day' => 4,
),
3 =>
(object) array(
'group_id' => '854b5b57-f863-4e48-ba9b-617899c64750',
'day' => 5,
),
4 =>
(object) array(
'group_id' => '854b5b57-f863-4e48-ba9b-617899c64750',
'day' => 6,
),
5 =>
(object) array(
'group_id' => '854b5b57-f863-4e48-ba9b-617899c64750',
'day' => 7,
),
6 =>
(object) array(
'group_id' => 'f3f739d2-77fe-4e1f-b7fc-44242f52610b',
'day' => 2,
),
7 =>
(object) array(
'group_id' => 'f3f739d2-77fe-4e1f-b7fc-44242f52610b',
'day' => 3,
),
8 =>
(object) array(
'group_id' => 'f3f739d2-77fe-4e1f-b7fc-44242f52610b',
'day' => 4,
),
9 =>
(object) array(
'group_id' => 'f3f739d2-77fe-4e1f-b7fc-44242f52610b',
'day' => 5,
),
10 =>
(object) array(
'group_id' => 'f3f739d2-77fe-4e1f-b7fc-44242f52610b',
'day' => 6,
),
And what I've done next is to get every date from start of the year until today and store it to an array.
$now = \Carbon\Carbon::now()->format('Y-m-d');
$start = \Carbon\Carbon::parse($now)->startOfYear()->format('Y-m-d');
$dateRangePeriod = \Carbon\CarbonPeriod::create($start, $now);
$dateRange = [];
foreach ($dateRangePeriod as $key => $date) {
$dateRange[] = $date->format('Y-m-d');
}
The result from code above is like this:
Array date
array (
0 => '2022-04-01',
1 => '2022-04-02',
2 => '2022-04-03',
3 => '2022-04-04',
4 => '2022-04-05',
5 => '2022-04-06',
6 => '2022-04-07',
7 => '2022-04-08',
8 => '2022-04-09',
9 => '2022-04-10',
10 => '2022-04-11',
11 => '2022-04-12',
12 => '2022-04-13',
)
What I want to do next is, I want to get only holiday date from array date above. But I don't know how to do that because from work_day I only get group_id and the number of day.
How to know if the day from array date is the holiday based on array work_day.
I'm trying some way to doing it, but I can't found the solution yet. I've tried like code bellow, but still not working:
// Loop all date from array date
foreach ($dateRange as $range) {
// Get number of day from date
$day = date('N', strtotime($range));
// Loop work day array
foreach ($work_day_arr as $work) {
// When day from work not equals to day from date (this is a right way to check if days from array date is a holiday)?
if($work->day != $day) {
// Check if group_id & off_date (holiday date) is not set
if(!isset($data['attendance_group_id'], $data['off_date'])) {
$data['attendance_group_id'] = $work->group_id;
$data['off_date'] = date('Y-m-d', strtotime($range));
$objData[] = $data;
}
}
}
}
The example result that I want is something like this (excluding holiday date):
From:
array (
0 => '2022-04-01', // holiday date
1 => '2022-04-02',
2 => '2022-04-03',
3 => '2022-04-04',
4 => '2022-04-05',
5 => '2022-04-06', // holiday date
6 => '2022-04-07',
7 => '2022-04-08',
8 => '2022-04-09',
9 => '2022-04-10',
10 => '2022-04-11',
11 => '2022-04-12', // holiday date
12 => '2022-04-13', // holiday date
)
To (excluding holiday date):
array (
0 => '2022-04-02',
1 => '2022-04-03',
2 => '2022-04-04',
3 => '2022-04-05',
4 => '2022-04-07',
5 => '2022-04-08',
6 => '2022-04-09',
7 => '2022-04-10',
8 => '2022-04-11',
)
Another case example
From array work day:
day = 1, which is Sunday
array date:
01-01-2022
02-02-2022 // if this date == sunday, then this is a holiday
03-02-2022
result:
02-02-2022 // only get holiday date

How can i sort the below array by index(Date)?

Please sort the below array by its index(date). I want to sort the below array by ASC order by its date. After sorting the first one will be 2020-06-29 and its array, then 2020-06-30, I have tried more sorting mechanism but it could not solve the issue. Please help me to sort out this issue
Array(
[2020-07-01] => Array
(
[0] => Array
(
[slot] => 09:00 AM-11:00 AM
[is_available] => 1
[slot_id] => 29
)
)
[2020-06-29] => Array
(
[0] => Array
(
[slot] => 02:16 AM-02:16 AM
[is_available] => 1
[slot_id] => 14
)
)
[2020-06-30] => Array
(
[0] => Array
(
[slot] => 09:00 AM-06:00 PM
[is_available] => 1
[slot_id] => 15
)
)
[2020-07-02] => Array
(
[0] => Array
(
[slot] => 10:00 AM-05:00 PM
[is_available] => 1
[slot_id] => 35
)
)
[2020-07-03] => Array
(
[0] => Array
(
[slot] => 10:00 AM-03:00 PM
[is_available] => 1
[slot_id] => 36
)
)
)
Try ksort
here is a short example :
<?php
$fruits = array("d"=>"lemon", "a"=>"orange", "b"=>"banana", "c"=>"apple");
ksort($fruits);
foreach ($fruits as $key => $val) {
echo "$key = $val\n";
}
?>
https://www.php.net/manual/en/function.ksort.php
EDIT :
Since ksort seems to not be working, you should use uksort.
function date_compare($a, $b)
{
$t1 = strtotime($a);
$t2 = strtotime($b);
return $t1 - $t2;
}
uksort($data, 'date_compare');
here is a working example :
https://repl.it/repls/FoolhardyDrabPolygon
Step 1 : Create a function which accepts two dates ( strings ) as parameters, this function returns 1 if first date is greater than the second, it returns -1 if second date > first date or 0 if date's are equal. Working of functions starts from Step 2.
Step 2 : Toeknize the strings to get respective year, month and day of the two dates respectively. [ see : https://www.php.net/manual/en/book.tokenizer.php ]
Step 3 : If first date's year > second date's year, return 1 . If second date's year > first date's year return -1, if they are equal proceed to Step 4.
Step 4 : If first date's month > second date's month, return 1 . If second date's month > first date's month return -1, if they are equal proceed to Step 5.
Step 5 : If first date's day > second date's day, return 1 . If second date's day > first date's day return -1, if they are equal return 0.
Now use php's usort function and pass your function in it
[see : https://www.php.net/usort ]

Displaying avg reading in seven days interval

Given an array and I need to to display the average after every seventh row
Array
(
[0] => Array
(
[date] => 01-03-2015
[site_id] => 1
[starting_reading] => 567
[close_reading] => 567
)
[1] => Array
(
[date] => 03-03-2015
[site_id] => 1
[starting_reading] => 567
[close_reading] => 567
)
[2] => Array
(
[date] => 08-03-2015
[site_id] => 1
[starting_reading] => 567
[close_reading] => 567
)
)
Now what i need, is to display all avg reading in 7 days like:
1 to 7
--------------------- avg=close-start----------
8 to 14
--------------------- avg=close-start----------
15 to 21
--------------------- avg=close-start----------
22 to 28
--------------------- avg=close-start----------
29 to 31
--------------------- avg=close-start----------
date starting_reading close_reading
01-03-2015
03-03-2015
--------------------- avg=close-start----------
08-03-2015
--------------------- avg=close-start----------
//$arr is as the array you described
foreach($arr as $k => $v){
//$k will be some integer 0...count($arr)-1 assuming a 'normal' index
//$v is your child array, where you can access attributes such as $v['date']
//every seventh row can be done in a number of ways, the easiest way is:
if($k % 7 == 0){
//then show new line. This will happen every time the number divides into seven. 0, 7, 14, 21... etc.
var_dump($v); will output your child of the seventh (multiple) item
}
}
Including your example for dates and averages assuming array is correctly formatted
//$arr is as the array you described
$close = 0;
$start = 0;
foreach($arr as $k => $v){
//$k will be some integer 0...count($arr)-1 assuming a 'normal' index
//$v is your child array, where you can access attributes such as $v['date']
//every seventh row can be done in a number of ways, the easiest way is:
if($k % 7 == 0){
$close = 0; //reset close
$start = 0; //reset start
}
$close += (int)$v['close_reading'];
$start += (int)$v['starting_reading'];
if(($k + 1) % 7 == 0){ //this is the last row, 6, 13, 20 etc.
echo ($k-5).' to '.($k+1);
echo 'Average: '.(($close - $start) / 7);
}
}

Traversing arrays php

I was wondering if there is a better solution to loop through an array from mid to end then from start to mid. Particularly for an associative array.
So for example if there is an associative array with the keys
$dow = array(Mon => etc, Tue => etc, Wed => etc, Thr => etc .. to .. Sun => etc).
I would start searching the array from Thurs to find the next day with something specific which could be anyday but happens to be on Tues, I usually iterate from Thurs (by index) to Sunday then, reset and start again from Monday to Wed and find the target when reaching Tues.
I count the index via an id and when it reaches 6 reset the id to 0
$id = 3 // Found day is Thursday id
//Loop function starts here
$id++; // start search from one day above found day
if ($id >= 6){ //when reaching Sunday
$id = 0 // start search from monday
}
// check array here for that specific thing
So the question is to ask if there is a more simple solution than this, ie split array from index thursday to sunday and add it onto the beginning of the array and then do the loop without having to count an index or if there are any other solutions without using the count index.
You can try with array_splice:
$array = array(1,2,3,4,5,6,7);
$lastDays = array_splice($array, 3);
$firstDays = $array;
print_r(array('first days' => $firstDays, 'last days' => $lastDays));
If the day is not in $lastDays (use a boolean like $matchFound) then you would search in $firstDays.
Or just use with array_merge:
$array = array(1,2,3,4,5,6,7);
$array = array_merge(array_splice($array, 3), $array);
print_r($array);
where output is:
Array
(
[0] => 4
[1] => 5
[2] => 6
[3] => 7
[4] => 1
[5] => 2
[6] => 3
)
and then you can search with a foreach.
maybe a foreach would be more efficient. hope this helps.
$id = 3 // Found day is Thursday id
$i =0;
//Loop function starts here
foreach($dow as $idx)
if($id == $i):
else if($i > $id):
endif;
if($i == count($dow)){$i=0;}else{$i++;}
endforeach;
<?php
$dow = array("mon","tue","wed","thu","fri","sat","sun");
$pick_a_day = 2; // user input; NON zero based. monday = 1
$pick_a_day--; // make it zero based to use in code
foreach($dow as $inc => $an_element )
{
echo $dow[($pick_a_day+(count($dow))) % (count($dow))]." - loop number:".($inc+1)."\n";
$pick_a_day++;
}
?>
output
tue - loop number:1
wed - loop number:2
thu - loop number:3
fri - loop number:4
sat - loop number:5
sun - loop number:6
mon - loop number:7
Maybe not the best solution, but a solution:
function half($array) {
$h = sizeof($array) / 2;
$a1 = array_splice($array, $h);
$a2 = array_splice($array, 0);
$res = array_merge($a1, $a2);
return $res;
}
$dow = array('Mon' => 'etc1', 'Tue' => 'etc2', 'Wed' => 'etc3', 'Thr' => 'etc4', 'Fri' => 'etc5', 'Sat' => 'etc6', 'Sun' => 'etc7');
$b = half($dow);
Now you can go through with a foreach, or how would you like. Result of $b:
Array
(
[Thr] => etc4
[Fri] => etc5
[Sat] => etc6
[Sun] => etc7
[Mon] => etc1
[Tue] => etc2
[Wed] => etc3
)

PHP, multidimensional arrays: to intersected events with days of the month

I want to build a movie timetable. I have $array1 containing the movie titles and airing dates and times:
array =
0: array =
Title: string = American Beauty
Date: string = 25/09/2012
Time: string = 15:00 - 16:20
1: array =
Title: string = The Godfather
Date: string = 25/09/2012
Time: string = 16:20 - 18:20
2: array =
Title: string = Pulp Fiction
Date: string = 26/09/2012
Time: string = 15:00 - 16:20
And I have $array2 containing the days of the month grouped by Mondays, Tuesday s, Wednesday s, Thursday s and Fridays (no movies during the weekend)
Array
(
[1] => Array
(
[0] => 3
[1] => 10
[2] => 17
[3] => 24
[4] =>
)
[2] => Array
(
[0] => 4
[1] => 11
[2] => 18
[3] => 25
[4] =>
)
[3] => Array
(
[0] => 5
[1] => 12
[2] => 19
[3] => 26
[4] =>
)
[4] => Array
(
[0] => 6
[1] => 13
[2] => 20
[3] => 27
[4] =>
)
[5] => Array
(
[0] => 7
[1] => 14
[2] => 21
[3] => 28
[4] =>
)
)
I need to intersect these two arrays so I can print under day 25 the movie “American Beauty” also under day 25 “The Godfather” and under day 26 “Pulp Fiction”.
Meaning I need to print:
SEPTEMBER 2012
Monday Tuesday Wednesday ....
3 4 5
10 11 12
17 18 19
24 25 26
15:00-16:20 American Beauty 15:00-16:20 Pulp Fiction
16:20-18:20 The Godfather
My tries so far:
foreach( $array1 as $key => $value )
{
$theTime = $value['Time'];
$theTime = explode("/", $theTime );
$days[] = $theTime [0];
$months[] = $theTime [1];
}
So I have all the airing days in array $days but from here I don’t know how to follow or even if this approach is the correct one.
Here's how I get $array2:
$month = 9;
$year = 2012;
for ($i = 1; $i <= 31; $i++)
{
$timestamp = mktime(0, 0, 0, $month , $i, $year);
if (date("n", $timestamp) == $month )
{
$day = date("N", $timestamp);
// Monday 1 to Friday 5
if ($day == 1 OR $day <= 5) {
$array2[$day][] = date("j", $timestamp);
}
}
}
Please help, I’m stuck.
Thanks very much
Ok you will iterate over $array1 and parse the date of the movie.
Then, you will look inside array2 if your day is there
foreach($array1 as $movie){
$movieDate = new DateTime($movie);
//as you indexed $array2 with monday = 1 -> friday = 5 you can use the "w" format
if(isset($array2[$movieDate->format("w"))){
$array[$movieDate->format("j")][] = $movie;
}
}
I made some mutation in your output array, it becomes :
SEPTEMBER 2012
Monday Tuesday Wednesday ....
3=>[] 4 =>[] 5=>[]
10=>[] 11 =>[] 12=>[]
17=>[] 18 =>[] 19=>[]
24 =>[] 25=>[ 26 =>[
15:00-16:20 American Beauty, 15:00-16:20 Pulp Fiction]
16:20-18:20 The Godfather]

Categories