How to make strtotime parse dates in Australian (i.e. UK) format: dd/mm/yyyy?

坚强是说给别人听的谎言 提交于 2019-11-29 06:13:10

There's a quick fix that seems to force PHP's strtotime into using the UK date format. That is: to replace all of the '/' in the incoming string with a '-'.

Example:

date('Y-m-d', strtotime('01/04/2011'));

Would produce: 2011-01-04

date('Y-m-d', strtotime('01-04-2011'));

Would produce: 2011-04-01

You could use str_replace to achieve this.

Example:

str_replace('/', '-', '01/04/2011');

EDIT:

As stated in the comments, this works because PHP interprets slashes as American and dots/dashes as European.

I've used this trick extensively and had no problems so far.

If anyone has any good reasons not to use this, please comment.

The problem is that strtotime doesn't take a format argument. What about strptime?

setlocale() sucks for exactly the reason you describe: You never know what you're going to get. Best to process the string manually.

Zend Framework's Zend_Date is one alternative promising more exact and consistent date handling. I don't have experience with it myself yet, just beginning to work with it, but so far, I like it.

Ah, the old problem us lucky Australians get.

What I've done in the past is something like this

public static function getTime($str) { // 3/12/2008

       preg_match_all('/^(\d{1,2})\/(\d{1,2})\/(\d{4})$/', $str, $matches);

       return (isset($matches[0][0])) ? strtotime($matches[3][0] . '-' . $matches[2][0] . '-' . $matches[1][0]) : NULL;

    }

Though this relies on dates in this format dd/mm/yyyy.

You can probably use another regex or so to convert from d M yy or use a modified one. I don't know if this would be correct but it may be a start:

/^(\d{1,2})(?:\/|\s)(\d{1,2})(?:\/|\s)(\d{2,4})$/

$date = date_create_from_format('d/m/Y', $date_string);
$unix_timestamp = $date->getTimestamp();

or

$date = DateTime::createFromFormat('d/m/Y', $date_string);
$unix_timestamp = $date->getTimestamp();

For future readers, try the following for parsing dates from unstrusted user input, for which strptime() is too rigid. It outputs ISO date strings which you can pass to new Date(), strtotime(), etc., or false for invalid dates, or null for no usable input. You'd have to adapt it to process times. It also accepts 2-digit year and ISO date input.

function parseUserDate($input, $allow_zero = false) {
    if (!is_string($input)) {
        return $input === null ? null : false;
    }
    $input = preg_split('/\\D+/', $input, null, PREG_SPLIT_NO_EMPTY);
    if (!$input) {
        return null;# no date
    }
    if (count($input) == 3) {
        list($od, , $oy) = $input;
        if (strlen($od) > 2 && strlen($oy) < 3) {# assume ISO
            $oy = $od;
            $input = array_reverse($input);
        }
        $intify = function($dig) {
            return (int) ltrim($dig, '0');# prevent octals
        };
        list($d, $m, $y) = array_map($intify, $input);
        if (strlen($oy) < 3) {
            $current_year = date('Y');
            $current_year_2 = $intify(substr($current_year, -2));
            $diff = $y - $current_year_2;
            if ($diff > 50) {
                $diff -= 100;
            }
            elseif ($diff < -50) {
                $diff += 100;
            }
            $y = $diff + $current_year;
        }
        if (
            ($allow_zero && $d == 0 && $m == 0 && $y == 0)
            || checkdate($m, $d, $y)# murrican function
        ) {
            return sprintf('%04d-%02d-%02d', $y, $m, $d);
        }
    }
    return false;# invalid date
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!