2011-11-17 35 views
17

Tôi làm cách nào để lấy mã dưới đây hoạt động khi tôi có tháng tháng hai? Hiện tại nó đang đến ngày và sau đó dừng lại trước khi đến để xác định xem đó có phải là năm nhuận hay không.javascript để tìm năm nhuận

if (month == 2) { 
    if (day == 29) { 
     if (year % 4 != 0 || year % 100 == 0 && year % 400 != 0) { 
      field.focus(); 
      field.value = month +'/' + ''; 
     } 
    } 
    else if (day > 28) { 
     field.focus(); 
      field.value = month +'/' + ''; 
    } 
} 
+0

"Dừng" làm thế nào? Có lỗi không? –

+0

nó không bao giờ đánh giá năm để xem nếu nó là một năm nhuận nó đi thẳng đến field.focus và field.value cho dù đó là một năm nhuận hay không –

+0

Các điều kiện của bạn trông hơi lạ - như chúng hiện đang viết bây giờ, bạn chỉ kiểm tra 'ngày' cho các giá trị từ 29 trở lên (dựa trên' ngày == 29' và 'ngày> 28' nếu mệnh đề). Tôi giả định rằng bạn có nghĩa là để viết 'ngày <= 28', nhưng nếu đó là trường hợp, bạn có thể thả mệnh đề' else if' thứ hai và sử dụng mệnh đề 'else' trực tiếp. Cũng có thể an toàn hơn để thêm một bộ ngoặc đơn bổ sung vào mệnh đề năm nhuận của bạn: 'if (năm% 4! = 0 || (năm% 100 == 0 && năm% 400! = 0))' – JW8

Trả lời

99

An toàn hơn để sử dụng Date objects cho nội dung ngày giờ, ví dụ:

isLeap = new Date(year, 1, 29).getMonth() == 1 

Kể từ khi người tiếp tục yêu cầu chính xác về cách thức hoạt động này, nó đã làm với bao JS tính toán giá trị ngày từ năm-tháng-ngày (chi tiết here). Về cơ bản, nó tính toán đầu tiên của tháng và sau đó thêm N -1 ngày vào nó. Vì vậy, khi chúng tôi đang yêu cầu cho 29 tháng hai trên một năm không bước nhảy vọt, kết quả sẽ là ngày 01 tháng 2 + 28 ngày = 01 tháng 3:

> new Date(2015, 1, 29) 
< Sun Mar 01 2015 00:00:00 GMT+0100 (CET) 

Trên một năm nhuận, ngày 1 + 28 = 29 Tháng Hai :

> new Date(2016, 1, 29) 
< Mon Feb 29 2016 00:00:00 GMT+0100 (CET) 

Trong đoạn mã trên, tôi đặt ngày 29 tháng 2 và xem liệu có xảy ra việc giới thiệu hay không. Nếu không (tháng vẫn là 1, tức là tháng Hai), đây là năm nhuận, nếu không thì sẽ là một bước nhảy vọt.

+14

Bò thánh. Thật là một hack. ':)' –

+1

** Bản trình diễn trực tiếp: ** http://jsfiddle.net/bJ4cH/ –

+0

hack rất tuyệt! –

5
isLeap = !(new Date(year, 1, 29).getMonth()-1) 

... phép trừ bởi một người nên hoạt động nhanh hơn so với hầu hết các cấu trúc CPU.

+0

Nếu bạn được yêu cầu tính 1000s của mỗi giây tôi có thể đồng ý, tuy nhiên khả năng đọc nên trump tốc độ khi sự khác biệt tốc độ liên quan là hầu như không đáng kể giữa chúng. –

+0

Chỉ cần chạy một số kiểm tra tốc độ và 'ngày mới' là chậm hơn khoảng 100 lần so với sử dụng logic boolean (nói một cái gì đó như'! ((% 4) || (! (Yr% 100) && (yr% 400))) ').Bạn có thể nói bây giờ tôi đã có thể đọc được cửa sổ với tốc độ này, nhưng 100 lần có thể đáng giá :) –

6

đúng và nhanh:

ily = function(yr) { return (yr%400)?((yr%100)?((yr%4)?false:true):false):true; } 

