PHP 5.2.0

Developer 應該會常處理到日期和時間的問題,該如何更簡單準確的建立和調整日期、時間、時區?

以下 5 種相關類別:


DateTime

Create:

new DateTime()

// 預設值為 now,等同 new DateTime('now');
$date = new DateTime();

// yesterday, tomorrow (時間為 00:00:00)
$date = new DateTime('yesterday');

// 2017-05-17 18:00:00
$date = new DateTime('2017-05-17 18:00:00');

// 2017-05-17 21:15:00
$date = new DateTime('2017/05/17 09:15 PM');

// +- day, week, month, year
$date = new DateTime('+1 day');

Relative Formats

特別的關鍵字解析

// today: 2018-07-22 (Sunday)

// 2018-07-01
$date = new DateTime('first day of this month');

// 2018-07-16
$date = new DateTime('monday this week');

PHP.net - Relative Formats

DateTime::createFromFormat()

因應不同格式建立物件

$date = DateTime::createFromFormat('Y/m/d H.i', '2017/05/17 15.15');

$date = DateTime::createFromFormat('\t\o\d\a\y \i\s Y F j', 'today is 2014 January 1');

PHP.net - datetime.createfromformat

Output:

format()

// 2017-05-18 13:27:43
echo $date->format('Y-m-d H:i:s');

PHP.net - format

getTimestamp()

// 1495088399
echo $date->getTimestamp();

Setting:

setDate()

$date->setDate(2017, 05, 17);

setTime()

$date->setTime(19, 30, 17);

setTimestamp()

$date->setTimestamp(1495088399);

modify()

// +- day, week, month, year
$date->modify('-10 years');

Compare:

diff()

帶入 DateTime 2物件,回傳 DateInterval 物件

$date1 = new DateTime('2017-05-11');
$datt2 = new DateTime('2017-05-17');
$interval = $date1->diff($datt2);

// +6 days
echo $interval->format('%R%a days');

PHP.net - DateInterval::format


DateTimeImmutable

DateTime 一樣,差別在於不會被修改,而使返回一個新的物件

$date = new DateTime('2018-06-06');
$date->modify('+10 days');
$date->format('Y-m-d'); // 2018-06-16

$date = new DateTimeImmutable('2018-06-06');
$date->modify('+10 days');
$date->format('Y-m-d'); // 2018-06-06

DateInterval

Create:

new DateInterval()

DateIntervale 類別代表固定或相對長度的時間,用來修改 DateTime 的值。
建構式接受一個字串參數,以 P 為開頭的字串,T分隔日期和時間,最後接上 period designator 修飾前一個整數。

Y (年), M (月), W (週), D (日), H (時), M (分), S (秒)

// 建立 2週 5小時
$interval = new DateInterval('P2WT5H');

DateInterval::createFromDateString

// 建立 2週 5小時
$interval = DateInterval::createFromDateString('2 weeks + 5 hours');

Setting:

add(), sub()

$date = new DateTime('2017-05-17');

// 建立 2週 5小時
$interval = new DateInterval('P2WT5H');

// 2017-05-31 05:00:00
$date->add($interval);
echo $date->format('Y-m-d H:i:s');

// 2017-05-17 00:00:00
$date->sub($interval);
echo $date->format('Y-m-d H:i:s');

DateTimeZone

DateTimeZone 類別代表時區,用來修改 DateTime 的值。

Create:

$timezone = new DateTimeZone('America/New_York');

$date = new DateTime('now', $timezone);

// OR
$date = DateTime::createFromFormat(
'Y/m/d',
'2017/05/17',
$timezone
);

PHP.net - List of Supported Timezones

Setting:

$date = new DateTime();

$timezone = new DateTimeZone('America/New_York');
$date->setTimezone($timezone);

DatePeriod

固定時間區間取得日期時間,DatePeriod 建構需要三個參數

  • DateTime 代表起始時間
  • DateInterval 代表時間區間
  • 整數代表總數 或 DateTime 代表結束時間
  • DatePeriod::EXCLUDE_START_DATE = 1 ,排除初始日期 (option)

DatePeriod是個迭代器,每次都會拋出一個 DateTime

  • 兩週為週期三輪

    $start = new DateTime('2017-05-17');
    $interval = new DateInterval('P2W');
    $period = new DatePeriod(
    $start,
    $interval,
    3,
    DatePeriod::EXCLUDE_START_DATE
    );

    foreach ($period as $nextDateTime) {
    echo $nextDateTime->format('Y-m-d') , PHP_EOL;
    }
    /*
    * 2017-05-31
    * 2017-06-14
    * 2017-06-28
    */
  • 往後時間區間

    $start = new DateTime('2017-05-14');
    $interval = DateInterval::createFromDateString('-1 day');
    $period = new DatePeriod($start, $interval, 3);

    foreach ($period as $date) {
    echo $date->format('Y-m-d') , PHP_EOL;
    }
    /**
    * 2017-05-17
    * 2017-05-16
    * 2017-05-15
    * 2017-05-14
    */

References