如何在 laravel 中添加新的 carbon 函数来处理 Carbon Dates?
How to add a new carbon function to work with Carbon Dates in laravel?
我知道碳的工作原理,但我想创建自定义碳功能。 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 Class 然后使用您的 Sub-Class 代替 Carbon 或者简单地使用 diffForHumansCustom()
方法创建一个特征并在您的 Classes
扩展 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...
}
}
使用 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
的子Class
<?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) );
}
}
我已经接受了@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;
对于 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
中注册您的服务提供商
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) 您现在可以从应用程序的任何位置访问您的宏。
示例控制器
<?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));
}
}
在这个例子中应该return
Carbon @1428192000 {#2663 ▼
date: 2015-04-05 00:00:00.0 UTC (+00:00)
}
尽情享受吧!
我知道碳的工作原理,但我想创建自定义碳功能。 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 Class 然后使用您的 Sub-Class 代替 Carbon 或者简单地使用 diffForHumansCustom()
方法创建一个特征并在您的 Classes
扩展 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...
}
}
使用 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
的子Class<?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) );
}
}
我已经接受了@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;
对于 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
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) 您现在可以从应用程序的任何位置访问您的宏。
示例控制器
<?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));
}
}
在这个例子中应该return
Carbon @1428192000 {#2663 ▼
date: 2015-04-05 00:00:00.0 UTC (+00:00)
}
尽情享受吧!