PHP时间戳转换为DateTime


94

您知道如何将其转换为strtotime或类似类型的值以传递给DateTime对象吗?

我的约会日期:

Mon, 12 Dec 2011 21:17:52 +0000

我尝试过的

$time = substr($item->pubDate, -14);
$date = substr($item->pubDate, 0, strlen($time));

$dtm = new DateTime(strtotime($time));
$dtm->setTimezone(new DateTimeZone(ADMIN_TIMEZONE));
$date = $dtm->format('D, M dS');
$time = $dtm->format('g:i a');

以上是不正确的。如果我遍历许多不同的日期,则它们都是相同的日期。

Answers:


164

您无需将字符串转换为时间戳即可创建DateTime对象(实际上,正如您所知,其构造函数甚至不允许您执行此操作)。您只需DateTime按原样将日期字符串输入构造函数即可:

// Assuming $item->pubDate is "Mon, 12 Dec 2011 21:17:52 +0000"
$dt = new DateTime($item->pubDate);

话虽如此,如果您确实希望使用时间戳而不是字符串,则可以使用DateTime::setTimestamp()

$timestamp = strtotime('Mon, 12 Dec 2011 21:17:52 +0000');
$dt = new DateTime();
$dt->setTimestamp($timestamp);

编辑(2014-05-07):

当时我实际上还没有意识到这一点,但是DateTime构造函数确实支持直接从时间戳创建实例。根据此文档,您需要做的就是在时间戳前面加上一个@字符:

$timestamp = strtotime('Mon, 12 Dec 2011 21:17:52 +0000');
$dt = new DateTime('@' . $timestamp);

这很好。我以前曾经尝试过,但是一定不能给它足够的机会!!!谢谢:))
JREAM 2012年

18
请注意,new DateTime('@' . $timestamp)$dt = new DateTime(); $dt->setTimestamp($timestamp)不处理时区以同样的方式。有关更多详细信息,请参阅我的答案@ stackoverflow.com / questions / 12038558/…
John Slegers '16

43

虽然@drrcknlsn是正确的断言,有多种方式的时间字符串转换为DATATIME,必须认识到这些不同的方式不处理以同样的方式时区是很重要的。


选项1 : DateTime('@' . $timestamp)

考虑以下代码:

date_format(date_create('@'. strtotime('Mon, 12 Dec 2011 21:17:52 +0800')), 'c');

strtotime位消除了时区信息,并且该date_create函数采用GMT(Europe/Brussels)。

这样,无论我在哪台服务器上运行,输出都是以下内容:

2011-12-12T13:17:52+00:00

选项2: date_create()->setTimestamp($timestamp)

考虑以下代码:

date_format(date_create()->setTimestamp(strtotime('Mon, 12 Dec 2011 21:17:52 +0800')), 'c');

您可能期望这会产生相同的输出。但是,如果我从比利时服务器执行此代码,则会得到以下输出:

2011-12-12T14:17:52+01:00

date_create函数不同,该setTimestamp方法采用服务器时区('Europe/Brussels'在我的情况下)而不是GMT。


明确设定您的时区

如果要确保输出与输入的时区匹配,最好进行显式设置。

考虑以下代码:

date_format(date_create('@'. strtotime('Mon, 12 Dec 2011 21:17:52 +0800'))->setTimezone(new DateTimeZone('Asia/Hong_Kong')), 'c')

现在,还要考虑以下代码:

date_format(date_create()->setTimestamp(strtotime('Mon, 12 Dec 2011 21:17:52 +0800'))->setTimezone(new DateTimeZone('Asia/Hong_Kong')), 'c')

因为我们显式设置了输出的时区以匹配输入的时区,所以两者都会创建相同的(正确的)输出:

2011-12-12T21:17:52+08:00

27

最简单的解决方案可能就是:

DateTime::createFromFormat('U', $timeStamp);

其中“ U”表示Unix时代。参见文档:http : //php.net/manual/en/datetime.createfromformat.php


3
此方法也忽略了时区
Bouke Versteegh

2
@BoukeVersteegh,哪一个没有?
forsberg

2
@BoukeVersteegh这是Unix时间戳!在创建对象时它使您摆脱了时区问题。只需->setTimezone在致电前用于设置首选时区->format()
会计م19'9

1
@BoukeVersteegh检查PHP手册中的 这一重要说明“当$ time参数是UNIX时间戳(例如@ 946684800)或指定时区(例如2010-01-28T15:00时,将忽略$ timezone参数和当前时区: 00 + 02:00)。”
会计师,

1
Unix时间戳没有时区,根据定义它们始终是UTC
the_nuts

0

这是我的解决方案:

    function changeDateTimezone($date, $from='UTC', $to='Asia/Tehran', $targetFormat="Y-m-d H:i:s")
    {
        $date = new DateTime($date, new DateTimeZone($from));
        $date->setTimeZone(new DateTimeZone($to));
        return $date->format($targetFormat);
    }
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.