CodeIgniter4 日期與時(shí)間類

2020-08-14 16:07 更新

CodeIgniter 提供了一個(gè)完全本地化的,不變的日期與時(shí)間類,這個(gè)類建立在 PHP 原生的 DateTime 類之上,但使用了 Intl 擴(kuò)展程序的功能 來進(jìn)行跨時(shí)區(qū)轉(zhuǎn)換時(shí)間并正確顯示不同語言環(huán)境的輸出。 這個(gè)類就是 Time 類,位于 CodeIgniter\I18n 命名空間中。

注解

由于 Time 類是 DateTime 類的拓展,因此如果您需要此類不提供的功能,可以在 DateTime 類中找到它們。

實(shí)例化

有多種創(chuàng)建 Time 類實(shí)例的方法。 首先是像其他類一樣簡(jiǎn)單地創(chuàng)建一個(gè)新實(shí)例。 當(dāng)您以這種方式進(jìn)行操作時(shí),您可以傳遞一 個(gè)表示所需時(shí)間的字符串。 它可以是 PHP 的 strtotime() 函數(shù)可以解析的任何字符串:

use CodeIgniter\I18n\Time;


$myTime = new Time('+3 week');
$myTime = new Time('now');

你可以在參數(shù)中分別傳遞表示時(shí)區(qū)和語言環(huán)境的字符串。時(shí)區(qū)可以是 PHP 的 DateTimeZone 類 可以支持所有時(shí)區(qū)。 語言環(huán)境可以是 PHP 的 Locale 類支持的任何語言環(huán)境。 如果未提供語言環(huán)境或時(shí)區(qū),則將使用應(yīng)用程序配置中的默認(rèn)值。

$myTime = new Time('now', 'America/Chicago', 'en_US');

now()

Time 類有幾個(gè)有用的 helper 方法來實(shí)例化這個(gè)類,首先是 now() 方法,該方法返回設(shè)置為當(dāng)前時(shí)間的新實(shí)例。 您可以在參數(shù)中 提供表示時(shí)區(qū)和語言環(huán)境的字符串。 如果未提供語言環(huán)境或時(shí)區(qū),則將使用應(yīng)用程序配置中的默認(rèn)值。

$myTime = Time::now('America/Chicago', 'en_US');

parse()

這個(gè) helper 程序方法是默認(rèn)的構(gòu)造函數(shù)的 static 版本。它以 DateTime 類構(gòu)造函數(shù)可接受的任何表示時(shí)間的字符串為第一個(gè)參數(shù), 將表示時(shí)區(qū)的字符串作為第二個(gè)參數(shù),將表示語言環(huán)境的字符串作為第三個(gè)參數(shù):

$myTime = Time::parse('next Tuesday', 'America/Chicago', 'en_US');

today()

返回一個(gè)新實(shí)例,該實(shí)例的日期設(shè)置為當(dāng)前日期,時(shí)間設(shè)置為午夜。它在第一個(gè)和第二個(gè)參數(shù)中分別接受表示時(shí)區(qū)和語言環(huán)境 的字符串:

$myTime = Time::today('America/Chicago', 'en_US');

yesterday()

返回一個(gè)新實(shí)例,該實(shí)例的日期設(shè)置為昨天的日期,時(shí)間設(shè)置為午夜。它在第一個(gè)和第二個(gè)參數(shù)中分別接受表示時(shí)區(qū)和語言環(huán)境 的字符串:

$myTime = Time::yesterday('America/Chicago', 'en_US');

tomorrow()

返回一個(gè)新實(shí)例,該實(shí)例的日期設(shè)置為明天的日期,時(shí)間設(shè)置為午夜。它在第一個(gè)和第二個(gè)參數(shù)中分別接受表示時(shí)區(qū)和語言環(huán)境 的字符串:

$myTime = Time::tomorrow('America/Chicago', 'en_US');

createFromDate()

給定 、 、 的單獨(dú)輸入,將返回一個(gè)新實(shí)例。如果未提供它們?nèi)齻€(gè)中的任何一個(gè),它將使用當(dāng)前時(shí)間的該值進(jìn)行填充。在第四 和第五個(gè)參數(shù)中接受時(shí)區(qū)和語言環(huán)境的字符串:

$today       = Time::createFromDate();      // 將使用現(xiàn)在時(shí)間的年、月、日
$anniversary = Time::createFromDate(2018);  // 將使用現(xiàn)在時(shí)間的月、日
$date        = Time::createFromDate(2018, 3, 15, 'America/Chicago', 'en_US');

