2015-07-31 15 views
6

Tôi có một kịch bản mà được tháng hiện tại và cuối cùng trong PHP như sau:Tại sao ngày PHP ('m', strtotime ('- 1 tháng')) không hoạt động chính xác cho ngày hôm nay? 31/07

$currentMonth = date('m'); 
//Expected:07 
//Result:07 
$lastMonth = date('m', strtotime('-1 months')); 
//Expected:06 
//Result:07 

Hôm nay tình cờ lại là 31 hoặc cuối tháng của tháng Bảy. Kết quả này có được mong đợi từ PHP không?

Khi sử dụng -31 ngày kết quả là như mong đợi:

$lastMonth = date('m', strtotime('-31 days')); 
//Expected:06 
//Result:06 
+0

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? –

+1

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 . –

+1

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

Trả lời

2

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.

-1

"s" trong dư thừa trong tháng. Nó phải là như thế này:

$lastMonth = date('m', strtotime('-1 month')); 
+5

không có sự khác biệt. PHP không phải là một ngữ pháp nazi và '1 tháng' và' 1 tháng' giống hệt như nó liên quan. –

+1

À đúng rồi ... Tôi có nên xóa câu trả lời không? – lisztomania

+1

Thật vậy, thêm 's' được cho phép/tùy chọn. [Tài liệu] (http://php.net/manual/en/datetime.formats.relative.php) xác nhận điều đó. – axiac

2

Bạn có thể làm theo cách này

$d = new DateTime(); 
$currentMonth = $d->format('m'); 
//Expected:07 
//Result:07 
print $currentMonth; 

$d->modify('first day of previous month'); 
print "<br/>"; 
$lastMonth = $d->format('m'); 
//Expected:06 
//Result:06 
print $lastMonth; 

DEMO: http://codepad.viper-7.com/kokWi8

2

Đây là một vấn đề với phân tích cú pháp ngày-chuỗi PHP. Xem tại đây: http://derickrethans.nl/obtaining-the-next-month-in-php.html

@Mr. Llama làm một kịch bản hiển thị những gì ngày khác vấn đề này ảnh hưởng: http://codepad.viper-7.com/E4gP0W

Các giải pháp tôi đã đi với:

//Date:07/31/15 
$currentMonth = date('m'); 
//Result:07 
$lastMonth = date('m', strtotime('first day of -1 months')); 
//Result:06 
+0

Câu trả lời hay cho một vấn đề rắc rối. – user2029890

1

-1 month được hiểu là "cùng ngày trong tháng, tháng trước". Nếu ngày này không tồn tại, ngày sẽ tràn vào tháng tiếp theo. Trên thực tế kết quả là giống như strtotime("31.6.2015") - hãy dùng thử!

Các vấn đề liên quan