• laravel carbon时间处理组件开发文档-中文版


    2020年2月26日14:45:17

    https://packagist.org/packages/nesbot/carbon

    官方文档:https://carbon.nesbot.com/docs/

    github地址:https://github.com/briannesbitt/Carbon

    composer require nesbot/carbon

    另一个版本的中文翻译但是2017年的,与最新版本差异较大

    https://www.jianshu.com/p/ca953bc245c4

    介绍

    Carbon类是从PHP DateTime继承

    <?php
    namespace Carbon;
    
    class Carbon extends DateTime
    {
        // code here
    }
    

    您可以从上面的代码片段中看到Carbon类是在Carbon名称空间中声明的。您需要导入名称空间以使用Carbon,而不必每次都提供其完全限定名称。

    use CarbonCarbon;

    本文档中的示例将假定您以这种方式导入了Carbon名称空间的类。

    我们还提供了CarbonImmutable类,扩展了DateTimeImmutable两种类都可以使用相同的方法,但是在Carbon实例上使用修饰符时,它会修改并返回相同的实例,在CarbonImmutable上使用它时,它将返回具有新值的新实例。

    $mutable = Carbon::now();
    $immutable = CarbonImmutable::now();
    $modifiedMutable = $mutable->add(1, 'day');
    $modifiedImmutable = CarbonImmutable::now()->add(1, 'day');
    
    var_dump($modifiedMutable === $mutable);             // bool(true)
    var_dump($mutable->isoFormat('dddd D'));             // string(11) "Saturday 15"
    var_dump($modifiedMutable->isoFormat('dddd D'));     // string(11) "Saturday 15"
    // So it means $mutable and $modifiedMutable are the same object
    // both set to now + 1 day.
    var_dump($modifiedImmutable === $immutable);         // bool(false)
    var_dump($immutable->isoFormat('dddd D'));           // string(9) "Friday 14"
    var_dump($modifiedImmutable->isoFormat('dddd D'));   // string(11) "Saturday 15"
    // While $immutable is still set to now and cannot be changed and
    // $modifiedImmutable is a new instance created from $immutable
    // set to now + 1 day.
    
    $mutable = CarbonImmutable::now()->toMutable();
    var_dump($mutable->isMutable());                     // bool(true)
    var_dump($mutable->isImmutable());                   // bool(false)
    $immutable = Carbon::now()->toImmutable();
    var_dump($immutable->isMutable());                   // bool(false)
    var_dump($immutable->isImmutable());                 // bool(true)
    

    该库还提供CarbonInterface接口扩展DateTimeInterfaceJsonSerializable, CarbonInterval类扩展DateInterval, CarbonTimeZone类扩展DateTimeZone 和CarbonPeriodpolyfills DatePeriod

    Carbon具有从基本DateTime类继承的所有功能。这种方法使您可以访问基本功能,例如 Modify, Format或 diff

    现在,让我们看看这个文档有多酷。点击下面的代码:

    $dtToronto = Carbon::create(2012, 1, 1, 0, 0, 0, 'America/Toronto');
    $dtVancouver = Carbon::create(2012, 1, 1, 0, 0, 0, 'America/Vancouver');
    // Try to replace the 4th number (hours) or the last argument (timezone) with
    // Europe/Paris for example and see the actual result on the right hand.
    // It's alive!
    
    echo $dtVancouver->diffInHours($dtToronto); // 3
    // Now, try to double-click on "diffInHours" or "create" to open
    // the References panel.
    // Once the references panel is open, you can use the search field to
    // filter the list or click the (<) button to close it.
    

    一些示例是静态代码段,其他一些示例是可编辑的(当有右上角的展开按钮时)。您也可以单击此按钮在新标签页中打开代码段。您可以在静态和动态示例中双击方法名称。

    实例化

    有几种不同的方法可用于创建Carbon的新实例。首先有一个构造函数。它会覆盖父构造函数,因此您最好阅读PHP手册中的第一个参数,并了解其接受的日期/时间字符串格式。希望您会发现自己很少使用构造函数,而是依靠显式的静态方法来提高可读性。

    $carbon = new Carbon();                  // equivalent to Carbon::now()
    $carbon = new Carbon('first day of January 2008', 'America/Vancouver');
    echo get_class($carbon);                 // 'CarbonCarbon'
    $carbon = new Carbon(new DateTime('first day of January 2008'), new DateTimeZone('America/Vancouver')); // equivalent to previous instance
    

    您会在上面注意到timezone(2nd)参数是作为字符串而不是DateTimeZone 实例传递的所有DateTimeZone参数都得到了增强,因此您可以将DateTimeZone实例,字符串或整数偏移量传递给GM​​T,并将为您创建时区。在下一个示例中再次显示了该示例,该示例还介绍了该now()功能。

    $now = Carbon::now(); // will use timezone as set with date_default_timezone_set
    // PS: we recommend you to work with UTC as default timezone and only use
    // other timezones (such as the user timezone) on display
    
    $nowInLondonTz = Carbon::now(new DateTimeZone('Europe/London'));
    
    // or just pass the timezone as a string
    $nowInLondonTz = Carbon::now('Europe/London');
    echo $nowInLondonTz->tzName;             // Europe/London
    echo "
    ";
    
    // or to create a date with a custom fixed timezone offset
    $date = Carbon::now('+13:30');
    echo $date->tzName;                      // +13:30
    echo "
    ";
    
    // Get/set minutes offset from UTC
    echo $date->utcOffset();                 // 810
    echo "
    ";
    
    $date->utcOffset(180);
    
    echo $date->tzName;                      // +03:00
    echo "
    ";
    echo $date->utcOffset();                 // 180
    

    如果您真的喜欢您的可变方法调用,并在使用构造函数时对多余的行或丑陋的括号感到沮丧,那么您会喜欢这种parse方法。

    echo (new Carbon('first day of December 2008'))->addWeeks(2);     // 2008-12-15 00:00:00
    echo "
    ";
    echo Carbon::parse('first day of December 2008')->addWeeks(2);    // 2008-12-15 00:00:00
    

    传递给Carbon::parse的字符串new Carbon可以表示相对时间(下一个星期日,明天,下个月的第一天,去年)或绝对时间(2008年12月的第一天,2017-01-06)。您可以使用来测试字符串是否会产生相对日期或绝对日期Carbon::hasRelativeKeywords()

    $string = 'first day of next month';
    if (strtotime($string) === false) {
        echo "'$string' is not a valid date/time string.";
    } elseif (Carbon::hasRelativeKeywords($string)) {
        echo "'$string' is a relative valid date/time string, it will returns different dates depending on the current date.";
    } else {
        echo "'$string' is an absolute date/time string, it will always returns the same date.";
    }

    伴随而来的是now(),还存在其他一些静态实例化助手来创建众所周知的实例。真正注意到这里的唯一的事情就是today()tomorrow()和 yesterday(),除了如预期表现,都接受一个时区参数,每个人都有自己的时间值设置为00:00:00

    $now = Carbon::now();
    echo $now;                               // 2020-02-14 16:05:16
    echo "
    ";
    $today = Carbon::today();
    echo $today;                             // 2020-02-14 00:00:00
    echo "
    ";
    $tomorrow = Carbon::tomorrow('Europe/London');
    echo $tomorrow;                          // 2020-02-15 00:00:00
    echo "
    ";
    $yesterday = Carbon::yesterday();
    echo $yesterday;                         // 2020-02-13 00:00:00
    

    下一组静态助手是createXXX()助手。大多数静态create 函数允许您根据需要提供任意数量的参数,并为所有其他参数提供默认值。通常,默认值为当前日期,时间或时区。较高的值将适当地换行,但无效的值将引发InvalidArgumentException带有提示信息的。该消息是从DateTime :: getLastErrors() 调用获得的。

    $year = 2000; $month = 4; $day = 19;
    $hour = 20; $minute = 30; $second = 15; $tz = 'Europe/Madrid';
    echo Carbon::createFromDate($year, $month, $day, $tz)."
    ";
    echo Carbon::createMidnightDate($year, $month, $day, $tz)."
    ";
    echo Carbon::createFromTime($hour, $minute, $second, $tz)."
    ";
    echo Carbon::createFromTimeString("$hour:$minute:$second", $tz)."
    ";
    echo Carbon::create($year, $month, $day, $hour, $minute, $second, $tz)."
    ";
    

    createFromDate()将默认为现在时间。createFromTime()将日期默认为今天。create()将把任何null参数默认为当前各自的值。和以前一样, $tz默认值是当前时区,否则可以是DateTimeZone实例,也可以只是一个字符串时区值。唯一的特殊情况是,create()对于缺少的参数,该参数的最小值为默认值,但在显式传递时,默认值为当前值null

    $xmasThisYear = Carbon::createFromDate(null, 12, 25);  // Year defaults to current year
    $Y2K = Carbon::create(2000, 1, 1, 0, 0, 0); // equivalent to Carbon::createMidnightDate(2000, 1, 1)
    $alsoY2K = Carbon::create(1999, 12, 31, 24);
    $noonLondonTz = Carbon::createFromTime(12, 0, 0, 'Europe/London');
    $teaTime = Carbon::createFromTimeString('17:00:00', 'Europe/London');
    
    try { Carbon::create(1975, 5, 21, 22, -2, 0); } catch(InvalidArgumentException $x) { echo $x->getMessage(); }
    // minute must be between 0 and 99, -2 given
    
    // Be careful, as Carbon::createFromDate() default values to current date, it can trigger overflow:
    // For example, if we are the 15th of June 2020, the following will set the date on 15:
    Carbon::createFromDate(2019, 4); // 2019-04-15
    // If we are the 31th of October, as 31th April does not exist, it overflows to May:
    Carbon::createFromDate(2019, 4); // 2019-05-01
    // That's why you simply should not use Carbon::createFromDate() with only 2 parameters (1 or 3 are safe, but no 2)
    

    创建异常会在此类负值上发生,但不会在溢出时发生,要在溢出时获取异常,请使用 createSafe()

    echo Carbon::create(2000, 1, 35, 13, 0, 0);
    // 2000-02-04 13:00:00
    echo "
    ";
    
    try {
        Carbon::createSafe(2000, 1, 35, 13, 0, 0);
    } catch (CarbonExceptionsInvalidDateException $exp) {
        echo $exp->getMessage();
    }
    // day : 35 is not a valid value.

    注1:2018-02-29也会产生例外,而2020-02-29不会例外,因为2020年是a年。

    注意2:Carbon::createSafe(2014, 3, 30, 1, 30, 0, 'Europe/London')也会产生一个例外,因为此时间以夏令时为单位(以小时为单位)。

    注意3:PHP原生API允许考虑0之间有一个年份-1 ,1即使它与公历无关。因此,小于1的年份会使用引发异常createSafe检查 isValid()是否检测到0年。

    Carbon::createFromFormat($format, $time, $tz);

    createFromFormat()主要是基本php函数DateTime :: createFromFormat的包装再次不同的是$tz参数可以是DateTimeZone实例或字符串时区值。另外,如果格式存在错误,此函数将调用该DateTime::getLastErrors()方法,然后将InvalidArgumentException带有错误的a作为消息抛出

    echo Carbon::createFromFormat('Y-m-d H', '1975-05-21 22')->toDateTimeString(); // 1975-05-21 22:00:00

    最后三个create函数用于处理unix时间戳第一个将创建一个与给定时间戳相等的Carbon实例,并将设置时区或将其默认为当前时区。第二个createFromTimestampUTC()是,不同之处在于,时区将保持UTC(GMT),其行为与UTC相同,Carbon::parse('@'.$timestamp) 但我只是更明确了一点。第三个(createFromTimestampMs())接受以毫秒为单位的时间戳,而不是秒。也可以使用负时间戳。

    echo Carbon::createFromTimestamp(-1)->toDateTimeString();                                  // 1969-12-31 23:59:59
    echo Carbon::createFromTimestamp(-1, 'Europe/London')->toDateTimeString();                 // 1970-01-01 00:59:59
    echo Carbon::createFromTimestampUTC(-1)->toDateTimeString();                               // 1969-12-31 23:59:59
    echo Carbon::createFromTimestampMs(1)->format('Y-m-dTH:i:s.uP T');                        // 1970-01-01T00:00:00.001000+00:00 UTC
    echo Carbon::createFromTimestampMs(1, 'Europe/London')->format('Y-m-dTH:i:s.uP T');       // 1970-01-01T01:00:00.001000+01:00 BST
    

    您还可以创建copy()现有Carbon实例的。如预期的那样,日期,时间和时区值都将复制到新实例。

    $dt = Carbon::now();
    echo $dt->diffInYears($dt->copy()->addYear());  // 1
    
    // $dt was unchanged and still holds the value of Carbon:now()
    

    您可以使用nowWithSameTz()现有的Carbon实例在同一时区现在获取一个新实例。

    $meeting = Carbon::createFromTime(19, 15, 00, 'Africa/Johannesburg');
    
    // 19:15 in Johannesburg
    echo 'Meeting starts at '.$meeting->format('H:i').' in Johannesburg.';                  // Meeting starts at 19:15 in Johannesburg.
    // now in Johannesburg
    echo "It's ".$meeting->nowWithSameTz()->format('H:i').' right now in Johannesburg.';    // It's 18:05 right now in Johannesburg.
    

    最后,如果您发现自己DateTime从另一个库继承实例,请不要担心!您可以Carbon通过友好的instance()方法创建实例或者使用更加灵活的方法make(),该方法可以从DateTime,Carbon或字符串返回新的Carbon实例,否则它仅返回null。

    $dt = new DateTime('first day of January 2008'); // <== instance from another API
    $carbon = Carbon::instance($dt);
    echo get_class($carbon);                               // 'CarbonCarbon'
    echo $carbon->toDateTimeString();                      // 2008-01-01 00:00:00
    

    Carbon 2(需要PHP> = 7.1)完美支持微秒。但是,如果您使用Carbon 1和PHP <7.1,请阅读我们 有关部分微秒支持的部分

    是否曾经需要遍历某些日期来查找最早或最新的日期?不知道将初始最大值/最小值设置为什么?现在有两个帮助程序使您的决定变得简单:

    echo Carbon::maxValue();                               // '9999-12-31 23:59:59'
    echo Carbon::minValue();                               // '0001-01-01 00:00:00'
    

    最小值和最大值主要取决于系统(32或64位)。

    对于32位OS系统或32位版本的PHP(您可以使用来在PHP中进行检查PHP_INT_SIZE === 4),最小值为0-unix-timestamp(1970-01-01 00:00:00),最大值为常数给出的时间戳PHP_INT_MAX

    对于64位OS系统和64位版本的PHP,最小值为01-01-01 00:00:00,最大值为9999-12-31 23:59:59。甚至可以使用负数年份,最大为-9999,但是请注意,由于PHP中存在年份0,但在公历中不存在年份,因此某些操作可能无法获得准确的结果。

    本土化

    通过Carbon 2,本地化发生了很大变化,支持749个新语言环境,我们现在嵌入了语言环境格式,日期名称,月份名称,序数后缀,子午线,星期开始等等。尽管Carbon 1提供了部分支持并依赖于IntlDateFormatter类和语言包等第三方进行高级翻译,但您现在可以从广泛的国际化支持中受益。您还在使用Carbon 1吗?我希望您会考虑升级,版本2确实具有很酷的新功能。否则,您仍然可以通过单击此处阅读本地化版本1文档

    从2.9.0版开始,您可以轻松自定义翻译:

     

    // we recommend to use custom language name/variant
    // rather than overriding an existing language
    // to avoid conflict such as "en_Boring" in the example below:
    $boringLanguage = 'en_Boring';
    $translator = CarbonTranslator::get($boringLanguage);
    $translator->setTranslations([
        'day' => ':count boring day|:count boring days',
    ]);
    // as this language starts with "en_" it will inherit from the locale "en"
    
    $date1 = Carbon::create(2018, 1, 1, 0, 0, 0);
    $date2 = Carbon::create(2018, 1, 4, 4, 0, 0);
    
    echo $date1->locale($boringLanguage)->diffForHumans($date2); // 3 boring days before
    
    $translator->setTranslations([
        'before' => function ($time) {
            return '['.strtoupper($time).']';
        },
    ]);
    
    echo $date1->locale($boringLanguage)->diffForHumans($date2); // [3 BORING DAYS]
    

    您可以通过以下方式使用后备语言环境locale()

    CarbonTranslator::get('xx')->setTranslations([
        'day' => ':count Xday',
    ]);
    CarbonTranslator::get('xy')->setTranslations([
        'day' => ':count Yday',
        'hour' => ':count Yhour',
    ]);
    
    $date = Carbon::now()->locale('xx', 'xy', 'es')->sub('3 days 6 hours 40 minutes');
    
    echo $date->ago(['parts' => 3]); // hace 3 Xday 6 Yhour 40 minutos
    

    在上面的示例中,它将尝试先在“ xx”中查找翻译,然后在“ xy”中查找缺失的翻译,然后在“ es”中查找,因此在这里,您会从“ xx”获得“ Xday”,从“ xy”,“ es”中的“ hace”和“ minutos”。

    请注意,Carbon::setTranslator($custom)只要给定翻译器实现,您也可以使用其他翻译器SymfonyComponentTranslationTranslatorInterface你可以使用得到全局默认的转换Carbon::getTranslator()(以及Carbon::setFallbackLocale($custom) 和Carbon::getFallbackLocale()回退区域,setFallbackLocale可以被多次获得多个后备语言环境),但这些方法将在全球范围改变行为(包括第三方库,你可以在你的应用程序),可能会导致意外结果。如上例所示,您应该使用自定义语言环境自定义翻译。

    Carbon嵌入了扩展Symfony Component Translation Translator的默认转换器。 您可以在此处检查我们添加到其中的方法

    因此,对于一个区域的支撑formatLocalized,吸气如localeMonthlocaleDayOfWeek 短的变体是由安装在操作系统语言环境驱动。对于其他翻译,Carbon社区在内部为它提供了支持。您可以检查以下方法支持什么:

    echo implode(', ', array_slice(Carbon::getAvailableLocales(), 0, 3)).'...';      // aa, aa_DJ, aa_ER...
    
    // Support diff syntax (before, after, from now, ago)
    var_dump(Carbon::localeHasDiffSyntax('en'));                                     // bool(true)
    var_dump(Carbon::localeHasDiffSyntax('zh_TW'));                                  // bool(true)
    // Support 1-day diff words (just now, yesterday, tomorrow)
    var_dump(Carbon::localeHasDiffOneDayWords('en'));                                // bool(true)
    var_dump(Carbon::localeHasDiffOneDayWords('zh_TW'));                             // bool(true)
    // Support 2-days diff words (before yesterday, after tomorrow)
    var_dump(Carbon::localeHasDiffTwoDayWords('en'));                                // bool(true)
    var_dump(Carbon::localeHasDiffTwoDayWords('zh_TW'));                             // bool(false)
    // Support short units (1y = 1 year, 1mo = 1 month, etc.)
    var_dump(Carbon::localeHasShortUnits('en'));                                     // bool(true)
    var_dump(Carbon::localeHasShortUnits('zh_TW'));                                  // bool(false)
    // Support period syntax (X times, every X, from X, to X)
    var_dump(Carbon::localeHasPeriodSyntax('en'));                                   // bool(true)
    var_dump(Carbon::localeHasPeriodSyntax('zh_TW'));                                // bool(false)
    

    因此,这是处理Carbon国际化的新推荐方法。

    $date = Carbon::now()->locale('fr_FR');
    
    echo $date->locale();            // fr_FR
    echo "
    ";
    echo $date->diffForHumans();     // il y a 1 seconde
    echo "
    ";
    echo $date->monthName;           // février
    echo "
    ";
    echo $date->isoFormat('LLLL');   // vendredi 14 février 2020 16:05
    

    ->locale()方法仅更改当前实例的语言,并且优先于全局设置。我们建议您使用这种方法,以免与其他可能使用Carbon的地方或第三方库发生冲突。但是,为了避免->locale() 每次都调用,可以使用工厂。

    // Let say Martin from Paris and John from Chicago play chess
    $martinDateFactory = new Factory([
        'locale' => 'fr_FR',
        'timezone' => 'Europe/Paris',
    ]);
    $johnDateFactory = new Factory([
        'locale' => 'en_US',
        'timezone' => 'America/Chicago',
    ]);
    // Each one will see date in his own language and timezone
    
    // When Martin moves, we display things in French, but we notify John in English:
    $gameStart = Carbon::parse('2018-06-15 12:34:00', 'UTC');
    $move = Carbon::now('UTC');
    $toDisplay = $martinDateFactory->make($gameStart)->isoFormat('lll')."
    ".
        $martinDateFactory->make($move)->calendar()."
    ";
    $notificationForJohn = $johnDateFactory->make($gameStart)->isoFormat('lll')."
    ".
        $johnDateFactory->make($move)->calendar()."
    ";
    echo $toDisplay;
    /*
    15 juin 2018 12:34
    Aujourd’hui à 16:05
    */
    
    echo $notificationForJohn;
    /*
    Jun 15, 2018 12:34 PM
    Today at 4:05 PM
    */
    

    您可以在工厂上调用任何静态Carbon方法(进行制造,现在,昨天,明天,解析,创建等)。工厂(以及生成CarbonImmutable实例的FactoryImmutable)是使事物保持组织和隔离的最佳方法。我们建议您尽可能多地使用UTC日期,然后在向用户显示日期之前在本地(或在工厂使用)时区和语言。

    工厂实际要做的是使用方法名称作为静态构造函数,然后使用调用settings() 方法,这是一种将区域设置,时区,月/年溢出等呼叫设置分组的方法。(有关完整列表请参见参考资料。

    $factory = new Factory([
        'locale' => 'fr_FR',
        'timezone' => 'Europe/Paris',
    ]);
    $factory->now(); // You can recall $factory as needed to generate new instances with same settings
    // is equivalent to:
    Carbon::now()->settings([
        'locale' => 'fr_FR',
        'timezone' => 'Europe/Paris',
    ]);
    // Important note: timezone setting calls ->shiftTimezone() and not ->setTimezone(),
    // It means it does not just set the timezone, but shift the time too:
    echo Carbon::today()->setTimezone('Asia/Tokyo')->format('d/m Gh e');        // 14/02 9h Asia/Tokyo
    echo "
    ";
    echo Carbon::today()->shiftTimezone('Asia/Tokyo')->format('d/m Gh e');      // 14/02 0h Asia/Tokyo
    

    settings() 还允许传递本地宏:

    $date = Carbon::parse('Today 12:34:56')->settings([
        'macros' => [
            'lastSecondDigit' => function () { return self::this()->second % 10; },
        ],
    ]);
    
    echo $date->lastSecondDigit(); // 6
    var_dump($date->hasLocalMacro('lastSecondDigit'));     // bool(true)
    // You can also retrieve the macro closure using ->getLocalMacro('lastSecondDigit')
    

    之后可以使用更改工厂设置,也可以将其setSettings(array $settings)与现有设置合并,mergeSettings(array $settings)然后可以将要生成的类初始化为构造的第二个参数,然后使用进行更改 setClassName(string $className)

    $factory = new Factory(['locale' => 'ja'], CarbonImmutable::class);
    var_dump($factory->now()->locale);                                           // string(2) "ja"
    var_dump(get_class($factory->now()));                                        // string(22) "CarbonCarbonImmutable"
    
    class MyCustomCarbonSubClass extends Carbon { /* ... */ }
    $factory
        ->setSettings(['locale' => 'zh_CN'])
        ->setClassName(MyCustomCarbonSubClass::class);
    var_dump($factory->now()->locale);                                           // string(5) "zh_CN"
    var_dump(get_class($factory->now()));                                        // string(22) "MyCustomCarbonSubClass"
    

    以前是Carbon::setLocale在全球范围内设置的。但是对于其他静态设置器,我们强烈建议您不要使用它。它违反了隔离原则,因为该配置将适用于所有使用Carbon的类。

    您可能也知道formatLocalized()Carbon 1中的方法。此方法在Carbon 2中仍然相同,但最好isoFormat()改用。

    ->isoFormat(string $format): string使用ISO格式而不是特定于PHP的格式,并使用内部翻译而不是需要在部署应用程序的每台计算机上安装的语言包。isoFormat该方法与momentjs格式方法兼容 ,这意味着您可以使用与前端或node.js相同的格式字符串。这里有些例子:

    $date = Carbon::parse('2018-06-15 17:34:15.984512', 'UTC');
    echo $date->isoFormat('MMMM Do YYYY, h:mm:ss a'); // June 15th 2018, 5:34:15 pm
    echo "
    ";
    echo $date->isoFormat('dddd');           // Friday
    echo "
    ";
    echo $date->isoFormat('MMM Do YY');      // Jun 15th 18
    echo "
    ";
    echo $date->isoFormat('YYYY [escaped] YYYY'); // 2018 escaped 2018
    

    您还可以根据ISO格式的字符串创建日期:

    $date = Carbon::createFromIsoFormat('!YYYY-MMMM-D h:mm:ss a', '2019-January-3 6:33:24 pm', 'UTC');
    echo $date->isoFormat('M/D/YY HH:mm'); // 1/3/19 18:33
    

    ->isoFormat 对日期名称和月份名称使用上下文化的方法,因为它们在某些语言中可以具有多种形式,请参见以下示例:

    $date = Carbon::parse('2018-03-16')->locale('uk');
    echo $date->getTranslatedDayName('[в] dddd'); // п’ятницю
    // By providing a context, we're saying translate day name like in a format such as [в] dddd
    // So the context itself has to be translated first consistently.
    echo "
    ";
    echo $date->getTranslatedDayName('[наступної] dddd'); // п’ятниці
    echo "
    ";
    echo $date->getTranslatedDayName('dddd, MMM'); // п’ятниця
    echo "
    ";
    // The same goes for short/minified variants:
    echo $date->getTranslatedShortDayName('[наступної] dd'); // пт
    echo "
    ";
    echo $date->getTranslatedMinDayName('[наступної] ddd'); // пт
    echo "
    ";
    
    // And the same goes for months
    $date->locale('ru');
    echo $date->getTranslatedMonthName('Do MMMM'); // марта
    echo "
    ";
    echo $date->getTranslatedMonthName('MMMM YYYY'); // март
    echo "
    ";
    // Short variant
    echo $date->getTranslatedShortMonthName('Do MMM'); // мар
    echo "
    ";
    echo $date->getTranslatedShortMonthName('MMM YYYY'); // мар
    echo "
    ";
    
    // And so you can force a different context to get those variants:
    echo $date->isoFormat('Do MMMM');        // 16-го марта
    echo "
    ";
    echo $date->isoFormat('MMMM YYYY');      // март 2018
    echo "
    ";
    echo $date->isoFormat('Do MMMM', 'MMMM YYYY'); // 16-го март
    echo "
    ";
    echo $date->isoFormat('MMMM YYYY', 'Do MMMM'); // марта 2018
    echo "
    ";
    

    这是可用替代品的完整列表(示例带有 $date = Carbon::parse('2017-01-05 17:04:05.084512');):

    描述
    外径 5 如果区域设置为ja_JP,则带备用数字的天数,例如三代表三
    OM 1个 如果区域设置为my_MM,则月份号带有备用数字,例如၀၂代表2
    OY 2017年 如果年份为fa,则年份编号带有其他编号,例如1998年的۱۹۹۸。
    17 24小时数字,带备用数字,例如,如果语言环境为shn_MM,则为13的႑႓
    5 12小时数字,如果区域设置为lzh_TW,则使用其他数字,例如11代表11
    m 4 分钟数,带备用数字,例如୫୭表示57,如果区域设置为或
    操作系统 5 如果区域设置为ja_JP,则第二个数字带有备用数字,例如15表示15
    d 5 月份中的天数(从1到31)
    DD 05 月份数字,尾随零(从01到31)
    第五名 每月后缀序号(从1日到31日),可翻译
    d 4 星期几(从0(星期日)到6(星期六))
    dd 最小日期名称(从Su到Sa),可翻译
    ddd 周四 短日名称(从星期日到星期六),可翻译
    dddd 星期四 日期名称(从星期日到星期六),可翻译
    DDD 5 一年中的第几天(从1到366)
    DDDD 005 年份数字,后跟零(3位数字,从001到366)
    DDDo 第五名 一年中的第几天,后缀为序号(从1到366),可翻译
    Ë 4 星期几号(从0(星期日)到6(星期六)),与“ d”相似,但该数字是可翻译的(采用当前语言环境的星期几)
    Ë 4 星期几(从1(星期一)到7(星期日))
    H 17 小时从0到23
    H 17 从00到23尾随零的小时
    H 5 0至12小时
    h 05 从00到12尾随零的小时
    ķ 17 1到24小时
    kk 17 小时,从01到24均为零
    4 分钟从0到59
    毫米 04 分钟,从00到59,尾随零
    一种 下午 Meridiem am / pm
    一种 下午 Meridiem AM / PM
    s 5 从0到59秒
    ss 05 秒,从00到59尾随零
    小号 0 第二十分
    SS 08 第二百分之一(在2位数字后跟零)
    SSS 084 毫秒(3位数字,后跟零)
    SSSS 0845 第二十分之一(4位数字,后跟零)
    社交网站 08451 二十分之一(在5位数字上带有结尾的零)
    SSSSSS 084512 微秒(6位数字,后跟零)
    SS 0845120 第二十分之一(7位数字后跟零)
    SSSSSSSS 08451200 第二百万分之一(在8位数字后跟零)
    SSSSSSSSS 084512000 纳秒(9位数字,后跟零)
    中号 1个 1到12个月
    MM 01 从01到12的零结尾月份
    MMM 一月 短月份名称,可翻译
    MMMM 一月 月名称,可翻译
    第一 序号后缀从1到12的月份,可以翻译
    1个 1至4季度
    o 第一 四分之一,后缀为第1到第4,可翻译
    G 2017年 ISO周年(请参阅ISO周日期
    GG 2017年 ISO周年(2位数字,后跟零)
    GG 2017年 ISO周年(3位数字,后跟零)
    GG 2017年 ISO周年(4位数字,后跟零)
    GG 02017 ISO周年(5位数字,后跟零)
    G 2017年 根据语言环境设置的星期,可翻译
    gg 2017年 根据语言环境设置的星期(2位数字,后跟零),可翻译
    gg 2017年 根据语言环境设置的星期(3位数字,后跟零),可翻译
    gggg 2017年 根据语言环境设置的星期年份(4位数字,后跟零),可翻译
    gg 02017 根据语言环境设置的星期年份(5位数字,后跟零),可翻译
    w ^ 1个 一年中的ISO周编号(请参阅ISO周日期
    WW 01 一年中的ISO周编号(两位数字,后跟零)
    第一 一年中具有序数后缀的ISO周号,可翻译
    w 1个 根据地区设置,一年中的星期数可翻译
    w 01 根据地区设置在一年中的星期数(以两位数字结尾为零)
    o 第一 根据语言环境设置,一年中的星期数,带序数后缀,可翻译
    X 1483635845085 毫秒级时间戳(与date.getTime()JavaScript中相同
    X 1483635845 时间戳记(自1970-01-01起的秒数)
    ÿ 2017年 全年-9999至9999
    YY 17 年份从00到99的2位数字
    YYYY 2017年 从0000到9999的4位数字的年份
    YYYYYY 02017 5位数字的年份,从00000到09999
    YYYYYY +002017 5位数字上的年份,符号从-09999到+09999
    ž 世界标准时间 时区缩写
    Z Z 世界标准时间 时区名称
    ž +00:00 时区偏移HH:mm
    Z Z +0000 时区偏移HHmm

    也可以使用一些宏格式。以下是每种语言的示例:

    frJA小时
    LT h:mm A
    5:04 PM
    高度:毫米
    17:04
    高度:毫米
    17:04
    高:毫米
    17:04
    LTS h:mm:ss A
    5:04:05 PM
    HH:mm:ss
    17:04:05
    HH:mm:ss
    17:04:05
    H:mm:ss
    17:04:05
    L

    l
    MM / DD / YYYY
    2017年1月5日
    2017年1月5日
    DD / MM / YYYY
    2017年5月1日
    2017年5月1日
    YYYY / MM / DD
    2017/01/05
    2017/1/5
    DD.MM.YYYY
    2017年5月1日
    2017年5月1日
    LL

    ll
    MMMM D,YYYY
    2017年
    月5日2017年 1月5日
    D MMMM YYYY
    2017年
    月 5日。2017年
    YYYY年M月D日
    2017年1月5日
    2017年1月5日
    D. MMMM YYYY
    5.siječanj2017年
    5骶髂关节。2017年
    LLL

    lll
    MMMM D,YYYY h:mm A
    2017年1月5日5:04 PM 2017年
    1月5日5:04 PM
    D MMMM YYYY HH:mm 5 Janvier
    2017 17:04
    5 Janv。2017 17:04
    YYYY年M月D日HH:mm
    2017年1月5日17:04
    2017年1月5日17:04

    D.MMMM YYYY H: mm5.siječanj2017 17:04
    5. sij。2017 17:04
    LLLL

    llll
    dddd,MMMM D,YYYY h:mm A
    2017年1月5日
    星期四5:04 PM 2017年1月5日 星期四5:04 PM
    dddd D MMMM YYYY HH:mm
    jeudi 5 Janvier 2017 17:04
    jeu。一月5日。2017 17:04
    YYYY年M月D日dddd HH:mm
    2017年1月5日木曜日17:04
    2017年1月5日木17:04
    dddd,
    D.MMMM YYYY H: mmčetvrtak,5.siječanj2017 17:
    04čet。,5. sij。2017 17:04

    与宏格式一起使用时createFromIsoFormat,可以指定区域设置以选择应以哪种语言搜索宏格式。

    $date = Carbon::createFromIsoFormat('LLLL', 'Monday 11 March 2019 16:28', null, 'fr');
    echo $date->isoFormat('M/D/YY HH:mm'); // 3/11/19 16:28
    

    另一种有用的翻译方法是calendar($referenceTime = null, array $formats = []): string

    $date = CarbonImmutable::now();
    echo $date->calendar();                                      // Today at 4:05 PM
    echo "
    ";
    echo $date->sub('1 day 3 hours')->calendar();                // Yesterday at 1:05 PM
    echo "
    ";
    echo $date->sub('3 days 10 hours 23 minutes')->calendar();   // Last Tuesday at 5:42 AM
    echo "
    ";
    echo $date->sub('8 days')->calendar();                       // 02/06/2020
    echo "
    ";
    echo $date->add('1 day 3 hours')->calendar();                // Tomorrow at 7:05 PM
    echo "
    ";
    echo $date->add('3 days 10 hours 23 minutes')->calendar();   // Tuesday at 2:28 AM
    echo "
    ";
    echo $date->add('8 days')->calendar();                       // 02/22/2020
    echo "
    ";
    echo $date->locale('fr')->calendar();                        // Aujourd’hui à 16:05
    

    如果您知道momentjs,那么它的工作方式相同。您可以将参考日期作为第二个参数传递,否则现在使用。您可以使用第二个参数来自定义一种或多种格式(作为数组键传递的格式为:sameDay,nextDay,nextWeek,lastDay,lastWeek和sameElse):

    $date1 = CarbonImmutable::parse('2018-01-01 12:00:00');
    $date2 = CarbonImmutable::parse('2018-01-02 8:00:00');
    
    echo $date1->calendar($date2, [
        'lastDay' => '[Previous day at] LT',
    ]);
    // Previous day at 12:00 PM
    

    单击此处是上一个Carbon版本支持的279个语言环境(和822个区域变体)的概述:

    如果您可以添加缺少的翻译或缺少的语言,请转到翻译工具,欢迎您的帮助。

    请注意,如果您使用Laravel 5.5+,将根据当前的上次App:setLocale执行自动设置语言环境 因此diffForHumansisoFormattranslatedFormat和本地化如属性->dayName->monthName将被透明地本地化。

    默认情况下,每个Carbon,CarbonImmutable,CarbonInterval或CarbonPeriod实例都CarbonTranslator根据其区域设置链接到一个 实例。您可以使用getLocalTranslator()获取和/或更改它setLocalTranslator(Translator $translator)

    如果您更喜欢date()pattern,则可以translatedFormat()使用模式一样使用format() 但是使用当前语言环境来翻译字符串。

    $date = Carbon::parse('2018-03-16 15:45')->locale('uk');
    
    echo $date->translatedFormat('g:i a l jS F Y'); // 3:45 дня п’ятниця 16-го березня 2018
    

    请注意,W不支持某些字母之类字母,因为它们不能安全翻译,并且 translatedFormat语法比短,但可能性比少isoFormat()

    您可以自定义format()方法的行为,以使用任何其他方法或自定义方法来代替PHP DateTime类中的本机方法:

    $date = Carbon::parse('2018-03-16 15:45')->locale('ja');
    
    echo $date->format('g:i a l jS F Y');    // 3:45 pm Friday 16th March 2018
    echo "
    ";
    
    $date->settings(['formatFunction' => 'translatedFormat']);
    
    echo $date->format('g:i a l jS F Y');    // 3:45 午後 金曜日 16日 3月 2018
    echo "
    ";
    
    $date->settings(['formatFunction' => 'isoFormat']);
    
    echo $date->format('LL');                // 2018年3月16日
    echo "
    ";
    
    // When you set a custom format() method you still can access the native method using rawFormat()
    echo $date->rawFormat('D');              // Fri
    

    您可以使用Carbon中可用的日期翻译将字符串从一种语言翻译为另一种:

    echo Carbon::translateTimeString('mercredi 8 juillet', 'fr', 'nl');
    // woensdag 8 juli
    echo "
    ";
    
    // You can select translations to use among available constants:
    // - CarbonInterface::TRANSLATE_MONTHS
    // - CarbonInterface::TRANSLATE_DAYS
    // - CarbonInterface::TRANSLATE_UNITS
    // - CarbonInterface::TRANSLATE_MERIDIEM
    // - CarbonInterface::TRANSLATE_ALL (all above)
    // You can combine them with pipes: like below (translate units and days but not months and meridiem):
    echo Carbon::translateTimeString('mercredi 8 juillet + 3 jours', 'fr', 'nl', CarbonInterface::TRANSLATE_DAYS | CarbonInterface::TRANSLATE_UNITS);
    // woensdag 8 juillet + 3 dagen
    

    如果未指定输入语言环境,Carbon::getLocale()则改为使用。如果未指定输出语言环境,"en"则改为使用。您还可以使用实例的语言环境进行翻译:

    echo Carbon::now()->locale('fr')->translateTimeStringTo('mercredi 8 juillet + 3 jours', 'nl');
    // woensdag 8 juli + 3 dagen
    

    您可以使用任何语言的字符串直接使用创建日期对象parseFromLocale

    $date = Carbon::parseFromLocale('mercredi 6 mars 2019 + 3 jours', 'fr', 'UTC'); // timezone is optional
    
    echo $date->isoFormat('LLLL'); // Saturday, March 9, 2019 12:00 AM
    

    或使用自定义格式createFromLocaleFormat (使用date()模式进行替换):

    $date = Carbon::createFromLocaleFormat('!d/F/y', 'fr', '25/Août/19', 'Europe/Paris'); // timezone is optional
    
    echo $date->isoFormat('LLLL'); // Sunday, August 25, 2019 12:00 AM
    

    使用ISO格式的等效方法是createFromLocaleIsoFormat

    $date = Carbon::createFromLocaleIsoFormat('!DD/MMMM/YY', 'fr', '25/Août/19', 'Europe/Paris'); // timezone is optional
    
    echo $date->isoFormat('LLLL'); // Sunday, August 25, 2019 12:00 AM
    

    要获取有关语言的一些有趣信息(例如完整的ISO名称或本机名称,地区(例如,显示在语言选择器中)),可以使用getAvailableLocalesInfo

    $zhTwInfo = Carbon::getAvailableLocalesInfo()['zh_TW'];
    $srCyrlInfo = Carbon::getAvailableLocalesInfo()['sr_Cyrl'];
    $caInfo = Carbon::getAvailableLocalesInfo()['ca'];
    
    var_dump($zhTwInfo->getId());                      // string(5) "zh_TW"
    var_dump($zhTwInfo->getNames());                  
    /*
    array(2) {
      ["isoName"]=>
      string(7) "Chinese"
      ["nativeName"]=>
      string(38) "中文 (Zhōngwén), 汉语, 漢語"
    }
    */
    var_dump($zhTwInfo->getCode());                    // string(2) "zh"
    var_dump($zhTwInfo->getVariant());                 // NULL
    var_dump($srCyrlInfo->getVariant());               // string(4) "Cyrl"
    var_dump($zhTwInfo->getVariantName());             // NULL
    var_dump($srCyrlInfo->getVariantName());           // string(8) "Cyrillic"
    var_dump($zhTwInfo->getRegion());                  // string(2) "TW"
    var_dump($srCyrlInfo->getRegion());                // NULL
    var_dump($zhTwInfo->getRegionName());              // string(25) "Taiwan, Province of China"
    var_dump($srCyrlInfo->getRegionName());            // NULL
    var_dump($zhTwInfo->getFullIsoName());             // string(7) "Chinese"
    var_dump($caInfo->getFullIsoName());               // string(18) "Catalan, Valencian"
    var_dump($zhTwInfo->getFullNativeName());          // string(38) "中文 (Zhōngwén), 汉语, 漢語"
    var_dump($caInfo->getFullNativeName());            // string(18) "català, valencià"
    var_dump($zhTwInfo->getIsoName());                 // string(7) "Chinese"
    var_dump($caInfo->getIsoName());                   // string(7) "Catalan"
    var_dump($zhTwInfo->getNativeName());              // string(20) "中文 (Zhōngwén)"
    var_dump($caInfo->getNativeName());                // string(7) "català"
    var_dump($zhTwInfo->getIsoDescription());          // string(35) "Chinese (Taiwan, Province of China)"
    var_dump($srCyrlInfo->getIsoDescription());        // string(18) "Serbian (Cyrillic)"
    var_dump($caInfo->getIsoDescription());            // string(7) "Catalan"
    var_dump($zhTwInfo->getNativeDescription());       // string(48) "中文 (Zhōngwén) (Taiwan, Province of China)"
    var_dump($srCyrlInfo->getNativeDescription());     // string(34) "српски језик (Cyrillic)"
    var_dump($caInfo->getNativeDescription());         // string(7) "català"
    var_dump($zhTwInfo->getFullIsoDescription());      // string(35) "Chinese (Taiwan, Province of China)"
    var_dump($srCyrlInfo->getFullIsoDescription());    // string(18) "Serbian (Cyrillic)"
    var_dump($caInfo->getFullIsoDescription());        // string(18) "Catalan, Valencian"
    var_dump($zhTwInfo->getFullNativeDescription());   // string(66) "中文 (Zhōngwén), 汉语, 漢語 (Taiwan, Province of China)"
    var_dump($srCyrlInfo->getFullNativeDescription()); // string(34) "српски језик (Cyrillic)"
    var_dump($caInfo->getFullNativeDescription());     // string(18) "català, valencià"
    
    $srCyrlInfo->setIsoName('foo, bar')->setNativeName('biz, baz');
    var_dump($srCyrlInfo->getIsoName());               // string(3) "foo"
    var_dump($srCyrlInfo->getFullIsoName());           // string(8) "foo, bar"
    var_dump($srCyrlInfo->getFullIsoDescription());    // string(19) "foo, bar (Cyrillic)"
    var_dump($srCyrlInfo->getNativeName());            // string(3) "biz"
    var_dump($srCyrlInfo->getFullNativeName());        // string(8) "biz, baz"
    var_dump($srCyrlInfo->getFullNativeDescription()); // string(19) "biz, baz (Cyrillic)"
    
    // You can also access directly regions/languages lists:
    var_dump(CarbonLanguage::all()['zh']);          
    /*
    array(2) {
      ["isoName"]=>
      string(7) "Chinese"
      ["nativeName"]=>
      string(38) "中文 (Zhōngwén), 汉语, 漢語"
    }
    */
    var_dump(CarbonLanguage::regions()['TW']);      
    /*
    string(25) "Taiwan, Province of China"
    */
    

    请让我感谢一些项目,这些项目对我们支持更多区域设置和国际化功能很有帮助:

    • jenssegers / date:此项目中的许多功能在扩展Carbon本身之前都对Carbon进行了扩展。
    • momentjs:许多功能均受momentjs的启发,并与该前端对项目兼容。
    • glibc是添加和检查语言的强大基础。
    • svenfuchs / rails-i18n还帮助添加和检查语言。
    • 我们经常使用glosbe.com来检查翻译和填空。

    测试辅助

    测试方法允许您设置创建“ now”实例时要返回的Carbon实例(真实或模拟)。从Carbon检索任何相对时间(现在,今天,昨天,下个月等)时,将使用提供的实例。

    $knownDate = Carbon::create(2001, 5, 21, 12);          // create testing date
    Carbon::setTestNow($knownDate);                        // set the mock (of course this could be a real mock object)
    echo Carbon::getTestNow();                             // 2001-05-21 12:00:00
    echo Carbon::now();                                    // 2001-05-21 12:00:00
    echo new Carbon();                                     // 2001-05-21 12:00:00
    echo Carbon::parse();                                  // 2001-05-21 12:00:00
    echo new Carbon('now');                                // 2001-05-21 12:00:00
    echo Carbon::parse('now');                             // 2001-05-21 12:00:00
    echo Carbon::create(2001, 4, 21, 12)->diffForHumans(); // 1 month ago
    var_dump(Carbon::hasTestNow());                        // bool(true)
    Carbon::setTestNow();                                  // clear the mock
    var_dump(Carbon::hasTestNow());                        // bool(false)
    echo Carbon::now();                                    // 2020-02-14 16:05:24
    

    一个更有意义的完整示例:

    class SeasonalProduct
    {
        protected $price;
    
        public function __construct($price)
        {
            $this->price = $price;
        }
    
        public function getPrice() {
            $multiplier = 1;
            if (Carbon::now()->month == 12) {
                $multiplier = 2;
            }
    
            return $this->price * $multiplier;
        }
    }
    
    $product = new SeasonalProduct(100);
    Carbon::setTestNow(Carbon::parse('first day of March 2000'));
    echo $product->getPrice();                                             // 100
    Carbon::setTestNow(Carbon::parse('first day of December 2000'));
    echo $product->getPrice();                                             // 200
    Carbon::setTestNow(Carbon::parse('first day of May 2000'));
    echo $product->getPrice();                                             // 100
    Carbon::setTestNow();
    

    相对短语也会根据给定的“ now”实例进行模拟。

    $knownDate = Carbon::create(2001, 5, 21, 12);          // create testing date
    Carbon::setTestNow($knownDate);                        // set the mock
    echo new Carbon('tomorrow');                           // 2001-05-22 00:00:00  ... notice the time !
    echo new Carbon('yesterday');                          // 2001-05-20 00:00:00
    echo new Carbon('next wednesday');                     // 2001-05-23 00:00:00
    echo new Carbon('last friday');                        // 2001-05-18 00:00:00
    echo new Carbon('this thursday');                      // 2001-05-24 00:00:00
    Carbon::setTestNow();                                  // always clear it !
    

    被视为相对修饰语的单词列表为:

    • +
    • --
    • 第一
    • 下一个
    • 持续
    • 这个
    • 今天
    • 明天
    • 昨天

    请注意,类似于next(),previous()和Modify()方法,其中一些相对修饰符会将时间设置为00:00:00。

    Carbon::parse($time, $tz)并且new Carbon($time, $tz)既可以采取时区作为第二个参数。

    echo Carbon::parse('2012-9-5 23:26:11.223', 'Europe/Paris')->timezone->getName(); // Europe/Paris
    

    有关更高级的碳测试功能,请参见Carbonite。

    Carbonite是一个附加软件包,您可以使用composer轻松安装:composer require --dev kylekatarnls/carbonite 然后像讲故事一样在单元测试中花费时间:

    use CarbonCarbonite;在文件顶部添加导入。

    $holidays = CarbonPeriod::create('2019-12-23', '2020-01-06', CarbonPeriod::EXCLUDE_END_DATE);
    
    Carbonite::freeze('2019-12-22'); // Freeze the time to a given date
    
    var_dump($holidays->isStarted());     // bool(false)
    
    // Then go to anytime:
    Carbonite::elapse('1 day');
    
    var_dump($holidays->isInProgress());  // bool(true)
    
    Carbonite::jumpTo('2020-01-05 22:00');
    
    var_dump($holidays->isEnded());       // bool(false)
    
    Carbonite::elapse('2 hours');
    
    var_dump($holidays->isEnded());       // bool(true)
    
    Carbonite::rewind('1 microsecond');
    
    var_dump($holidays->isEnded());       // bool(false)
    
    Carbonite::release(); // Release time after each test
    

    吸气剂

    吸气剂是通过PHP的__get()方法实现的这样一来,您就可以像对待属性而不是调用函数一样访问该值。

    $dt = Carbon::parse('2012-10-5 23:26:11.123789');
    
    // These getters specifically return integers, ie intval()
    var_dump($dt->year);                                         // int(2012)
    var_dump($dt->month);                                        // int(10)
    var_dump($dt->day);                                          // int(5)
    var_dump($dt->hour);                                         // int(23)
    var_dump($dt->minute);                                       // int(26)
    var_dump($dt->second);                                       // int(11)
    var_dump($dt->micro);                                        // int(123789)
    // dayOfWeek returns a number between 0 (sunday) and 6 (saturday)
    var_dump($dt->dayOfWeek);                                    // int(5)
    // dayOfWeekIso returns a number between 1 (monday) and 7 (sunday)
    var_dump($dt->dayOfWeekIso);                                 // int(5)
    var_dump($dt->englishDayOfWeek);                             // string(6) "Friday"
    var_dump($dt->shortEnglishDayOfWeek);                        // string(3) "Fri"
    var_dump($dt->locale('de')->dayName);                        // string(7) "Freitag"
    var_dump($dt->locale('de')->shortDayName);                   // string(3) "Fr."
    var_dump($dt->locale('de')->minDayName);                     // string(2) "Fr"
    var_dump($dt->englishMonth);                                 // string(7) "October"
    var_dump($dt->shortEnglishMonth);                            // string(3) "Oct"
    var_dump($dt->locale('de')->monthName);                      // string(7) "Oktober"
    var_dump($dt->locale('de')->shortMonthName);                 // string(3) "Okt"
    
    // Following are deprecated, locale* and shortLocale* properties
    // are translated using formatLocalized() based on LC_TIME language.
    setlocale(LC_TIME, 'German');
    var_dump($dt->localeDayOfWeek);                              // string(7) "Freitag"
    var_dump($dt->shortLocaleDayOfWeek);                         // string(2) "Fr"
    var_dump($dt->localeMonth);                                  // string(7) "Oktober"
    var_dump($dt->shortLocaleMonth);                             // string(3) "Okt"
    setlocale(LC_TIME, '');
    
    var_dump($dt->dayOfYear);                                    // int(279)
    var_dump($dt->weekNumberInMonth);                            // int(1)
    // weekNumberInMonth consider weeks from monday to sunday, so the week 1 will
    // contain 1 day if the month start with a sunday, and up to 7 if it starts with a monday
    var_dump($dt->weekOfMonth);                                  // int(1)
    // weekOfMonth will returns 1 for the 7 first days of the month, then 2 from the 8th to
    // the 14th, 3 from the 15th to the 21st, 4 from 22nd to 28th and 5 above
    var_dump($dt->weekOfYear);                                   // int(40)
    var_dump($dt->daysInMonth);                                  // int(31)
    var_dump($dt->timestamp);                                    // int(1349479571)
    // Millisecond-precise timestamp (useful to pass it to JavaScript)
    var_dump($dt->valueOf());                                    // float(1349479571124)
    // Custom-precision timestamp
    var_dump($dt->getPreciseTimestamp(6));                       // float(1.3494795711238E+15)
    var_dump(Carbon::createFromDate(1975, 5, 21)->age);          // int(44) calculated vs now in the same tz
    var_dump($dt->quarter);                                      // int(4)
    
    // Returns an int of seconds difference from UTC (+/- sign included)
    var_dump(Carbon::createFromTimestampUTC(0)->offset);         // int(0)
    var_dump(Carbon::createFromTimestamp(0, 'Europe/Paris')->offset);                // int(3600)
    var_dump(Carbon::createFromTimestamp(0, 'Europe/Paris')->getOffset());           // int(3600)
    
    // Returns an int of hours difference from UTC (+/- sign included)
    var_dump(Carbon::createFromTimestamp(0, 'Europe/Paris')->offsetMinutes);         // int(60)
    var_dump(Carbon::createFromTimestamp(0, 'Europe/Paris')->offsetHours);           // int(1)
    
    // Returns timezone offset as string
    var_dump(Carbon::createFromTimestamp(0, 'Europe/Paris')->getOffsetString());     // string(6) "+01:00"
    
    // Returns timezone as CarbonTimeZone
    var_dump(Carbon::createFromTimestamp(0, 'Europe/Paris')->getTimezone());
    /* object(CarbonCarbonTimeZone)#3456 (2) {
      ["timezone_type"]=>
      int(3)
      ["timezone"]=>
      string(12) "Europe/Paris"
    } */
    
    // Indicates if day light savings time is on
    var_dump(Carbon::createFromDate(2012, 1, 1)->dst);           // bool(false)
    var_dump(Carbon::createFromDate(2012, 9, 1)->dst);           // bool(false)
    var_dump(Carbon::createFromDate(2012, 9, 1)->isDST());       // bool(false)
    
    // Indicates if the instance is in the same timezone as the local timezone
    var_dump(Carbon::now()->local);                              // bool(true)
    var_dump(Carbon::now('America/Vancouver')->local);           // bool(false)
    var_dump(Carbon::now()->isLocal());                          // bool(true)
    var_dump(Carbon::now('America/Vancouver')->isLocal());       // bool(false)
    var_dump(Carbon::now()->isUtc());                            // bool(true)
    var_dump(Carbon::now('America/Vancouver')->isUtc());         // bool(false)
    // can also be written ->isUTC()
    
    // Indicates if the instance is in the UTC timezone
    var_dump(Carbon::now()->utc);                                // bool(true)
    // London is not UTC on summer time
    var_dump(Carbon::parse('2018-10-01', 'Europe/London')->utc); // bool(false)
    // London is UTC on winter time
    var_dump(Carbon::parse('2018-11-01', 'Europe/London')->utc); // bool(true)
    var_dump(Carbon::createFromTimestampUTC(0)->utc);            // bool(true)
    
    // Gets the DateTimeZone instance
    echo get_class(Carbon::now()->timezone);                     // CarbonCarbonTimeZone
    echo "
    ";
    echo get_class(Carbon::now()->tz);                           // CarbonCarbonTimeZone
    echo "
    ";
    
    // Gets the DateTimeZone instance name, shortcut for ->timezone->getName()
    echo Carbon::now()->timezoneName;                            // UTC
    echo "
    ";
    echo Carbon::now()->tzName;                                  // UTC
    echo "
    ";
    
    // You can get any property dynamically too:
    $unit = 'second';
    var_dump(Carbon::now()->get($unit));                         // int(24)
    // equivalent to:
    var_dump(Carbon::now()->$unit);                              // int(24)
    // If you have plural unit name, use singularUnit()
    $unit = Carbon::singularUnit('seconds');
    var_dump(Carbon::now()->get($unit));                         // int(24)
    // Prefer using singularUnit() because some plurals are not the word with S:
    var_dump(Carbon::pluralUnit('century'));                     // string(9) "centuries"
    var_dump(Carbon::pluralUnit('millennium'));                  // string(9) "millennia"
    

    二传手

    以下设置器是通过PHP的__set()方法实现的在此需要注意的是,除了显式设置时区的明显例外之外,所有设置器都不会更改实例的时区。具体来说,设置时间戳不会将相应时区设置为UTC。

    $dt = Carbon::now();
    
    $dt->year = 1975;
    $dt->month = 13;             // would force year++ and month = 1
    $dt->month = 5;
    $dt->day = 21;
    $dt->hour = 22;
    $dt->minute = 32;
    $dt->second = 5;
    
    $dt->timestamp = 169957925;  // This will not change the timezone
    // Same as:
    $dt->setTimestamp(169957925);
    $dt->timestamp(169957925);
    
    // Set the timezone via DateTimeZone instance or string
    $dt->tz = new DateTimeZone('Europe/London');
    $dt->tz = 'Europe/London';
    
    // The ->timezone is also available for backward compatibility but
    // it will be overridden by native php DateTime class as soon as
    // the object is dump (passed foreach, serialize, var_export, clone, etc.)
    // making the Carbon setter inefficient, if it happen, you can cleanup
    // those overridden properties by calling ->cleanupDumpProperties() on
    // the instance, but we rather recommend to simply use ->tz instead
    // of ->timezone everywhere.
    
    // verbose way:
    $dt->setYear(2001);
    echo $dt->year;      // 2001
    echo "
    ";
    
    // set/get method:
    $dt->year(2002);
    echo $dt->year();    // 0000-05-22 03:32:05
    echo "
    ";
    
    // dynamic way:
    $dt->set('year', 2003);
    echo $dt->get('year'); // 2003
    echo "
    ";
    
    // these methods exist for every units even for calculated properties such as:
    echo $dt->dayOfYear(35)->format('Y-m-d'); // 2003-02-04
    

    周数

    如果您熟悉momentjs,那么您会发现所有Week方法都工作相同。它们大多数具有iso {Method}变体。Week方法遵循当前语言环境的规则(例如,使用en_US,默认语言环境,一周的第一天为Sunday,一年的第一周为包含1月1日的一周)。ISO方法遵循ISO 8601规范,这意味着星期从星期一开始,一年的第一周是包含1月4日的星期。

    $en = CarbonImmutable::now()->locale('en_US');
    $ar = CarbonImmutable::now()->locale('ar');
    
    var_dump($en->firstWeekDay);                           // int(0)
    var_dump($en->lastWeekDay);                            // int(6)
    var_dump($en->startOfWeek()->format('Y-m-d H:i'));     // string(16) "2020-02-09 00:00"
    var_dump($en->endOfWeek()->format('Y-m-d H:i'));       // string(16) "2020-02-15 23:59"
    
    echo "-----------
    ";
    
    // We still can force to use an other day as start/end of week
    $start = $en->startOfWeek(Carbon::TUESDAY);
    $end = $en->endOfWeek(Carbon::MONDAY);
    var_dump($start->format('Y-m-d H:i'));                 // string(16) "2020-02-11 00:00"
    var_dump($end->format('Y-m-d H:i'));                   // string(16) "2020-02-17 23:59"
    
    echo "-----------
    ";
    
    var_dump($ar->firstWeekDay);                           // int(6)
    var_dump($ar->lastWeekDay);                            // int(5)
    var_dump($ar->startOfWeek()->format('Y-m-d H:i'));     // string(16) "2020-02-08 00:00"
    var_dump($ar->endOfWeek()->format('Y-m-d H:i'));       // string(16) "2020-02-14 23:59"
    
    $en = CarbonImmutable::parse('2015-02-05'); // use en_US as default locale
    
    echo "-----------
    ";
    
    var_dump($en->weeksInYear());                          // int(52)
    var_dump($en->isoWeeksInYear());                       // int(53)
    
    $en = CarbonImmutable::parse('2017-02-05');
    
    echo "-----------
    ";
    
    var_dump($en->week());                                 // int(6)
    var_dump($en->isoWeek());                              // int(5)
    var_dump($en->week(1)->format('Y-m-d H:i'));           // string(16) "2017-01-01 00:00"
    var_dump($en->isoWeek(1)->format('Y-m-d H:i'));        // string(16) "2017-01-08 00:00"
    var_dump($en->weekday());                              // int(0)
    var_dump($en->isoWeekday());                           // int(7)
    var_dump($en->weekday(3)->format('Y-m-d H:i'));        // string(16) "2017-02-08 00:00"
    var_dump($en->isoWeekday(3)->format('Y-m-d H:i'));     // string(16) "2017-02-01 00:00"
    
    $en = CarbonImmutable::parse('2017-01-01');
    
    echo "-----------
    ";
    
    var_dump($en->weekYear());                             // int(2017)
    var_dump($en->isoWeekYear());                          // int(2016)
    var_dump($en->weekYear(2016)->format('Y-m-d H:i'));    // string(16) "2015-12-27 00:00"
    var_dump($en->isoWeekYear(2016)->format('Y-m-d H:i')); // string(16) "2017-01-01 00:00"
    var_dump($en->weekYear(2015)->format('Y-m-d H:i'));    // string(16) "2014-12-28 00:00"
    var_dump($en->isoWeekYear(2015)->format('Y-m-d H:i')); // string(16) "2015-12-27 00:00"
    
    // Note you still can force first day of week and year to use:
    $en = CarbonImmutable::parse('2017-01-01');
    
    echo "-----------
    ";
    
    var_dump($en->weeksInYear(null, 6, 12));               // int(52)
    var_dump($en->isoWeeksInYear(null, 6, 12));            // int(52)
    var_dump($en->week(null, 6, 12));                      // int(52)
    var_dump($en->isoWeek(null, 6, 12));                   // int(52)
    var_dump($en->weekYear(null, 6, 12));                  // int(2016)
    var_dump($en->isoWeekYear(null, 6, 12));               // int(2016)
    var_dump($en->weekYear(2016, 6, 12)->format('Y-m-d H:i')); // string(16) "2017-01-01 00:00"
    var_dump($en->isoWeekYear(2016, 6, 12)->format('Y-m-d H:i')); // string(16) "2017-01-01 00:00"
    // Then you can see using a method or its ISO variant return identical results
    

    流利的二传手

    您可以将任何基本单元称为设置器或某些分组的设置器:

    $dt = Carbon::now();
    
    $dt->year(1975)->month(5)->day(21)->hour(22)->minute(32)->second(5)->toDateTimeString();
    $dt->setDate(1975, 5, 21)->setTime(22, 32, 5)->toDateTimeString();
    $dt->setDate(1975, 5, 21)->setTimeFromTimeString('22:32:05')->toDateTimeString();
    $dt->setDateTime(1975, 5, 21, 22, 32, 5)->toDateTimeString();
    
    // All allow microsecond as optional argument
    $dt->year(1975)->month(5)->day(21)->hour(22)->minute(32)->second(5)->microsecond(123456)->toDateTimeString();
    $dt->setDate(1975, 5, 21)->setTime(22, 32, 5, 123456)->toDateTimeString();
    $dt->setDate(1975, 5, 21)->setTimeFromTimeString('22:32:05.123456')->toDateTimeString();
    $dt->setDateTime(1975, 5, 21, 22, 32, 5, 123456)->toDateTimeString();
    
    $dt->timestamp(169957925); // Note: timestamps are UTC but do not change the date timezone
    
    $dt->timezone('Europe/London')->tz('America/Toronto')->setTimezone('America/Vancouver');
    

    您还可以与其他DateTime / Carbon对象分别设置日期和时间:

    $source1 = new Carbon('2010-05-16 22:40:10.1');
    
    $dt = new Carbon('2001-01-01 01:01:01.2');
    $dt->setTimeFrom($source1);
    
    echo $dt; // 2001-01-01 22:40:10
    
    $source2 = new DateTime('2013-09-01 09:22:56.2');
    
    $dt->setDateFrom($source2);
    
    echo $dt; // 2013-09-01 22:40:10
    
    $dt->setDateTimeFrom($source2); // set date and time including microseconds
    // bot not settings as locale, timezone, options.
    

    IsSet

    PHP函数__isset()已实现。这样做是因为某些外部系统(例如Twig)在使用属性之前先对其进行了验证。这是使用isset()or empty() 方法完成的你可以阅读更多有关这些的PHP站点:__isset() isset()函数空() 

    var_dump(isset(Carbon::now()->iDoNotExist));       // bool(false)
    var_dump(isset(Carbon::now()->hour));              // bool(true)
    var_dump(empty(Carbon::now()->iDoNotExist));       // bool(true)
    var_dump(empty(Carbon::now()->year));              // bool(false)
    

    字符串格式

    所有可用toXXXString()方法都依赖于基类方法DateTime :: format()您会注意到__toString() 定义了该方法,方法允许在字符串上下文中使用Carbon实例时,将其打印为漂亮的日期时间字符串。

    $dt = Carbon::create(1975, 12, 25, 14, 15, 16);
    
    var_dump($dt->toDateTimeString() == $dt);          // bool(true) => uses __toString()
    echo $dt->toDateString();                          // 1975-12-25
    echo $dt->toFormattedDateString();                 // Dec 25, 1975
    echo $dt->toTimeString();                          // 14:15:16
    echo $dt->toDateTimeString();                      // 1975-12-25 14:15:16
    echo $dt->toDayDateTimeString();                   // Thu, Dec 25, 1975 2:15 PM
    
    // ... of course format() is still available
    echo $dt->format('l jS \of F Y h:i:s A');         // Thursday 25th of December 1975 02:15:16 PM
    
    // The reverse hasFormat method allows you to test if a string looks like a given format
    var_dump($dt->hasFormat('Thursday 25th December 1975 02:15:16 PM', 'l jS F Y h:i:s A')); // bool(true)
    

    您还可以设置在发生类型变戏法Y-m-d H:i:s使用的默认__toString()格式(默认为

    echo $dt;                                          // 1975-12-25 14:15:16
    echo "
    ";
    $dt->settings([
        'toStringFormat' => 'jS of F, Y g:i:s a',
    ]);
    echo $dt;                                          // 25th of December, 1975 2:15:16 pm
    
    // As any setting, you can get the current value for a given date using:
    var_dump($dt->getSettings());
    /*
    array(3) {
      ["toStringFormat"]=>
      string(20) "jS of F, Y g:i:s a"
      ["locale"]=>
      string(2) "en"
      ["timezone"]=>
      string(3) "UTC"
    }*/
    

    作为设置的一部分,'toStringFormat'也可以在工厂中使用。它也可能是一个闭包,因此您可以在字符串强制转换上运行任何代码。

    如果您使用Carbon 1或要将其作为默认格式全局应用,则可以使用:

    $dt = Carbon::create(1975, 12, 25, 14, 15, 16);
    Carbon::setToStringFormat('jS of F, Y g:i:s a');
    echo $dt;                                          // 25th of December, 1975 2:15:16 pm
    echo "
    ";
    Carbon::resetToStringFormat();
    echo $dt;                                          // 1975-12-25 14:15:16
    

    注意:有关本地化支持,请参见“ 本地化”部分。

    常用格式

    以下是DateTime类提供的常见格式的包装

    $dt = Carbon::createFromFormat('Y-m-d H:i:s.u', '2019-02-01 03:45:27.612584');
    
    // $dt->toAtomString() is the same as $dt->format(DateTime::ATOM);
    echo $dt->toAtomString();           // 2019-02-01T03:45:27+00:00
    echo $dt->toCookieString();         // Friday, 01-Feb-2019 03:45:27 UTC
    
    echo $dt->toIso8601String();        // 2019-02-01T03:45:27+00:00
    // Be aware we chose to use the full-extended format of the ISO 8601 norm
    // Natively, DateTime::ISO8601 format is not compatible with ISO-8601 as it
    // is explained here in the PHP documentation:
    // https://php.net/manual/class.datetime.php#datetime.constants.iso8601
    // We consider it as a PHP mistake and chose not to provide method for this
    // format, but you still can use it this way:
    echo $dt->format(DateTime::ISO8601); // 2019-02-01T03:45:27+0000
    
    echo $dt->toISOString();            // 2019-02-01T03:45:27.612584Z
    echo $dt->toJSON();                 // 2019-02-01T03:45:27.612584Z
    
    echo $dt->toIso8601ZuluString();    // 2019-02-01T03:45:27Z
    echo $dt->toDateTimeLocalString();  // 2019-02-01T03:45:27
    echo $dt->toRfc822String();         // Fri, 01 Feb 19 03:45:27 +0000
    echo $dt->toRfc850String();         // Friday, 01-Feb-19 03:45:27 UTC
    echo $dt->toRfc1036String();        // Fri, 01 Feb 19 03:45:27 +0000
    echo $dt->toRfc1123String();        // Fri, 01 Feb 2019 03:45:27 +0000
    echo $dt->toRfc2822String();        // Fri, 01 Feb 2019 03:45:27 +0000
    echo $dt->toRfc3339String();        // 2019-02-01T03:45:27+00:00
    echo $dt->toRfc7231String();        // Fri, 01 Feb 2019 03:45:27 GMT
    echo $dt->toRssString();            // Fri, 01 Feb 2019 03:45:27 +0000
    echo $dt->toW3cString();            // 2019-02-01T03:45:27+00:00
    

    转换次数

    $dt = Carbon::createFromFormat('Y-m-d H:i:s.u', '2019-02-01 03:45:27.612584');
    
    var_dump($dt->toArray());
    /*
    array(12) {
      ["year"]=>
      int(2019)
      ["month"]=>
      int(2)
      ["day"]=>
      int(1)
      ["dayOfWeek"]=>
      int(5)
      ["dayOfYear"]=>
      int(32)
      ["hour"]=>
      int(3)
      ["minute"]=>
      int(45)
      ["second"]=>
      int(27)
      ["micro"]=>
      int(612584)
      ["timestamp"]=>
      int(1548992727)
      ["formatted"]=>
      string(19) "2019-02-01 03:45:27"
      ["timezone"]=>
      object(CarbonCarbonTimeZone)#3438 (2) {
        ["timezone_type"]=>
        int(3)
        ["timezone"]=>
        string(3) "UTC"
      }
    }
    */
    
    var_dump($dt->toObject());
    /*
    object(stdClass)#3438 (12) {
      ["year"]=>
      int(2019)
      ["month"]=>
      int(2)
      ["day"]=>
      int(1)
      ["dayOfWeek"]=>
      int(5)
      ["dayOfYear"]=>
      int(32)
      ["hour"]=>
      int(3)
      ["minute"]=>
      int(45)
      ["second"]=>
      int(27)
      ["micro"]=>
      int(612584)
      ["timestamp"]=>
      int(1548992727)
      ["formatted"]=>
      string(19) "2019-02-01 03:45:27"
      ["timezone"]=>
      object(CarbonCarbonTimeZone)#3444 (2) {
        ["timezone_type"]=>
        int(3)
        ["timezone"]=>
        string(3) "UTC"
      }
    }
    */
    
    var_dump($dt->toDate()); // Same as $dt->toDateTime()
    /*
    object(DateTime)#3438 (3) {
      ["date"]=>
      string(26) "2019-02-01 03:45:27.612584"
      ["timezone_type"]=>
      int(3)
      ["timezone"]=>
      string(3) "UTC"
    }
    */
    
    // Note than both Carbon and CarbonImmutable can be cast
    // to both DateTime and DateTimeImmutable
    var_dump($dt->toDateTimeImmutable());
    /*
    object(DateTimeImmutable)#3438 (3) {
      ["date"]=>
      string(26) "2019-02-01 03:45:27.612584"
      ["timezone_type"]=>
      int(3)
      ["timezone"]=>
      string(3) "UTC"
    }
    */
    
    class MySubClass extends Carbon {}
    // MySubClass can be any class implementing CarbonInterface or a public static instance() method.
    
    $copy = $dt->cast(MySubClass::class);
    // Since 2.23.0, cast() can also take as argument any class that extend DateTime or DateTimeImmutable
    
    echo get_class($copy).': '.$copy; // Same as MySubClass::instance($dt)
    /*
    MySubClass: 2019-02-01 03:45:27
    */
    

    您可以使用该方法 根据给定的源实例(根据需要用作参考)carbonize将许多事物转换为Carbon实例。它返回一个新实例。

    $dt = Carbon::createFromFormat('Y-m-d H:i:s.u', '2019-02-01 03:45:27.612584', 'Europe/Paris');
    
    // Can take a date string and will apply the timezone from reference object
    var_dump($dt->carbonize('2019-03-21'));
    /*
    object(CarbonCarbon)#3444 (3) {
      ["date"]=>
      string(26) "2019-03-21 00:00:00.000000"
      ["timezone_type"]=>
      int(3)
      ["timezone"]=>
      string(12) "Europe/Paris"
    }
    */
    
    // If you pass a DatePeriod or CarbonPeriod, it will copy the period start
    var_dump($dt->carbonize(CarbonPeriod::create('2019-12-10', '2020-01-05')));
    /*
    object(CarbonCarbon)#3439 (3) {
      ["date"]=>
      string(26) "2019-12-10 00:00:00.000000"
      ["timezone_type"]=>
      int(3)
      ["timezone"]=>
      string(3) "UTC"
    }
    */
    
    // If you pass a DateInterval or CarbonInterval, it will add the interval to
    // the reference object
    var_dump($dt->carbonize(CarbonInterval::days(3)));
    /*
    object(CarbonCarbon)#3444 (3) {
      ["date"]=>
      string(26) "2019-02-04 03:45:27.612584"
      ["timezone_type"]=>
      int(3)
      ["timezone"]=>
      string(12) "Europe/Paris"
    }
    */
    

    比较方式

    通过以下功能可以进行简单比较。请记住,比较是在UTC时区进行的,因此情况并非总是如此。

    echo Carbon::now()->tzName;                        // UTC
    $first = Carbon::create(2012, 9, 5, 23, 26, 11);
    $second = Carbon::create(2012, 9, 5, 20, 26, 11, 'America/Vancouver');
    
    echo $first->toDateTimeString();                   // 2012-09-05 23:26:11
    echo $first->tzName;                               // UTC
    echo $second->toDateTimeString();                  // 2012-09-05 20:26:11
    echo $second->tzName;                              // America/Vancouver
    
    var_dump($first->equalTo($second));                // bool(false)
    // equalTo is also available on CarbonInterval and CarbonPeriod
    var_dump($first->notEqualTo($second));             // bool(true)
    // notEqualTo is also available on CarbonInterval and CarbonPeriod
    var_dump($first->greaterThan($second));            // bool(false)
    // greaterThan is also available on CarbonInterval
    var_dump($first->greaterThanOrEqualTo($second));   // bool(false)
    // greaterThanOrEqualTo is also available on CarbonInterval
    var_dump($first->lessThan($second));               // bool(true)
    // lessThan is also available on CarbonInterval
    var_dump($first->lessThanOrEqualTo($second));      // bool(true)
    // lessThanOrEqualTo is also available on CarbonInterval
    
    $first->setDateTime(2012, 1, 1, 0, 0, 0);
    $second->setDateTime(2012, 1, 1, 0, 0, 0);         // Remember tz is 'America/Vancouver'
    
    var_dump($first->equalTo($second));                // bool(false)
    var_dump($first->notEqualTo($second));             // bool(true)
    var_dump($first->greaterThan($second));            // bool(false)
    var_dump($first->greaterThanOrEqualTo($second));   // bool(false)
    var_dump($first->lessThan($second));               // bool(true)
    var_dump($first->lessThanOrEqualTo($second));      // bool(true)
    
    // All have short hand aliases and PHP equivalent code:
    
    var_dump($first->eq($second));                     // bool(false)
    var_dump($first->equalTo($second));                // bool(false)
    var_dump($first == $second);                       // bool(false)
    
    var_dump($first->ne($second));                     // bool(true)
    var_dump($first->notEqualTo($second));             // bool(true)
    var_dump($first != $second);                       // bool(true)
    
    var_dump($first->gt($second));                     // bool(false)
    var_dump($first->greaterThan($second));            // bool(false)
    var_dump($first->isAfter($second));                // bool(false)
    var_dump($first > $second);                        // bool(false)
    
    var_dump($first->gte($second));                    // bool(false)
    var_dump($first->greaterThanOrEqualTo($second));   // bool(false)
    var_dump($first >= $second);                       // bool(false)
    
    var_dump($first->lt($second));                     // bool(true)
    var_dump($first->lessThan($second));               // bool(true)
    var_dump($first->isBefore($second));               // bool(true)
    var_dump($first < $second);                        // bool(true)
    
    var_dump($first->lte($second));                    // bool(true)
    var_dump($first->lessThanOrEqualTo($second));      // bool(true)
    var_dump($first <= $second);                       // bool(true)
    

    这些方法使用PHP提供的自然比较,$date1 == $date2因此所有这些方法都将在PHP 7.1之前忽略毫秒/微秒,然后从7.1开始考虑它们。

    要确定当前实例是否在其他两个实例之间,可以使用适当命名的 between()方法(或isBetween()别名)。第三个参数指示是否应该进行等于比较。默认值是true,它确定其介于边界之间还是等于边界。

    $first = Carbon::create(2012, 9, 5, 1);
    $second = Carbon::create(2012, 9, 5, 5);
    var_dump(Carbon::create(2012, 9, 5, 3)->between($first, $second));          // bool(true)
    var_dump(Carbon::create(2012, 9, 5, 5)->between($first, $second));          // bool(true)
    var_dump(Carbon::create(2012, 9, 5, 5)->between($first, $second, false));   // bool(false)
    var_dump(Carbon::create(2012, 9, 5, 5)->isBetween($first, $second, false)); // bool(false)
    // Rather than passing false as a third argument, you can use betweenExcluded
    var_dump(Carbon::create(2012, 9, 5, 5)->betweenExcluded($first, $second));  // bool(false)
    // All those methods are also available on CarbonInterval
    

    哇!您忘记了min()和max()吗?不。适当命名的min()和 max()方法或minimum()maximum()别名也涵盖了这一点与往常一样,如果指定了null,则默认参数现在为。

    $dt1 = Carbon::createMidnightDate(2012, 1, 1);
    $dt2 = Carbon::createMidnightDate(2014, 1, 30);
    echo $dt1->min($dt2);                              // 2012-01-01 00:00:00
    echo $dt1->minimum($dt2);                          // 2012-01-01 00:00:00
    // Also works with string
    echo $dt1->minimum('2014-01-30');                  // 2012-01-01 00:00:00
    
    $dt1 = Carbon::createMidnightDate(2012, 1, 1);
    $dt2 = Carbon::createMidnightDate(2014, 1, 30);
    echo $dt1->max($dt2);                              // 2014-01-30 00:00:00
    echo $dt1->maximum($dt2);                          // 2014-01-30 00:00:00
    
    // now is the default param
    $dt1 = Carbon::createMidnightDate(2000, 1, 1);
    echo $dt1->max();                                  // 2020-02-14 16:05:24
    echo $dt1->maximum();                              // 2020-02-14 16:05:24
    
    // Remember min and max PHP native function work fine with dates too:
    echo max(Carbon::create('2002-03-15'), Carbon::create('2003-01-07'), Carbon::create('2002-08-25')); // 2003-01-07 00:00:00
    echo min(Carbon::create('2002-03-15'), Carbon::create('2003-01-07'), Carbon::create('2002-08-25')); // 2002-03-15 00:00:00
    // This way you can pass as many dates as you want and get no ambiguities about parameters order
    
    $dt1 = Carbon::createMidnightDate(2010, 4, 1);
    $dt2 = Carbon::createMidnightDate(2010, 3, 28);
    $dt3 = Carbon::createMidnightDate(2010, 4, 16);
    
    // returns the closest of two date (no matter before or after)
    echo $dt1->closest($dt2, $dt3);                    // 2010-03-28 00:00:00
    echo $dt2->closest($dt1, $dt3);                    // 2010-04-01 00:00:00
    echo $dt3->closest($dt2, $dt1);                    // 2010-04-01 00:00:00
    
    // returns the farthest of two date (no matter before or after)
    echo $dt1->farthest($dt2, $dt3);                   // 2010-04-16 00:00:00
    echo $dt2->farthest($dt1, $dt3);                   // 2010-04-16 00:00:00
    echo $dt3->farthest($dt2, $dt1);                   // 2010-03-28 00:00:00
    

    为了处理最常用的情况,有一些简单的辅助函数,希望它们的名称是显而易见的。对于now()以某种方式(例如isToday())进行比较的方法,now()会在与实例相同的时区中创建。

    $dt = Carbon::now();
    $dt2 = Carbon::createFromDate(1987, 4, 23);
    
    $dt->isSameAs('w', $dt2); // w is the date of the week, so this will return true if $dt and $dt2
                              // the same day of week (both monday or both sunday, etc.)
                              // you can use any format and combine as much as you want.
    $dt->isFuture();
    $dt->isPast();
    
    $dt->isSameYear($dt2);
    $dt->isCurrentYear();
    $dt->isNextYear();
    $dt->isLastYear();
    $dt->isLongYear(); // see https://en.wikipedia.org/wiki/ISO_8601#Week_dates
    $dt->isLeapYear();
    
    $dt->isSameQuarter($dt2); // same quarter of the same year of the given date
    $dt->isSameQuarter($dt2, false); // same quarter (3 months) no matter the year of the given date
    $dt->isCurrentQuarter();
    $dt->isNextQuarter(); // date is in the next quarter
    $dt->isLastQuarter(); // in previous quarter
    
    $dt->isSameMonth($dt2); // same month of the same year of the given date
    $dt->isSameMonth($dt2, false); // same month no matter the year of the given date
    $dt->isCurrentMonth();
    $dt->isNextMonth();
    $dt->isLastMonth();
    
    $dt->isWeekday();
    $dt->isWeekend();
    $dt->isMonday();
    $dt->isTuesday();
    $dt->isWednesday();
    $dt->isThursday();
    $dt->isFriday();
    $dt->isSaturday();
    $dt->isSunday();
    $dt->isDayOfWeek(Carbon::SATURDAY); // is a saturday
    $dt->isLastOfMonth(); // is the last day of the month
    
    $dt->is('Sunday');
    $dt->is('June');
    $dt->is('2019');
    $dt->is('12:23');
    $dt->is('2 June 2019');
    $dt->is('06-02');
    
    $dt->isSameDay($dt2); // Same day of same month of same year
    $dt->isCurrentDay();
    $dt->isYesterday();
    $dt->isToday();
    $dt->isTomorrow();
    $dt->isNextWeek();
    $dt->isLastWeek();
    
    $dt->isSameHour($dt2);
    $dt->isCurrentHour();
    $dt->isSameMinute($dt2);
    $dt->isCurrentMinute();
    $dt->isSameSecond($dt2);
    $dt->isCurrentSecond();
    
    $dt->isStartOfDay(); // check if hour is 00:00:00
    $dt->isMidnight(); // check if hour is 00:00:00 (isStartOfDay alias)
    $dt->isEndOfDay(); // check if hour is 23:59:59
    $dt->isMidday(); // check if hour is 12:00:00 (or other midday hour set with Carbon::setMidDayAt())
    $born = Carbon::createFromDate(1987, 4, 23);
    $noCake = Carbon::createFromDate(2014, 9, 26);
    $yesCake = Carbon::createFromDate(2014, 4, 23);
    $overTheHill = Carbon::now()->subYears(50);
    var_dump($born->isBirthday($noCake));              // bool(false)
    var_dump($born->isBirthday($yesCake));             // bool(true)
    var_dump($overTheHill->isBirthday());              // bool(true) -> default compare it to today!
    
    // isCurrentX, isSameX, isNextX and isLastX are available for each unit
    

    加减

    默认的DateTime提供了几种不同的方法来轻松地增加和减少时间。还有 modify()add()sub()modify()需要一个神奇的 日期/时间格式字符串'last day of next month',它解析并同时适用修改add()sub()期望DateInterval的实例,这不是那么明显,(例如,new DateInterval('P6YT5M')将意味着6年5分钟)。希望在几个星期没看到代码后,使用这些流利的函数会更清晰,更容易阅读。但是,我当然不会让您选择,因为基类函数仍然可用。

    $dt = Carbon::create(2012, 1, 31, 0);
    
    echo $dt->toDateTimeString();            // 2012-01-31 00:00:00
    
    echo $dt->addCenturies(5);               // 2512-01-31 00:00:00
    echo $dt->addCentury();                  // 2612-01-31 00:00:00
    echo $dt->subCentury();                  // 2512-01-31 00:00:00
    echo $dt->subCenturies(5);               // 2012-01-31 00:00:00
    
    echo $dt->addYears(5);                   // 2017-01-31 00:00:00
    echo $dt->addYear();                     // 2018-01-31 00:00:00
    echo $dt->subYear();                     // 2017-01-31 00:00:00
    echo $dt->subYears(5);                   // 2012-01-31 00:00:00
    
    echo $dt->addQuarters(2);                // 2012-07-31 00:00:00
    echo $dt->addQuarter();                  // 2012-10-31 00:00:00
    echo $dt->subQuarter();                  // 2012-07-31 00:00:00
    echo $dt->subQuarters(2);                // 2012-01-31 00:00:00
    
    echo $dt->addMonths(60);                 // 2017-01-31 00:00:00
    echo $dt->addMonth();                    // 2017-03-03 00:00:00 equivalent of $dt->month($dt->month + 1); so it wraps
    echo $dt->subMonth();                    // 2017-02-03 00:00:00
    echo $dt->subMonths(60);                 // 2012-02-03 00:00:00
    
    echo $dt->addDays(29);                   // 2012-03-03 00:00:00
    echo $dt->addDay();                      // 2012-03-04 00:00:00
    echo $dt->subDay();                      // 2012-03-03 00:00:00
    echo $dt->subDays(29);                   // 2012-02-03 00:00:00
    
    echo $dt->addWeekdays(4);                // 2012-02-09 00:00:00
    echo $dt->addWeekday();                  // 2012-02-10 00:00:00
    echo $dt->subWeekday();                  // 2012-02-09 00:00:00
    echo $dt->subWeekdays(4);                // 2012-02-03 00:00:00
    
    echo $dt->addWeeks(3);                   // 2012-02-24 00:00:00
    echo $dt->addWeek();                     // 2012-03-02 00:00:00
    echo $dt->subWeek();                     // 2012-02-24 00:00:00
    echo $dt->subWeeks(3);                   // 2012-02-03 00:00:00
    
    echo $dt->addHours(24);                  // 2012-02-04 00:00:00
    echo $dt->addHour();                     // 2012-02-04 01:00:00
    echo $dt->subHour();                     // 2012-02-04 00:00:00
    echo $dt->subHours(24);                  // 2012-02-03 00:00:00
    
    echo $dt->addMinutes(61);                // 2012-02-03 01:01:00
    echo $dt->addMinute();                   // 2012-02-03 01:02:00
    echo $dt->subMinute();                   // 2012-02-03 01:01:00
    echo $dt->subMinutes(61);                // 2012-02-03 00:00:00
    
    echo $dt->addSeconds(61);                // 2012-02-03 00:01:01
    echo $dt->addSecond();                   // 2012-02-03 00:01:02
    echo $dt->subSecond();                   // 2012-02-03 00:01:01
    echo $dt->subSeconds(61);                // 2012-02-03 00:00:00
    
    echo $dt->addMilliseconds(61);           // 2012-02-03 00:00:00
    echo $dt->addMillisecond();              // 2012-02-03 00:00:00
    echo $dt->subMillisecond();              // 2012-02-03 00:00:00
    echo $dt->subMillisecond(61);            // 2012-02-03 00:00:00
    
    echo $dt->addMicroseconds(61);           // 2012-02-03 00:00:00
    echo $dt->addMicrosecond();              // 2012-02-03 00:00:00
    echo $dt->subMicrosecond();              // 2012-02-03 00:00:00
    echo $dt->subMicroseconds(61);           // 2012-02-03 00:00:00
    
    // and so on for any unit: millenium, century, decade, year, quarter, month, week, day, weekday,
    // hour, minute, second, microsecond.
    
    // Generic methods add/sub (or subtract alias) can take many different arguments:
    echo $dt->add(61, 'seconds');                      // 2012-02-03 00:01:01
    echo $dt->sub('1 day');                            // 2012-02-02 00:01:01
    echo $dt->add(CarbonInterval::months(2));          // 2012-04-02 00:01:01
    echo $dt->subtract(new DateInterval('PT1H'));      // 2012-04-01 23:01:01
    

    为了好玩,您还可以将负值传递给addXXX(),实际上subXXX()就是这样实现的。

    PS不要担心,如果您忘记和使用,addDay(5)或者subYear(3),我有您的支持;)

    默认情况下,Carbon依赖于基础父类PHP DateTime行为。结果,增加或减少月份可能会溢出,例如:

    $dt = CarbonImmutable::create(2017, 1, 31, 0);
    
    echo $dt->addMonth();                    // 2017-03-03 00:00:00
    echo "
    ";
    echo $dt->subMonths(2);                  // 2016-12-01 00:00:00
    

    从Carbon 2开始,您可以为每个实例设置本地溢出行为:

    $dt = CarbonImmutable::create(2017, 1, 31, 0);
    $dt->settings([
        'monthOverflow' => false,
    ]);
    
    echo $dt->addMonth();                    // 2017-02-28 00:00:00
    echo "
    ";
    echo $dt->subMonths(2);                  // 2016-11-30 00:00:00
    

    这将应用于方法addMonth(s)subMonth(s)add($x, 'month'), sub($x, 'month')和等效季度方法。但是它不适用于间隔对象或字符串,例如add(CarbonInterval::month())add('1 month')

    存在静态助手,但已弃用。如果您确定需要应用全局设置或使用Carbon的版本1,请查看“溢出静态助手”部分

    你也可以使用->addMonthsNoOverflow->subMonthsNoOverflow, ->addMonthsWithOverflow->subMonthsWithOverflow (或奇异的方法,没有s到“月”),明确添加/带或不带溢出子月,无论现在的模式与同为任何更大的单元(季,年,十年,百年,千年)。

    $dt = Carbon::createMidnightDate(2017, 1, 31)->settings([
        'monthOverflow' => false,
    ]);
    
    echo $dt->copy()->addMonthWithOverflow();          // 2017-03-03 00:00:00
    // plural addMonthsWithOverflow() method is also available
    echo $dt->copy()->subMonthsWithOverflow(2);        // 2016-12-01 00:00:00
    // singular subMonthWithOverflow() method is also available
    echo $dt->copy()->addMonthNoOverflow();            // 2017-02-28 00:00:00
    // plural addMonthsNoOverflow() method is also available
    echo $dt->copy()->subMonthsNoOverflow(2);          // 2016-11-30 00:00:00
    // singular subMonthNoOverflow() method is also available
    
    echo $dt->copy()->addMonth();                      // 2017-02-28 00:00:00
    echo $dt->copy()->subMonths(2);                    // 2016-11-30 00:00:00
    
    $dt = Carbon::createMidnightDate(2017, 1, 31)->settings([
        'monthOverflow' => true,
    ]);
    
    echo $dt->copy()->addMonthWithOverflow();          // 2017-03-03 00:00:00
    echo $dt->copy()->subMonthsWithOverflow(2);        // 2016-12-01 00:00:00
    echo $dt->copy()->addMonthNoOverflow();            // 2017-02-28 00:00:00
    echo $dt->copy()->subMonthsNoOverflow(2);          // 2016-11-30 00:00:00
    
    echo $dt->copy()->addMonth();                      // 2017-03-03 00:00:00
    echo $dt->copy()->subMonths(2);                    // 2016-12-01 00:00:00
    

    多年以来一直可用。

    使用未知输入时,您还可以控制任何单元的溢出:

    $dt = CarbonImmutable::create(2018, 8, 30, 12, 00, 00);
    
    // Add hours without overflowing day
    echo $dt->addUnitNoOverflow('hour', 7, 'day');     // 2018-08-30 19:00:00
    echo "
    ";
    echo $dt->addUnitNoOverflow('hour', 14, 'day');    // 2018-08-30 23:59:59
    echo "
    ";
    echo $dt->addUnitNoOverflow('hour', 48, 'day');    // 2018-08-30 23:59:59
    
    echo "
    -------
    ";
    
    // Substract hours without overflowing day
    echo $dt->subUnitNoOverflow('hour', 7, 'day');     // 2018-08-30 05:00:00
    echo "
    ";
    echo $dt->subUnitNoOverflow('hour', 14, 'day');    // 2018-08-30 00:00:00
    echo "
    ";
    echo $dt->subUnitNoOverflow('hour', 48, 'day');    // 2018-08-30 00:00:00
    
    echo "
    -------
    ";
    
    // Set hours without overflowing day
    echo $dt->setUnitNoOverflow('hour', -7, 'day');    // 2018-08-30 00:00:00
    echo "
    ";
    echo $dt->setUnitNoOverflow('hour', 14, 'day');    // 2018-08-30 14:00:00
    echo "
    ";
    echo $dt->setUnitNoOverflow('hour', 25, 'day');    // 2018-08-30 23:59:59
    
    echo "
    -------
    ";
    
    // Adding hours without overflowing month
    echo $dt->addUnitNoOverflow('hour', 7, 'month');   // 2018-08-30 19:00:00
    echo "
    ";
    echo $dt->addUnitNoOverflow('hour', 14, 'month');  // 2018-08-31 02:00:00
    echo "
    ";
    echo $dt->addUnitNoOverflow('hour', 48, 'month');  // 2018-08-31 23:59:59
    

    任何可修改的单位都可以作为这些方法的参数传递:

    $units = [];
    foreach (['millennium', 'century', 'decade', 'year', 'quarter', 'month', 'week', 'weekday', 'day', 'hour', 'minute', 'second', 'millisecond', 'microsecond'] as $unit) {
        $units[$unit] = Carbon::isModifiableUnit($unit);
    }
    
    echo json_encode($units, JSON_PRETTY_PRINT);
    /* {
        "millennium": true,
        "century": true,
        "decade": true,
        "year": true,
        "quarter": true,
        "month": true,
        "week": true,
        "weekday": true,
        "day": true,
        "hour": true,
        "minute": true,
        "second": true,
        "millisecond": true,
        "microsecond": true
    } */
    

    区别

    随着Carbon扩展,DateTime它继承了其方法,例如以diff()第二个date对象作为参数并返回一个DateInterval实例。

    我们还提供diffAsCarbonInterval()类似行为,diff()但返回一个CarbonInterval 实例。有关更多信息,参见CarbonInterval章节Carbon也为每个单元添加了diff方法,例如diffInYears()diffInMonths()等等。diffAsCarbonInterval() 和diffIn*()floatDiffIn*()方法都可以使用2个可选参数:要与之进行比较的日期(如果缺失,则改为使用它),以及一个绝对布尔值选项(true默认情况下),该布尔值选项使该方法返回绝对值,而不管哪个日期大于另一个日期。 。如果设置为false,当调用该方法的实例大于比较日期(第一个参数或现在)时,它将返回负值。注意diff()原型是不同的:其第一个参数(日期)是必需的,其第二个参数(绝对选项)默认为false

    这些函数总是返回以指定的请求时间表示总差这与基类diff()函数不同,在基类函数中,DateInterval实例将返回122秒的间隔,分别为2分2秒diffInMinutes()函数将简单地返回2而diffInSeconds()返回122。所有值都将被截断而不是四舍五入。下面的每个函数都有一个默认的第一个参数,即要比较的Carbon实例;如果要使用,则为null now()第二个参数同样是可选的,它指示您是否希望返回值是绝对值或相对值,可能会有一个-(负)符号(如果传入的日期小于当前实例)。这将默认为true,返回绝对值。

    echo Carbon::now('America/Vancouver')->diffInSeconds(Carbon::now('Europe/London')); // 0
    
    $dtOttawa = Carbon::createMidnightDate(2000, 1, 1, 'America/Toronto');
    $dtVancouver = Carbon::createMidnightDate(2000, 1, 1, 'America/Vancouver');
    echo $dtOttawa->diffInHours($dtVancouver);                             // 3
    echo $dtVancouver->diffInHours($dtOttawa);                             // 3
    
    echo $dtOttawa->diffInHours($dtVancouver, false);                      // 3
    echo $dtVancouver->diffInHours($dtOttawa, false);                      // -3
    
    $dt = Carbon::createMidnightDate(2012, 1, 31);
    echo $dt->diffInDays($dt->copy()->addMonth());                         // 31
    echo $dt->diffInDays($dt->copy()->subMonth(), false);                  // -31
    
    $dt = Carbon::createMidnightDate(2012, 4, 30);
    echo $dt->diffInDays($dt->copy()->addMonth());                         // 30
    echo $dt->diffInDays($dt->copy()->addWeek());                          // 7
    
    $dt = Carbon::createMidnightDate(2012, 1, 1);
    echo $dt->diffInMinutes($dt->copy()->addSeconds(59));                  // 0
    echo $dt->diffInMinutes($dt->copy()->addSeconds(60));                  // 1
    echo $dt->diffInMinutes($dt->copy()->addSeconds(119));                 // 1
    echo $dt->diffInMinutes($dt->copy()->addSeconds(120));                 // 2
    
    echo $dt->addSeconds(120)->secondsSinceMidnight();                     // 120
    
    $interval = $dt->diffAsCarbonInterval($dt->copy()->subYears(3), false);
    // diffAsCarbonInterval use same arguments as diff($other, $absolute)
    // (native method from DateTime)
    // except $absolute is true by default for diffAsCarbonInterval and false for diff
    // $absolute parameter allow to get signed value if false, or always positive if true
    echo ($interval->invert ? 'minus ' : 'plus ') . $interval->years;      // minus 3
    

    这些方法的结果被截断。这意味着diffInMinutes对于包含1和排除2之间的任何差值,将返回1。但是相同的方法可用于浮点结果:

    echo Carbon::parse('06:01:23.252987')->floatDiffInSeconds('06:02:34.321450');    // 71.068463
    echo Carbon::parse('06:01:23')->floatDiffInMinutes('06:02:34');                  // 1.1833333333333
    echo Carbon::parse('06:01:23')->floatDiffInHours('06:02:34');                    // 0.019722222222222
    // Those methods are absolute by default but can return negative value
    // setting the second argument to false when start date is greater than end date
    echo Carbon::parse('12:01:23')->floatDiffInHours('06:02:34', false);             // -5.9802777777778
    echo Carbon::parse('2000-01-01 12:00')->floatDiffInDays('2000-02-11 06:00');     // 40.75
    echo Carbon::parse('2000-01-15 12:00')->floatDiffInMonths('2000-02-24 06:00');   // 1.301724137931
    // floatDiffInMonths count as many full months as possible from the start date, then consider the number
    // of days in the months for ending chunks to reach the end date
    // So the following result (ending with 24 march is different from previous one with 24 february):
    echo Carbon::parse('2000-02-15 12:00')->floatDiffInMonths('2000-03-24 06:00');   // 1.2822580645161
    // floatDiffInYears apply the same logic (and so different results with leap years)
    echo Carbon::parse('2000-02-15 12:00')->floatDiffInYears('2010-03-24 06:00');    // 10.100684931507
    

    关于夏令时(DST)的重要说明,默认情况下,PHP DateTime不考虑DST,这意味着例如,像2014年3月30日在伦敦这样仅23小时的一天将被计为24小时。

    $date = new DateTime('2014-03-30 00:00:00', new DateTimeZone('Europe/London')); // DST off
    echo $date->modify('+25 hours')->format('H:i');                   // 01:00 (DST on, 24 hours only have been actually added)
    

    碳也遵循此行为,持续增加/减少/差异秒/分钟/小时。但是我们提供了 使用时间戳实际时间中工作的方法

    $date = new Carbon('2014-03-30 00:00:00', 'Europe/London');       // DST off
    echo $date->addRealHours(25)->format('H:i');                      // 02:00 (DST on)
    echo $date->diffInRealHours('2014-03-30 00:00:00');               // 25
    echo $date->diffInHours('2014-03-30 00:00:00');                   // 26
    echo $date->diffInRealMinutes('2014-03-30 00:00:00');             // 1500
    echo $date->diffInMinutes('2014-03-30 00:00:00');                 // 1560
    echo $date->diffInRealSeconds('2014-03-30 00:00:00');             // 90000
    echo $date->diffInSeconds('2014-03-30 00:00:00');                 // 93600
    echo $date->diffInRealMilliseconds('2014-03-30 00:00:00');        // 90000000
    echo $date->diffInMilliseconds('2014-03-30 00:00:00');            // 93600000
    echo $date->diffInRealMicroseconds('2014-03-30 00:00:00');        // 90000000000
    echo $date->diffInMicroseconds('2014-03-30 00:00:00');            // 93600000000
    echo $date->subRealHours(25)->format('H:i');                      // 00:00 (DST off)
    
    // with float diff:
    $date = new Carbon('2019-10-27 00:00:00', 'Europe/Paris');       
    echo $date->floatDiffInRealHours('2019-10-28 12:30:00');          // 37.5
    echo $date->floatDiffInHours('2019-10-28 12:30:00');              // 36.5
    echo $date->floatDiffInRealMinutes('2019-10-28 12:00:30');        // 2220.5
    echo $date->floatDiffInMinutes('2019-10-28 12:00:30');            // 2160.5
    echo $date->floatDiffInRealSeconds('2019-10-28 12:00:00.5');      // 133200.5
    echo $date->floatDiffInSeconds('2019-10-28 12:00:00.5');          // 129600.5
    // above day unit, "real" will affect the decimal part based on hours and smaller units
    echo $date->floatDiffInRealDays('2019-10-28 12:30:00');           // 1.5625
    echo $date->floatDiffInDays('2019-10-28 12:30:00');               // 1.5208333333333
    echo $date->floatDiffInRealMonths('2019-10-28 12:30:00');         // 0.050403225806452
    echo $date->floatDiffInMonths('2019-10-28 12:30:00');             // 0.049059139784946
    echo $date->floatDiffInRealYears('2019-10-28 12:30:00');          // 0.0042808219178082
    echo $date->floatDiffInYears('2019-10-28 12:30:00');              // 0.0041666666666667
    

    用同样的方法,你可以使用addRealX()subRealX()任何设备上。

    还具有特殊的过滤功能diffInDaysFiltered()diffInHoursFiltered()和 diffFiltered(),以帮助您按天,小时或自定义间隔过滤差异。例如,计算两个实例之间的周末天数:

    $dt = Carbon::create(2014, 1, 1);
    $dt2 = Carbon::create(2014, 12, 31);
    $daysForExtraCoding = $dt->diffInDaysFiltered(function(Carbon $date) {
       return $date->isWeekend();
    }, $dt2);
    
    echo $daysForExtraCoding;      // 104
    
    $dt = Carbon::create(2014, 1, 1)->endOfDay();
    $dt2 = $dt->copy()->startOfDay();
    $littleHandRotations = $dt->diffFiltered(CarbonInterval::minute(), function(Carbon $date) {
       return $date->minute === 0;
    }, $dt2, true); // true as last parameter returns absolute value
    
    echo $littleHandRotations;     // 24
    
    $date = Carbon::now()->addSeconds(3666);
    
    echo $date->diffInSeconds();                       // 3665
    echo $date->diffInMinutes();                       // 61
    echo $date->diffInHours();                         // 1
    echo $date->diffInDays();                          // 0
    
    $date = Carbon::create(2016, 1, 5, 22, 40, 32);
    
    echo $date->secondsSinceMidnight();                // 81632
    echo $date->secondsUntilEndOfDay();                // 4767
    
    $date1 = Carbon::createMidnightDate(2016, 1, 5);
    $date2 = Carbon::createMidnightDate(2017, 3, 15);
    
    echo $date1->diffInDays($date2);                   // 435
    echo $date1->diffInWeekdays($date2);               // 311
    echo $date1->diffInWeekendDays($date2);            // 124
    echo $date1->diffInWeeks($date2);                  // 62
    echo $date1->diffInMonths($date2);                 // 14
    echo $date1->diffInYears($date2);                  // 1
    

    所有diffIn * Filtered方法都将1个可调用过滤器作为必需参数,将date对象作为可选的第二个参数(如果缺少),现在使用。您也可以将true作为第三个参数传递以获得绝对值。

    要了解周/周末的高级信息,请使用以下工具:

    echo implode(', ', Carbon::getDays());                       // Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday
    
    $saturday = new Carbon('first saturday of 2019');
    $sunday = new Carbon('first sunday of 2019');
    $monday = new Carbon('first monday of 2019');
    
    echo implode(', ', Carbon::getWeekendDays());                // 6, 0
    var_dump($saturday->isWeekend());                            // bool(true)
    var_dump($sunday->isWeekend());                              // bool(true)
    var_dump($monday->isWeekend());                              // bool(false)
    
    Carbon::setWeekendDays([
        Carbon::SUNDAY,
        Carbon::MONDAY,
    ]);
    
    echo implode(', ', Carbon::getWeekendDays());                // 0, 1
    var_dump($saturday->isWeekend());                            // bool(false)
    var_dump($sunday->isWeekend());                              // bool(true)
    var_dump($monday->isWeekend());                              // bool(true)
    
    Carbon::setWeekendDays([
        Carbon::SATURDAY,
        Carbon::SUNDAY,
    ]);
    // weekend days and start/end of week or not linked
    Carbon::setWeekStartsAt(Carbon::FRIDAY);
    Carbon::setWeekEndsAt(Carbon::WEDNESDAY); // and it does not need neither to precede the start
    
    var_dump(Carbon::getWeekStartsAt() === Carbon::FRIDAY);      // bool(true)
    var_dump(Carbon::getWeekEndsAt() === Carbon::WEDNESDAY);     // bool(true)
    echo $saturday->copy()->startOfWeek()->toRfc850String();     // Friday, 31-Jan-20 00:00:00 UTC
    echo $saturday->copy()->endOfWeek()->toRfc850String();       // Wednesday, 05-Feb-20 23:59:59 UTC
    
    // Be very careful with those global setters, remember, some other
    // code or third-party library in your app may expect initial weekend
    // days to work properly.
    Carbon::setWeekStartsAt(Carbon::MONDAY);
    Carbon::setWeekEndsAt(Carbon::SUNDAY);
    
    echo $saturday->copy()->startOfWeek()->toRfc850String();     // Monday, 27-Jan-20 00:00:00 UTC
    echo $saturday->copy()->endOfWeek()->toRfc850String();       // Sunday, 02-Feb-20 23:59:59 UTC
    

    人类的差异

    1 month ago与30天前相比,人类更容易阅读这是大多数日期库中常见的功能,因此我想也将其添加到此处。该函数的唯一参数是要比较的另一个Carbon实例,当然,now()如果未指定,则默认为默认值

    此方法将在相对于实例和传入实例的差值之后添加一个短语。有4种可能性:

    • 将过去的值与现在的默认值进行比较时:
      • 1小时前
      • 5个月前
    • 将将来的值与现在的默认值进行比较时:
      • 从现在开始1小时
      • 从现在起5个月
    • 将过去的值与另一个值进行比较时:
      • 1小时前
      • 5个月前
    • 将将来的值与另一个值进行比较时:
      • 1小时后
      • 5个月后

    您也可以通过CarbonInterface::DIFF_ABSOLUTE作为第二个参数,以去除改性剂从现在开始,等: diffForHumans($other, CarbonInterface::DIFF_ABSOLUTE)CarbonInterface::DIFF_RELATIVE_TO_NOW 得到改性从现在开始CarbonInterface::DIFF_RELATIVE_TO_OTHER得到改性剂 之前之后,或者CarbonInterface::DIFF_RELATIVE_AUTO(默认模式),以获得修饰或者 / 从现在开始,如果2第二个参数是空值或 / 如果没有。

    true如果使用的语言环境可用,则可以作为第三个参数传递以使用简短语法diffForHumans($other, CarbonInterface::DIFF_RELATIVE_AUTO, true)

    可在1和6之间传递的数作为第四参数来获取在多个部分中的差异(更精确的差异): diffForHumans($other, CarbonInterface::DIFF_RELATIVE_AUTO, false, 4)

    $other实例可以是DateTime,Carbon实例或实现DateTimeInterface的任何对象,如果传递了字符串,则将对其进行解析以获取Carbon实例;如果null传递了字符串Carbon::now()则将使用它。

    为避免过多的参数并混合使用顺序,可以使用详细方法:

    • shortAbsoluteDiffForHumans(DateTimeInterface | null $other = null, int $parts = 1)
    • longAbsoluteDiffForHumans(DateTimeInterface | null $other = null, int $parts = 1)
    • shortRelativeDiffForHumans(DateTimeInterface | null $other = null, int $parts = 1)
    • longRelativeDiffForHumans(DateTimeInterface | null $other = null, int $parts = 1)
    • shortRelativeToNowDiffForHumans(DateTimeInterface | null $other = null, int $parts = 1)
    • longRelativeToNowDiffForHumans(DateTimeInterface | null $other = null, int $parts = 1)
    • shortRelativeToOtherDiffForHumans(DateTimeInterface | null $other = null, int $parts = 1)
    • longRelativeToOtherDiffForHumans(DateTimeInterface | null $other = null, int $parts = 1)

    PS:$other$parts参数可以根据需要交换。

    // The most typical usage is for comments
    // The instance is the date the comment was created and its being compared to default now()
    echo Carbon::now()->subDays(5)->diffForHumans();               // 5 days ago
    
    echo Carbon::now()->diffForHumans(Carbon::now()->subYear());   // 11 months after
    
    $dt = Carbon::createFromDate(2011, 8, 1);
    
    echo $dt->diffForHumans($dt->copy()->addMonth());                        // 1 month before
    echo $dt->diffForHumans($dt->copy()->subMonth());                        // 1 month after
    
    echo Carbon::now()->addSeconds(5)->diffForHumans();                      // 4 seconds from now
    
    echo Carbon::now()->subDays(24)->diffForHumans();                        // 3 weeks ago
    echo Carbon::now()->subDays(24)->longAbsoluteDiffForHumans();            // 3 weeks
    
    echo Carbon::parse('2019-08-03')->diffForHumans('2019-08-13');           // 1 week before
    echo Carbon::parse('2000-01-01 00:50:32')->diffForHumans('@946684800');  // 50 minutes after
    
    echo Carbon::create(2018, 2, 26, 4, 29, 43)->longRelativeDiffForHumans(Carbon::create(2016, 6, 21, 0, 0, 0), 6); // 1 year 8 months 5 days 4 hours 29 minutes 43 seconds after
    

    您还可以$date->locale('fr')在diffForHumans()调用之前使用来更改字符串的语言环境有关更多详细信息,请参见本地化部分。

    由于2.9.0 diffForHumans()参数可以作为数组传递:

    echo Carbon::now()->diffForHumans(['options' => 0]); // 0 seconds ago
    echo "
    ";
    // default options:
    echo Carbon::now()->diffForHumans(['options' => Carbon::NO_ZERO_DIFF]); // 1 second ago
    echo "
    ";
    echo Carbon::now()->diffForHumans(['options' => Carbon::JUST_NOW]); // just now
    echo "
    ";
    echo Carbon::now()->subDay()->diffForHumans(['options' => 0]); // 1 day ago
    echo "
    ";
    echo Carbon::now()->subDay()->diffForHumans(['options' => Carbon::ONE_DAY_WORDS]); // yesterday
    echo "
    ";
    echo Carbon::now()->subDays(2)->diffForHumans(['options' => 0]); // 2 days ago
    echo "
    ";
    echo Carbon::now()->subDays(2)->diffForHumans(['options' => Carbon::TWO_DAY_WORDS]); // before yesterday
    echo "
    ";
    
    // Options can be combined with pipes
    $now = Carbon::now();
    
    echo $now->diffForHumans(['options' => Carbon::JUST_NOW | Carbon::ONE_DAY_WORDS | Carbon::TWO_DAY_WORDS]); // just now
    echo "
    ";
    
    // Reference date for differences is `now` but you can use any other date (string, DateTime or Carbon instance):
    $yesterday = $now->copy()->subDay();
    echo $now->diffForHumans($yesterday); // 1 day after
    echo "
    ";
    // By default differences methods produce "ago"/"from now" syntax using default reference (now),
    // and "after"/"before" with other references
    // But you can customize the syntax:
    echo $now->diffForHumans($yesterday, ['syntax' => CarbonInterface::DIFF_RELATIVE_TO_NOW]); // 1 day from now
    echo "
    ";
    echo $now->diffForHumans($yesterday, ['syntax' => 0]); // 1 day after
    echo "
    ";
    echo $yesterday->diffForHumans(['syntax' => CarbonInterface::DIFF_ABSOLUTE]); // 1 day
    echo "
    ";
    // Combined with options:
    echo $now->diffForHumans($yesterday, [
        'syntax' => CarbonInterface::DIFF_RELATIVE_TO_NOW,
        'options' => Carbon::JUST_NOW | Carbon::ONE_DAY_WORDS | Carbon::TWO_DAY_WORDS,
    ]); // tomorrow
    echo "
    ";
    
    // Other parameters:
    echo $now->copy()->subHours(5)->subMinutes(30)->subSeconds(10)->diffForHumans([
        'parts' => 2,
    ]); // 5 hours 30 minutes ago
    echo "
    ";
    echo $now->copy()->subHours(5)->subMinutes(30)->subSeconds(10)->diffForHumans([
        'parts' => 3, // Use -1 or INF for no limit
    ]); // 5 hours 30 minutes 10 seconds ago
    echo "
    ";
    echo $now->copy()->subHours(5)->subMinutes(30)->subSeconds(10)->diffForHumans([
        'parts' => 3,
        'join' => ', ', // join with commas
    ]); // 5 hours, 30 minutes, 10 seconds ago
    echo "
    ";
    echo $now->copy()->subHours(5)->subMinutes(30)->subSeconds(10)->diffForHumans([
        'parts' => 3,
        'join' => true, // join with natural syntax as per current locale
    ]); // 5 hours, 30 minutes and 10 seconds ago
    echo "
    ";
    echo $now->copy()->subHours(5)->subMinutes(30)->subSeconds(10)->locale('fr')->diffForHumans([
        'parts' => 3,
        'join' => true, // join with natural syntax as per current locale
    ]); // il y a 5 heures, 30 minutes et 10 secondes
    echo "
    ";
    echo $now->copy()->subHours(5)->subMinutes(30)->subSeconds(10)->diffForHumans([
        'parts' => 3,
        'short' => true, // short syntax as per current locale
    ]); // 5h 30m 10s ago
    // 'aUnit' option added in 2.13.0 allows you to prefer "a day", "an hour", etc. over "1 day", "1 hour"
    // for singular values when it's available in the current locale
    echo $now->copy()->subHour()->diffForHumans([
        'aUnit' => true,
    ]); // an hour ago
    
    // Before 2.9.0, you need to pass parameters as ordered parameters:
    // ->diffForHumans($other, $syntax, $short, $parts, $options)
    // and 'join' was not supported
    

    如果参数被省略或设置为null,则仅Carbon::NO_ZERO_DIFF启用。可用的选项有:

    • Carbon::ROUNDCarbon::CEILCarbon::FLOOR(默认无):仅3中的一个可在同一时间使用(其他被忽略),它需要'parts'进行设置。默认情况下,一旦差异按'parts'要求进行设置,然后忽略所有剩余单位。
      • 如果Carbon::ROUND启用,将对剩余的单位求和,并且如果它们 > = diff的最后一个单位的0.5,则此单位将舍入为上限值。
      • 如果Carbon::CEIL启用,则将对剩余的单位求和,并且如果它们 大于 diff的最后一个单位的0,则此单位将四舍五入为最大值。
      • 如果Carbon::FLOOR启用,则最后一个差异单元将四舍五入。它与默认行为没有什么区别,diffForHumans()因为该间隔不会溢出,但与CarbonInterval::forHumans()(和可能长达60分钟或更长,24小时或更长时间的未经检查的间隔)一起使用时,可能需要使用此选项 例如: CarbonInterval::make('1 hour and 67 minutes')->forHumans(['parts' => 1])return "1 hour"而 CarbonInterval::make('1 hour and 67 minutes')->forHumans(['parts' => 1, 'options' => Carbon::FLOOR]) return "2 hours"
    • Carbon::NO_ZERO_DIFF (默认启用):将空diff变为1秒
    • Carbon::JUST_NOW 默认情况下处于禁用状态):将diff从现在到现在变成“ just now”
    • Carbon::ONE_DAY_WORDS (默认情况下处于禁用状态):将“从现在/前1天”更改为“昨天/明天”
    • Carbon::TWO_DAY_WORDS (默认情况下处于禁用状态):将“从现在/前2天”更改为“昨天/之前”
    • Carbon::SEQUENTIAL_PARTS_ONLY (默认情况下处于禁用状态):将仅保留间隔的第一个单位序列,例如,如果差异将是“ 2周1天34分钟12秒”,因为日和分钟不是连续的单位,则将得到: 2周1天”。

    使用管道运算符一次启用/禁用多个选项,例如: Carbon::ONE_DAY_WORDS | Carbon::TWO_DAY_WORDS

    你也可以使用Carbon::enableHumanDiffOption($option), Carbon::disableHumanDiffOption($option)Carbon::setHumanDiffOptions($options)更改默认选项,并Carbon::getHumanDiffOptions() 获得默认选项,但你应该避免使用它为静态的,可能与其他的部分代码/第三方库调用冲突。

    出于语义目的提供了别名和反向方法:

    • from($other = null, $syntax = null, $short = false, $parts = 1, $options = null) (diffForHumans的别名)
    • since($other = null, $syntax = null, $short = false, $parts = 1, $options = null) (diffForHumans的别名)
    • to($other = null, $syntax = null, $short = false, $parts = 1, $options = null) (相反的结果,交换之前和将来的差异)
    • until($other = null, $syntax = null, $short = false, $parts = 1, $options = null) (至的别名)
    • fromNow($syntax = null, $short = false, $parts = 1, $options = null)(除非第一个参数是a DateTimeInterface否则将省略from与第一个参数的别名,除非现在使用第一个参数),用于语义用法:生成一个类似“从现在开始3小时”的字符串,并带有将来的日期
    • ago($syntax = null, $short = false, $parts = 1, $options = null) (fromNow的别名),用于语义用法:生成一个类似“ 3小时前”的字符串,其中带有过去的日期
    • toNow($syntax = null, $short = false, $parts = 1, $options = null) (省略了第一个参数的to的别名,现在改为使用)
    • timespan($other = null, $timezone = null)调用diffForHumans并带有选项join = ', '(以逗号 分隔), syntax = CarbonInterface::DIFF_ABSOLUTE(没有“ ago” /“从现在开始” /“之前” /“之后”这句话), options = CarbonInterface::NO_ZERO_DIFF(没有“仅此刻” /“昨天” /“明天”这句话), parts = -1(没有限制)在此模式下,您无法更改选项,但可以传递一个可选日期以与之比较,或者传递一个字符串+时区以进行解析以获取该日期。

    修饰符

    这组方法对当前实例执行有用的修改。他们中的大多数人的名字都是不言自明的……至少应该如此。您还会注意到,对于大于天的单位,startOfXXX(),next()和previous()方法将时间设置为00:00:00,而endOfXXX()方法将时间设置为23:59:59。

    唯一略有不同的是average()功能。它将您的实例移动到其自身与所提供的Carbon参数之间的中间日期。

    强大的本机modify() 方法DateTime可供使用。但是,我们还提供了它的增强版本: change()它允许一些附加的语法,例如"next 3pm"和,它们在->next()and 内部调用->previous()

    $dt = new Carbon('2012-01-31 15:32:45.654321');
    echo $dt->startOfSecond()->format('s.u');          // 45.000000
    
    
    $dt = new Carbon('2012-01-31 15:32:45.654321');
    echo $dt->endOfSecond()->format('s.u');            // 45.999999
    
    $dt = new Carbon('2012-01-31 15:32:45.654321');
    echo $dt->startOf('second')->format('s.u');        // 45.000000
    
    $dt = new Carbon('2012-01-31 15:32:45.654321');
    echo $dt->endOf('second')->format('s.u');          // 45.999999
    // ->startOf() and ->endOf() are dynamic equivalents to those methods
    
    $dt = Carbon::create(2012, 1, 31, 15, 32, 45);
    echo $dt->startOfMinute();                         // 2012-01-31 15:32:00
    
    $dt = Carbon::create(2012, 1, 31, 15, 32, 45);
    echo $dt->endOfMinute();                           // 2012-01-31 15:32:59
    
    $dt = Carbon::create(2012, 1, 31, 15, 32, 45);
    echo $dt->startOfHour();                           // 2012-01-31 15:00:00
    
    $dt = Carbon::create(2012, 1, 31, 15, 32, 45);
    echo $dt->endOfHour();                             // 2012-01-31 15:59:59
    
    $dt = Carbon::create(2012, 1, 31, 15, 32, 45);
    echo Carbon::getMidDayAt();                        // 12
    echo $dt->midDay();                                // 2012-01-31 12:00:00
    Carbon::setMidDayAt(13);
    echo Carbon::getMidDayAt();                        // 13
    echo $dt->midDay();                                // 2012-01-31 13:00:00
    Carbon::setMidDayAt(12);
    
    $dt = Carbon::create(2012, 1, 31, 12, 0, 0);
    echo $dt->startOfDay();                            // 2012-01-31 00:00:00
    
    $dt = Carbon::create(2012, 1, 31, 12, 0, 0);
    echo $dt->endOfDay();                              // 2012-01-31 23:59:59
    
    $dt = Carbon::create(2012, 1, 31, 12, 0, 0);
    echo $dt->startOfMonth();                          // 2012-01-01 00:00:00
    
    $dt = Carbon::create(2012, 1, 31, 12, 0, 0);
    echo $dt->endOfMonth();                            // 2012-01-31 23:59:59
    
    $dt = Carbon::create(2012, 1, 31, 12, 0, 0);
    echo $dt->startOfYear();                           // 2012-01-01 00:00:00
    
    $dt = Carbon::create(2012, 1, 31, 12, 0, 0);
    echo $dt->endOfYear();                             // 2012-12-31 23:59:59
    
    $dt = Carbon::create(2012, 1, 31, 12, 0, 0);
    echo $dt->startOfDecade();                         // 2010-01-01 00:00:00
    
    $dt = Carbon::create(2012, 1, 31, 12, 0, 0);
    echo $dt->endOfDecade();                           // 2019-12-31 23:59:59
    
    $dt = Carbon::create(2012, 1, 31, 12, 0, 0);
    echo $dt->startOfCentury();                        // 2001-01-01 00:00:00
    
    $dt = Carbon::create(2012, 1, 31, 12, 0, 0);
    echo $dt->endOfCentury();                          // 2100-12-31 23:59:59
    
    $dt = Carbon::create(2012, 1, 31, 12, 0, 0);
    echo $dt->startOfWeek();                           // 2012-01-30 00:00:00
    var_dump($dt->dayOfWeek == Carbon::MONDAY);        // bool(true) : ISO8601 week starts on Monday
    
    $dt = Carbon::create(2012, 1, 31, 12, 0, 0);
    echo $dt->endOfWeek();                             // 2012-02-05 23:59:59
    var_dump($dt->dayOfWeek == Carbon::SUNDAY);        // bool(true) : ISO8601 week ends on Sunday
    
    $dt = Carbon::create(2012, 1, 31, 12, 0, 0);
    echo $dt->next(Carbon::WEDNESDAY);                 // 2012-02-01 00:00:00
    var_dump($dt->dayOfWeek == Carbon::WEDNESDAY);     // bool(true)
    echo $dt->next('Wednesday');                       // 2012-02-08 00:00:00
    echo $dt->next('04:00');                           // 2012-02-08 04:00:00
    echo $dt->next('12:00');                           // 2012-02-08 12:00:00
    echo $dt->next('04:00');                           // 2012-02-09 04:00:00
    
    $dt = Carbon::create(2012, 1, 1, 12, 0, 0);
    echo $dt->next();                                  // 2012-01-08 00:00:00
    
    $dt = Carbon::create(2012, 1, 31, 12, 0, 0);
    echo $dt->previous(Carbon::WEDNESDAY);             // 2012-01-25 00:00:00
    var_dump($dt->dayOfWeek == Carbon::WEDNESDAY);     // bool(true)
    
    $dt = Carbon::create(2012, 1, 1, 12, 0, 0);
    echo $dt->previous();                              // 2011-12-25 00:00:00
    
    $start = Carbon::create(2014, 1, 1, 0, 0, 0);
    $end = Carbon::create(2014, 1, 30, 0, 0, 0);
    echo $start->average($end);                        // 2014-01-15 12:00:00
    
    echo Carbon::create(2014, 5, 30, 0, 0, 0)->firstOfMonth();                       // 2014-05-01 00:00:00
    echo Carbon::create(2014, 5, 30, 0, 0, 0)->firstOfMonth(Carbon::MONDAY);         // 2014-05-05 00:00:00
    echo Carbon::create(2014, 5, 30, 0, 0, 0)->lastOfMonth();                        // 2014-05-31 00:00:00
    echo Carbon::create(2014, 5, 30, 0, 0, 0)->lastOfMonth(Carbon::TUESDAY);         // 2014-05-27 00:00:00
    echo Carbon::create(2014, 5, 30, 0, 0, 0)->nthOfMonth(2, Carbon::SATURDAY);      // 2014-05-10 00:00:00
    
    echo Carbon::create(2014, 5, 30, 0, 0, 0)->firstOfQuarter();                     // 2014-04-01 00:00:00
    echo Carbon::create(2014, 5, 30, 0, 0, 0)->firstOfQuarter(Carbon::MONDAY);       // 2014-04-07 00:00:00
    echo Carbon::create(2014, 5, 30, 0, 0, 0)->lastOfQuarter();                      // 2014-06-30 00:00:00
    echo Carbon::create(2014, 5, 30, 0, 0, 0)->lastOfQuarter(Carbon::TUESDAY);       // 2014-06-24 00:00:00
    echo Carbon::create(2014, 5, 30, 0, 0, 0)->nthOfQuarter(2, Carbon::SATURDAY);    // 2014-04-12 00:00:00
    echo Carbon::create(2014, 5, 30, 0, 0, 0)->startOfQuarter();                     // 2014-04-01 00:00:00
    echo Carbon::create(2014, 5, 30, 0, 0, 0)->endOfQuarter();                       // 2014-06-30 23:59:59
    
    echo Carbon::create(2014, 5, 30, 0, 0, 0)->firstOfYear();                        // 2014-01-01 00:00:00
    echo Carbon::create(2014, 5, 30, 0, 0, 0)->firstOfYear(Carbon::MONDAY);          // 2014-01-06 00:00:00
    echo Carbon::create(2014, 5, 30, 0, 0, 0)->lastOfYear();                         // 2014-12-31 00:00:00
    echo Carbon::create(2014, 5, 30, 0, 0, 0)->lastOfYear(Carbon::TUESDAY);          // 2014-12-30 00:00:00
    echo Carbon::create(2014, 5, 30, 0, 0, 0)->nthOfYear(2, Carbon::SATURDAY);       // 2014-01-11 00:00:00
    
    echo Carbon::create(2018, 2, 23, 0, 0, 0)->nextWeekday();                        // 2018-02-26 00:00:00
    echo Carbon::create(2018, 2, 23, 0, 0, 0)->previousWeekday();                    // 2018-02-22 00:00:00
    echo Carbon::create(2018, 2, 21, 0, 0, 0)->nextWeekendDay();                     // 2018-02-24 00:00:00
    echo Carbon::create(2018, 2, 21, 0, 0, 0)->previousWeekendDay();                 // 2018-02-18 00:00:00
    

    四舍五入也适用于任何单位:

    $dt = new Carbon('2012-01-31 15:32:45.654321');
    echo $dt->roundMillisecond()->format('H:i:s.u');   // 15:32:45.654000
    
    $dt = new Carbon('2012-01-31 15:32:45.654321');
    echo $dt->roundSecond()->format('H:i:s.u');        // 15:32:46.000000
    
    $dt = new Carbon('2012-01-31 15:32:45.654321');
    echo $dt->floorSecond()->format('H:i:s.u');        // 15:32:45.000000
    
    $dt = new Carbon('2012-01-31 15:32:15');
    echo $dt->roundMinute()->format('H:i:s');          // 15:32:00
    
    $dt = new Carbon('2012-01-31 15:32:15');
    echo $dt->ceilMinute()->format('H:i:s');           // 15:33:00
    
    // and so on up to millennia!
    
    // precision rounding can be set, example: rounding to ten minutes
    $dt = new Carbon('2012-01-31 15:32:15');
    echo $dt->roundMinute(10)->format('H:i:s');        // 15:30:00
    
    // and round, floor and ceil methods are shortcut for second rounding:
    $dt = new Carbon('2012-01-31 15:32:45.654321');
    echo $dt->round()->format('H:i:s.u');              // 15:32:46.000000
    $dt = new Carbon('2012-01-31 15:32:45.654321');
    echo $dt->floor()->format('H:i:s.u');              // 15:32:45.000000
    $dt = new Carbon('2012-01-31 15:32:45.654321');
    echo $dt->ceil()->format('H:i:s.u');               // 15:32:46.000000
    
    // you can also pass the unit dynamically (and still precision as second argument):
    $dt = new Carbon('2012-01-31');
    echo $dt->roundUnit('month', 2)->format('Y-m-d');  // 2012-03-01
    $dt = new Carbon('2012-01-31');
    echo $dt->floorUnit('month')->format('Y-m-d');     // 2012-03-01
    $dt = new Carbon('2012-01-31');
    echo $dt->ceilUnit('month', 4)->format('Y-m-d');   // 2012-05-01
    

    常数

    在Carbon类中定义了以下常量。

    // These getters specifically return integers, ie intval()
    var_dump(Carbon::SUNDAY);                          // int(0)
    var_dump(Carbon::MONDAY);                          // int(1)
    var_dump(Carbon::TUESDAY);                         // int(2)
    var_dump(Carbon::WEDNESDAY);                       // int(3)
    var_dump(Carbon::THURSDAY);                        // int(4)
    var_dump(Carbon::FRIDAY);                          // int(5)
    var_dump(Carbon::SATURDAY);                        // int(6)
    
    var_dump(Carbon::YEARS_PER_CENTURY);               // int(100)
    var_dump(Carbon::YEARS_PER_DECADE);                // int(10)
    var_dump(Carbon::MONTHS_PER_YEAR);                 // int(12)
    var_dump(Carbon::WEEKS_PER_YEAR);                  // int(52)
    var_dump(Carbon::DAYS_PER_WEEK);                   // int(7)
    var_dump(Carbon::HOURS_PER_DAY);                   // int(24)
    var_dump(Carbon::MINUTES_PER_HOUR);                // int(60)
    var_dump(Carbon::SECONDS_PER_MINUTE);              // int(60)
    
    $dt = Carbon::createFromDate(2012, 10, 6);
    if ($dt->dayOfWeek === Carbon::SATURDAY) {
        echo 'Place bets on Ottawa Senators Winning!';
    }
    

    序列化

    Carbon实例可以序列化(包括CarbonImmutable,CarbonInterval和CarbonPeriod)。

    $dt = Carbon::create(2012, 12, 25, 20, 30, 00, 'Europe/Moscow');
    
    echo serialize($dt);                                              // O:13:"CarbonCarbon":3:{s:4:"date";s:26:"2012-12-25 20:30:00.000000";s:13:"timezone_type";i:3;s:8:"timezone";s:13:"Europe/Moscow";}
    // same as:
    echo $dt->serialize();                                            // O:13:"CarbonCarbon":3:{s:4:"date";s:26:"2012-12-25 20:30:00.000000";s:13:"timezone_type";i:3;s:8:"timezone";s:13:"Europe/Moscow";}
    
    $dt = 'O:13:"CarbonCarbon":3:{s:4:"date";s:26:"2012-12-25 20:30:00.000000";s:13:"timezone_type";i:3;s:8:"timezone";s:13:"Europe/Moscow";}';
    
    echo unserialize($dt)->format('Y-m-dTH:i:s.uP T');               // 2012-12-25T20:30:00.000000+04:00 MSK
    // same as:
    echo Carbon::fromSerialized($dt)->format('Y-m-dTH:i:s.uP T');    // 2012-12-25T20:30:00.000000+04:00 MSK
    
    

    JSON格式

    Carbon实例可以编码为JSON或从JSON解码。从2.4版开始,我们明确要求使用PHP JSON扩展名。它应该没有影响,因为此扩展默认情况下与PHP捆绑在一起。如果扩展名被禁用,请注意您将被锁定在2.3。但是您仍然可以--ignore-platform-reqs在composer上使用update / install进行升级,然后JsonSerializable通过包含JsonSerializable.php来填充缺少的接口 

    $dt = Carbon::create(2012, 12, 25, 20, 30, 00, 'Europe/Moscow');
    echo json_encode($dt);
    // "2012-12-25T16:30:00.000000Z"
    
    $json = '{"date":"2012-12-25 20:30:00.000000","timezone_type":3,"timezone":"Europe/Moscow"}';
    $dt = Carbon::__set_state(json_decode($json, true));
    echo $dt->format('Y-m-dTH:i:s.uP T');
    // 2012-12-25T20:30:00.000000+04:00 MSK
    

    您可以用settings(['toJsonFormat' => $format])来自定义序列化。

    $dt = Carbon::create(2012, 12, 25, 20, 30, 00, 'Europe/Moscow')->settings([
        'toJsonFormat' => function ($date) {
            return $date->getTimestamp();
        },
    ]);
    echo json_encode($dt); // 1356453000
    

    如果要在全球范围内使用此功能,请首先考虑使用factory,否则,或者如果我使用Carbon 1,则可以使用:

    $dt = Carbon::create(2012, 12, 25, 20, 30, 00, 'Europe/Moscow');
    Carbon::serializeUsing(function ($date) {
        return $date->valueOf();
    });
    echo json_encode($dt); // 1356453000000
    
    // Call serializeUsing with null to reset the serializer:
    Carbon::serializeUsing(null);
    

    如果未指定自定义序列化jsonSerialize()方法允许您调用给定的函数 Carbon::serializeUsing()或结果toJson()

    巨集

    如果您习惯于使用Laravel和诸如响应 或集合之类的对象,您可能会熟悉宏概念 Carbon宏就像Laravel MacroableTrait一样工作。

    Carbon::macro()以宏名作为第一个参数,以闭包作为第二个参数来调用该方法。这将使关闭操作可用于所有Carbon实例。

    Carbon::macro('diffFromYear', static function ($year, $absolute = false, $short = false, $parts = 1) {
        return self::this()->diffForHumans(Carbon::create($year, 1, 1, 0, 0, 0), $absolute, $short, $parts);
    });
    
    // Can be called on Carbon instances: self::this() = current instance ($this)
    echo Carbon::parse('2020-01-12 12:00:00')->diffFromYear(2019);                 // 1 year after
    echo "
    ";
    echo Carbon::parse('2020-01-12 12:00:00')->diffFromYear(2019, true);           // 1 year
    echo "
    ";
    echo Carbon::parse('2020-01-12 12:00:00')->diffFromYear(2019, true, true);     // 1yr
    echo "
    ";
    echo Carbon::parse('2020-01-12 12:00:00')->diffFromYear(2019, true, true, 5);  // 1yr 1w 4d 12h
    
    // Can also be called statically, in this case self::this() = Carbon::now()
    echo "
    ";
    echo Carbon::diffFromYear(2017);                                               // 3 years after
    

    请注意,闭包之前static和使用self::this()(自版本2.25.0起可用)代替$this这是创建碳宏的标准方法,这也适用于其他类的宏(CarbonImmutableCarbonIntervalCarbonInterval)。

    通过遵循这种模式,可以确保您团队(以及您将来)的其他开发人员可以安全地依赖断言:Carbon::anyMacro()等效于Carbon::now()->anyMacro()这使宏的用法一致且可预测,并确保可以安全地静态或动态调用比任何宏都大的开发人员。

    可悲的是,IDE本身并不是您的宏方法(diffFromYear上面示例中的方法无法自动完成 )。但这要归功于我们的CLI工具:carbon-cli它不再是一个问题 ,它使您可以为mixin和宏生成IDE帮助程序文件。

    宏是使用某些设置或用户首选项输出日期的理想工具。

    // Let assume you get user settings from the browser or preferences stored in a database
    $userTimezone = 'Europe/Paris';
    $userLanguage = 'fr_FR';
    
    Carbon::macro('formatForUser', static function () use ($userTimezone, $userLanguage) {
        $date = self::this()->copy()->tz($userTimezone)->locale($userLanguage);
    
        return $date->calendar(); // or ->isoFormat($customFormat), ->diffForHumans(), etc.
    });
    
    // Then let assume you store all your dates/times in UTC (because you definitely should)
    $dateString = '2010-01-23 10:00:00'; // Get this from your database or any input
    
    // Then now you can easily display any date in a page/e-mail using those user settings and the chosen format
    echo Carbon::parse($dateString, 'UTC')->formatForUser();   // 23/01/2010
    echo "
    ";
    echo Carbon::tomorrow()->formatForUser();                  // Demain à 01:00
    echo "
    ";
    echo Carbon::now()->subDays(3)->formatForUser();           // mardi dernier à 17:05
    

    宏也可以分组在类中,并与 mixin()

    class BeerDayCarbonMixin
    {
        public function nextBeerDay()
        {
            return static function () {
                return self::this()->modify('next wednesday');
            };
        }
    
        public function previousBeerDay()
        {
            return static function () {
                return self::this()->modify('previous wednesday');
            };
        }
    }
    
    Carbon::mixin(new BeerDayCarbonMixin());
    
    $date = Carbon::parse('First saturday of December 2018');
    
    echo $date->previousBeerDay();                                                 // 2018-11-28 00:00:00
    echo "
    ";
    echo $date->nextBeerDay();                                                     // 2018-12-05 00:00:00
    

    从Carbon 2.23.0开始,还可以使用特征来缩短mixin语法:

    trait BeerDayCarbonTrait
    {
        public function nextBeerDay()
        {
            return $this->modify('next wednesday');
        }
    
        public function previousBeerDay()
        {
            return $this->modify('previous wednesday');
        }
    }
    
    Carbon::mixin(BeerDayCarbonTrait::class);
    
    $date = Carbon::parse('First saturday of December 2018');
    
    echo $date->previousBeerDay();                                                 // 2018-11-28 00:00:00
    echo "n";
    echo $date->nextBeerDay();                                                     // 2018-12-05 00:00:00
    

    您可以检查宏(包括混合)是否可用,hasMacro()并使用来检索宏闭包getMacro()

    var_dump(Carbon::hasMacro('previousBeerDay'));                                 // bool(true)
    var_dump(Carbon::hasMacro('diffFromYear'));                                    // bool(true)
    echo "
    ";
    var_dump(Carbon::hasMacro('dontKnowWhat'));                                    // bool(false)
    

    宏起始与get后跟大写字母将自动提供动态吸气而一个宏开始set和后跟一个大写字母将提供一个动态调节器:

    // Let's say a school year starts 5 months before the start of the year, so the school year of 2018 actually begins in August 2017 and ends in July 2018,
    // Then you can create get/set method this way:
    Carbon::macro('setSchoolYear', static function ($schoolYear) {
        $date = self::this();
        $date->year = $schoolYear;
    
        if ($date->month > 7) {
            $date->year--;
        }
    });
    Carbon::macro('getSchoolYear', static function () {
        $date = self::this();
        $schoolYear = $date->year;
    
        if ($date->month > 7) {
            $schoolYear++;
        }
    
        return $schoolYear;
    });
    // This will make getSchoolYear/setSchoolYear as usual, but get/set prefix will also enable
    // the getter and setter methods for the ->schoolYear property.
    
    $date = Carbon::parse('2016-06-01');
    
    var_dump($date->schoolYear);                   // int(2016)
    $date->addMonths(3);
    var_dump($date->schoolYear);                   // int(2017)
    $date->schoolYear++;
    var_dump($date->format('Y-m-d'));              // string(10) "2017-09-01"
    $date->schoolYear = 2020;
    var_dump($date->format('Y-m-d'));              // string(10) "2019-09-01"
    

    您还可以使用通用宏拦截其他任何调用:

    Carbon::genericMacro(static function ($method) {
        // As an example we will convert firstMondayOfDecember into first Monday Of December to get strings that
        // DateTime can parse.
        $time = preg_replace('/[A-Z]/', ' $0', $method);
    
        try {
            return self::this()->modify($time);
        } catch (Throwable $exception) {
            if (stripos($exception->getMessage(), 'Failed to parse') !== false) {
                // When throwing BadMethodCallException from inside a generic macro will go to next generic macro
                // if there are other registered.
                throw new BadMethodCallException('Try next macro', 0, $exception);
            }
    
            // Other exceptions thrown will not be caught
            throw $exception;
        }
    }, 1 /* you can optionally pass a priority as a second argument, 0 by default, can be negative, higher priority ran first */);
    // Generic macro get the asked method name as first argument, and method arguments as others.
    // They can return any value.
    // They can be added via "genericMacros" setting and this setting has precedence over statically declared generic macros.
    
    $date = Carbon::parse('2016-06-01');
    
    echo $date->nextSunday();                  // 2016-06-05 00:00:00
    echo "
    ";
    echo $date->lastMondayOfPreviousMonth();   // 2016-05-30 00:00:00
    Carbon::resetMacros(); // resetMacros remove all macros and generic macro declared statically
    

    你猜怎么着?所有宏方法也可在CarbonInterval 和CarbonPeriod类上使用。

    CarbonInterval::macro('twice', static function () {
        return self::this()->times(2);
    });
    echo CarbonInterval::day()->twice()->forHumans(); // 2 days
    $interval = CarbonInterval::hours(2)->minutes(15)->twice();
    echo $interval->forHumans(['short' => true]); // 4h 30m
    

    forHumans($syntax, $short, $parts, $options)允许使用与默认情况下设置为-1(无限制)的Carbon::diffForHumans()除外相同的选项参数 $parts。 查看Carbon::diffForHumans()选项。

    CarbonPeriod::macro('countWeekdays', static function () {
        return self::this()->filter('isWeekday')->count();
    });
    echo CarbonPeriod::create('2017-11-01', '2017-11-30')->countWeekdays();  // 22
    echo CarbonPeriod::create('2017-12-01', '2017-12-31')->countWeekdays();  // 21
    

    检查cmixin /营业时间 (包括cmixin / business-day),以使用许多高级功能处理假日和营业时间。

    class CurrentDaysCarbonMixin
    {
        /**
         * Get the all dates of week
         *
         * @return array
         */
        public static function getCurrentWeekDays()
        {
            return static function () {
                $startOfWeek = self::this()->startOfWeek()->subDay();
                $weekDays = [];
    
                for ($i = 0; $i < static::DAYS_PER_WEEK; $i++) {
                    $weekDays[] = $startOfWeek->addDay()->startOfDay()->copy();
                }
    
                return $weekDays;
            };
        }
    
        /**
         * Get the all dates of month
         *
         * @return array
         */
        public static function getCurrentMonthDays()
        {
            return static function () {
                $date = self::this();
                $startOfMonth = $date->copy()->startOfMonth()->subDay();
                $endOfMonth = $date->copy()->endOfMonth()->format('d');
                $monthDays = [];
    
                for ($i = 0; $i < $endOfMonth; $i++)
                {
                    $monthDays[] = $startOfMonth->addDay()->startOfDay()->copy();
                }
    
                return $monthDays;
            };
        }
    }
    
    Carbon::mixin(new CurrentDaysCarbonMixin());
    
    function dumpDateList($dates) {
        echo substr(implode(', ', $dates), 0, 100).'...';
    }
    
    dumpDateList(Carbon::getCurrentWeekDays());                       // 2020-02-10 00:00:00, 2020-02-11 00:00:00, 2020-02-12 00:00:00, 2020-02-13 00:00:00, 2020-02-14 00:00...
    dumpDateList(Carbon::getCurrentMonthDays());                      // 2020-02-01 00:00:00, 2020-02-02 00:00:00, 2020-02-03 00:00:00, 2020-02-04 00:00:00, 2020-02-05 00:00...
    dumpDateList(Carbon::now()->subMonth()->getCurrentWeekDays());    // 2020-01-13 00:00:00, 2020-01-14 00:00:00, 2020-01-15 00:00:00, 2020-01-16 00:00:00, 2020-01-17 00:00...
    dumpDateList(Carbon::now()->subMonth()->getCurrentMonthDays());   // 2020-01-01 00:00:00, 2020-01-02 00:00:00, 2020-01-03 00:00:00, 2020-01-04 00:00:00, 2020-01-05 00:00...
    

    图片来源:meteguerlek#1191)。

    Carbon::macro('toAtomStringWithNoTimezone', static function () {
        return self::this()->format('Y-m-dTH:i:s');
    });
    echo Carbon::parse('2021-06-16 20:08:34')->toAtomStringWithNoTimezone(); // 2021-06-16T20:08:34
    

    信用:afrojuju1#1063)。

    Carbon::macro('easterDate', static function ($year) {
        return Carbon::createMidnightDate($year, 3, 21)->addDays(easter_days($year));
    });
    echo Carbon::easterDate(2015)->format('d/m'); // 05/04
    echo Carbon::easterDate(2016)->format('d/m'); // 27/03
    echo Carbon::easterDate(2017)->format('d/m'); // 16/04
    echo Carbon::easterDate(2018)->format('d/m'); // 01/04
    echo Carbon::easterDate(2019)->format('d/m'); // 21/04
    

    图片来源:andreisena36864 (#1052)。

    检查cmixin / business-day以获取更完整的假期处理程序。

    Carbon::macro('datePeriod', static function ($startDate, $endDate) {
        return new DatePeriod($startDate, new DateInterval('P1D'), $endDate);
    });
    foreach (Carbon::datePeriod(Carbon::createMidnightDate(2019, 3, 28), Carbon::createMidnightDate(2019, 4, 3)) as $date) {
        echo "$date
    ";
    }
    /*
    2019-03-28 00:00:00
    2019-03-29 00:00:00
    2019-03-30 00:00:00
    2019-03-31 00:00:00
    2019-04-01 00:00:00
    2019-04-02 00:00:00
    */
    

    信用:重新灌墨#132)。

    class UserTimezoneCarbonMixin
    {
        public $userTimeZone;
    
        /**
         * Set user timezone, will be used before format function to apply current user timezone
         *
         * @param $timezone
         */
        public function setUserTimezone()
        {
            $mixin = $this;
    
            return static function ($timezone) use ($mixin) {
                $mixin->userTimeZone = $timezone;
            };
        }
    
        /**
         * Returns date formatted according to given format.
         *
         * @param string $format
         *
         * @return string
         *
         * @link http://php.net/manual/en/datetime.format.php
         */
        public function tzFormat()
        {
            $mixin = $this;
    
            return static function ($format) use ($mixin) {
                $date = self::this();
    
                if (!is_null($mixin->userTimeZone)) {
                    $date->timezone($mixin->userTimeZone);
                }
    
                return $date->format($format);
            };
        }
    }
    
    Carbon::mixin(new UserTimezoneCarbonMixin());
    
    Carbon::setUserTimezone('Europe/Berlin');
    echo Carbon::createFromTime(12, 0, 0, 'UTC')->tzFormat('H:i'); // 13:00
    echo Carbon::createFromTime(15, 0, 0, 'UTC')->tzFormat('H:i'); // 16:00
    Carbon::setUserTimezone('America/Toronto');
    echo Carbon::createFromTime(12, 0, 0, 'UTC')->tzFormat('H:i'); // 07:00
    echo Carbon::createFromTime(15, 0, 0, 'UTC')->tzFormat('H:i'); // 10:00
    

    图片来源:thiagocordeiro#927)。

    虽然推荐使用宏向Carbon添加新方法或行为,但是您可以进一步扩展类本身,从而允许使用一些替代方法来覆盖主要方法。解析,格式化和createFromFormat。

    class MyDateClass extends Carbon
    {
        protected static $formatFunction = 'translatedFormat';
    
        protected static $createFromFormatFunction = 'createFromLocaleFormat';
    
        protected static $parseFunction = 'myCustomParse';
    
        public static function myCustomParse($string)
        {
            return static::rawCreateFromFormat('d m Y', $string);
        }
    }
    
    $date = MyDateClass::parse('20 12 2001')->locale('de');
    echo $date->format('jS F y');            // 20. Dezember 01
    echo "
    ";
    
    $date = MyDateClass::createFromFormat('j F Y', 'pt', '20 fevereiro 2001')->locale('pt');
    
    echo $date->format('d/m/Y');             // 20/02/2001
    echo "
    ";
    
    // Note than you can still access native methods using rawParse, rawFormat and rawCreateFromFormat:
    $date = MyDateClass::rawCreateFromFormat('j F Y', '20 February 2001', 'UTC')->locale('pt');
    
    echo $date->rawFormat('jS F y');         // 20th February 01
    echo "
    ";
    
    $date = MyDateClass::rawParse('2001-02-01', 'UTC')->locale('pt');
    
    echo $date->format('jS F y');            // 1º fevereiro 01
    echo "
    ";
    

    以下宏允许您仅使用城市名称(省略大洲)来选择时区。使您的单元测试更加流畅的完美之选:

    Carbon::macro('goTo', function (string $city) {
        static $cities = null;
    
        if ($cities === null) {
            foreach (DateTimeZone::listIdentifiers() as $identifier) {
                $chunks = explode('/', $identifier);
    
                if (isset($chunks[1])) {
                    $id = strtolower(end($chunks));
                    $cities[$id] = $identifier;
                }
            }
        }
    
        $city = str_replace(' ', '_', strtolower($city));
    
        if (!isset($cities[$city])) {
            throw new InvalidArgumentException("$city not found.");
        }
    
        return $this->tz($cities[$city]);
    });
    
    echo Carbon::now()->goTo('Chicago')->tzName; // America/Chicago
    echo "
    ";
    echo Carbon::now()->goTo('Buenos Aires')->tzName; // America/Argentina/Buenos_Aires
    

    碳间隔

    CarbonInterval类是从PHP DateInterval继承

    <?php
    class CarbonInterval extends DateInterval
    {
        // code here
    }
    

    您可以通过以下方式创建实例:

    echo CarbonInterval::createFromFormat('H:i:s', '10:20:00'); // 10 hours 20 minutes
    echo "
    ";
    echo CarbonInterval::year();                           // 1 year
    echo "
    ";
    echo CarbonInterval::months(3);                        // 3 months
    echo "
    ";
    echo CarbonInterval::days(3)->seconds(32);             // 3 days 32 seconds
    echo "
    ";
    echo CarbonInterval::weeks(3);                         // 3 weeks
    echo "
    ";
    echo CarbonInterval::days(23);                         // 3 weeks 2 days
    echo "
    ";
    // years, months, weeks, days, hours, minutes, seconds, microseconds
    echo CarbonInterval::create(2, 0, 5, 1, 1, 2, 7, 123); // 2 years 5 weeks 1 day 1 hour 2 minutes 7 seconds
    echo "
    ";
    echo CarbonInterval::createFromDateString('3 months'); // 3 months
    

    如果您发现自己DateInterval从另一个库继承实例,请不要担心!您可以CarbonInterval通过友好instance()函数创建实例

    $di = new DateInterval('P1Y2M'); // <== instance from another API
    $ci = CarbonInterval::instance($di);
    echo get_class($ci);                                   // 'CarbonCarbonInterval'
    echo $ci;                                              // 1 year 2 months
    

    相反,您可以DateIntervalCarbonInterval 任何扩展的类中提取原始数据,甚至将其转换为DateInterval

    $ci = CarbonInterval::days(2);
    $di = $ci->toDateInterval();
    echo get_class($di);   // 'DateInterval'
    echo $di->d;           // 2
    
    // Your custom class can also extends CarbonInterval
    class CustomDateInterval extends DateInterval {}
    
    $di = $ci->cast(CustomDateInterval::class);
    echo get_class($di);   // 'CustomDateInterval'
    echo $di->d;           // 2
    

    您可以比较的时间间隔比碳对象以相同的方式,使用equalTo()notEqualTo() lessThan()lessThanOrEqualTo()greaterThan(), greaterThanOrEqualTo()between()betweenExcluded(),等。

    其他帮助程序,但请注意,该实现使帮助程序可以处理数周,但仅节省了几天。周数是根据当前实例的总天数计算得出的。

    echo CarbonInterval::year()->years;                    // 1
    echo CarbonInterval::year()->dayz;                     // 0
    echo CarbonInterval::days(24)->dayz;                   // 24
    echo CarbonInterval::days(24)->daysExcludeWeeks;       // 3
    echo CarbonInterval::weeks(3)->days(14)->weeks;        // 2  <-- days setter overwrites the current value
    echo CarbonInterval::weeks(3)->weeks;                  // 3
    echo CarbonInterval::minutes(3)->weeksAndDays(2, 5);   // 2 weeks 5 days 3 minutes
    

    CarbonInterval扩展了DateInterval,您可以使用ISO-8601持续时间格式来创建两者

    $ci = CarbonInterval::create('P1Y2M3D');
    var_dump($ci->isEmpty()); // bool(false)
    $ci = new CarbonInterval('PT0S');
    var_dump($ci->isEmpty()); // bool(true)
    

    借助方法,可以从人性化的弦创建碳间隔fromString()

    CarbonInterval::fromString('2 minutes 15 seconds');
    CarbonInterval::fromString('2m 15s'); // or abbreviated
    

    请注意,月份缩写为“ mo”以区别分钟,并且整个语法不区分大小写。

    它还具有一个handy forHumans(),它被映射为__toString()实现,可以打印人类的时间间隔。

    CarbonInterval::setLocale('fr');
    echo CarbonInterval::create(2, 1)->forHumans();        // 2 ans 1 mois
    echo CarbonInterval::hour()->seconds(3);               // 1 heure 3 secondes
    CarbonInterval::setLocale('en');
    

    如您所见,您可以使用更改字符串的语言环境CarbonInterval::setLocale('fr')

    至于Carbon,您可以使用make方法从其他间隔或字符串中返回CarbonInterval的新实例:

    $dateInterval = new DateInterval('P2D');
    $carbonInterval = CarbonInterval::month();
    echo CarbonInterval::make($dateInterval)->forHumans();       // 2 days
    echo CarbonInterval::make($carbonInterval)->forHumans();     // 1 month
    echo CarbonInterval::make('PT3H')->forHumans();              // 3 hours
    echo CarbonInterval::make('1h 15m')->forHumans();            // 1 hour 15 minutes
    // forHumans has many options, since version 2.9.0, the recommended way is to pass them as an associative array:
    echo CarbonInterval::make('1h 15m')->forHumans(['short' => true]); // 1h 15m
    $interval = CarbonInterval::make('1h 15m 45s');
    echo $interval->forHumans(['join' => true]);                 // 1 hour, 15 minutes and 45 seconds
    $esInterval = CarbonInterval::make('1h 15m 45s');
    echo $esInterval->forHumans(['join' => true]);               // 1 hour, 15 minutes and 45 seconds
    echo $interval->forHumans(['join' => true, 'parts' => 2]);   // 1 hour and 15 minutes
    echo $interval->forHumans(['join' => ' - ']);                // 1 hour - 15 minutes - 45 seconds
    
    // Available syntax modes:
    // ago/from now (translated in the current locale)
    echo $interval->forHumans(['syntax' => CarbonInterface::DIFF_RELATIVE_TO_NOW]);      // 1 hour 15 minutes 45 seconds ago
    // before/after (translated in the current locale)
    echo $interval->forHumans(['syntax' => CarbonInterface::DIFF_RELATIVE_TO_OTHER]);    // 1 hour 15 minutes 45 seconds before
    // default for intervals (no prefix/suffix):
    echo $interval->forHumans(['syntax' => CarbonInterface::DIFF_ABSOLUTE]);             // 1 hour 15 minutes 45 seconds
    
    // Available options:
    // transform empty intervals into "just now":
    echo CarbonInterval::hours(0)->forHumans([
        'options' => CarbonInterface::JUST_NOW,
        'syntax' => CarbonInterface::DIFF_RELATIVE_TO_NOW,
    ]); // just now
    // transform empty intervals into "1 second":
    echo CarbonInterval::hours(0)->forHumans([
        'options' => CarbonInterface::NO_ZERO_DIFF,
        'syntax' => CarbonInterface::DIFF_RELATIVE_TO_NOW,
    ]); // 1 second ago
    // transform "1 day ago"/"1 day from now" into "yesterday"/"tomorrow":
    echo CarbonInterval::day()->forHumans([
        'options' => CarbonInterface::ONE_DAY_WORDS,
        'syntax' => CarbonInterface::DIFF_RELATIVE_TO_NOW,
    ]); // 1 day ago
    // transform "2 days ago"/"2 days from now" into "before yesterday"/"after tomorrow":
    echo CarbonInterval::days(2)->forHumans([
        'options' => CarbonInterface::TWO_DAY_WORDS,
        'syntax' => CarbonInterface::DIFF_RELATIVE_TO_NOW,
    ]); // 2 days ago
    // options can be piped:
    echo CarbonInterval::days(2)->forHumans([
        'options' => CarbonInterface::ONE_DAY_WORDS | CarbonInterface::TWO_DAY_WORDS,
        'syntax' => CarbonInterface::DIFF_RELATIVE_TO_NOW,
    ]); // 2 days ago
    
    // Before version 2.9.0, parameters could only be passed sequentially:
    // $interval->forHumans($syntax, $short, $parts, $options)
    // and join parameter was not available
    

    加,减(或减),时间,份额,乘和除法允许进行间隔计算:

    $interval = CarbonInterval::make('7h 55m');
    $interval->add(CarbonInterval::make('17h 35m'));
    $interval->subtract(10, 'minutes');
    // add(), sub() and subtract() can take DateInterval, CarbonInterval, interval as string or 2 arguments factor and unit
    $interval->times(3);
    echo $interval->forHumans();                                       // 72 hours 240 minutes
    echo "
    ";
    $interval->shares(7);
    echo $interval->forHumans();                                       // 10 hours 34 minutes
    echo "
    ";
    // As you can see add(), times() and shares() operate naively a rounded calculation on each unit
    
    // You also can use multiply() of divide() to cascade units and get precise calculation:
    echo CarbonInterval::make('19h 55m')->multiply(3)->forHumans();    // 2 days 11 hours 45 minutes
    echo "
    ";
    echo CarbonInterval::make('19h 55m')->divide(3)->forHumans();      // 6 hours 38 minutes 20 seconds
    

    您可以从输入单位中获得纯计算。要将分钟分为几小时,将几小时变为几天等,请使用级联方法:

    echo $interval->forHumans();             // 10 hours 34 minutes
    echo $interval->cascade()->forHumans();  // 10 hours 34 minutes
    

    默认因素是:

    • 1分钟= 60秒
    • 1小时= 60分钟
    • 1天= 24小时
    • 1周= 7天
    • 1个月= 4周
    • 1年= 12个月

    CarbonIntervals不带有上下文,因此它们不能更精确(没有DST,没有leap年,没有实际月份长度或年份长度考虑)。但是您可以完全自定义这些因素。例如处理工作时间日志:

    $cascades = CarbonInterval::getCascadeFactors(); // save initial factors
    
    CarbonInterval::setCascadeFactors([
        'minute' => [60, 'seconds'],
        'hour' => [60, 'minutes'],
        'day' => [8, 'hours'],
        'week' => [5, 'days'],
        // in this example the cascade won't go farther than week unit
    ]);
    
    echo CarbonInterval::fromString('20h')->cascade()->forHumans();              // 2 days 4 hours
    echo CarbonInterval::fromString('10d')->cascade()->forHumans();              // 2 weeks
    echo CarbonInterval::fromString('3w 18d 53h 159m')->cascade()->forHumans();  // 7 weeks 4 days 7 hours 39 minutes
    
    // You can see currently set factors with getFactor:
    echo CarbonInterval::getFactor('minutes', /* per */ 'hour');                 // 60
    echo CarbonInterval::getFactor('days', 'week');                              // 5
    
    // And common factors can be get with short-cut methods:
    echo CarbonInterval::getDaysPerWeek();                                       // 5
    echo CarbonInterval::getHoursPerDay();                                       // 8
    echo CarbonInterval::getMinutesPerHour();                                    // 60
    echo CarbonInterval::getSecondsPerMinute();                                  // 60
    echo CarbonInterval::getMillisecondsPerSecond();                             // 1000
    echo CarbonInterval::getMicrosecondsPerMillisecond();                        // 1000
    
    CarbonInterval::setCascadeFactors($cascades); // restore original factors
    

    是否可以将间隔转换为给定的单位(使用提供的级联系数)。

    echo CarbonInterval::days(3)->hours(5)->total('hours');    // 77
    echo CarbonInterval::days(3)->hours(5)->totalHours;        // 77
    echo CarbonInterval::months(6)->totalWeeks;                // 24
    echo CarbonInterval::year()->totalDays;                    // 336
    

    ->total 方法和属性需要级联间隔,如果间隔可能溢出,请在调用以下功能之前将它们级联:

    echo CarbonInterval::minutes(1200)->cascade()->total('hours'); // 20
    echo CarbonInterval::minutes(1200)->cascade()->totalHours; // 20
    

    您还可以通过以下方式获得该inverval的ISO 8601规范 spec()

    echo CarbonInterval::days(3)->hours(5)->spec(); // P3DT5H
    

    也可以从DateInterval对象中获取它,直到静态帮助器为止:

    echo CarbonInterval::getDateIntervalSpec(new DateInterval('P3DT6M10S')); // P3DT6M10S
    

    可以通过compare()compareDateIntervals() 方法对日期间隔列表进行排序

    $halfDay = CarbonInterval::hours(12);
    $oneDay = CarbonInterval::day();
    $twoDay = CarbonInterval::days(2);
    
    echo CarbonInterval::compareDateIntervals($oneDay, $oneDay);   // 0
    echo $oneDay->compare($oneDay);                                // 0
    echo CarbonInterval::compareDateIntervals($oneDay, $halfDay);  // 1
    echo $oneDay->compare($halfDay);                               // 1
    echo CarbonInterval::compareDateIntervals($oneDay, $twoDay);   // -1
    echo $oneDay->compare($twoDay);                                // -1
    
    $list = [$twoDay, $halfDay, $oneDay];
    usort($list, ['CarbonCarbonInterval', 'compareDateIntervals']);
    
    echo implode(', ', $list);                                     // 12 hours, 1 day, 2 days
    

    将间隔值转储为具有以下内容的数组:

    $interval = CarbonInterval::months(2)->hours(12)->seconds(50);
    
    // All the values:
    print_r($interval->toArray());
    /*
    Array
    (
        [years] => 0
        [months] => 2
        [weeks] => 0
        [days] => 0
        [hours] => 12
        [minutes] => 0
        [seconds] => 50
        [microseconds] => 0
    )
    
    */
    
    // Values sequence from the biggest to the smallest non-zero ones:
    print_r($interval->getValuesSequence());
    /*
    Array
    (
        [months] => 2
        [weeks] => 0
        [days] => 0
        [hours] => 12
        [minutes] => 0
        [seconds] => 50
    )
    
    */
    
    // Non-zero values:
    print_r($interval->getNonZeroValues());
    /*
    Array
    (
        [months] => 2
        [hours] => 12
        [seconds] => 50
    )
    
    */
    

    最后,可以通过toPeriod() 使用互补参数调用将CarbonInterval实例转换为CarbonPeriod实例

    我听到你问什么是CarbonPeriod实例。哦! 完美过渡到下一章。

    碳素期

    CarbonPeriod是一个人性化的版本DatePeriod 有许多快捷键。

    // Create a new instance:
    $period = new CarbonPeriod('2018-04-21', '3 days', '2018-04-27');
    // Use static constructor:
    $period = CarbonPeriod::create('2018-04-21', '3 days', '2018-04-27');
    // Use the fluent setters:
    $period = CarbonPeriod::since('2018-04-21')->days(3)->until('2018-04-27');
    // Start from a CarbonInterval:
    $period = CarbonInterval::days(3)->toPeriod('2018-04-21', '2018-04-27');
    // toPeriod can also be called from a Carbon or CarbonImmutable instance:
    $period = Carbon::parse('2018-04-21')->toPeriod('2018-04-27', '3 days'); // pass end and interval
    // interval can be a string, a DateInterval or a CarbonInterval
    // You also can pass 2 arguments: number an string:
    $period = Carbon::parse('2018-04-21')->toPeriod('2018-04-27', 3, 'days');
    // Same as above:
    $period = Carbon::parse('2018-04-21')->range('2018-04-27', 3, 'days'); // Carbon::range is an alias of Carbon::toPeriod
    // Still the same:
    $period = Carbon::parse('2018-04-21')->daysUntil('2018-04-27', 3);
    // By default daysUntil will use a 1-day interval:
    $period = Carbon::parse('2018-04-21')->daysUntil('2018-04-27'); // same as CarbonPeriod::create('2018-04-21', '1 day', '2018-04-27')
    /*
        microsUntil() or microsecondsUntil() provide the same feature for microseconds intervals
        millisUntil() or millisecondsUntil() provide the same feature for milliseconds intervals
        secondsUntil() provides the same feature for seconds intervals
        minutesUntil() provides the same feature for minutes intervals
        hoursUntil() provides the same feature for hours intervals
        weeksUntil() provides the same feature for weeks intervals
        monthsUntil() provides the same feature for months intervals
        quartersUntil() provides the same feature for quarters intervals
        yearsUntil() provides the same feature for years intervals
        decadesUntil() provides the same feature for decades intervals
        centuriesUntil() provides the same feature for centuries intervals
        millenniaUntil() provides the same feature for millennia intervals
    */
    

    CarbonPeriod可以通过多种方式构造:

    • 开始日期,结束日期和可选间隔(默认为1天),
    • 开始日期,重复次数和可选间隔,
    • ISO 8601间隔规范,
    • 从其他DatePeriodCarbonPeriod使用CarbonPeriod::instance($period)

    日期可以作为DateTime / Carbon实例,绝对字符串(例如“ 2007-10-15 15:00”)或相对字符串(例如“下周一”)给出。间隔可以指定为DateInterval / CarbonInterval实例,ISO 8601间隔规范(例如“ P4D”)或人类可读的字符串(例如“ 4 days”)。

    默认构造函数和create()方法在参数类型和顺序方面是非常宽容的,因此,如果您想更精确地建议使用流利的语法。另一方面,您可以传递值的动态数组,createFromArray()数组将使用给定数组作为参数列表来构造新实例。

    CarbonPeriod实现了Iterator接口。这意味着它可以直接传递给foreach循环:

    $period = CarbonPeriod::create('2018-04-21', '3 days', '2018-04-27');
    foreach ($period as $key => $date) {
        if ($key) {
            echo ', ';
        }
        echo $date->format('m-d');
    }
    // 04-21, 04-24, 04-27
    echo "
    ";
    
    // Here is what happens under the hood:
    $period->rewind(); // restart the iteration
    while ($period->valid()) { // check if current item is valid
        if ($period->key()) { // echo comma if current key is greater than 0
            echo ', ';
        }
        echo $period->current()->format('m-d'); // echo current date
        $period->next(); // move to the next item
    }
    // 04-21, 04-24, 04-27
    

    可以在迭代期间修改参数:

    $period = CarbonPeriod::create('2018-04-29', 7);
    $dates = [];
    foreach ($period as $key => $date) {
        if ($key === 3) {
            $period->invert()->start($date); // invert() is an alias for invertDateInterval()
        }
        $dates[] = $date->format('m-d');
    }
    
    echo implode(', ', $dates); // 04-29, 04-30, 05-01, 05-02, 05-01, 04-30, 04-29
    

    就像DatePeriod一样,CarbonPeriod也支持ISO 8601时间间隔规范

    请注意,本机DatePeriod将重复次数视为重复间隔的次数。因此,如果不包括开始日期,结果将少一。在CarbonPeriod中引入了自定义过滤器后,更加难以知道结果的数量。因此,我们对实现进行了一些更改,并且将重复作为返回日期总数的整体限制。

    // Possible options are: CarbonPeriod::EXCLUDE_START_DATE | CarbonPeriod::EXCLUDE_END_DATE
    // Default value is 0 which will have the same effect as when no options are given.
    $period = CarbonPeriod::createFromIso('R4/2012-07-01T00:00:00Z/P7D', CarbonPeriod::EXCLUDE_START_DATE);
    $dates = [];
    foreach ($period as $date) {
        $dates[] = $date->format('m-d');
    }
    
    echo implode(', ', $dates); // 07-08, 07-15, 07-22, 07-29
    

    您可以使用多种吸气剂从该期间检索数据:

    $period = CarbonPeriod::create('2010-05-06', '2010-05-25', CarbonPeriod::EXCLUDE_START_DATE);
    
    $exclude = $period->getOptions() & CarbonPeriod::EXCLUDE_START_DATE;
    
    echo $period->getStartDate();            // 2010-05-06 00:00:00
    echo "
    ";
    echo $period->getEndDate();              // 2010-05-25 00:00:00
    // Note than ->getEndDate() will return null when the end is not fixed.
    // For example CarbonPeriod::since('2018-04-21')->times(3) use repetition, so we don't know the end before iteration.
    // Then you can use ->calculateEnd() instead that will use getEndDate() if available and else will execute a complete
    // iteration to calculate the end date.
    echo "
    ";
    echo $period->getDateInterval();         // 1 day
    echo "
    ";
    echo $exclude ? 'exclude' : 'include';   // exclude
    echo "
    ";
    
    var_dump($period->isStartIncluded());    // bool(false)
    echo "
    ";
    var_dump($period->isEndIncluded());      // bool(true)
    echo "
    ";
    var_dump($period->isStartExcluded());    // bool(true)
    echo "
    ";
    var_dump($period->isEndExcluded());      // bool(false)
    echo "
    ";
    
    echo $period->getIncludedStartDate();    // 2010-05-07 00:00:00
    // If start is included getIncludedStartDate() = getStartDate()
    // If start is excluded getIncludedStartDate() = getStartDate() + 1 interval
    echo "
    ";
    echo $period->getIncludedEndDate();      // 2010-05-25 00:00:00
    // If end is included getIncludedEndDate() = getEndDate()
    // If end is excluded getIncludedEndDate() = getEndDate() - 1 interval
    // If end is null getIncludedEndDate() = calculateEnd(), it means the period is actually iterated to get the last date
    echo "
    ";
    
    echo $period->toString();                // Every 1 day from 2010-05-06 to 2010-05-25
    echo "
    ";
    echo $period; /*implicit toString*/      // Every 1 day from 2010-05-06 to 2010-05-25
    

    其他获取器使您可以将结果作为数组访问:

    $period = CarbonPeriod::create('2010-05-11', '2010-05-13');
    
    echo $period->count();                   // 3, equivalent to count($period)
    echo "
    ";
    echo implode(', ', $period->toArray());  // 2010-05-11 00:00:00, 2010-05-12 00:00:00, 2010-05-13 00:00:00
    echo "
    ";
    echo $period->first();                   // 2010-05-11 00:00:00
    echo "
    ";
    echo $period->last();                    // 2010-05-13 00:00:00
    

    请注意,如果您打算使用上述功能,则最好将toArray()调用结果存储 到变量中并改用它,因为每个调用都在内部执行完整的迭代。

    要更改参数,可以使用setter方法:

    $period = CarbonPeriod::create('2010-05-01', '2010-05-14', CarbonPeriod::EXCLUDE_END_DATE);
    
    $period->setStartDate('2010-05-11');
    echo implode(', ', $period->toArray());  // 2010-05-11 00:00:00, 2010-05-12 00:00:00, 2010-05-13 00:00:00
    echo "
    ";
    
    // Second argument can be optionally used to exclude the date from the results.
    $period->setStartDate('2010-05-11', false);
    $period->setEndDate('2010-05-14', true);
    echo implode(', ', $period->toArray());  // 2010-05-12 00:00:00, 2010-05-13 00:00:00, 2010-05-14 00:00:00
    echo "
    ";
    
    $period->setRecurrences(2);
    echo implode(', ', $period->toArray());  // 2010-05-12 00:00:00, 2010-05-13 00:00:00
    echo "
    ";
    
    $period->setDateInterval('PT12H');
    echo implode(', ', $period->toArray());  // 2010-05-11 12:00:00, 2010-05-12 00:00:00
    

    您可以使用setOptions()替换所有选项来更改选项,但也可以单独更改它们:

    $period = CarbonPeriod::create('2010-05-06', '2010-05-25');
    
    var_dump($period->isStartExcluded());    // bool(false)
    var_dump($period->isEndExcluded());      // bool(false)
    
    $period->toggleOptions(CarbonPeriod::EXCLUDE_START_DATE, true); // true, false or nothing to invert the option
    var_dump($period->isStartExcluded());    // bool(true)
    var_dump($period->isEndExcluded());      // bool(false) (unchanged)
    
    $period->excludeEndDate();               // specify false to include, true or omit to exclude
    var_dump($period->isStartExcluded());    // bool(true) (unchanged)
    var_dump($period->isEndExcluded());      // bool(true)
    
    $period->excludeStartDate(false);        // specify false to include, true or omit to exclude
    var_dump($period->isStartExcluded());    // bool(false)
    var_dump($period->isEndExcluded());      // bool(true)
    

    您可以检查两个周期是否重叠:

    $period = CarbonPeriod::create('2010-05-06', '2010-05-25');
    
    var_dump($period->overlaps('2010-05-22', '2010-06-03'));   // bool(true)$period2 = CarbonPeriod::create('2010-05-22', '2010-05-24');
    var_dump($period->overlaps($period2));                     // bool(true)
    
    $period = CarbonPeriod::create('2010-05-06 12:00', '2010-05-25');
    $start = Carbon::create('2010-05-06 05:00');
    $end = Carbon::create('2010-05-06 11:59');
    var_dump($period->overlaps($start, $end));                 // bool(false)
    

    如前所述,根据ISO 8601规范,重复是间隔应重复的次数。因此,本机DatePeriod将根据排除的开始日期来改变返回日期的数量。同时,CarbonPeriod在输入方面更为宽容,并允许自定义过滤器,将重复性视为返回日期数的整体限制:

    $period = CarbonPeriod::createFromIso('R4/2012-07-01T00:00:00Z/P7D');
    $days = [];
    foreach ($period as $date) {
        $days[] = $date->format('d');
    }
    
    echo $period->getRecurrences();          // 4
    echo implode(', ', $days);               // 01, 08, 15, 22
    
    $days = [];
    $period->setRecurrences(3)->excludeStartDate();
    foreach ($period as $date) {
        $days[] = $date->format('d');
    }
    
    echo $period->getRecurrences();          // 3
    echo implode(', ', $days);               // 08, 15, 22
    
    $days = [];
    $period = CarbonPeriod::recurrences(3)->sinceNow();
    foreach ($period as $date) {
        $days[] = $date->format('Y-m-d');
    }
    
    echo implode(', ', $days);               // 2020-02-14, 2020-02-15, 2020-02-16
    

    DatePeriod返回的日期可以轻松过滤。过滤器可用于例如跳过某些日期或仅在工作日或周末进行迭代。过滤器功能应返回true接受日期,false跳过日期 但继续搜索或CarbonPeriod::END_ITERATION结束迭代。

    $period = CarbonPeriod::between('2000-01-01', '2000-01-15');
    $weekendFilter = function ($date) {
        return $date->isWeekend();
    };
    $period->filter($weekendFilter);
    
    $days = [];
    foreach ($period as $date) {
        $days[] = $date->format('m-d');
    }
    echo implode(', ', $days);                         // 01-01, 01-02, 01-08, 01-09, 01-15
    

    您也可以在循环内跳过一个或多个值。

    $period = CarbonPeriod::between('2000-01-01', '2000-01-10');
    $days = [];
    foreach ($period as $date) {
        $day = $date->format('m-d');
        $days[] = $day;
        if ($day === '01-04') {
            $period->skip(3);
        }
    }
    echo implode(', ', $days);                         // 01-01, 01-02, 01-03, 01-04, 01-08, 01-09, 01-10
    

    getFilters()允许您在一段时间内检索所有存储的过滤器。但是请注意,递归限制和结束日期将作为返回值存储在内部作为过滤器存储在返回数组中。

    $period = CarbonPeriod::end('2000-01-01')->recurrences(3);
    var_export($period->getFilters());
    /*
    array (
      0 => 
      array (
        0 => 'Carbon\CarbonPeriod::filterEndDate',
        1 => NULL,
      ),
      1 => 
      array (
        0 => 'Carbon\CarbonPeriod::filterRecurrences',
        1 => NULL,
      ),
    )
    */
    

    筛选器存储在堆栈中,可以使用一组特殊的方法进行管理:

    $period = CarbonPeriod::between('2000-01-01', '2000-01-15');
    $weekendFilter = function ($date) {
        return $date->isWeekend();
    };
    
    var_dump($period->hasFilter($weekendFilter));      // bool(false)
    $period->addFilter($weekendFilter);
    var_dump($period->hasFilter($weekendFilter));      // bool(true)
    $period->removeFilter($weekendFilter);
    var_dump($period->hasFilter($weekendFilter));      // bool(false)
    
    // To avoid storing filters as variables you can name your filters:
    $period->prependFilter(function ($date) {
        return $date->isWeekend();
    }, 'weekend');
    
    var_dump($period->hasFilter('weekend'));           // bool(true)
    $period->removeFilter('weekend');
    var_dump($period->hasFilter('weekend'));           // bool(false)
    

    添加过滤器的顺序可能会影响性能和结果,因此可以用来addFilter() 在堆栈末尾添加过滤器。您可以prependFilter()在开始时添加一个。您甚至可以setFilters()用来更换所有过滤器。请注意,您必须保持正确的堆栈格式,并记住有关重复发生限制和结束日期的内部过滤器。或者,您可以使用 resetFilters()方法,然后一个接一个地添加新的过滤器。

    例如,当您添加一个限制尝试日期数量的自定义过滤器时,如果在工作日过滤器之前或之后添加结果,结果将有所不同。

    // Note that you can pass a name of any Carbon method starting with "is", including macros
    $period = CarbonPeriod::between('2018-05-03', '2018-05-25')->filter('isWeekday');
    
    $attempts = 0;
    $attemptsFilter = function () use (&$attempts) {
        return ++$attempts <= 5 ? true : CarbonPeriod::END_ITERATION;
    };
    
    $period->prependFilter($attemptsFilter, 'attempts');
    $days = [];
    foreach ($period as $date) {
        $days[] = $date->format('m-d');
    }
    echo implode(', ', $days);                         // 05-03, 05-04, 05-07
    
    $attempts = 0;
    
    $period->removeFilter($attemptsFilter)->addFilter($attemptsFilter, 'attempts');
    $days = [];
    foreach ($period as $date) {
        $days[] = $date->format('m-d');
    }
    echo implode(', ', $days);                         // 05-03, 05-04, 05-07, 05-08, 05-09
    

    请注意,内置的重复发生过滤器无法通过这种方式工作。相反,它基于当前密钥,每个密钥仅递增一次,无论找到有效日期之前必须检查多少个日期。如果将其放在堆栈的开头或结尾,此技巧将使其工作相同。

    添加了一些别名以简化CarbonPeriod的构建:

    // "start", "since", "sinceNow":
    CarbonPeriod::start('2017-03-10') == CarbonPeriod::create()->setStartDate('2017-03-10');
    // Same with optional boolean argument $inclusive to change the option about include/exclude start date:
    CarbonPeriod::start('2017-03-10', true) == CarbonPeriod::create()->setStartDate('2017-03-10', true);
    // "end", "until", "untilNow":
    CarbonPeriod::end('2017-03-20') == CarbonPeriod::create()->setEndDate('2017-03-20');
    // Same with optional boolean argument $inclusive to change the option about include/exclude end date:
    CarbonPeriod::end('2017-03-20', true) == CarbonPeriod::create()->setEndDate('2017-03-20', true);
    // "dates", "between":
    CarbonPeriod::dates(..., ...) == CarbonPeriod::create()->setDates(..., ...);
    // "recurrences", "times":
    CarbonPeriod::recurrences(5) == CarbonPeriod::create()->setRecurrences(5);
    // "options":
    CarbonPeriod::options(...) == CarbonPeriod::create()->setOptions(...);
    // "toggle":
    CarbonPeriod::toggle(..., true) == CarbonPeriod::create()->toggleOptions(..., true);
    // "filter", "push":
    CarbonPeriod::filter(...) == CarbonPeriod::create()->addFilter(...);
    // "prepend":
    CarbonPeriod::prepend(...) == CarbonPeriod::create()->prependFilter(...);
    // "filters":
    CarbonPeriod::filters(...) == CarbonPeriod::create()->setFilters(...);
    // "interval", "each", "every", "step", "stepBy":
    CarbonPeriod::interval(...) == CarbonPeriod::create()->setDateInterval(...);
    // "invert":
    CarbonPeriod::invert() == CarbonPeriod::create()->invertDateInterval();
    // "year", "months", "month", "weeks", "week", "days", "dayz", "day",
    // "hours", "hour", "minutes", "minute", "seconds", "second":
    CarbonPeriod::hours(5) == CarbonPeriod::create()->setDateInterval(new CarbonInterval::hours(5));
    

    CarbonPeriod可以轻松转换为人类可读的字符串并符合ISO 8601规范:

    $period = CarbonPeriod::create('2000-01-01 12:00', '3 days 12 hours', '2000-01-15 12:00');
    echo $period->toString();            // Every 3 days and 12 hours from 2000-01-01 12:00:00 to 2000-01-15 12:00:00
    echo "
    ";
    echo $period->toIso8601String();     // 2000-01-01T12:00:00+00:00/P3DT12H/2000-01-15T12:00:00+00:00
    

    定期使用并默认返回Carbon实例,但是您可以轻松地设置/获取要使用的日期类,例如以获取不可变的日期或任何实现CarbonInterface的类。

    $period = new CarbonPeriod;
    $period->setDateClass(CarbonImmutable::class);
    $period->every('3 days 12 hours')->since('2000-01-01 12:00')->until('2000-01-15 12:00');
    
    echo $period->getDateClass();              // CarbonCarbonImmutable
    echo "n";
    echo $period->getStartDate();              // 2000-01-01 12:00:00
    echo "n";
    echo get_class($period->getStartDate());   // CarbonCarbonImmutable
    

    CarbonPeriod具有forEach()map()辅助方法:

    $period = CarbonPeriod::create('2018-04-21', '3 days', '2018-04-27');
    $dates = $period->map(function (Carbon $date) {
        return $date->format('m-d');
    });
    // Or with PHP 7.4:
    // $dates = $period->map(fn(Carbon $date) => $date->format('m-d'));
    $array = iterator_to_array($dates); // $dates is a iterable Generator
    var_dump($array);
    echo implode(', ', $array);
    /*
    array(3) {
      [0]=>
      string(5) "04-21"
      [1]=>
      string(5) "04-24"
      [2]=>
      string(5) "04-27"
    }
    04-21, 04-24, 04-27
    */
    echo "
    ";
    
    // Here is what happens under the hood:
    $period->forEach(function (Carbon $date) {
        echo $date->format('m-d')."
    ";
    });
    /*
    04-21
    04-24
    04-27
    */
    

    与所有其他Carbon类一样,CarbonPeriod有一种cast()方法可以将其转换:

    $period = CarbonPeriod::create('2000-01-01 12:00', '3 days 12 hours', '2000-01-15 12:00');
    
    // It would also works if your class extends DatePeriod
    class MyPeriod extends CarbonPeriod {}
    
    echo get_class($period->cast(MyPeriod::class)); // MyPeriod
    
    // Shortcut to export as raw DatePeriod:
    echo get_class($period->toDatePeriod());   // DatePeriod
    

    您可以检查期间是否跟随自己。期间如下周期如果的第一次迭代日期等于的最后一次迭代日期 +的间隔例如,[2019-02-01 => 2019-02-16]下面的 示例[2019-01-15 => 2019-01-31](假设通过该时段的开始和结束均未排除,并以(1天)为间隔)。

    $a = CarbonPeriod::create('2019-01-15', '2019-01-31');
    $b = CarbonPeriod::create('2019-02-01', '2019-02-16');
    
    var_dump($b->follows($a));               // bool(true)
    var_dump($a->isFollowedBy($b));          // bool(true)
    // ->isConsecutiveWith($period) is true if it either ->follows($period) or ->isFollowedBy($period)
    var_dump($b->isConsecutiveWith($a));     // bool(true)
    var_dump($a->isConsecutiveWith($b));     // bool(true)
    

    contains()方法使您可以检查日期是否在时间段范围内。

    $period = CarbonPeriod::create('2019-01-15', '2019-01-31');
    
    var_dump($period->contains('2019-01-22'));         // bool(true)
    

    比较包括开始和结束,除非您在选项中排除它们,并且就此而言contains(),排除只排除确切的日期,因此:

    $period = CarbonPeriod::create('2019-01-15', '2019-01-31', CarbonPeriod::EXCLUDE_END_DATE);
    
    var_dump($period->contains('2019-01-31 00:00:00')); // bool(false)
    var_dump($period->contains('2019-01-30 23:59:59')); // bool(true)
    

    您可以使用开始/结束比较方法(忽略排除项)进行更精确的比较:

    • startsAt() 开始==日期
    • startsBefore() 开始<日期
    • startsBeforeOrAt() 开始<=日期
    • startsAfter() 开始>日期
    • startsAfterOrAt() 开始> =日期
    • endsAt() 结束==日期
    • endsBefore() 结束<日期
    • endsBeforeOrAt() 结束<=日期
    • endsAfter() 结束>日期
    • endsAfterOrAt() 结束> =日期
    • isStarted() 现在开始<=
    • isEnded() 结束<=现在
    • isInProgress() 开始但未结束

    CarbonTimeZone

    从Carbon 2开始,时区现在由CarbonTimeZone 扩展DateTimeZone的专用类处理

    $tz = new CarbonTimeZone('Europe/Zurich'); // instance way
    $tz = CarbonTimeZone::create('Europe/Zurich'); // static way
    
    // Get the original name of the timezone (can be region name or offset string):
    echo $tz->getName();                 // Europe/Zurich
    echo "
    ";
    // Casting a CarbonTimeZone to string will automatically call getName:
    echo $tz;                            // Europe/Zurich
    echo "
    ";
    echo $tz->getAbbreviatedName();      // cet
    echo "
    ";
    // With DST on:
    echo $tz->getAbbreviatedName(true);  // cest
    echo "
    ";
    // Alias of getAbbreviatedName:
    echo $tz->getAbbr();                 // cet
    echo "
    ";
    echo $tz->getAbbr(true);             // cest
    echo "
    ";
    // toRegionName returns the first matching region or false, if timezone was created with a region name,
    // it will simply return this initial value.
    echo $tz->toRegionName();            // Europe/Zurich
    echo "
    ";
    // toOffsetName will give the current offset string for this timezone:
    echo $tz->toOffsetName();            // +01:00
    echo "
    ";
    // As with DST, this offset can change depending on the date, you may pass a date argument to specify it:
    $winter = Carbon::parse('2018-01-01');
    echo $tz->toOffsetName($winter);     // +01:00
    echo "
    ";
    $summer = Carbon::parse('2018-07-01');
    echo $tz->toOffsetName($summer);     // +02:00
    
    // With no parameters, a default timezone is created:
    echo new CarbonTimeZone();           // UTC
    echo "
    ";
    echo CarbonTimeZone::create();       // UTC
    

    默认时区由date_default_timezone_get给出, 因此它将由INI设置date.timezone驱动, 但是您确实应该在应用程序级别使用date_default_timezone_set覆盖它 "UTC",如果您打算或已经使用其他时区, 则应将其设置为,默认情况下,请阅读以下文章: 始终使用UTC日期和时间

    它解释了为什么UTC是可靠的标准。而且,这种最佳实践在PHP中甚至更为重要,因为PHP DateTime API有许多错误,其中包括偏移量更改和DST时区。其中一些出现在次要版本上,甚至出现在补丁版本上(例如,在PHP 7.1.7和7.1.8上运行相同的代码,您可以获得不同的结果),而某些错误甚至尚未修复。因此,我们强烈建议您在任何地方都使用UTC,并且仅在要显示日期时才更改时区。请参阅我们的第一个宏示例

    虽然区域时区(“大陆/城市”)可以具有DST,因此一年中的偏移量可变,但偏移量时区具有固定的固定偏移量:

    $tz = CarbonTimeZone::create('+03:00'); // full string
    $tz = CarbonTimeZone::create(3); // or hour integer short way
    
    echo $tz->getName();                 // +03:00
    echo "
    ";
    echo $tz;                            // +03:00
    echo "
    ";
    // toRegionName will try to guess what region it could be:
    echo $tz->toRegionName();            // Europe/Helsinki
    echo "
    ";
    // to guess with DST off:
    echo $tz->toRegionName(null, 0);     // Europe/Moscow
    echo "
    ";
    // toOffsetName will give the initial offset no matter the date:
    echo $tz->toOffsetName();            // +03:00
    echo "
    ";
    echo $tz->toOffsetName($winter);     // +03:00
    echo "
    ";
    echo $tz->toOffsetName($summer);     // +03:00
    

    您还可以将区域时区相互转换为偏移时区。

    $tz = new CarbonTimeZone(7);
    
    echo $tz;                            // +07:00
    echo "
    ";
    $tz = $tz->toRegionTimeZone();
    echo $tz;                            // Asia/Novosibirsk
    echo "
    ";
    $tz = $tz->toOffsetTimeZone();
    echo $tz;                            // +07:00
    

    您可以CarbonTimeZone使用instance()方法根据混合值创建一个

    $tz = CarbonTimeZone::instance(new DateTimeZone('Europe/Paris'));
    
    echo $tz;                            // Europe/Paris
    echo "
    ";
    
    // Bad timezone will return false without strict mode
    Carbon::useStrictMode(false);
    $tz = CarbonTimeZone::instance('Europe/Chicago');
    var_dump($tz);                       // bool(false)
    echo "
    ";
    
    // or throw an exception using strict mode
    Carbon::useStrictMode(true);
    try {
        CarbonTimeZone::instance('Europe/Chicago');
    } catch (InvalidArgumentException $exception) {
        $error = $exception->getMessage();
    }
    echo $error;                         // Unknown or bad timezone (Europe/Chicago)
    
    // as some value cannot be dump as string in an error message or
    // have unclear dump, you may pass a second argument to display
    // instead in the errors
    Carbon::useStrictMode(true);
    try {
        $mixedValue = ['dummy', 'array'];
        CarbonTimeZone::instance($mixedValue, json_encode($mixedValue));
    } catch (InvalidArgumentException $exception) {
        $error = $exception->getMessage();
    }
    echo $error;                         // Unknown or bad timezone (["dummy","array"])
    

    迁移到Carbon 2

    如果您打算从Carbon 1迁移到Carbon 2,请注意以下重要更改,您应该注意。

    • 默认值(省略参数时),用于$month$day在所述 ::create()方法现在1(分别为值从当前日期在碳1)。而且$hour$minute和的默认值$second现在是 0,用于省略的值,但是您仍然可以显式传递null 以获取从现在开始的当前值(与Carbon 1中的行为类似)。
    • 现在,您到处都能获得微秒的精度,这也意味着同一秒中的2个日期不再相等,而同一微秒中的2个日期不再相等。
    • $date->jsonSerialize()并且json_encode($date)不再返回数组,而是简单的字符串:"2017-06-27T13:14:15.000000Z"这样可以在JavaScript中更轻松地创建日期。您仍然可以使用以下方法获得以前的行为:
      Carbon::serializeUsing(function ($date) {
          return [
              'date' => $date->toDateTimeString(),
          ] + (array) $date->tz;
      });
    • $date->setToStringFormat()闭包不再返回格式,而是最终字符串。因此,您可以在Carbon 1中返回任何字符串和以下内容:
      Carbon::setToStringFormat(function ($date) {
          return $date->year === 1976 ?
              'jS of F g:i:s a' :
              'jS of F, Y g:i:s a';
      });
      会变成碳2:
      Carbon::setToStringFormat(function ($date) {
          return $date->formatLocalized($date->year === 1976 ?
              'jS of F g:i:s a' :
              'jS of F, Y g:i:s a'
          );
      });
    • setWeekStartsAt并且setWeekEndsAt不再对超出范围的值抛出异常,但它们也已弃用。
    • isSameMonthisCurrentMonth现在返回false在不同年份同一月份,但你可以通过false作为第二参数isSameMonth或第一参数isCurrentMonth比较忽略的一年。
    • ::compareYearWithMonth()::compareYearWithMonth()已被删除。严格比较现在是默认设置。而且,您可以将isSame / isCurrent的下一个参数设置为false,以获取仅月份的比较。
    • 当我们删除PHP 5时,$selfmixin不再需要,$this 而应该使用它
    • 由于PHP 7.1+完美支持微秒,useMicrosecondsFallback并且 isMicrosecondsFallbackEnabled不再需要,因此已被删除。
    • 在Carbon 1中,对CarbonInterval (ex:)的未知方法的调用CarbonInterval::anything()仅返回null。现在他们抛出异常。
    • 在Carbon 1中,dayOfYear从开始0现在开始于1
    • 所有人!在Carbon 1中使用的所有其他方法应继续与Carbon 2相同。
  • 相关阅读:
    使用公钥和私钥实现LINUX下免密登录
    XML入门
    JSP页面中的errorPage属性和web.xml<error-page>标签的区别
    JAVA、TOMCAT环境变量配置
    在Eclipse Neon中导入serlvet-api等jar包
    56. Merge Intervals
    55. Jump Game
    34. Find First and Last Position of Element in Sorted Array
    33. Search in Rotated Sorted Array
    3. Longest Substring Without Repeating Characters
  • 原文地址:https://www.cnblogs.com/zx-admin/p/12367201.html
Copyright © 2020-2023  润新知