How to add a new carbon function to work with Carbon Dates in laravel?
Asked Answered
M

3

6

i know how carbon works but i want to create custom carbon function. carbon have a function called diffForHumans(), i want to do some modifications to that function and call that function diffForHumansCustom(). i can achieve my goal if i edit the Carbon.php vendor file but the modification will be gone after composer update. any suggestion or code help is appreciated.

original function

public function diffForHumans(Carbon $other = null, $absolute = false)
    {
        $isNow = $other === null;

        if ($isNow) {
            $other = static::now($this->tz);
        }

        $diffInterval = $this->diff($other);

        switch (true) {
            case ($diffInterval->y > 0):
                $unit = 'year';
                $delta = $diffInterval->y;
                break;

            case ($diffInterval->m > 0):
                $unit = 'month';
                $delta = $diffInterval->m;
                break;

            case ($diffInterval->d > 0):
                $unit = 'day';
                $delta = $diffInterval->d;
                if ($delta >= self::DAYS_PER_WEEK) {
                    $unit = 'week';
                    $delta = floor($delta / self::DAYS_PER_WEEK);
                }
                break;

            case ($diffInterval->h > 0):
                $unit = 'hour';
                $delta = $diffInterval->h;
                break;

            case ($diffInterval->i > 0):
                $unit = 'minute';
                $delta = $diffInterval->i;
                break;

            default:
                $delta = $diffInterval->s;
                $unit = 'second';
                break;
        }

        if ($delta == 0) {
            $delta = 1;
        }

        $txt = $delta . ' ' . $unit;
        $txt .= $delta == 1 ? '' : 's';

        if ($absolute) {
            return $txt;
        }

        $isFuture = $diffInterval->invert === 1;

        if ($isNow) {
            if ($isFuture) {
                return $txt . ' from now';
            }

            return $txt . ' ago';
        }

        if ($isFuture) {
            return $txt . ' after';
        }

        return $txt . ' before';
    }

my modified function

public function diffForHumansCustom(Carbon $other = null, $absolute = false)
    {
        $isNow = $other === null;

        if ($isNow) {
            $other = static::now($this->tz);
        }

        $diffInterval = $this->diff($other);

        switch (true) {
            case ($diffInterval->y > 0):
                $unit = 'year';
                $delta = $diffInterval->y;
                break;

            case ($diffInterval->m > 0):
                $unit = 'month';
                $delta = $diffInterval->m;
                break;

            case ($diffInterval->d > 0):
                $unit = 'day';
                $delta = $diffInterval->d;
                if ($delta >= self::DAYS_PER_WEEK) {
                    $unit = 'week';
                    $delta = floor($delta / self::DAYS_PER_WEEK);
                }
                break;

            case ($diffInterval->h > 0):
                $unit = 'hour';
                $delta = $diffInterval->h;
                break;

            case ($diffInterval->i > 0):
                $unit = 'minute';
                $delta = $diffInterval->i;
                break;

            default:
                $delta = $diffInterval->s;
                $unit = 'second';
                break;
        }

        if ($delta == 0) {
            $delta = 1;
        }

        $txt = $delta . ' ' . $unit;
        $txt .= $delta == 1 ? '' : 's';
        if($unit == 'second' && $delta<=59) {
           return 'Just now';
        }

        // Greater than 3 days
        // [xx] [Month] [year, only displays if not current year'] at [time in 24 clock].
        if(($unit == 'day' && $delta > 3) || ($unit == 'week') || ($unit == 'month') || ($unit == 'year')) {
           $timestamp = $this->getTimestamp();
           $curYear = date('Y');
           $y = ($curYear == date('Y', $timestamp)) ? '': date('Y', $timestamp);
           $date = date('j F '.$y, $timestamp);
           $time = date('H:i', $timestamp);
           $txt = rtrim($date).' at '.$time;
           return $txt;
        }
        if ($absolute) {
            return $txt;
        }

        $isFuture = $diffInterval->invert === 1;

        if ($isNow) {
            if ($isFuture) {
                return $txt . ' from now';
            }

            return $txt . ' ago';
        }

        if ($isFuture) {
            return $txt . ' after';
        }

        return $txt . ' before';
    }
Meemeece answered 16/8, 2016 at 7:7 Comment(1)
Create your own class that extends Carbon (e.g. MyCarbon) and implement that method in your version of the classSleepy
C
7