createFromTime()

createFromDate() 相似,只不過它只和 小時(shí) 、 分鐘 有關(guān)。 使用當(dāng)前時(shí)間的日期作為 Time 實(shí)例的日期 部分。 在第四個(gè)和第五個(gè)參數(shù)中接受時(shí)區(qū)和語言環(huán)境的字符串:

$lunch  = Time::createFromTime(11, 30)       // 11:30 am today
$lunch  = Time::createFromTime(11, 30)      // 今天的 11:30
$dinner = Time::createFromTime(18, 00, 00)  // 6:00 pm today
$dinner = Time::createFromTime(18, 00, 00)  // 今天的 18:00
$time   = Time::createFromTime($hour, $minutes, $seconds, $timezone, $locale);

create()

前面兩種方法的組合,將 、 、 、 小時(shí) 、 分鐘 作為單獨(dú)的參數(shù)。 任何未提供的值將使用當(dāng)前的日期和時(shí)間來確定。 在第四個(gè)和第五個(gè)參數(shù)中接受時(shí)區(qū)和語言環(huán)境的字符串:

$time = Time::create($year, $month, $day, $hour, $minutes, $seconds, $timezone, $locale);

createFromFormat()

它是替代 DateTime 構(gòu)造函數(shù)的方法。它允許同時(shí)設(shè)置時(shí)區(qū),并返回一個(gè) Time 實(shí)例,而不是 DateTime 實(shí)例:

$time = Time::createFromFormat('j-M-Y', '15-Feb-2009', 'America/Chicago');

createFromTimestamp()

該方法使用 UNIX 時(shí)間戳以及時(shí)區(qū)和語言環(huán)境(可選)來創(chuàng)建新的 Time 實(shí)例:

$time = Time::createFromTimestamp(1501821586, 'America/Chicago', 'en_US');

instance()

與提供 DateTime 實(shí)例的其他 library 一起使用時(shí),可以使用此方法將其轉(zhuǎn)換為 Time 實(shí)例,可以選擇設(shè)置語言環(huán)境。 時(shí)區(qū)將根據(jù)傳入的 DateTime 實(shí)例自動(dòng)確定:

$dt   = new DateTime('now');
$time = Time::instance($dt, 'en_US');

toDateTime()

它不是用來實(shí)例化的,此方法與 實(shí)例化 方法相反,它允許您將 Time 實(shí)例轉(zhuǎn)換為 DateTime 實(shí)例。這樣會(huì)保留時(shí)區(qū)設(shè)置, 但會(huì)丟失語言環(huán)境,因?yàn)?DateTime 并不了解語言環(huán)境:

$datetime = Time::toDateTime();

顯示時(shí)間值

由于 Time 是 DateTime 類的拓展,因此您將獲得提供的所有輸出方法,包括 format() 方法。 但是,DateTime 方法不提供本地化結(jié)果。 不過, Time 類提供了許多 helper 方法來顯示值的本地化版本。

toLocalizedString()

這是 DateTime 的 format() 方法的本地化版本。但是,必須使用 IntlDateFormatter 類可以接受的值, 而不能使用你熟悉的值。完整的值列表可以在 這里 找到。

$time = Time::parse('March 9, 2016 12:00:00', 'America/Chicago');
echo $time->toLocalizedString('MMM d, yyyy');   // March 9, 2016

toDateTimeString()

這是與 IntlDateFormatter 一起使用的三種輔助方法中的第一種,無需記住它們的值。這將返回一個(gè)格式化的字符串, 該字符串的格式與數(shù)據(jù)庫中日期時(shí)間列的常用格式相同(Y-m-d H:i:s):

$time = Time::parse('March 9, 2016 12:00:00', 'America/Chicago');
echo $time->toDateTimeString();     // 2016-03-09 12:00:00

toDateString()

僅返回時(shí)間與日期的日期部分:

$time = Time::parse('March 9, 2016 12:00:00', 'America/Chicago');
echo $time->toDateTimeString();     // 2016-03-09

toTimeString()

僅返回時(shí)間與日期的時(shí)間部分:

$time = Time::parse('March 9, 2016 12:00:00', 'America/Chicago');
echo $time->toTimeString();     // 12:00:00

humanize()

