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';
    }
1
  • 2
    Create your own class that extends Carbon (e.g. MyCarbon) and implement that method in your version of the class Commented Aug 16, 2016 at 7:24

3 Answers 3

14

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!

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

Comments

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) );

        }
    }

Comments

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;

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.