【问题标题】:How to add a new carbon function to work with Carbon Dates in laravel?如何在 laravel 中添加一个新的碳函数来处理碳日期?
【发布时间】:2016-12-22 10:56:57
【问题描述】:

我知道碳的工作原理,但我想创建自定义碳功能。 carbon 有一个名为diffForHumans() 的函数,我想对该函数进行一些修改并调用该函数diffForHumansCustom()。如果我编辑Carbon.php 供应商文件,我可以实现我的目标,但修改将在composer update 之后消失。任何建议或代码帮助表示赞赏。

原函数

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';
    }

我修改后的函数

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';
    }

【问题讨论】:

  • 创建您自己的扩展 Carbon 的类(例如 MyCarbon)并在您的类版本中实现该方法

标签: php laravel date datetime php-carbon


【解决方案1】:

您可以扩展 Carbon 类,然后使用您的子类代替 Carbon,或者简单地使用 diffForHumansCustom() 方法创建一个特征并在您的类中使用它

扩展碳\碳:

<?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...
        }

    }

改用 Trait:

<?php

    namespace App\Http\Controllers\Helpers;

    use Carbon\Carbon;

    trait CarbonT {     

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

    }

在控制器内部使用:作为特征

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

        }
    }

在控制器内部使用:作为 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) );

        }
    }

【讨论】:

    【解决方案2】:

    对于 2019 年来到这里的任何人,我发现添加 Carbon::macro 函数之类的更简洁的解决方案是使用 Laravel ServiceProvider

    1) 使用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) 在config/app.php注册您的服务提供商

    应用程序/配置

    <?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) 您现在可以从应用程序中的任何位置访问您的宏。

    示例控制器

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

    在示例中应该返回

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

    享受吧!

    【讨论】:

      【解决方案3】:

      我已经接受了@Poiz 的回答,但我只是想向你们展示我是如何做到的。

      创建了一个模型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';
          }
      
      }
      

      创建了一个辅助函数

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

      用法

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-09-06
        • 2016-02-07
        • 2017-08-25
        • 2018-03-16
        • 2016-08-09
        相关资源
        最近更新 更多