此方法返回一個(gè)字符串,該字符串以易于理解的人類可讀格式顯示當(dāng)前日期或時(shí)間與實(shí)例之間的差異。它會(huì)返回“ 3 小時(shí)前”、“ 1 個(gè)月內(nèi)” 等字符串:

// 假設(shè)現(xiàn)在的時(shí)間是:March 10, 2017 (America/Chicago)
$time = Time::parse('March 9, 2016 12:00:00', 'America/Chicago');


echo $time->humanize();     // 1 year ago

通過以下方式確定顯示的確切時(shí)間:

時(shí)間差異 結(jié)果
$time > 1 year && < 2 years in 1 year / 1 year ago
$time > 1 month && < 1 year in 6 months / 6 months ago
$time > 7 days && < 1 month in 3 weeks / 3 weeks ago
$time > today && < 7 days in 4 days / 4 days ago
$time == tomorrow / yesterday Tomorrow / Yesterday
$time > 59 minutes && < 1 day 1:37pm
$time > now && < 1 hour in 35 minutes / 35 minutes ago
$time == now Now

返回的結(jié)果的語言被語言文件 Time.php 所控制。

處理各個(gè)時(shí)間的值

Time 對(duì)象提供了許多方法來獲取和設(shè)置現(xiàn)有實(shí)例的各個(gè)項(xiàng)目,例如年、月、時(shí)等。通過以下方法檢索到的的所有值都會(huì)被完全本地化, 并遵守創(chuàng)建 Time 實(shí)例所使用的語言環(huán)境。

以下所有 getX 和 setX 方法也可以當(dāng)作類屬性使用。因此,對(duì)像 getYear 這樣調(diào)用的方法也可以通過 $time->year 進(jìn)行調(diào)用,依此類推。

獲取器

有以下幾種基本的獲取器:

$time = Time::parse('August 12, 2016 4:15:23pm');


echo $time->getYear();      // 2016
echo $time->getMonth();     // 8
echo $time->getDay();       // 12
echo $time->getHour();      // 16
echo $time->getMinute();    // 15
echo $time->getSecond();    // 23


echo $time->year;           // 2016
echo $time->month;          // 8
echo $time->day;            // 12
echo $time->hour;           // 16
echo $time->minute;         // 15
echo $time->second;         // 23

除這些之外,還有許多方法可以獲取有關(guān)日期的其他信息:

$time = Time::parse('August 12, 2016 4:15:23pm');


echo $time->getDayOfWeek();     // 6 - 但可能會(huì)因地區(qū)的一個(gè)星期的第一天而有所不同
echo $time->getDayOfYear();     // 225
echo $time->getWeekOfMonth();   // 2
echo $time->getWeekOfYear();    // 33
echo $time->getTimestamp();     // 1471018523 - UNIX 時(shí)間戳
echo $time->getQuarter();       // 3


echo $time->dayOfWeek;          // 6
echo $time->dayOfYear;          // 225
echo $time->weekOfMonth;        // 2
echo $time->weekOfYear;         // 33
echo $time->timestamp;          // 1471018523
echo $time->quarter;            // 3

getAge()

返回 Time 實(shí)例與當(dāng)前時(shí)間之間的差值(以年為單位)。主要是用于根據(jù)某人的生日檢查其年齡:

$time = Time::parse('5 years ago');


echo $time->getAge();   // 5
echo $time->age;        // 5

getDST()

根據(jù) Time 實(shí)例是否正在遵守夏令時(shí),返回布爾值 true 或 false:

echo Time::createFromDate(2012, 1, 1)->getDst();     // false
echo Time::createFromDate(2012, 9, 1)->dst;     // true

getLocal()

如果 Time 實(shí)例的時(shí)區(qū)與 web 應(yīng)用程序當(dāng)前所在的時(shí)區(qū)位于同一時(shí)區(qū),則返回布爾值 true:

echo Time::now()->getLocal();                   // true
echo Time::now('Europe/London')->getLocal();    // false

getUtc()

如果 Time 實(shí)例使用 UTC 時(shí)間,則返回 true:

echo Time::now('America/Chicago')->getUtc();    // false
echo Time::now('UTC')->utc;                     // true

getTimezone()

返回一個(gè)新的 DateTimeZone 實(shí)例,該實(shí)例是 Time 實(shí)例的時(shí)區(qū):

$tz = Time::now()->getTimezone();
$tz = Time::now()->timezone;


echo $tz->getName();
echo $tz->getOffset();

