在PHP中将一个日期格式转换为另一个日期格式

383

在PHP中,有没有简单的方法将一个日期格式转换为另一个日期格式?

我有这样一个代码:

$old_date = date('y-m-d-h-i-s');            // works

$middle = strtotime($old_date);             // returns bool(false)

$new_date = date('Y-m-d H:i:s', $middle);   // returns 1970-01-01 00:00:00

但我当然希望它返回当前日期,而不是黎明时刻。 我做错了什么?


非常棒的文章:http://tech-blog.maddyzone.com/php/type-date-convert-php - Rituraj ratan
https://dev59.com/4HI95IYBdhLWcg3wwwyY - Raci
这个问题的样本输入字符串格式和期望输出格式是“有损”的,因为 h 是无法识别的。h 永远不会高于12,因此输出中的 H 不可能大于12。由于输入数据不好,所以无法得到好的输出数据。 - mickmackusa
18个回答

326
date()的第二个参数需要是一个正确的时间戳(自1970年1月1日以来的秒数)。你正在传递一个字符串,而date()无法识别。
你可以使用strtotime()将日期字符串转换为时间戳。但是,即使是strtotime()也无法识别y-m-d-h-i-s格式。 PHP 5.3及更高版本 使用DateTime::createFromFormat。它允许您使用date()语法指定精确掩码来解析传入的字符串日期。 PHP 5.2及更低版本 您必须使用substr()手动解析元素(年、月、日、小时、分钟、秒),并将结果传递给mktime()来构建时间戳。但是这很麻烦!我建议使用strftime()可以理解的不同格式。strftime()可以理解任何日期输入,例如,这个格式可以工作:
$old_date = date('l, F d y h:i:s');              // returns Saturday, January 30 10 02:06:34
$old_date_timestamp = strtotime($old_date);
$new_date = date('Y-m-d H:i:s', $old_date_timestamp);   

注意:根据php.net的说明,自PHP 5.2起,DateTime已经存在于PHP核心中,并且可以在编译时启用对PHP 5.1的实验性支持。https://secure.php.net/manual/en/datetime.installation.php - Charlotte Dunois

132

最简单的方法是

$myDateTime = DateTime::createFromFormat('Y-m-d', $dateString);
$newDateString = $myDateTime->format('m/d/Y');

首先,您需要为$dateString指定日期格式。然后,您告诉它您想要$newDateString使用的格式。

这也避免了使用strtotime,在某些情况下可能很难使用。

如果您不是将日期格式从一种转换为另一种,而只是想以特定格式获取当前日期(或日期时间),那么它甚至更容易:

$now = new DateTime();
$timestring = $now->format('Y-m-d h:i:s');

这个问题也涉及到同一个主题:将日期格式从yyyy-mm-dd转换为dd-mm-yyyy.


1
我已经编辑了回复。我只是想指出这两个问题应该以某种方式链接起来。 - ceiroa
$timestring = $now->format('Y-m-d h:i:s'); 这个肯定没错吧?m 表示月份, i 表示分钟。 - Mark Baker
@madlopt ~ 静态方法:https://secure.php.net/manual/zh/language.oop5.static.php - ceiroa
你是对的。但如果日期不正确,它无法创建对象。 - madlopt

64

基础知识

将一种日期格式转换为另一种最简单的方法是使用strtotime()date()strtotime()会将日期转换为Unix时间戳。然后可以将该Unix时间戳传递给date()以将其转换为新格式。

$timestamp = strtotime('2008-07-01T22:35:17.02');
$new_date_format = date('Y-m-d H:i:s', $timestamp);

或者作为一行代码:

$new_date_format = date('Y-m-d H:i:s', strtotime('2008-07-01T22:35:17.02'));

请记住,strtotime() 需要日期以有效格式提供。如果未提供有效格式,则会导致 strtotime() 返回 false,这将使您的日期变为 1969-12-31。

使用 DateTime()

从 PHP 5.2 开始,PHP 提供了 DateTime() 类,它为我们处理日期(和时间)提供了更强大的工具。我们可以使用 DateTime() 重新编写上面的代码,如下所示:

$date = new DateTime('2008-07-01T22:35:17.02');
$new_date_format = $date->format('Y-m-d H:i:s');

使用Unix时间戳

date()函数以Unix时间戳为第二个参数,返回格式化后的日期:

$new_date_format = date('Y-m-d H:i:s', '1234567890');

DateTime()函数通过在时间戳前面添加@来处理Unix时间戳:

$date = new DateTime('@1234567890');
$new_date_format = $date->format('Y-m-d H:i:s');

如果你拥有的时间戳是以毫秒为单位的(可能以000结尾且/或时间戳长度为13个字符),在转换为另一种格式之前,你需要将其转换为秒。有两种方法可以做到这一点:

  • 使用substr()删除最后三位数字

删除最后三位数字可以通过多种方式实现,但使用substr()是最简单的方法:

$timestamp = substr('1234567899000', -3);
  • 将子字符串除以1000

你也可以通过将时间戳除以1000来转换为秒。由于时间戳对于32位系统来说太大了,无法进行数学运算,因此您需要使用BCMath库以字符串方式进行运算:

