2012-04-12 31 views
6

Hi tôi dường như gặp khó khăn khi nhận được phương pháp datetime để làm việc như mong đợi? Tôi có thể làm điều gì sai?php DateTime createFromFormat chức năng

// Passes OK 
$dateTime = DateTime::createFromFormat('d/m/Y', '12/12/2012'); 
var_dump($dateTime); 

// should fail but returns - 2016-09-25 
$dateTime = DateTime::createFromFormat('d/m/Y', '56/56/2012'); 
var_dump($dateTime); 

// correctly returns False 
$dateTime = DateTime::createFromFormat('d/m/Y', '56/56/fail'); 
var_dump($dateTime); 

// should fail but returns 2019-08-29 09:58:10 
$dateTime = DateTime::createFromFormat('m/d/Y', '90/90/2012'); 
var_dump($dateTime); 

enter image description here

Trả lời

30

Những điều về DateTime::createFromFormat là có hai loại đầu vào bất ngờ nó nhận ra: các loại mà tạo ra lỗi, và loại mà tạo ra cảnh báo.

Đầu vào như '56/56/fail' tạo ra lỗi, vì vậy, false được trả về và mọi thứ đều tốt. Tuy nhiên, '56/56/2012' không phải là lỗi mà là cảnh báo và được phân tích cú pháp là ngày thứ 56 của tháng thứ 56 năm 2012. Kể từ năm 2012 không có 56 tháng, PHP sẽ thay đổi nội dung này thành 2016 + 8 tháng = tháng 8 năm 2016. Và từ đó tháng không có 56 ngày, chúng tôi có một khoản bồi thường khác cho tháng 9 năm 2016 + (56 - 31) ngày = 25 tháng 9 năm 2016. Vì vậy, mặc dù không mong đợi, điều này thực tế là chính xác.

Nếu bạn muốn không cho phép tự động điều chỉnh này, bạn phải quấn phương pháp DateTime nhà máy và sử dụng DateTime::getLastErrors như tài liệu tham khảo:

$dateTime = DateTime::createFromFormat('d/m/Y', '56/56/2012'); 
$errors = DateTime::getLastErrors(); 
if (!empty($errors['warning_count'])) { 
    echo "Strictly speaking, that date was invalid!\n"; 
} 

See it in action.

+0

Cảm ơn bạn đã trả lời. Đã được 100% tại chỗ và rất tốt giải thích. –

+0

Để séc sẵn sàng để sao chép/dán nó cũng cần có séc ban đầu: if (! $ DateTime ||! Empty ($ errors ['warning_count'])) { :) –

1

Thực ra đây là đúng: Ví dụ, nếu bạn tạo một ngày với 2012/04/31 (ngày không hợp lệ) PHP trả về 2012/05/01 (ngày đầu tiên của tháng)!

này được thực hiện đằng sau hậu trường

1

PHP là một con thú kỳ lạ (để nói ít nhất). 56/56/2012 kết quả trong tất cả các tháng bổ sung và ngày được thêm vào ngày cho đến khi nó trở thành chính xác (thần chỉ biết logic đằng sau này).

+1

Tôi nghi ngờ logic là nó cho phép các lập trình viên làm một số calcs ngày lười biếng. Nếu bạn muốn thêm 90 ngày hoặc 18 tháng vào một cái gì đó, bạn có thể chỉ cần méo các số trong đó mà không làm các calcs, gói các tháng/năm, vv và PHP sẽ sắp xếp nó cho bạn và trả về những gì bạn muốn. –