getTimezoneName()

返回 Time 實(shí)例的 完整時(shí)區(qū)字符串

echo Time::now('America/Chicago')->getTimezoneName();   // America/Chicago
echo Time::now('Europe/London')->timezoneName;          // Europe/London

設(shè)置器

存在以下的基本設(shè)置器。如果設(shè)置的任何值超出允許范圍,則會(huì)拋出 InvalidArgumentExeption 。

注解

所有設(shè)置器都將返回一個(gè)新的 Time 實(shí)例,而原始實(shí)例保持不變。

如果值超出范圍,則設(shè)置器將拋出 InvalidArgumentException。

$time = $time->setYear(2017);
$time = $time->setMonthNumber(4);           // April
$time = $time->setMonthLongName('April');
$time = $time->setMonthShortName('Feb');    // February
$time = $time->setDay(25);
$time = $time->setHour(14);                 // 2:00 pm
$time = $time->setMinute(30);
$time = $time->setSecond(54);

setTimezone()

將時(shí)間從當(dāng)前時(shí)區(qū)轉(zhuǎn)換為新時(shí)區(qū):

$time  = Time::parse('May 10, 2017', 'America/Chicago');
$time2 = $time->setTimezone('Europe/London');           // 將時(shí)間從當(dāng)前時(shí)區(qū)轉(zhuǎn)換為新時(shí)區(qū)


echo $time->timezoneName;   // American/Chicago
echo $time2->timezoneName;  // Europe/London

setTimestamp()

返回日期設(shè)置為新時(shí)間戳的新實(shí)例:

$time = Time::parse('May 10, 2017', 'America/Chicago');
$time2 = $time->setTimestamp(strtotime('April 1, 2017'));


echo $time->toDateTimeString();     // 2017-05-10 00:00:00
echo $time2->toDateTimeString();     // 2017-04-01 00:00:00

Modifying the Value

通過以下方法,您可以通過在當(dāng)前時(shí)間上增加或減少值來修改日期。這不會(huì)修改現(xiàn)有的 Time 實(shí)例,只會(huì)返回一個(gè)新實(shí)例。

$time = $time->addSeconds(23);
$time = $time->addMinutes(15);
$time = $time->addHours(12);
$time = $time->addDays(21);
$time = $time->addMonths(14);
$time = $time->addYears(5);


$time = $time->subSeconds(23);
$time = $time->subMinutes(15);
$time = $time->subHours(12);
$time = $time->subDays(21);
$time = $time->subMonths(14);
$time = $time->subYears(5);

比較兩個(gè) Time

以下方法使您可以將一個(gè) Time 實(shí)例與另一個(gè) Time 實(shí)例進(jìn)行比較。在進(jìn)行比較之前,首先將所有比較轉(zhuǎn)換為 UTC,以確保不同時(shí)區(qū)都正確響應(yīng)。

equals()

確定傳入的日期時(shí)間是否等于當(dāng)前實(shí)例。在這種情況下,相等意味著它們表示同一時(shí)間,并且不需要位于同一時(shí)區(qū),因?yàn)閮蓚€(gè)時(shí)間都轉(zhuǎn)換為 UTC 并以這種方式進(jìn)行比較:

$time1 = Time::parse('January 10, 2017 21:50:00', 'America/Chicago');
$time2 = Time::parse('January 11, 2017 03:50:00', 'Europe/London');


$time1->equals($time2);    // true

要作比較的值可以是 Time 實(shí)例,DateTime 實(shí)例或 DateTime 類可以理解的任何表示時(shí)間的字符串。當(dāng)將字符串作為第一個(gè)參數(shù)傳遞時(shí), 可以將時(shí)區(qū)字符串作為第二個(gè)參數(shù)傳遞。 如果沒有給出時(shí)區(qū),將使用配置的默認(rèn)值:

$time1->equals('January 11, 2017 03:50:00', 'Europe/London');  // true

sameAs()

除了只有在日期,時(shí)間和時(shí)區(qū)都相同時(shí)才返回 true,這與 equals 方法相同:

$time1 = Time::parse('January 10, 2017 21:50:00', 'America/Chicago');
$time2 = Time::parse('January 11, 2017 03:50:00', 'Europe/London');


$time1->sameAs($time2);    // false
$time2->sameAs('January 10, 2017 21:50:00', 'America/Chicago');    // true

isBefore()

