2016-03-23 21 views
5

Làm cách nào để xác thực ngày? Ý tôi không phải là định dạng, mà là logic. Ví dụ: ngày 30 tháng 2 không phải là ngày hợp lệ.Ngày Javascript cho phép dữ liệu không hợp lệ (ví dụ: ngày 30 tháng 2)

var date = new Date("2015-02-29T13:02:49.073Z"); // 2015 Feb 29th does not exist 
console.log(date.toISOString()); 

Returns 2015-03-01T13: 02: 49.073Z (01 tháng 3).

Nhưng tôi muốn thông tin rằng ngày này (đầu vào) không hợp lệ.

Chỉnh sửa: Đã thử nghiệm trong Chrome. Firefox trả về "ngày không hợp lệ". Nhưng không phải trên phân tích cú pháp. Chỉ khi ngày được sử dụng (ví dụ: toISOString()) một ngoại lệ được ném.

try 
{ 
    var date = new Date("2015-02-29T13:02:49.073Z"); 
    console.log(date.toISOString()); 
} 
catch(e) 
{ 
    console.log("error: " + e.message); 
} 

Firefox:

ngày không hợp lệ

Chrome: (. Không có gì, chỉ cần chuyển sang ngày tiếp theo)

Tóm tắt: Nó phụ thuộc vào trình duyệt. Vì vậy, không nên sử dụng.

jsfiddle example

+0

Dừng này: Tôi thấy bây giờ mà điều này phụ thuộc vào trình duyệt. Firefox trả lại ngày không hợp lệ và chrome bỏ qua và tính đến ngày hôm sau. Ok, nhưng điều này thật khủng khiếp. Tôi phải viết một hàm riêng để xác thực chuỗi ngày tháng. (?) – Dominik

+0

_Không nên sử dụng Date.parse như cho đến ** ES5 **, việc phân tích cú pháp các chuỗi đã hoàn toàn phụ thuộc vào việc triển khai thực hiện. Vẫn còn nhiều khác biệt về cách các chuỗi ngày phân tích các host khác nhau, do đó các chuỗi ngày phải được phân tích cú pháp theo cách thủ công (một thư viện có thể trợ giúp nếu nhiều định dạng khác nhau được cung cấp) ._ ([ref.] (Https: //developer.mozilla. org/en-US/docs/Web/JavaScript/Tham chiếu/Global_Objects/Ngày/phân tích cú pháp)) – hindmost

+0

Có câu hỏi nào ở đây không? Logic đằng sau cách hàm tạo ngày giao dịch với các đối số khác nhau được ghi đầy đủ trong [* ECMA-262 *] (http://ecma-international.org/ecma-262/6.0/index.html#sec-date-year- tháng-ngày-giờ-phút-giây-ms). Cách xác thực ngày (tức là các giá trị) đã được đề cập trong [* nhiều câu hỏi tại đây *] (http://stackoverflow.com/search?q=%5Bjavascript%5D+validate+a+date). – RobG

Trả lời

4

Điều đơn giản nhất tôi có thể nghĩ ra, là để chuyển đổi ngày phân tích chuỗi ISO và so sánh nó với đầu vào gốc:

var input = "2015-02-29T13:02:49.073Z" 
var date = new Date(input); 
var isValid = (input === date.toISOString()); 
+0

Có, cảm ơn vì điều này. Tôi chỉ có ý tưởng tương tự. Nó chỉ hoạt động với cùng một định dạng chuỗi. Nhưng đây chính là điều tôi cần. Tôi đã có một regex để xác nhận hợp lệ chuỗi ISO. – Dominik

4

tôi sử dụng chức năng này để kiểm tra xem một ngày là hợp lệ hay không:

function isValidDate(year, month, day) { 
    month = month - 1; 
    var d = new Date(year, month, day); 
    if (d.getFullYear() == year && d.getMonth() == month && d.getDate() == day) { 
     return true; 
    } 
    return false; 
} 
+0

Vâng, tôi cũng nghĩ rằng bạn phải làm điều này. Chỉ cần phân tích cú pháp với Date() là không đủ. :) – Dominik

+0

Lưu ý rằng bạn có thể cần phải bình thường hóa và thêm tiết kiệm múi giờ/ánh sáng ban ngày vào mã này như được đề cập trong câu trả lời của tôi – mplungjan

+0

@ mplungjan — tiết kiệm ánh sáng ban ngày có thể bị bỏ qua trong ngày (miễn là trình duyệt không có lỗi). Chỉ tháng cần phải được kiểm tra (vì một ngày ngoài phạm vi tháng và một tháng ngoài 1 đến 12 bao gồm sẽ dẫn đến * getMonth * trả về một số tháng khác). – RobG

0

tôi đã tìm thấy hành vi đó khá thú vị. Tôi đã từng chỉ chuyển đổi đầu vào thành một ngày (như bạn đã làm), sau đó cập nhật văn bản trong hộp văn bản để hiển thị ngày được JavaScript giải nghĩa để người dùng sẽ thấy ngày kết quả (hợp lệ).

May mắn thay, chúng tôi có thể làm tốt hơn bây giờ. Moment.js là một thư viện tuyệt vời để xử lý các giá trị ngày/giờ trong JavaScript. Nó chắc chắn làm cho cuộc sống dễ dàng hơn rất nhiều cho tôi!

http://momentjs.com/

0

Ngày trong trình duyệt luôn rất khó khăn, tôi đề nghị bạn sử dụng một js lib như thời điểm: http://momentjs.com/

sau đó bạn có thể sử dụng phương pháp cho ex .:

moment('03:55', 'HH:mm').isValid(); 
moment('2012-05-25', 'YYYY-MM-DD').isValid(); 
moment('2015-02-29T13:02:49.073Z', "YYYY-MM-DDTHH:mm:ss", true).isValid(); 
.isValid()
+0

theo như tôi thấy nó không được đề xuất gì cả. – thegio

+0

Tôi đặt một ví dụ. – thegio

+0

trông đẹp hơn .... – thegio

0

Nếu bạn vượt qua một chuỗi bắt đầu với định dạng 'YYYY-MM', như bạn có trong câu hỏi, bạn có thể sử dụng chức năng này:

function makeDate(s) { 
    var date = new Date(s); 
    if (date.toISOString(date).substr(0,7) != s.substr(0,7)) throw "Invalid date"; 
    return date; 
} 

dt = makeDate('2015-02-29T13:02:49.073Z'); 

makeDate Chức năng này sẽ thay thế đồng bằng new Date(...) cuộc gọi, nhưng cũng sẽ ném một lỗi trong Chrome khi nó được chuyển một chuỗi ngày không hợp lệ.

2

tôi đã viết chức năng nhỏ cho bạn:

function check_date(str){ 
    try{ 
     return str == new Date(str).toISOString() 
    }catch(e){ 
     return false; 
    } 
} 

Hãy thử

console.log(check_date('2015-02-01T13:02:49.073Z')); 
console.log(check_date('2015-02-35T13:02:49.073Z')); 
console.log(check_date('2015-02-29T13:02:49.073Z')); 

https://jsfiddle.net/8o040ctr/

+0

@trincot Tôi nghĩ rằng anh ấy đã trả lời nó theo cách sẽ hoạt động trong bất kỳ trình duyệt nào – mplungjan

+0

Bạn nói đúng, tôi đã bỏ lỡ câu trả lời :-) – trincot

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