0

I have an array of results fetched from mysql database. I want to group those data based on dates as below:

Input array:

$resultSet = [
   0 => [
     'id' => 123,
     'name' => 'ABC',
     'start_date' => '2019-12-18 20:00:00'
   ], 
   1 => [
     'id' => 124,
     'name' => 'CDE',
     'start_date' => '2019-12-19 20:00:00'
   ],  
   2 => [
     'id' => 125,
     'name' => 'TEST',
     'start_date' => '2019-12-23 20:00:00'
   ],
   3 => [
     'id' => 126,
     'name' => 'BWM',
     'start_date' => '2019-12-18 20:00:00'
   ], 
   4 => [
     'id' => 127,
     'name' => 'XYZ',
     'start_date' => '2019-12-19 20:00:00'
   ], 
   5 => [
     'id' => 128,
     'name' => 'GHJ',
     'start_date' => '2019-12-21 20:00:00'
   ], 
   6 => [
     'id' => 129,
     'name' => 'GHJK',
     'start_date' => '2019-12-22 20:00:00'
   ], 
   7 => [
     'id' => 130,
     'name' => 'GHL',
     'start_date' => '2019-12-20 20:00:00'
   ], 
   8 => [
     'id' => 131,
     'name' => 'JKL',
     'start_date' => '2019-12-25 20:00:00'
   ]
];

Output: Display all the list of products group by filters (Today, Tomorrow, This Weekend, Next Weekend etc.) Consider we are running script on Wednesday.