檢查傳入的時(shí)間是否在當(dāng)前實(shí)例之前。兩種情況下都針對(duì) UTC 版本進(jìn)行了比較:

$time1 = Time::parse('January 10, 2017 21:50:00', 'America/Chicago');
$time2 = Time::parse('January 11, 2017 03:50:00', 'America/Chicago');


$time1->isBefore($time2);  // true
$time2->isBefore($time1);  // false

要作比較的值可以是 Time 實(shí)例,DateTime 實(shí)例或 DateTime 類可以理解的任何表示時(shí)間的字符串。當(dāng)將字符串作為第一個(gè)參數(shù)傳遞時(shí), 可以將時(shí)區(qū)字符串作為第二個(gè)參數(shù)傳遞。 如果沒有給出時(shí)區(qū),將使用配置的默認(rèn)值:

$time1->isBefore('March 15, 2013', 'America/Chicago');  // false

isAfter()

除了檢查時(shí)間是否在傳入的時(shí)間之后,其他的與 isBefore() 完全相同:

$time1 = Time::parse('January 10, 2017 21:50:00', 'America/Chicago');
$time2 = Time::parse('January 11, 2017 03:50:00', 'America/Chicago');


$time1->isAfter($time2);  // false
$time2->isAfter($time1);  // true

查看差異

要直接比較兩個(gè) Times,可以使用 difference() 方法,該方法返回 CodeIgniter\I18n\TimeDifference 實(shí)例。第一個(gè)參數(shù)可以是 Time 實(shí)例、 DateTime 實(shí)例或帶有日期或時(shí)間的字符串。 如果在第一個(gè)參數(shù)中傳遞了表示時(shí)間字符串,則第二個(gè)參數(shù)可以是時(shí)區(qū)字符串:

$time = Time::parse('March 10, 2017', 'America/Chicago');


$diff = $time->difference(Time::now());
$diff = $time->difference(new DateTime('July 4, 1975', 'America/Chicago');
$diff = $time->difference('July 4, 1975 13:32:05', 'America/Chicago');

有了 TimeDifference 實(shí)例后,您可以使用多種方法來查找有關(guān)兩個(gè) Time 間的信息。如果比較時(shí)間在待比較時(shí)間之前,則返回值為負(fù)數(shù);反之, 如果比較時(shí)間在帶比較時(shí)間之后,則返回的值為正數(shù):

$current = Time::parse('March 10, 2017', 'America/Chicago');
$test    = Time::parse('March 10, 2010', 'America/Chicago');


$diff = $current->difference($test);


echo $diff->getYears();     // -7
echo $diff->getMonths();    // -84
echo $diff->getWeeks();     // -365
echo $diff->getDays();      // -2557
echo $diff->getHours();     // -61368
echo $diff->getMinutes();   // -3682080
echo $diff->getSeconds();   // -220924800

你可以用 getX() 方法,也可以像使用屬性一樣訪問計(jì)算值:

echo $diff->years;     // -7
echo $diff->months;    // -84
echo $diff->weeks;     // -365
echo $diff->days;      // -2557
echo $diff->hours;     // -61368
echo $diff->minutes;   // -3682080
echo $diff->seconds;   // -220924800

humanize()

與 Time 的 humanize() 方法非常相似,此方法返回一個(gè)字符串,該字符串以易于理解的格式顯示時(shí)間之間的時(shí)差。 它可以創(chuàng)建像“3 小時(shí)前”、“1 個(gè)月內(nèi)”這樣的的字符串。它們之間最大的區(qū)別在于最近日期的處理方式:

// Assume current time is: March 10, 2017 (America/Chicago)
// 假設(shè)現(xiàn)在時(shí)間是: March 10, 2017 (America/Chicago)
$time = Time::parse('March 9, 2016 12:00:00', 'America/Chicago');


echo $time->humanize();     // 1 year ago

通過以下方式確定顯示的確切時(shí)間:

時(shí)間差異 結(jié)果
$time > 1 year && < 2 years in 1 year / 1 year ago
$time > 1 month && < 1 year in 6 months / 6 months ago
$time > 7 days && < 1 month in 3 weeks / 3 weeks ago
$time > today && < 7 days in 4 days / 4 days ago
$time > 1 hour && < 1 day in 8 hours / 8 hours ago
$time > 1 minute && < 1 hour in 35 minutes / 35 minutes ago
$time < 1 minute Now

返回的結(jié)果的語言被語言文件 Time.php 所控制。

以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)