Strtotime()无法处理dd/mm/YYYY格式的日期

194

我非常喜欢strtotime()函数,但是用户手册没有提供完整支持的日期格式的描述。使用strtotime('dd/mm/YYYY')无法正常工作,它只能使用mm/dd/YYYY格式。

如果我的日期格式是dd/mm/YYYY,如何将其转换为YYYY-mm-dd格式? 我可以使用explode()函数来完成,但我认为还有更好的解决方案。


8
你实际上不需要将其转换为“YYYY-mm-dd”的格式来解析它-你只需要将其改为“dd-mm-YYYY”,可以使用str_replace('/', '-', $date);来完成。 - Gavin Coates
17个回答

458

这里是简化的解决方案:

$date = '25/05/2010';
$date = str_replace('/', '-', $date);
echo date('Y-m-d', strtotime($date));

结果:

2010-05-25

strtotime文档中写道:

日期格式为m/d/yd-m-y的日期通过查看各个组件之间的分隔符进行消歧义:如果分隔符是斜杠(/),则假定为美国的m/d/y格式;而如果分隔符是破折号(-)或句点(.),则假定为欧洲的d-m-y格式。


2
@Web Logic 我无法理解strtotime()函数的默认格式,如果我写strtotime('01-01-2010'),它会将其理解为dd-mm-YYYY还是mm-dd-YYYY格式? - Simon
3
如果你使用以下代码测试:echo date('Y-m-l', strtotime('01-01-2010'));,结果会是 2010-01-Friday。因此,日期的显示顺序取决于你如何在date函数中设置日期格式。请注意,这里的 "l" 是小写字母 L,不是数字 1。 - Web Logic
1
虽然您在此发布的内容是正确的,并回答了用户的问题,但这是解决实际问题的一种迂回方式。为了使strtotime()能够正确解析格式为“dd/mm/yy”的日期,您需要用“-”替换“/”。因此,您实际上只需要答案的前两行: $date = '25/05/2010'; $date = str_replace('/', '-', $date);额外的一行对于解决您的问题并不必要。 - Gavin Coates
只有当日期大于12时才是正确的:$date='1/2/34'; //2034年2月1日 echo date('d M Y', strtotime($date)); //2034年1月02日 - kurdtpage
date('Y-m-d H:i:s', strtotime('26/05/17');会返回2026-05-17,但实际上是2017年5月26日。如果使用26.05.17则可以正常工作。 - Ponzio Pilato
为什么你在文档中引用的内容说“如果分隔符是破折号(-)或点号(.),则默认使用欧洲格式d-m-y”,而你却使用了Y-m-d? - wbinky

78

你可以使用DateTime :: createFromFormat 方法(从 PHP 5.3 版本开始)解析自定义格式的日期。

$timestamp = DateTime::createFromFormat('!d/m/Y', '23/05/2010')->getTimestamp();

(附带说明:!用于将未指定的值重置为Unix时间戳,即时间将会是午夜。)


如果您不想(或无法)使用PHP 5.3,则strtotime接受的所有可用日期/时间格式的完整列表在日期格式手册页面上列出。该页面更全面地描述了m/d/Yd/m/Y被推断出来的事实(但正如本文中提到的答案所述,您也可以使用d-m-Yd.m.Yd\tm\tY)。


过去,我也曾使用另一个答案中提到的快速的str_replace,以及将日期字符串自行解析为另一种格式。

$subject   = '23/05/2010';
$formatted = vsprintf('%3$04d/%2$02d/%1$02d', sscanf($subject,'%02d/%02d/%04d'));
$timestamp = strtotime($formatted);

22

这是许多问题的好解决方案:

function datetotime ($date, $format = 'YYYY-MM-DD') {

    if ($format == 'YYYY-MM-DD') list($year, $month, $day) = explode('-', $date);
    if ($format == 'YYYY/MM/DD') list($year, $month, $day) = explode('/', $date);
    if ($format == 'YYYY.MM.DD') list($year, $month, $day) = explode('.', $date);

    if ($format == 'DD-MM-YYYY') list($day, $month, $year) = explode('-', $date);
    if ($format == 'DD/MM/YYYY') list($day, $month, $year) = explode('/', $date);
    if ($format == 'DD.MM.YYYY') list($day, $month, $year) = explode('.', $date);

    if ($format == 'MM-DD-YYYY') list($month, $day, $year) = explode('-', $date);
    if ($format == 'MM/DD/YYYY') list($month, $day, $year) = explode('/', $date);
    if ($format == 'MM.DD.YYYY') list($month, $day, $year) = explode('.', $date);

    return mktime(0, 0, 0, $month, $day, $year);

}

17

从STRTOTIME的说明中

注意:

以m/d/y或d-m-y格式表示的日期通过查看各个组件之间的分隔符来消除歧义: 如果分隔符是斜杠(/),则假定为美国的m/d/y格式;而如果分隔符是短横线(-)或点(.),则假定为欧洲的d-m-y格式。

就这么简单。


我们可以实现它,因为它们不会产生错误,但是当我检查时,$t和$t1显示出不同的结果。我像这样进行了检查:$t = strtotime(date('d-m-Y'));$t1 = strtotime(date('m/d/Y')); - vusan

7

$srchDate = date_format(date_create_from_format('d/m/Y', $srchDate), 'Y/m/d');

这段代码可以帮助你。 你可以将字符串转换为自定义日期格式,在其中指定给PHP的原始字符串格式。 现在它是一个日期格式,你可以将其转换为PHP的默认日期格式,这与MySQL使用的日期格式相同。


最干净和最好的解决方案 - Marco Marsala
1
非常优雅的解决方案! - dns

3

最快的可能应该是

false!== ($date !== $date=preg_replace(';[0-2]{2}/[0-2]{2}/[0-2]{2};','$3-$2-$1',$date))

如果格式不正确,它将返回false,但不会检查日期是否有效。


2

这种解决方法比使用explode函数更简单、更优雅:

$my_date = str_replace("/", ".", $my_date);
$my_date = strtotime($my_date);
$my_date = date("Y-m-d", $my_date);

您不必知道日期的格式,但如果带有斜杠,则会将其替换为点,并按照欧洲时间格式进行strtotime处理。


2
简单如此。
date('Y-m-d H:i:s', strtotime( str_replace('/', '-', $from_date ) ) );

2

我尝试将ddmmyy格式转换为date("Y-m-d")格式,但是当我直接传递ddmmyy =date('dmy')时无法正常工作。

然后意识到它必须是yyyy-mm-dd格式,因此使用子字符串来进行整理。

$strParam = '20'.substr($_GET['date'], 4, 2).'-'.substr($_GET['date'], 2, 2).'-'.substr($_GET['date'], 0, 2);  

然后传递给 date("Y-m-d",strtotime($strParam));

它起作用了!


1

我还没有找到更好的解决方案。你可以使用explode()preg_match_all()等函数。

我有一个静态辅助函数,像这样:

class Date {

    public static function ausStrToTime($str) {
        $dateTokens = explode('/', $str);
        return strtotime($dateTokens[1] . '/' . $dateTokens[0] . '/' . $dateTokens[2]); 

    }

}

这个函数可能有更好的名称,但我使用 ausStrToTime() 因为它适用于澳大利亚日期(我经常处理澳大利亚日期)。更好的名称可能是标准化的名称,但我不确定是什么。


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