Today: Display only record of index: 0, 3 (Today's Date: 2019-12-18)

Tomorrow: Display only record of index: 0, 3 (Tomorrow Date: 2019-12-19)

This Weekend: Display only record of index: 5, 6, 7 (Friday, Saturday & Sunday: 2019-12-20, 2019-12-21, 2019-12-22)

Next Week: Display only record of index: 2, 8 (Date: 2019-12-23, 2019-12-25)

Result will display dynamically and every week different record will display as above.

Sample Code Used:

$arrayList = [];
 foreach($resultSet as $element){
   $arrayList[$element->start_date][] = $element;
 }

 dd($arrayList);

Need to alter the above code to fetch the result as per the requirement below.

Framework: Laravel 5.2

Requirements:

  1. Script will either run on Wednesday or Thrusday (90% of time).
  2. In case for some reason script did not run on those days. We will manually run it on Friday. In that case Today is Friday and Saturday is Tomorrow. Also This Weekend will include data of Friday, Saturday and Sunday.
  3. This Weekend will include data of Friday, Saturday & Sunday.
  4. Today, Tomorrow, This Weekend & Next Weekend label will be filtered from the "start_date".

Expected OUTPUT:

$output = [
   'today' => [
       0 => [
         'id' => 123,
         'name' => 'ABC',
         'start_date' => '2019-12-18 20:00:00'
       ],
       1 => [
         'id' => 126,
         'name' => 'BWM',
         'start_date' => '2019-12-18 20:00:00'
       ]
    ],
    'tomorrow' => [
       0 => [
         'id' => 124,
         'name' => 'CDE',
         'start_date' => '2019-12-19 20:00:00'
       ],
       1 =>  [
         'id' => 127,
         'name' => 'XYZ',
         'start_date' => '2019-12-19 20:00:00'
       ]
    ],

    'this_weekend' => [
       0 => [
         'id' => 130,
         'name' => 'GHL',
         'start_date' => '2019-12-20 20:00:00'
       ],
       1 =>  [
         'id' => 128,
         'name' => 'GHJ',
         'start_date' => '2019-12-21 20:00:00'
       ],
       2 =>  [
         'id' => 129,
         'name' => 'GHJK',
         'start_date' => '2019-12-22 20:00:00'
       ]
    ],
    'next_week' => [
       0 => [
         'id' => 125,
         'name' => 'TEST',
         'start_date' => '2019-12-23 20:00:00'
       ],
       1 => [
         'id' => 131,
         'name' => 'JKL',
         'start_date' => '2019-12-25 20:00:00'
       ]
     ]
  ];    

I am running simple foreach loop in view page to display data. Please feel free to comment below if any queries.

6
  • 1
    You don't need to repost your unclear question as many times as you can. It will be closed either. Commented Dec 16, 2019 at 13:21
  • @AksenP - What is the additional information you required ? Is there further question you have ? I am stuck with this, expecting a help. Let me know if any other information required Commented Dec 16, 2019 at 13:22
  • SO is not project writing service, firstly you should show what you've tried so far. You didn't do anything at all. Also, you didn't presented desired output. Commented Dec 16, 2019 at 13:24
  • @AksenP I have already provided sample code above which i have tried. But I know it is not the getting me the correct output i am looking for. That is the reason i am here. If possible do help. Requesting you do not downvote or raise a close request. Commented Dec 16, 2019 at 13:25
  • Nice, and HTML, and JS? You didn't do anything for to solve this. I can print any foreach loop also. How could somebody represent your issue? Commented Dec 16, 2019 at 13:29

4 Answers 4

2

At the beginning you should define a useful date format for further comparing of dates:

 $s = new DateTime();                         // create date value
 $s->modify('+2 days');                       // in fact today is 2019-12-16
                                              // but you've choose 2019-12-18
                                              // you can comment this line
 //echo $s->format('Y-m-d H:i:s').PHP_EOL;    // today
 $today = $s->format('Ymd');                  // format 20191218

 echo $today.' <- today'.PHP_EOL;             // today

 $nextmonday = $s->modify('next monday')->format('Ymd');
 echo $nextmonday.' <- next monday'.PHP_EOL.PHP_EOL;     // next monday, format 20191223

Then you need to make a foreach loop like this one:

foreach($resultSet as $rec){
    $d = date('Ymd', strtotime($rec['start_date']));      // transform to format 20191218 
    $d2 = date('l', strtotime($rec['start_date']));       // name of the day
    echo $d.' --- '.$d2.PHP_EOL;    

    if ($d == $today) {                 // 2019-12-18 == 2019-12-18
        $res['today'][] = $rec;
    } else if ($d - $today == 1) {      // 2019-12-19 - 2019-12-18 == 1
        $res['tomorrow'][] = $rec;
    } else if (in_array($d2,['Friday','Saturday','Sunday']) && $d < $nextmonday){    // < 2019-12-23 and by day name
        $res['this_weekend'][] = $rec;
    } else if ($d >= $nextmonday){       // next week (not a weekend)
        $res['next_weekend'][] = $rec;
    } 
}

Outputs will be:

Array
(
    [today] => Array
        (
            [0] => Array
                (
                    [id] => 123
                    [name] => ABC
                    [start_date] => 2019-12-18 20:00:00
                )

            [1] => Array
                (
                    [id] => 126
                    [name] => BWM
                    [start_date] => 2019-12-18 20:00:00
                )

        )

    [tomorrow] => Array
        (
            [0] => Array
                (
                    [id] => 124
                    [name] => CDE
                    [start_date] => 2019-12-19 20:00:00
                )

            [1] => Array
                (
                    [id] => 127
                    [name] => XYZ
                    [start_date] => 2019-12-19 20:00:00
                )

        )

    [next_weekend] => Array
        (
            [0] => Array
                (
                    [id] => 125
                    [name] => TEST
                    [start_date] => 2019-12-23 20:00:00
                )

            [1] => Array
                (
                    [id] => 131
                    [name] => JKL
                    [start_date] => 2019-12-25 20:00:00
                )

        )

    [this_weekend] => Array
        (
            [0] => Array
                (
                    [id] => 128
                    [name] => GHJ
                    [start_date] => 2019-12-21 20:00:00
                )

            [1] => Array
                (
                    [id] => 129
                    [name] => GHJK
                    [start_date] => 2019-12-22 20:00:00
                )

            [2] => Array
                (
                    [id] => 130
                    [name] => GHL
                    [start_date] => 2019-12-20 20:00:00
                )

        )

)

Note: the last array named as next_weekend , perhaps you need to rename it as next_week , cause it has dates just after your current weekend.

I think you've understood an idea and will be able to add your further logic.

Demo

Sign up to request clarification or add additional context in comments.

Comments

1

Well if you are using laravel then you can use the power of carbon and collection methods to solve such kinds of issues.

You can map the array key and group them by using carbon method. Check the following snippets will give you the exact result.

date_default_timezone_set("Asia/Kolkata");
$resultSet = [ 
   0 => [
     'id' => 127,
     'name' => 'XYZ',
     'start_date' => '2020-01-03 20:00:00'
   ], 
   1 => [
     'id' => 128,
     'name' => 'GHJ',
     'start_date' => '2020-01-04 20:00:00'
   ], 
   2 => [
     'id' => 129,
     'name' => 'GHJK',
     'start_date' => '2020-01-05 16:00:00'
   ], 
   3 => [
     'id' => 130,
     'name' => 'GHL',
     'start_date' => '2020-01-05 20:00:00'
   ], 
   4 => [
     'id' => 131,
     'name' => 'JKL',
     'start_date' => '2020-01-18 20:00:00'
   ]
];

in case if you want the future date will be in "in_future" key.

$output = collect($resultSet)->map(function ($value) {
    $group_by_key = Carbon::parse($value['start_date']);
    switch ($group_by_key) {
        case $group_by_key->isToday():
            $group_by_key = 'today';
            break;
        case $group_by_key->isTomorrow():
            $group_by_key = 'tomorrow';
            break;
        case $group_by_key->isNextWeek():
            $group_by_key = 'next_week';
            break;
        case $group_by_key->weekOfYear > Carbon::now()->addWeek()->weekOfYear:
            $group_by_key = 'in_future';
            break;
        case $group_by_key->isWeekend():
            $group_by_key = 'this_weekend';
            break;

        default:
            $group_by_key = $group_by_key->format('l');;
            break;
    }
    $value['group_by_key'] = $group_by_key;
    return $value;
})->groupBy('group_by_key');
var_dump($output);

or in case if you want the future date will be in "next_week" key.

$output = collect($resultSet)->map(function ($value) {
    $group_by_key = Carbon::parse($value['start_date']);
    switch ($group_by_key) {
        case $group_by_key->isToday():
            $group_by_key = 'today';
            break;
        case $group_by_key->isTomorrow():
            $group_by_key = 'tomorrow';
            break;
        case $group_by_key->weekOfYear > Carbon::now()->addWeek()->weekOfYear:
            $group_by_key = 'next_week';
            break;
        case $group_by_key->isWeekend():
            $group_by_key = 'this_weekend';
            break;

        default:
            $group_by_key = $group_by_key->format('l');;
            break;
    }
    $value['group_by_key'] = $group_by_key;
    return $value;
})->groupBy('group_by_key');
var_dump($output);

5 Comments

Thanks, really appreciate your answer. I am trying this solution with real time data, let you know if any issues.
While testing, above code is breaking for next week condition. @sachin kumar Sample input array: 3v4l.org/Ovd8u
As by default carbon compare the parsed date's weekOfTheYear with the current date's weekOfTheYear. and in your use case "2020-01-18 20:00:00" is not belongs to next week but belongs to after next week. So check my updated answer(both variation).
I am still checking with real data. There are some cases i found it is displaying wrong record in the "this weekend" category. Trying to figure it out and update you. @sachin
Ok. Don't forget to set the default timezone for this script.
0

Try the bellow example

$group = [];
    foreach ($start_date as $item)  {
        if (!isset($group[$item['start_date']])) {
            $group[$item['start_date']] = [];
        }
        foreach ($item as $key => $value) {
            if ($key == 'start_date') continue;
            $group[$item['start_date']][$key] = $value;
        }
    }

7 Comments

@sss S This is not what exactly I want. I have already achieved it using my code. Please check the requirement above.
@appsntech, I told you - your question is unclear. People don't know what do you need.
Let me paste you a sample output what exactly i am looking for. Give me a moment please.
@AksenP added expected output. Hope this is clear now. Thanks for directing me to the right direction. Let me know if any queries.
|
0

I think you should make the array of different dates: Today, tomorrow, this weekend, nextweek

Check link for time formats:https://carbon.nesbot.com/docs/

$now = Carbon::now();
echo $now;                               // 2019-11-20 16:41:03
echo "\n";
$today = Carbon::today();
echo $today;                             // 2019-11-20 00:00:00
echo "\n";
$tomorrow = Carbon::tomorrow('Europe/London');
echo $tomorrow;                          // 2019-11-21 00:00:00
echo "\n";

Check your results with compare condition of dates and make arrays and combine them to one array.

$totalarr = array('today'=>$todayarr,'tomorrow'=>$tomorrowarr,'thisweek'=>$thisweek,'nextweek'=>$nextweekarr);

print_r($totalarr);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.