You can either Extend the Carbon Class and then Use your Sub-Class in place of Carbon or simply create a Trait with the diffForHumansCustom() Method and use it in your Classes

Extending Carbon\Carbon:

<?php

    namespace App\Http\Controllers\Helpers;

    use Carbon\Carbon;

    class CarbonCopy extends Carbon {

        public function diffForHumansCustom(Carbon $other = null, $absolute = false) {
            // YOUR UNIQUE IMPLEMENTATION, CODE & LOGIC...
        }

    }

Using Trait, instead:

<?php

    namespace App\Http\Controllers\Helpers;

    use Carbon\Carbon;

    trait CarbonT {     

        public function diffForHumansCustom(Carbon $other = null, $absolute = false) {
            // YOUR UNIQUE IMPLEMENTATION, CODE & LOGIC...
        }

    }

Usage Inside Your Controller: as Trait

<?php
    namespace App\Http\Controllers;
    use App\Http\Controllers\Helpers\CarbonT;
    use Carbon\Carbon;
    use Illuminate\Http\Request;
    use App\Http\Requests;
    use App\User;

    class TestController extends Controller {

        use CarbonT;

        public function carbonRelatedOperation(){
            $cbnDate    = Carbon::createFromFormat("Y-m-d H:i:s", "2016-05-02 11:11:11");
            $customDiff = $this->diffForHumansCustom($cbnDate);

            dd( $customDiff );

        }
    }

Usage Inside Your Controller: as Sub-Class of Carbon

<?php
    namespace App\Http\Controllers;
    use App\Http\Controllers\Helpers\CarbonCopy;
    use Carbon\Carbon;
    use Illuminate\Http\Request;
    use App\Http\Requests;
    use App\User;

    class TestController extends Controller {

        public function carbonRelatedOperation(){
            $cbnDate    = Carbon::createFromFormat("Y-m-d H:i:s", "2016-05-02 11:11:11");
            $cbCopy     = new CarbonCopy();

            dd( $cbCopy->diffForHumansCustom($cbnDate) );

        }
    }
Carlsen answered 16/8, 2016 at 7:34 Comment(0)
M
13

To anyone coming here in 2019, I have found that a neater solution for adding things like Carbon::macro functions is use a Laravel ServiceProvider

1) Create your service provider with php artisan make:provider CarbonServiceProvider

CarbonServiceProvider

<?php

namespace App\Providers;

use Carbon\Carbon;
use Illuminate\Support\ServiceProvider;

class CarbonServiceProvider extends ServiceProvider
{
    /**
     * Register services.
     */
    public function register()
    {
    }

    /**
     * Bootstrap services.
     */
    public function boot()
    {
        Carbon::macro('easterDate', function ($year) {
            return Carbon::createMidnightDate($year, 3, 21)->addDays(easter_days($year));
        });
    }
}

2) Register your service provider in config/app.php

app/config

<?php

return [

    'providers' => [

        ...

        /*
         * Application Service Providers...
         */
        App\Providers\AppServiceProvider::class,
        App\Providers\AuthServiceProvider::class,
        App\Providers\BroadcastServiceProvider::class,
        App\Providers\EventServiceProvider::class,
        App\Providers\RouteServiceProvider::class,
        App\Providers\DatabaseServiceProvider::class,
        App\Providers\CarbonServiceProvider::class,

        ...
    ],
];

3) You can now access your Macro's from anywhere in your application.

ExampleController

<?php

namespace App\Http\Controllers;

use Carbon\Carbon;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;

class ExampleController extends Controller
{
    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index(Request $request)
    {
        dd(Carbon::easterDate(2015));
    }
}

In the example this should return

Carbon @1428192000 {#2663 ▼
  date: 2015-04-05 00:00:00.0 UTC (+00:00)
}

Enjoy!

Myrtamyrtaceous answered 2/7, 2019 at 11:6 Comment(0)
C
7

You can either Extend the Carbon Class and then Use your Sub-Class in place of Carbon or simply create a Trait with the diffForHumansCustom() Method and use it in your Classes

Extending Carbon\Carbon:

<?php

    namespace App\Http\Controllers\Helpers;

    use Carbon\Carbon;

    class CarbonCopy extends Carbon {

        public function diffForHumansCustom(Carbon $other = null, $absolute = false) {
            // YOUR UNIQUE IMPLEMENTATION, CODE & LOGIC...
        }

    }

Using Trait, instead:

