# Introduction
學習一個框架, Ray 的想法是, 在深入理解底層實作的原理之前, 應該先知道這個框架的 使用方法
; 先學習怎麼使用這個前人造的輪子, 再學習怎麼樣造一個輪子。
所以本篇文章重點在於細讀官方文件, 並將內容理解後以 Q&A 的方式記錄下來, 加速學習以及查詢。
Laravel Carbon 是 extends 哪個 PHP class?
DateTime class
以下的 Laravel example code 的意思是?
- Example:
<?php
$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(12) "Wednesday 10"
var_dump($modifiedMutable->isoFormat('dddd D')); // string(12) "Wednesday 10"
var_dump($modifiedImmutable === $immutable); // bool(false)
var_dump($immutable->isoFormat('dddd D')); // string(9) "Tuesday 9"
var_dump($modifiedImmutable->isoFormat('dddd D')); // string(12) "Wednesday 10"
$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) - Answer:
Carbon::now()
所取得的 object 可被修改, 即同一個 objectCarbonImmutable::now()
取得的 object 不可被修改, 每次取都是新的
mutable 與 immutable 可互相轉換
以下的 Laravel example code, 意思相同嗎?
- Example:
<?php
$time = Carbon::now;
$time = new Carbon(); - Answer:
一樣
以下的 Laravel example code 的意思是?
Example:
<?php
$now = Carbon::now();
$nowInLondonTz = Carbon::now(new DateTimeZone('Europe/London'));
$nowInLondonTz = Carbon::now('Europe/London');
echo $nowInLondonTz->tzName;
echo "\n";
$date = Carbon::now('+13:30');
echo $date->tzName;
echo "\n";
echo $date->utcOffset();
echo "\n";
$date->utcOffset(180);
echo $date->tzName;
echo "\n";
echo $date->utcOffset();Answer:
<?php
$now = Carbon::now(); // 使用 default timezone
// 建議使用 UTC, 然後透過轉換時區轉成使用者的時區
$nowInLondonTz = Carbon::now(new DateTimeZone('Europe/London'));
// 直接設定時區
$nowInLondonTz = Carbon::now('Europe/London');
echo $nowInLondonTz->tzName; // Europe/London
echo "\n";
// 直接帶入 offset 設定時區
$date = Carbon::now('+13:30');
echo $date->tzName; // +13:30
echo "\n";
// 取得距 UTC 的 offset (分鐘)
echo $date->utcOffset(); // 810
echo "\n";
// 重設為距 UTC 180 分鐘
$date->utcOffset(180);
// timezone 變為距 UTC 180 分鐘, 即 3 小時
echo $date->tzName; // +03:00
echo "\n";
echo $date->utcOffset(); // 180
以下的 Laravel example code 的意思是?
- Example:
<?php
echo (new Carbon('first day of December 2008'))->addWeeks(2);
echo "\n";
echo Carbon::parse('first day of December 2008')->addWeeks(2); - Answer:
都是 // 2008-12-15 00:00:00, 使用 parse 少一個 bracket
以下的 Laravel example code 的意思是?
- Example:
<?php
$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.";
} - Answer:
使用 hasRelativeKeywords() 來判斷帶入的 string 是否為 relative
以下的 Laravel example code 的意思是?
- Example:
<?php
$now = Carbon::now();
echo $now; // 2021-02-09 18:29:22
echo "\n";
$today = Carbon::today();
echo $today; // 2021-02-09 00:00:00
echo "\n";
$tomorrow = Carbon::tomorrow('Europe/London');
echo $tomorrow; // 2021-02-10 00:00:00
echo "\n";
$yesterday = Carbon::yesterday();
echo $yesterday; // 2021-02-08 00:00:00 - Answer:
可使用 Carbon 的 today(), yesterday(), tomorrow() 取得相對應的日期, 也可帶入 timezone
以下的 Laravel example code 的意思是?
- Example:
<?php
$year = 2000; $month = 4; $day = 19;
$hour = 20; $minute = 30; $second = 15; $tz = 'Europe/Madrid';
echo Carbon::createFromDate($year, $month, $day, $tz)."\n";
echo Carbon::createMidnightDate($year, $month, $day, $tz)."\n";
echo Carbon::createFromTime($hour, $minute, $second, $tz)."\n";
echo Carbon::createFromTimeString("$hour:$minute:$second", $tz)."\n";
echo Carbon::create($year, $month, $day, $hour, $minute, $second, $tz)."\n"; - Answer:
000-04-19 06:58:09
2000-04-19 00:00:00
2021-04-11 20:30:15
2021-04-11 20:30:15
2000-04-19 20:30:15
createFromDate, 時間為預設
createMidnightDate, 時間為 00:00:00
createFromTime, 年月日為預設
createFromTimeString, 年月日為預設
create(), 帶 null 皆為預設
以下的 Laravel example code 的意思是?
- Example:
<?php
$xmasThisYear = Carbon::createFromDate(null, 12, 25);
$Y2K = Carbon::create(2000, 1, 1, 0, 0, 0);
$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) - Answer:
<?php
$xmasThisYear = Carbon::createFromDate(null, 12, 25); // Year 為 default
$Y2K = Carbon::create(2000, 1, 1, 0, 0, 0); // 等同 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 需為 0-99, 帶入 -2 會報錯, 若帶 99 為 22 時加上 99 分, 即 23:39
// 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)
# Additional
以下的 Laravel example code 的意思是?
- Example:
<?php
echo Carbon::createFromFormat('Y-m-d H', '1975-05-21 22')->toDateTimeString(); - Answer:
// 1975-05-21 22:00:00
使用 createFromFormat() 來自定義 format
以下的 Laravel example code 的意思是?
- Example:
<?php
echo Carbon::create(2000, 1, 35, 13, 0, 0);
echo "\n";
try {
Carbon::createSafe(2000, 1, 35, 13, 0, 0);
} catch (\Carbon\Exceptions\InvalidDateException $exp) {
echo $exp->getMessage();
} - Answer:
// 2000-02-04 13:00:00
// day : 35 is not a valid value.
使用 createSafe() 來產生 Carbon exception
以下的 Laravel example code 的意思是?
- Example:
<?php
Carbon::parse($request->changed_at)->setTimezone(config('app.timezone')); - Answer:
就算帶入的 string 本身已經是 ISO8601 格式, 如果不特別使用 setTimezone 或 toIso8601String 的話, 存入 MySQL 的 date 是不會根據當前的 timezone 去做轉換的, 也就是 Laravel 會無視 timezone 的部分, 直接將 datetime 的部分存入資料庫, 這樣就失去 ISO8601 註明 timezone 意義了
以下的 Laravel example code 的意思是?
- Example:
<?php
public function test()
{
Carbon::setTestNow(Carbon::parse('January 1, 2020'))
} - Answer:
使用 setTestNow() 可以設定 Carbon 的當前時間
留言