CodeIgniter 提供了一個完全本地化的,不變的日期與時間類,這個類建立在 PHP 原生的 DateTime 類之上,但使用了 Intl 擴展程序的功能 來進行跨時區(qū)轉(zhuǎn)換時間并正確顯示不同語言環(huán)境的輸出。 這個類就是 Time 類,位于 CodeIgniter\I18n 命名空間中。
注解
由于 Time 類是 DateTime 類的拓展,因此如果您需要此類不提供的功能,可以在 DateTime 類中找到它們。
有多種創(chuàng)建 Time 類實例的方法。 首先是像其他類一樣簡單地創(chuàng)建一個新實例。 當您以這種方式進行操作時,您可以傳遞一 個表示所需時間的字符串。 它可以是 PHP 的 strtotime() 函數(shù)可以解析的任何字符串:
use CodeIgniter\I18n\Time;
$myTime = new Time('+3 week');
$myTime = new Time('now');
你可以在參數(shù)中分別傳遞表示時區(qū)和語言環(huán)境的字符串。時區(qū)可以是 PHP 的 DateTimeZone 類 可以支持所有時區(qū)。 語言環(huán)境可以是 PHP 的 Locale 類支持的任何語言環(huán)境。 如果未提供語言環(huán)境或時區(qū),則將使用應用程序配置中的默認值。
$myTime = new Time('now', 'America/Chicago', 'en_US');
Time 類有幾個有用的 helper 方法來實例化這個類,首先是 now() 方法,該方法返回設置為當前時間的新實例。 您可以在參數(shù)中 提供表示時區(qū)和語言環(huán)境的字符串。 如果未提供語言環(huán)境或時區(qū),則將使用應用程序配置中的默認值。
$myTime = Time::now('America/Chicago', 'en_US');
這個 helper 程序方法是默認的構(gòu)造函數(shù)的 static 版本。它以 DateTime 類構(gòu)造函數(shù)可接受的任何表示時間的字符串為第一個參數(shù), 將表示時區(qū)的字符串作為第二個參數(shù),將表示語言環(huán)境的字符串作為第三個參數(shù):
$myTime = Time::parse('next Tuesday', 'America/Chicago', 'en_US');
返回一個新實例,該實例的日期設置為當前日期,時間設置為午夜。它在第一個和第二個參數(shù)中分別接受表示時區(qū)和語言環(huán)境 的字符串:
$myTime = Time::today('America/Chicago', 'en_US');
返回一個新實例,該實例的日期設置為昨天的日期,時間設置為午夜。它在第一個和第二個參數(shù)中分別接受表示時區(qū)和語言環(huán)境 的字符串:
$myTime = Time::yesterday('America/Chicago', 'en_US');
返回一個新實例,該實例的日期設置為明天的日期,時間設置為午夜。它在第一個和第二個參數(shù)中分別接受表示時區(qū)和語言環(huán)境 的字符串:
$myTime = Time::tomorrow('America/Chicago', 'en_US');
給定 年 、 月 、 日 的單獨輸入,將返回一個新實例。如果未提供它們?nèi)齻€中的任何一個,它將使用當前時間的該值進行填充。在第四 和第五個參數(shù)中接受時區(qū)和語言環(huán)境的字符串:
$today = Time::createFromDate(); // 將使用現(xiàn)在時間的年、月、日
$anniversary = Time::createFromDate(2018); // 將使用現(xiàn)在時間的月、日
$date = Time::createFromDate(2018, 3, 15, 'America/Chicago', 'en_US');
與 createFromDate() 相似,只不過它只和 小時 、 分鐘 和 秒 有關(guān)。 使用當前時間的日期作為 Time 實例的日期 部分。 在第四個和第五個參數(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);
前面兩種方法的組合,將 年 、 月 、 日 、 小時 、 分鐘 和 秒 作為單獨的參數(shù)。 任何未提供的值將使用當前的日期和時間來確定。 在第四個和第五個參數(shù)中接受時區(qū)和語言環(huán)境的字符串:
$time = Time::create($year, $month, $day, $hour, $minutes, $seconds, $timezone, $locale);
它是替代 DateTime 構(gòu)造函數(shù)的方法。它允許同時設置時區(qū),并返回一個 Time 實例,而不是 DateTime 實例:
$time = Time::createFromFormat('j-M-Y', '15-Feb-2009', 'America/Chicago');
該方法使用 UNIX 時間戳以及時區(qū)和語言環(huán)境(可選)來創(chuàng)建新的 Time 實例:
$time = Time::createFromTimestamp(1501821586, 'America/Chicago', 'en_US');
與提供 DateTime 實例的其他 library 一起使用時,可以使用此方法將其轉(zhuǎn)換為 Time 實例,可以選擇設置語言環(huán)境。 時區(qū)將根據(jù)傳入的 DateTime 實例自動確定:
$dt = new DateTime('now');
$time = Time::instance($dt, 'en_US');
它不是用來實例化的,此方法與 實例化 方法相反,它允許您將 Time 實例轉(zhuǎn)換為 DateTime 實例。這樣會保留時區(qū)設置, 但會丟失語言環(huán)境,因為 DateTime 并不了解語言環(huán)境:
$datetime = Time::toDateTime();
由于 Time 是 DateTime 類的拓展,因此您將獲得提供的所有輸出方法,包括 format() 方法。 但是,DateTime 方法不提供本地化結(jié)果。 不過, Time 類提供了許多 helper 方法來顯示值的本地化版本。
這是 DateTime 的 format() 方法的本地化版本。但是,必須使用 IntlDateFormatter 類可以接受的值, 而不能使用你熟悉的值。完整的值列表可以在 這里 找到。
$time = Time::parse('March 9, 2016 12:00:00', 'America/Chicago');
echo $time->toLocalizedString('MMM d, yyyy'); // March 9, 2016
這是與 IntlDateFormatter 一起使用的三種輔助方法中的第一種,無需記住它們的值。這將返回一個格式化的字符串, 該字符串的格式與數(shù)據(jù)庫中日期時間列的常用格式相同(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
僅返回時間與日期的日期部分:
$time = Time::parse('March 9, 2016 12:00:00', 'America/Chicago');
echo $time->toDateTimeString(); // 2016-03-09
僅返回時間與日期的時間部分:
$time = Time::parse('March 9, 2016 12:00:00', 'America/Chicago');
echo $time->toTimeString(); // 12:00:00
此方法返回一個字符串,該字符串以易于理解的人類可讀格式顯示當前日期或時間與實例之間的差異。它會返回“ 3 小時前”、“ 1 個月內(nèi)” 等字符串:
// 假設現(xiàn)在的時間是:March 10, 2017 (America/Chicago)
$time = Time::parse('March 9, 2016 12:00:00', 'America/Chicago');
echo $time->humanize(); // 1 year ago
通過以下方式確定顯示的確切時間:
時間差異 | 結(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 所控制。
Time 對象提供了許多方法來獲取和設置現(xiàn)有實例的各個項目,例如年、月、時等。通過以下方法檢索到的的所有值都會被完全本地化, 并遵守創(chuàng)建 Time 實例所使用的語言環(huán)境。
以下所有 getX 和 setX 方法也可以當作類屬性使用。因此,對像 getYear 這樣調(diào)用的方法也可以通過 $time->year 進行調(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 - 但可能會因地區(qū)的一個星期的第一天而有所不同
echo $time->getDayOfYear(); // 225
echo $time->getWeekOfMonth(); // 2
echo $time->getWeekOfYear(); // 33
echo $time->getTimestamp(); // 1471018523 - UNIX 時間戳
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
返回 Time 實例與當前時間之間的差值(以年為單位)。主要是用于根據(jù)某人的生日檢查其年齡:
$time = Time::parse('5 years ago');
echo $time->getAge(); // 5
echo $time->age; // 5
根據(jù) Time 實例是否正在遵守夏令時,返回布爾值 true 或 false:
echo Time::createFromDate(2012, 1, 1)->getDst(); // false
echo Time::createFromDate(2012, 9, 1)->dst; // true
如果 Time 實例的時區(qū)與 web 應用程序當前所在的時區(qū)位于同一時區(qū),則返回布爾值 true:
echo Time::now()->getLocal(); // true
echo Time::now('Europe/London')->getLocal(); // false
如果 Time 實例使用 UTC 時間,則返回 true:
echo Time::now('America/Chicago')->getUtc(); // false
echo Time::now('UTC')->utc; // true
返回一個新的 DateTimeZone 實例,該實例是 Time 實例的時區(qū):
$tz = Time::now()->getTimezone();
$tz = Time::now()->timezone;
echo $tz->getName();
echo $tz->getOffset();
返回 Time 實例的 完整時區(qū)字符串 :
echo Time::now('America/Chicago')->getTimezoneName(); // America/Chicago
echo Time::now('Europe/London')->timezoneName; // Europe/London
存在以下的基本設置器。如果設置的任何值超出允許范圍,則會拋出 InvalidArgumentExeption
。
注解
所有設置器都將返回一個新的 Time 實例,而原始實例保持不變。
如果值超出范圍,則設置器將拋出 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);
將時間從當前時區(qū)轉(zhuǎn)換為新時區(qū):
$time = Time::parse('May 10, 2017', 'America/Chicago');
$time2 = $time->setTimezone('Europe/London'); // 將時間從當前時區(qū)轉(zhuǎn)換為新時區(qū)
echo $time->timezoneName; // American/Chicago
echo $time2->timezoneName; // Europe/London
返回日期設置為新時間戳的新實例:
$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
通過以下方法,您可以通過在當前時間上增加或減少值來修改日期。這不會修改現(xiàn)有的 Time 實例,只會返回一個新實例。
$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);
以下方法使您可以將一個 Time 實例與另一個 Time 實例進行比較。在進行比較之前,首先將所有比較轉(zhuǎn)換為 UTC,以確保不同時區(qū)都正確響應。
確定傳入的日期時間是否等于當前實例。在這種情況下,相等意味著它們表示同一時間,并且不需要位于同一時區(qū),因為兩個時間都轉(zhuǎn)換為 UTC 并以這種方式進行比較:
$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 實例,DateTime 實例或 DateTime 類可以理解的任何表示時間的字符串。當將字符串作為第一個參數(shù)傳遞時, 可以將時區(qū)字符串作為第二個參數(shù)傳遞。 如果沒有給出時區(qū),將使用配置的默認值:
$time1->equals('January 11, 2017 03:50:00', 'Europe/London'); // true
除了只有在日期,時間和時區(qū)都相同時才返回 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
檢查傳入的時間是否在當前實例之前。兩種情況下都針對 UTC 版本進行了比較:
$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 實例,DateTime 實例或 DateTime 類可以理解的任何表示時間的字符串。當將字符串作為第一個參數(shù)傳遞時, 可以將時區(qū)字符串作為第二個參數(shù)傳遞。 如果沒有給出時區(qū),將使用配置的默認值:
$time1->isBefore('March 15, 2013', 'America/Chicago'); // false
除了檢查時間是否在傳入的時間之后,其他的與 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
要直接比較兩個 Times,可以使用 difference() 方法,該方法返回 CodeIgniter\I18n\TimeDifference 實例。第一個參數(shù)可以是 Time 實例、 DateTime 實例或帶有日期或時間的字符串。 如果在第一個參數(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 實例后,您可以使用多種方法來查找有關(guān)兩個 Time 間的信息。如果比較時間在待比較時間之前,則返回值為負數(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() 方法,也可以像使用屬性一樣訪問計算值:
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
與 Time 的 humanize() 方法非常相似,此方法返回一個字符串,該字符串以易于理解的格式顯示時間之間的時差。 它可以創(chuàng)建像“3 小時前”、“1 個月內(nèi)”這樣的的字符串。它們之間最大的區(qū)別在于最近日期的處理方式:
// Assume current time is: March 10, 2017 (America/Chicago)
// 假設現(xiàn)在時間是: March 10, 2017 (America/Chicago)
$time = Time::parse('March 9, 2016 12:00:00', 'America/Chicago');
echo $time->humanize(); // 1 year ago
通過以下方式確定顯示的確切時間:
時間差異 | 結(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 所控制。
更多建議: