Dưới đây là một cleaner test case mà không hết hạn:
<?php
$origin = mktime(18, 0, 0, 7, 31, 2015);
var_dump(date('r', $origin), date('r', strtotime('-1 months', $origin)));
string(31) "Fri, 31 Jul 2015 18:00:00 +0200"
string(31) "Wed, 01 Jul 2015 18:00:00 +0200"
Tôi khá chắc chắn đó là một vấn đề tài liệu, bởi vì hướng dẫn rõ ràng nêu rõ điều này (nhấn mạnh của tôi):
giá trị tháng tương đối được tính dựa vào độ dài của tháng rằng họ đi qua. Một ví dụ sẽ là "+2 tháng 2011-11-30", sẽ tạo ra "2012-01-30". Điều này là do tháng 11 là 30 ngày và tháng 12 dài 31 ngày, tạo ra tổng số tổng cộng 61 ngày.
... và điều đó sai.
Trình theo dõi lỗi PHP có tons of dupes về việc này. Tất cả chúng đều bị đóng là không phải là lỗi. Đây là số comment from 2009 có liên quan giải thích:
Tôi đồng ý rằng đây là hành vi gây phiền nhiễu.
Ngoài ra, việc triển khai có vấn đề. Về cơ bản, nếu bạn sử dụng '+1 tháng', nó sẽ lấy số tháng, thêm 1 và phân tích kết quả là ngày mới.
Nếu bạn sử dụng 'tháng +1' vào ngày đầu tiên của tháng, nó sẽ đặt ngày thành ngày đầu tiên tiếp theo của tháng.
Hành vi này mang lại ấn tượng, rằng php xem xét độ dài một tháng, điều đó không đúng.
Nhưng nếu bạn sử dụng '1 tháng' vào ngày cuối cùng của một tháng, kết quả là bất ngờ như 2009/05/31 trở nên 2009/06/31 đó là một ngày không hợp lệ và sau đó giải thích như 2009-07-01.
Điều này ít nhất nên được đề cập trong tài liệu.
tính toán tháng luôn nguy hiểm. tháng là gì? "Hôm nay trong ($ curmonth-1)" ?, Điều gì xảy ra nếu nó là ngày 31 tháng 3, bạn có muốn ngày 31 tháng 2, hoặc feb 28? feb 29? –
Có vẻ như đó không phải là những ngày duy nhất '-1 tháng' bị phá vỡ vào: http://codepad.viper-7.com/E4gP0W Ngày 31 của tháng không làm tôi ngạc nhiên, nhưng ngày 29 và 30 tháng 3 . –
Luôn ngạc nhiên khi tôi tìm thấy ai đó vẫn không sử dụng https://github.com/briannesbitt/Carbon để làm ngày trong PHP. – ceejayoz