php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Request #71802 strtotime parses "13:01 PM" as 16:01
Submitted: 2016-03-11 17:15 UTC Modified: 2016-03-12 04:52 UTC
From: php at richardneill dot org Assigned:
Status: Open Package: Date/time related
PHP Version: 5.6.19 OS: Linux
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If this is not your bug, you can add a comment by following this link.
If this is your bug, but you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: php at richardneill dot org
New email:
PHP Version: OS:

 

 [2016-03-11 17:15 UTC] php at richardneill dot org
Description:
------------
The time expression "13:01 P.M." is technically malformed (it's tautologous), but people are still likely to use it sometimes. PHP mis-converts it, turning 13 into 16 !.
(In comparison, the Unix date command rejects it)

Test script:
---------------
PHP:
<?
echo date  ("Y-m-d H:i:s", strtotime("13:01 P.M."));
#result:   2016-03-11 16:01:00
#expected: 2016-03-11 13:01:00

echo date  ("Y-m-d H:i:s", strtotime("12:01 P.M."));
#result:   2016-03-11 12:01:00
#correct
?>

Shell:	

$ date -d '13:01 P.M.';
date: invalid date ‘13:01 P.M.’

$ date -d '12:01 P.M.';
Fri Mar 11 12:01:00 GMT 2016


Expected result:
----------------
PHP shouldn't be off-by-3. 


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2016-03-12 04:52 UTC] requinix@php.net
-Type: Bug +Type: Feature/Change Request
 [2016-03-12 04:52 UTC] requinix@php.net
https://3v4l.org/2beus

Since "13:01 PM" isn't valid as time with meridian, the other behavior is to parse the P as a timezone (military style where P=UTC-3). The M is a timezone too but ignored.

As a request, though, this doesn't sound unreasonable: allow an AM/PM after any time specification, and warn or ignore if H>12.

For a workaround you could use date_parse() then check if hour>12 and tz_addr={A,P}. It'd be work to construct a timestamp on your own from there, so maybe if you detect this problem you could try a regex to remove /[AaPp]\.?[Mm]\.?/ from the input.
 [2016-03-12 17:25 UTC] php at richardneill dot org
Thanks - I had no idea that there even was such a thing as a military P timezone.

My workaround, which may help anyone else, is just to do:
str_replace (array ("a.m.","p.m."), array("am","pm"), strtolower($input));
before parsing with strtotime().

That way, "13:01 P.M." or "14:01 A.M." will always fail, rather than be valid-but-wrong. 

Correct use of am or pm is still fine.
 
PHP Copyright © 2001-2020 The PHP Group
All rights reserved.
Last updated: Wed Nov 25 09:01:23 2020 UTC