Nếu bạn đang ở trong một vòng lặp hoặc đếm nano giây, đây là hai cường độ nhanh hơn so với chạy năm của bạn thông qua một ngày mới() đối tượng. So sánh hiệu suất tại đây: http://jsperf.com/ily

+2

Vì đây chỉ là kết hợp so sánh boolean với kết quả boolean, bạn có thể diễn tả điều này mà không có toán tử điều kiện chỉ & & rsquo; s, || s và ngắn mạch. Còn nhanh hơn khoảng 5%: http://jsperf.com/ily/6 –

1

Tôi sử dụng điều này vì tôi ghét phải tiếp tục giới thiệu vào tháng 1 là 0 và tháng 2 là 1. Với tôi và PHP và ngày có thể đọc, tháng 2 = 2. Tôi biết nó không thực sự quan trọng vì con số không bao giờ thay đổi nhưng nó chỉ giữ cho bộ não của tôi suy nghĩ giống nhau trên các mã khác nhau.

var year = 2012; 
var isLeap = new Date(year,2,1,-1).getDate()==29; 
9

So với sử dụng new Date() đây là khoảng nhanh hơn 100 lần!

Cập nhật:

phiên bản mới nhất này sử dụng một thử nghiệm chút của 3 bit đáy (là nó một bội số của 4), cũng như một tấm séc cho năm là một bội số của 16 (dưới 4 bit trong hệ nhị phân là 15) và là một bội số của 25.

ily = function(y) {return !(y & 3 || !(y % 25) && y & 15);}; 

http://jsperf.com/ily/15

Nó là nhanh hơn một chút nữa so với phiên bản trước đây của tôi (dưới đây):

ily = function(yr) {return !((yr % 4) || (!(yr % 100) && (yr % 400)));}; 

http://jsperf.com/ily/7

Đây cũng là 5% nhanh hơn, so với phiên bản điều hành đã nhanh chóng có điều kiện bởi broc.seib Kết quả thử nghiệm

Tốc độ: http://jsperf.com/ily/6

Dự kiến ​​kết quả kiểm tra logic:

alert(ily(1900)); // false 
alert(ily(2000)); // true 
alert(ily(2001)); // false 
alert(ily(2002)); // false 
alert(ily(2003)); // false 
alert(ily(2004)); // true 
alert(ily(2100)); // false 
alert(ily(2400)); // true 
0

Better tính lịch sử của năm nhuận.

Mã dưới đây tính đến năm nhuận được giới thiệu trong 45BC với lịch Julian và phần lớn thế giới phương Tây đã sử dụng lịch Gregory năm 1582CE và 0CE = 1BC.

isLeap = function(yr) { 
    if (yr > 1582) return !((yr % 4) || (!(yr % 100) && (yr % 400))); 
    if (yr >= 0) return !(yr % 4); 
    if (yr >= -45) return !((yr + 1) % 4); 
    return false; 
}; 

Anh và các thuộc địa của nó thông qua lịch Gregorian năm 1752, vì vậy nếu bạn có nhiều Anglo tâm phiên bản này là tốt hơn (Chúng tôi sẽ giả Anh đã thông qua lịch với cuộc chinh phục La Mã bắt đầu từ năm 43CE Julian).

isLeap = function(yr) { 
    if (yr > 1752) return !((yr % 4) || (!(yr % 100) && (yr % 400))); 
    if (yr >= 43) return !(yr % 4); 
    return false; 
}; 
0
year = window.prompt("Input a Year : "); 
x = (year % 100 === 0) ? (year % 400 === 0) : (year % 4 === 0); 
console.log(x); 

này có thể giúp bạn để có được nếu năm đầu vào là một năm nhuận hay không.

dưới hình thức true hoặc false

JavaScript Basics w3resource

1

Bạn có thể dễ dàng thực hiện để làm việc này gọi .isLeapYear() từ momentjs:

var notLeapYear = moment('2018-02-29') 
 
console.log(notLeapYear.isLeapYear()); // false 
 

 
var leapYear = moment('2020-02-29') 
 
console.log(leapYear.isLeapYear()); // true
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.21.0/moment.min.js"></script>

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