$timestamp = bcdiv('1234567899000', '1000');

要获取Unix时间戳,您可以使用strtotime()函数,它将返回一个Unix时间戳:

$timestamp = strtotime('1973-04-18');

使用 DateTime(),您可以使用 DateTime::getTimestamp() 方法。

$date = new DateTime('2008-07-01T22:35:17.02');
$timestamp = $date->getTimestamp();

如果你正在使用 PHP 5.2,你可以使用 U 格式选项代替:

$date = new DateTime('2008-07-01T22:35:17.02');
$timestamp = $date->format('U');

处理非标准和模糊日期格式

不幸的是,开发人员需要处理的并非所有日期都是按照标准格式表示的。幸运的是,PHP 5.3为我们提供了解决方案。 DateTime::createFromFormat()允许我们告诉PHP日期字符串的格式,以便将其成功解析为DateTime对象进行进一步操作。

$date = DateTime::createFromFormat('F-d-Y h:i A', 'April-18-1973 9:48 AM');
$new_date_format = $date->format('Y-m-d H:i:s');
在 PHP 5.4 中,我们获得了在实例化时进行类成员访问的能力,这使得我们可以将 DateTime() 代码转换为一行代码。
$new_date_format = (new DateTime('2008-07-01T22:35:17.02'))->format('Y-m-d H:i:s');

$new_date_format = DateTime::createFromFormat('F-d-Y h:i A', 'April-18-1973 9:48 AM')->format('Y-m-d H:i:s');

29

试试这个:

$old_date = date('y-m-d-h-i-s');
$new_date = date('Y-m-d H:i:s', strtotime($old_date));

无法工作,strtotime()无法识别该格式。我刚试过了。 - Pekka
同意,我只是把提问者提供的格式代码放进去了,应该指定适当的格式。 - Sarfraz
这个答案缺少教育性的解释。 - mickmackusa
这个答案可证明是不正确的,它的存在(和正分)只会损害研究人员的体验。 - mickmackusa

16

$datedd-mm-yyyy hh:mm:ss格式转换为适当的MySQL datetime,我会这样做:

$date = DateTime::createFromFormat('d-m-Y H:i:s',$date)->format('Y-m-d H:i:s');

4
除非您确信 $date 是一个有效的日期并符合格式,否则不应链接这些方法。话虽如此,一个不匹配格式的无效日期会返回:“致命错误:调用一个对象上的成员函数format()”。提醒一下! - Rob W
更好的解决方案是通过3个步骤进行,其中第二步是空值检查。 - Jelle de Fries

15
以下是一种简单的方法来将日期转换为不同的格式。
// Create a new DateTime object
$date = DateTime::createFromFormat('Y-m-d', '2016-03-25');

// Output the date in different formats
echo $date->format('Y-m-d')."\n";
echo $date->format('d-m-Y')."\n";
echo $date->format('m-d-Y')."\n";

11

这种原生方式可以帮助将任何输入格式转换为所需的格式。

$formatInput = 'd-m-Y'; //Give any format here, this would be converted into your format
$dateInput = '01-02-2018'; //date in above format

$formatOut = 'Y-m-d'; // Your format
$dateOut = DateTime::createFromFormat($formatInput, $dateInput)->format($formatOut);

我不认为这个答案给页面增加了任何新的价值。有几个答案在多年前就提供了这种技术。 - mickmackusa

11
$old_date = date('y-m-d-h-i-s');       // works

你在这里做错了,应该是这样

$old_date = date('y-m-d h:i:s');       // works

时间分隔符为 ':'。


我认为这会有所帮助...

$old_date = date('y-m-d-h-i-s');              // works

preg_match_all('/(\d+)-(\d+)-(\d+)-(\d+)-(\d+)-(\d+)/', $old_date, $out, PREG_SET_ORDER);
$out = $out[0];
$time = mktime($out[4], $out[5], $out[6], $out[2], $out[3], $out[1]);

$new_date = date('Y-m-d H:i:s', $time); 

或者


$old_date = date('y-m-d-h-i-s');              // works

$out = explode('-', $old_date);
$time = mktime($out[3], $out[4], $out[5], $out[1], $out[2], $out[0]);

$new_date = date('Y-m-d H:i:s', $time); 

是的,当然谢谢。我想要将一个GUID文件名转换回正确的日期格式。 - Tom
如果您不循环preg_match_all()的返回值,那么调用_all似乎有点愚蠢。当您只需要一个时,为什么要调用_all呢? - mickmackusa

9

strtotime可以解决这个问题。日期格式并不相同,而且都是美国格式。

<?php
$e1 = strtotime("2013-07-22T12:00:03Z");
echo date('y.m.d H:i', $e1);
echo "2013-07-22T12:00:03Z";

$e2 = strtotime("2013-07-23T18:18:15Z");
echo date ('y.m.d H:i', $e2);
echo "2013-07-23T18:18:15Z";

$e1 = strtotime("2013-07-21T23:57:04Z");
echo date ('y.m.d H:i', $e2);
echo "2013-07-21T23:57:04Z";
?>

8
你需要将$old_date转换回时间戳,因为date function函数需要一个时间戳作为它的第二个参数。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接