I'm trying to count integer value from JSON: https://pomber.github.io/covid19/timeseries.json but I got 1 for each key. What I expect is to count the total 'confirmed' from all countries by date as a key.
Here's my controller:
$client = new Client();$request = $client->get('https://pomber.github.io/covid19/timeseries.json');
$response = $request->getBody()->getContents();
$posts_dates = json_decode($response, true);
$confirmed_array = array();
if ( ! empty( $posts_dates ) ) {
foreach ( $posts_dates as $key => $val ) {
foreach ( ((array)$posts_dates)[$key] as $data ) {
$date_confirmed = new \DateTime( $data['date'] );
$day = $date_confirmed->format( 'd M y' );
$confirmed = count((array)$data['confirmed']);
$confirmed_array [ $day ] = $confirmed;
}
}
}
return $confirmed_array;
Here's the result:
{
"22 Jan 20": 1,
"23 Jan 20": 1,
"24 Jan 20": 1,
"25 Jan 20": 1,
"26 Jan 20": 1,
"27 Jan 20": 1,
"28 Jan 20": 1,
"29 Jan 20": 1,
"30 Jan 20": 1,
"31 Jan 20": 1,
....
}
UPDATE
I want to get the output to looks like below:
{
"date": [
"22 Jan 20",
"23 Jan 20",
"24 Jan 20",
"25 Jan 20",
.....
],
"total_confirmed": [
555,
653,
941,
1434,
.....
],
"max_value_of_total_confirmed": 12214
}
Any help would be appreciated :)
This code just loops through each countries data and then for each date it adds the data to the result array...
foreach ( $posts_dates as $country => $data ) {
foreach ( $data as $date => $dateData ) {
if ( !isset($confirmed_array[$dateData['date']]) ) {
$confirmed_array[$dateData['date']] = 0;
}
$confirmed_array[$dateData['date']] += $dateData['confirmed'];
}
}
Update:
For the new format, you just need to extract the data from the array so far...
$output = ["date" => array_keys($confirmed_array),
"total_confirmed" => array_values($confirmed_array),
"max_value_of_total_confirmed" => max($confirmed_array)
];
Related
I am obtaining the information of the dates of some classes created, but I need to obtain them by month and show the number of classes registered in that month, I use the Resources to format the response.
These are my tables:
In my class model, I have this relation
public function classDates() {
return $this->hasMany(ClassDate::class, 'class_id');
}
This is my method for get classes:
public function index(Request $request) {
$request->validate(['timezone' => 'string|timezone']);
$userId = $this->validateCookieAndGetAuthUserId();
$userTimeZone = $this->getUserTimezone($userId);
$requestTimeZone = $request->timezone;
$classes = ClassModel::select('id', 'title', 'cuisine_id', 'owner_id', 'language_id',
'duration_class_time', 'class_capacity', 'regular_price', 'status')
->with(['likes' => function($q) use ($userId) {
$q->select('id','likeable_id','liked')
->where('user_id', $userId ? $userId : 0)
->where('liked', 1);
}])
->withCount('ratings')
->withAvg('ratings', 'rate')
->with('pictures:pictureable_id,url', 'cuisine', 'language')
->with(['user.personal:user_id,timezone_id', 'user.personal.timezone:id,name'])
->with(['classDates' => function($q) {
$q->select('id', 'class_id', 'timestamp', 'timezone', 'event_type');
}])
->where('owner_id', $userId);
/*PAGINATION*/
list($count, $data) = $this->paginationService->pagination($classes, $request);
foreach ($data as $class) {
$timezone = null;
if(!is_null($class->user) &&
!is_null($class->user->personal) &&
!is_null($class->user->personal->timezone)
) {
$timezone = $class->user->personal->timezone->name;
} else if(!is_null($this->getUserTimezone($userId))) {
$timezone = $userTimeZone;
}else{
$timezone = $requestTimeZone;
}
$class->timezone = $timezone;
}
return response(['count' => $count, 'classes' => ClassResource::collection($data)], HttpResponse::HTTP_OK);
}
This is my ClassResource:
public function toArray($request)
{
return [
'id' => $this->id,
'is_liked' => $this->likes ? $this->likes->pluck('liked')->first() : null,
'ratings' => $this->ratings_count,
'rating_avg' => $this->ratings_avg_rate,
'title' => $this->title,
'cuisine' => $this->cuisine ? $this->cuisine->key : null,
'language' => $this->language ? $this->language->alias : null,
'owner' => $this->user ? $this->user->first_name : null,
'duration_class_time' => $this->convertToHoursMins($this->duration_class_time),
'class_capacity' => '10/'.$this->class_capacity, //TODO - FIELD SEATS LEFT
'class_price' => $this->regular_price,
'status' => $this->status,
'class_dates' => $this->customClassDates($this->classDates, $this->timezone, $this->duration_class_time),
'timezone_user' => $this->timezone,
'pictures' => $this->pictures ? $this->pictures->pluck('url')->first() : null
];
}
private function customClassDates($classDates, $timezone, $duration) {
foreach ($classDates as $classDate) {
if(!is_null($classDate->timestamp) && !is_null($timezone) && is_numeric($classDate->timestamp)) {
$date = new DateTime("now", new DateTimeZone($timezone));
$date->setTimestamp($classDate->timestamp);
$classDate->date = $date->format('l, d M, Y \a\t g:i A') . ' (' . $date->format('P').')';
$classDate->time = $date->format("g:i A (P)");
$dateEnd = clone $date;
$dateEnd->add(new DateInterval('PT' . $duration . 'M'));
$classDate->timeDuration = $date->format("g:i").' - '.$dateEnd->format("g:i A (P)");
}
}
return $classDates->first();
}
I get the response:
{
"count": 18,
"classes": [
{
"id": 60,
"is_liked": null,
"ratings": 0,
"rating_avg": 0,
"title": "Class New",
"cuisine": "Colombian",
"language": "English",
"owner": "User",
"duration_class_time": "1 hour 0m",
"class_capacity": "10/80",
"class_price": "2.30",
"status": "Draft",
"class_dates": {
"id": 113,
"class_id": 60,
"timestamp": "1675461300",
"timezone": "GMT-06:00",
"event_type": "public",
"date": "Friday, 03 Feb, 2023 at 4:55 PM (-05:00)",
"time": "4:55 PM (-05:00)",
"timeDuration": "4:55 - 5:55 PM (-05:00)"
},
"timezone_user": "America/Bogota",
"pictures": "https://api.app.localhost/storage/images/classes//img2023020320523668286700.jpeg"
},
]
}
But I want to get as follows:
{
"count":18,
"February":[
{
"amountByMonth":5
},
{
"id":113,
"class_id":60,
"timestamp":"1675461300",
"timezone":"GMT-06:00",
"event_type":"public",
"date":"Friday, 03 Feb, 2023 at 4:55 PM (-05:00)",
"time":"4:55 PM (-05:00)",
"timeDuration":"4:55 - 5:55 PM (-05:00)",
"class":{
"class_id":60,
"is_liked":null,
"ratings":0,
"rating_avg":0,
"title":"Class New",
"cuisine":"Colombian",
"language":"English",
"owner":"User",
"duration_class_time":"1 hour 0m",
"class_capacity":"10/80",
"class_price":"2.30",
"status":"Draft",
"timezone_user":"America/Bogota",
"pictures":"https://api.app.localhost/storage/images/classes//img2023020320523668286700.jpeg"
}
},
{
"id":114,
"class_id":60,
"timestamp":"1675461300",
"timezone":"GMT-06:00",
"event_type":"public",
"date":"Friday, 03 Feb, 2023 at 4:55 PM (-05:00)",
"time":"4:55 PM (-05:00)",
"timeDuration":"4:55 - 5:55 PM (-05:00)",
"class":{
"class_id":60,
"is_liked":null,
"ratings":0,
"rating_avg":0,
"title":"Class New",
"cuisine":"Colombian",
"language":"English",
"owner":"User",
"duration_class_time":"1 hour 0m",
"class_capacity":"10/80",
"class_price":"2.30",
"status":"Draft",
"timezone_user":"America/Bogota",
"pictures":"https://api.app.localhost/storage/images/classes//img2023020320523668286700.jpeg"
}
}
],
"March":[
{
"amountByMonth":2
},
{
"id":115,
"class_id":60,
"timestamp":"1675461300",
"timezone":"GMT-06:00",
"event_type":"public",
"date":"Friday, 03 Mar, 2023 at 4:55 PM (-05:00)",
"time":"4:55 PM (-05:00)",
"timeDuration":"4:55 - 5:55 PM (-05:00)",
"class":{
"class_id":61,
"is_liked":null,
"ratings":0,
"rating_avg":0,
"title":"Class New",
"cuisine":"Colombian",
"language":"English",
"owner":"User",
"duration_class_time":"1 hour 0m",
"class_capacity":"10/80",
"class_price":"2.30",
"status":"Draft",
"timezone_user":"America/Bogota",
"pictures":"https://api.app.localhost/storage/images/classes//img2023020320523668286700.jpeg"
}
},
{
"id":116,
"class_id":61,
"timestamp":"1675461300",
"timezone":"GMT-06:00",
"event_type":"public",
"date":"Friday, 03 Mar, 2023 at 4:55 PM (-05:00)",
"time":"4:55 PM (-05:00)",
"timeDuration":"4:55 - 5:55 PM (-05:00)",
"class":{
"class_id":60,
"is_liked":null,
"ratings":0,
"rating_avg":0,
"title":"Class New",
"cuisine":"Colombian",
"language":"English",
"owner":"User",
"duration_class_time":"1 hour 0m",
"class_capacity":"10/80",
"class_price":"2.30",
"status":"Draft",
"timezone_user":"America/Bogota",
"pictures":"https://api.app.localhost/storage/images/classes//img2023020320523668286700.jpeg"
}
}
]
}
How can I format this in my Resource, or should I modify the initial query. I would like to obtain the records by month, and that would show the number of classes for that month
The bounty expires in 7 days. Answers to this question are eligible for a +50 reputation bounty.
Cem Firat wants to draw more attention to this question.
try to create or update a json file based on the processed data.
first I arrange the contents using assamble() and create a multidimensional array:
$rawData = [
"AAAA 2022 12 23 21:37:56 dc:16:b2:4c:d2:e6",
"BBB 2023 01 12 02:08:23 f0:8a:76:16:57:e8",
"BBB 2023 02 19 17:34:33 a0:c9:a0:b6:79:3c",
"AAAA 2023 02 23 12:21:09 f0:8a:76:16:57:e8",
"AAAA 2023 02 23 18:15:10 f0:8a:76:16:57:e8",
"CCCCC 2023 03 19 17:07:26 f0:8a:76:16:57:e8",
"QQQ 2023 04 01 00:00:03 a0:c9:a0:b6:79:3c"
];
function dirMaker($a, $b, $c)
{
if (!is_dir($a . $b . $c)) {
mkdir(
$a . $b . $c,
0777,
true
// If true, then any parent directories
// to the directory specified will also be created,
// with the same permissions.
);
}
}
$archive = 'archive/';
assemble data
function assemble()
{
global $rawData, $dailyData;
foreach ($rawData as $row) {
[$group, $y, $m, $d, $t, $id] = explode(' ', $row);
$result[$y][$m][$d][$group]['user'][$id][] = $t;
$years[] = $y;
$months[] = $m;
$days[] = $d;
}
$dailyData = $result;
}
assemble();
result
array (
2022 =>
array (
12 =>
array (
23 =>
array (
'AAAA' =>
array (
'user' =>
array (
'dc:16:b2:4c:d2:e6' =>
array (
0 => '21:37:56',
),
),
),
),
),
),
2023 =>
array (
'01' =>
array (
12 =>
array (
'BBB' =>
array (
'user' =>
array (
'f0:8a:76:16:57:e8' =>
array (
0 => '02:08:23',
),
),
),
),
),
/...
And now comes the big challenge:
create a y-m-d.json file in the respective directory (year/month) by iterating multidimensional array
In json files the year, month and day should not be omitted. But put in the correct year/month directory with which json filenames (y-m-d.json) are written.
function archiveJSON()
{
global $y, $m, $d, $archive, $dailyData, $rawData;
foreach ($rawData as $year) {
[$group, $y, $m, $d, $t, $id] = explode(' ', $year);
dirMaker($archive, $y . '/', $m . '/');
$p = $archive . $y . '/' . $m . '/';
$f = $y . '-' . $m . '-' . $d . '.json';
if (!file_exists($p . $f)) {
// Create a new json file in current date directory
// and write data
fopen($p . $f, 'w');
file_put_contents($p . $f, json_encode($dailyData[$y][$m][$d], JSON_PRETTY_PRINT));
} else {
# Existing Data
$existingtJSON = file_get_contents($p . $f);
$existingtArr = json_decode($existingtJSON, true);
foreach ($dailyData as $letter => $set) {
if (!isset($existingtArr[$letter])) {
$existingtArr[$letter] = $set;
} else {
$existingtArr[$letter]['user'] = array_merge_recursive(
$existingtArr[$letter]['user'],
$set['user']
);
}
}
// update file
file_put_contents($p . $f, json_encode($dailyData, JSON_PRETTY_PRINT));
}
}
}
archiveJSON();
yes! if the directories (year/month) do not exist, they will be created if (!file_exists($p . $f)):
2022/12, 2023/1,2,3,4 and the json files with the right names (Y-m-d.json) in the right directory too.
for the 1st i'm stuck here:
but if one of the letters has 2 entries on the same date as in this example: AAAA 2023 02 23 12:21:09 ... and AAAA 2023 02 23 18:15:10 ... then the 2023-02-23.json file all year entries written:
{
"2022": {
"12": {
"23": {
"AAAA": {
"user": {
"dc:16:b2:4c:d2:e6": [
"21:37:56"
]
}
}
}
}
},
"2023": {
"01": {
"12": {
"BBB": {
"user": {
"f0:8a:76:16:57:e8": [
"02:08:23"
]
}
}
}
},
"02": {
"19": {
"BBB": {
"user": {
"a0:c9:a0:b6:79:3c": [
"17:34:33"
]
}
}
},
"23": {
"AAAA": {
"user": {
"f0:8a:76:16:57:e8": [
"12:21:09",
"18:15:10"
]
}
}
}
},
"03": {
"19": {
"CCCCC": {
"user": {
"f0:8a:76:16:57:e8": [
"17:07:26"
]
}
}
}
},
"04": {
"01": {
"QQQ": {
"user": {
"a0:c9:a0:b6:79:3c": [
"00:00:03"
]
}
}
}
}
}
}
else: if there are json data in the right directory with the right files, then complete them with the new entries:
secondly, I'm stuck here as well:
as above, all entries are written in each of the json files.
I would have to put $dailyData[$y][$m][$d] in the right place. Or am I misunderstanding something?
i try many hours around. I spin around in circles.
Please don't be too harsh with me, because I'm an ambitious beginner and my head is getting tired.
How can I get the Financial Year date range in PHP like below when I pass year and return date range of every year start and end.
Like Eg.
Input Array = [2017,2018]
Financial Start Month = 04
Output Array =
[
'2017' => [
'start' => '2016-04-01',
'end' => '2017-03-31'
],
'2018' => [
'start' => '2017-04-01',
'end' => '2018-03-31'
]
]
My Effort:-
$year_arr = [2017,2018];
$fn_month = 04;
$date_range_arr = [];
foreach ($year_arr as $key => $value) {
$fn_start_date_year = ($value - 1);
$fn_start_date_month = $fn_month;
$fn_start_date_day = '01';
$fn_start_date_string = $fn_start_date_year.'-'.$fn_start_date_month.'-'.$fn_start_date_day;
$start_date = date('Y-m-d',strtotime($fn_start_date_string));
$fn_end_date_year = ($value);
$fn_end_date_month = (fn_month == 1)?12:(fn_month-1);
$fn_end_date_day = date('t',strtotime($fn_end_date_year.'-'.$fn_end_date_month.'-01'));
$fn_start_date_string = $fn_end_date_year.'-'.$fn_end_date_month.'-'.$fn_end_date_day;
$end_date = date('Y-m-d',strtotime($fn_start_date_string));
$date_range_arr[$value] = [
'start_date' => $start_date,
'end_date' => $end_date
];
}
Above is my effort. It is working perfectly but needs a more robust code.
A good way to manipulate dates in PHP is using the DateTime class. Here's an example of how to get the results you want using it. By using the modify method, we can avoid worries about complications like leap years (see the result for 2016 below).
$year_arr = [2016,2017,2018];
$fn_month = 03;
foreach ($year_arr as $year) {
$end_date = new DateTime($year . '-' . $fn_month . '-01');
$start_date = clone $end_date;
$start_date->modify('-1 year');
$end_date->modify('-1 day');
$date_range_arr[$year] = array('start_date' => $start_date->format('Y-m-d'),
'end_date' => $end_date->format('Y-m-d'));
}
print_r($date_range_arr);
Output:
Array (
[2016] => Array (
[start_date] => 2015-03-01
[end_date] => 2016-02-29
)
[2017] => Array (
[start_date] => 2016-03-01
[end_date] => 2017-02-28
)
[2018] => Array (
[start_date] => 2017-03-01
[end_date] => 2018-02-28
)
)
Demo on 3v4l.org
Maybe this is what you need?
I use strtotime to parse the date strings.
$year_arr = [2017,2018];
$fn_month = 04;
$date_range_arr = [];
foreach($year_arr as $year){
$date_range_arr[$year] =['start' => date("Y-m-d", strtotime($year-1 . "-" .$fn_month . "-01")),
'end' => date("Y-m-d", strtotime($year . "-" .$fn_month . "-01 - 1 day"))];
}
var_dump($date_range_arr);
Output:
array(2) {
[2017]=>
array(2) {
["start"]=>
string(10) "2016-04-01"
["end"]=>
string(10) "2017-03-31"
}
[2018]=>
array(2) {
["start"]=>
string(10) "2017-04-01"
["end"]=>
string(10) "2018-03-31"
}
}
https://3v4l.org/nMUHt
Try this snippet,
function pr($a)
{
echo "<pre>";
print_r($a);
echo "</pre>";
}
$year_arr = [2017, 2018];
$fn_month = 4;
$date_range_arr = [];
foreach ($year_arr as $key => $value) {
$fn_month = str_pad(intval($fn_month),2, 0, STR_PAD_LEFT);
$date = "".($value-1)."-$fn_month-01"; // first day of month
$date_range_arr[$value] = [
'start_date' => $date,
'end_date' => date("Y-m-t", strtotime($date.' 11 months')), // last month minus and last date of month
];
}
pr($date_range_arr);
die;
str_pad - Pad a string to a certain length with another string
Here is working demo.
I basically have this code which determines the number of same dates in an array:
function get_archives_html ($blog) {
//tag array to store arrays with same tag
$count_tags = array();
//store output
$output = '';
foreach($blog as $id) {
//abbreviate date name
$originalDate = $id["date"]["year"].'-'.$id["date"]["month"].'-'.$id["date"]["day"];
$abbrevDate = date("F, Y", strtotime($originalDate));
if(!isset($count_tags[$abbrevDate])) {
$count_tags[$abbrevDate] = 0;
}
++$count_tags[$abbrevDate];
}
// Sort your tags from hi to low
//arsort($count_tags);
var_dump($count_tags);
foreach($count_tags as $month=>$id) {
$output.= '<p>'. $month.($id > 1 ? ' ('.$id .')' : '').'</p>';
}
return $output;
}
The output would look like this:
$arr = array(
"November, 2016" => "2",
"October, 2016" => "5",
"October, 2017" => "3",
"September, 2017" => "6"
);
Now, I use the keys to display it on the html. Problem is that it is not arranged properly by date but rather by alphabet.
So, my question is, how can I sort this array by key and by date. Example would be October, 2016, November 2016, September, 2017, October 2014 Thank you
<?php
$arr = array(
"November, 2016" => "2",
"October, 2016" => "5",
"October, 2017" => "3",
"September, 2017" => "6"
);
//Sort by ascending date in the key
uksort($arr,function($a,$b){
return strtotime(strtr($a,',',' '))<=>strtotime(strtr($b,',',' '));
});
//result
$expected = array (
'October, 2016' => "5",
'November, 2016' => "2",
'September, 2017' => "6",
'October, 2017' => "3",
);
var_dump($arr === $expected); //bool(true)
Iam developing an appliacation using CI.I have got a problem and I need a help for that.this is my problem.
I have an array generated with php:
Array
(
[0] => Array
(
[0] => 3
[1] => 0
)
[1] => Array
(
[0] => 2
[1] => 0
)
[2] => Array
(
[0] => 1
[1] => 246
)
[3] => Array
(
[0] => 0
[1] => 4528
)
)
This is the code that genarate above array.
public function get_previous_months_total()
{
$f = 1;
$dataset2 = array();
$result;
for($i=0;$i<4;$i++){
$firstday = mktime(0, 0, 0, date('m')-$f, 1, date('Y'));
$lastday = mktime(0, 0, 0, date('m')-$i, 0, date('Y'));
$end = date("Y-m-d", $lastday);
$start = date("Y-m-d", $firstday);
$f++;
$result = $this->LineChart_Model->get_months_total($start,$end);
foreach ($result as $return_result ){
$dataset2[] = array($i,int)$return_result['SUM(operation_production)']);
}
}
$mon = array(array_reverse($dataset2));
return $mon;
}
Here is the code in the Model.
public function get_months_total($start,$end){
$sql = "SELECT SUM(operation_production) FROM plant WHERE date BETWEEN '".$start."' AND '".$end."' ORDER BY operation_id DESC";
$result = $this->linechart_db->query($sql);
return $result->result_array();
}
after this I encode this using json_encode which gives me the result below:
var total = [
[
3,
0
],
[
2,
0
],
[
1,
246
],
[
0,
4528
]
];
I need to change the order to this:
var total = [
[
0,
0
],
[
1,
0
],
[
2,
246
],
[
3,
4528
]
];
please help me on this. I have tried many ways, but none have worked. any help is really appreciated.
You should be able to use the array_mulisort() function to resolve this issue.
**EDIT:
After further investigation the array_multisort() function will not give you your answer, I apologize.
Since the values of your array are already set, your going to have to manipulate them to get the result you want. Here is what worked for me (in your code just replace the $oldArray variable with the name of your array) :
$replacementArray = array();
$i = 0;
foreach($oldArray as $array) {
$newArray =[$i, $array[1]];
array_push($replacementArray, $newArray);
$i++;
}
$finalArray = array_replace($oldArray, $replacementArray);
$json = json_encode($finalArray);
echo $json;
This will give the following output:
[[0,0],[1,0],[2,246],[3,4528]]