<?php

    namespace App\Http\Controllers\Helpers;

    use Carbon\Carbon;

    trait CarbonT {     

        public function diffForHumansCustom(Carbon $other = null, $absolute = false) {
            // YOUR UNIQUE IMPLEMENTATION, CODE & LOGIC...
        }

    }

Usage Inside Your Controller: as Trait

<?php
    namespace App\Http\Controllers;
    use App\Http\Controllers\Helpers\CarbonT;
    use Carbon\Carbon;
    use Illuminate\Http\Request;
    use App\Http\Requests;
    use App\User;

    class TestController extends Controller {

        use CarbonT;

        public function carbonRelatedOperation(){
            $cbnDate    = Carbon::createFromFormat("Y-m-d H:i:s", "2016-05-02 11:11:11");
            $customDiff = $this->diffForHumansCustom($cbnDate);

            dd( $customDiff );

        }
    }

Usage Inside Your Controller: as Sub-Class of Carbon

<?php
    namespace App\Http\Controllers;
    use App\Http\Controllers\Helpers\CarbonCopy;
    use Carbon\Carbon;
    use Illuminate\Http\Request;
    use App\Http\Requests;
    use App\User;

    class TestController extends Controller {

        public function carbonRelatedOperation(){
            $cbnDate    = Carbon::createFromFormat("Y-m-d H:i:s", "2016-05-02 11:11:11");
            $cbCopy     = new CarbonCopy();

            dd( $cbCopy->diffForHumansCustom($cbnDate) );

        }
    }
Carlsen answered 16/8, 2016 at 7:34 Comment(0)
M
0

i have accepted an answer by @Poiz but i just want to show you guys how i did it.

created a Model IddCarbon.php

<?php
namespace App\Models;

use Carbon\Carbon as Carbon;


class IddCarbon extends Carbon {

    public function diffForHumansIdd(Carbon $other = null, $absolute = false)
    {
        $isNow = $other === null;

        if ($isNow) {
            $other = Carbon::now($this->tz);
        }

        $diffInterval = $this->diff($other);

        switch (true) {
            case ($diffInterval->y > 0):
                $unit = 'year';
                $delta = $diffInterval->y;
                break;

            case ($diffInterval->m > 0):
                $unit = 'month';
                $delta = $diffInterval->m;
                break;

            case ($diffInterval->d > 0):
                $unit = 'day';
                $delta = $diffInterval->d;
                if ($delta >= Carbon::DAYS_PER_WEEK) {
                    $unit = 'week';
                    $delta = floor($delta / Carbon::DAYS_PER_WEEK);
                }
                break;

            case ($diffInterval->h > 0):
                $unit = 'hour';
                $delta = $diffInterval->h;
                break;

            case ($diffInterval->i > 0):
                $unit = 'minute';
                $delta = $diffInterval->i;
                break;

            default:
                $delta = $diffInterval->s;
                $unit = 'second';
                break;
        }

        if ($delta == 0) {
            $delta = 1;
        }

        $txt = $delta . ' ' . $unit;
        $txt .= $delta == 1 ? '' : 's';
        if($unit == 'second' && $delta<=59) {
            return 'Just now';
        }

        // Greater than 3 days
        // [xx] [Month] [year, only displays if not current year'] at [time in 24 clock].
        if(($unit == 'day' && $delta > 3) || ($unit == 'week') || ($unit == 'month') || ($unit == 'year')) {
            $timestamp = $this->getTimestamp();
            $curYear = date('Y');
            $y = ($curYear == date('Y', $timestamp)) ? '': date('Y', $timestamp);
            $date = date('j F '.$y, $timestamp);
            $time = date('H:i', $timestamp);
            $txt = rtrim($date).' at '.$time;
            return $txt;
        }
        if ($absolute) {
            return $txt;
        }

        $isFuture = $diffInterval->invert === 1;

        if ($isNow) {
            if ($isFuture) {
                return $txt . ' from now';
            }

            return $txt . ' ago';
        }

        if ($isFuture) {
            return $txt . ' after';
        }

        return $txt . ' before';
    }

}

created a helper function

function diffForHumans($date)
{
        $timeDiff = App\Models\IddCarbon::parse($date);
        return $timeDiff->diffForHumansIdd();
}

usage

$article = Article::where('id','=','123')->first();//Eloquent result
$created = $article->created_at->toDateTimeString();//sample $created '2016-08-08 11:50:38'

$result = diffForHumans($created);

echo $result;
Meemeece answered 17/8, 2016 at 4:59 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.