Kiểm tra xem một chuỗi có phải là giá trị ngày không


207

Cách dễ dàng để kiểm tra xem giá trị có phải là ngày hợp lệ hay không, bất kỳ định dạng ngày đã biết nào được phép.

Ví dụ tôi có các giá trị 10-11-2009, 10/11/2009, 2009-11-10T07:00:00+0000mà tất cả phải được công nhận là giá trị ngày, và các giá trị 200, 10, 350, mà không nên được công nhận là một giá trị ngày tháng. Cách đơn giản nhất để kiểm tra điều này, nếu điều này thậm chí có thể là gì? Bởi vì dấu thời gian cũng sẽ được cho phép.


Câu trả lời:


40

Sẽ Date.parse()đủ?

Xem trang Tài liệu MDN tương đối của nó .


23
Hãy cẩn thận với điều này vì nó vẫn sẽ trả lại cho những ngày không hợp lệ vào tháng 2, ví dụ: 2013 / 02-31
leojh

58
Một lý do khác để cẩn thận - số phân tích là ngày. Date.parse("4.3")986270400000.
Mogsdad

Tôi đã thử một câu đố với cả hai trường hợp 'thận trọng' ở trên: console.log (Date.parse ("2013 / 02-31")); console.log (Date.parse ("4.3")); và trong cả hai trường hợp (trên firefox), nó đã trả về NaN, vì vậy đối với tôi, Date.parse có vẻ ổn (tôi đang sử dụng dấu gạch ngang và độ dài chính xác trước khi phân tích cú pháp).
Cloudranger

55
Xin lỗi @Asmor, đây không phải là một câu trả lời đúng. Date.parse sẽ phân tích bất kỳ chuỗi nào có số đó.
jwerre

11
Date.parse ("Tên tôi 8") là 99662040000, sai. Tôi đã sử dụng điều này và bây giờ đau khổ.
Rohith

250

Cập nhật 2015

Đây là một câu hỏi cũ nhưng những câu hỏi mới khác như:

được đóng lại như là bản sao của cái này, vì vậy tôi nghĩ điều quan trọng là thêm một số thông tin mới ở đây. Tôi đang viết nó bởi vì tôi đã sợ rằng mọi người thực sự sao chép và dán một số mã được đăng ở đây và sử dụng nó trong sản xuất.

Hầu hết các câu trả lời ở đây đều sử dụng một số biểu thức chính quy phức tạp chỉ khớp với một số định dạng rất cụ thể và thực sự làm sai (như khớp ngày 32 tháng 1 trong khi không khớp với ngày ISO thực tế như được quảng cáo - xem bản demo ) hoặc chúng cố gắng chuyển bất cứ điều gì cho nhà Datexây dựng và chúc cho những điều tốt đẹp nhất

Sử dụng khoảnh khắc

Như tôi đã giải thích trong câu trả lời này này, hiện tại có một thư viện có sẵn cho điều đó: Moment.js

Đây là một thư viện để phân tích, xác thực, thao tác và hiển thị ngày trong JavaScript, có API phong phú hơn nhiều so với các hàm xử lý ngày JavaScript tiêu chuẩn.

Nó được 12kB rút gọn / gzipped và hoạt động ở Node.js và các nơi khác:

bower install moment --save # bower
npm install moment --save   # npm
Install-Package Moment.js   # NuGet
spm install moment --save   # spm
meteor add momentjs:moment  # meteor

Sử dụng Khoảnh khắc bạn có thể rất cụ thể về việc kiểm tra ngày hợp lệ. Đôi khi rất quan trọng để thêm một số manh mối về định dạng mà bạn mong đợi. Ví dụ: một ngày như 22/12/2015 trông giống như một ngày hợp lệ, trừ khi bạn sử dụng định dạng DD / MM / YYYY trong trường hợp ngày này sẽ bị từ chối là không hợp lệ. Có một số cách bạn có thể nói với Moment về định dạng mà bạn mong đợi, ví dụ:

moment("06/22/2015", "MM/DD/YYYY", true).isValid(); // true
moment("06/22/2015", "DD/MM/YYYY", true).isValid(); // false

Đối truesố là có vì vậy Khoảnh khắc sẽ không cố phân tích cú pháp đầu vào nếu nó không chính xác tuân thủ một trong các định dạng được cung cấp (theo ý kiến ​​của tôi nên là một hành vi mặc định).

Bạn có thể sử dụng một định dạng được cung cấp nội bộ:

moment("2015-06-22T13:17:21+0000", moment.ISO_8601, true).isValid(); // true

Và bạn có thể sử dụng nhiều định dạng như một mảng:

var formats = [
    moment.ISO_8601,
    "MM/DD/YYYY  :)  HH*mm*ss"
];
moment("2015-06-22T13:17:21+0000", formats, true).isValid(); // true
moment("06/22/2015  :)  13*17*21", formats, true).isValid(); // true
moment("06/22/2015  :(  13*17*21", formats, true).isValid(); // false

Xem: DEMO .

Thư viện khác

Nếu bạn không muốn sử dụng Moment.js, thì cũng có các thư viện khác:

Cập nhật năm 2016

Tôi tạo ra các immoment mô-đun đó là tương tự (một tập hợp con của) Moment nhưng không bất ngờ gây ra bởi đột biến của các đối tượng hiện có (xem các tài liệu để biết thêm).

Cập nhật 2018

Hôm nay tôi khuyên bạn nên sử dụng Luxon để thao tác ngày / giờ thay vì Khoảnh khắc, điều này (không giống như Khoảnh khắc) làm cho tất cả các đối tượng không thay đổi để không có những bất ngờ khó chịu liên quan đến đột biến ngày.

Thêm thông tin

Xem thêm:

Một loạt các bài viết của Rob Gravelle về các thư viện phân tích ngày tháng JavaScript:

Dòng dưới cùng

Tất nhiên ai cũng có thể thử phát minh lại bánh xe, viết biểu thức chính quy (nhưng thực sự vui lòng đọc ISO 8601 và RFC 3339 trước khi bạn làm điều đó) hoặc gọi các nhà xây dựng buit-in với dữ liệu ngẫu nhiên để phân tích các thông báo lỗi như 'Invalid Date'(Bạn có chắc là thông báo này là hoàn toàn giống nhau trên tất cả các nền tảng? Trong tất cả các địa phương? Trong tương lai?) hoặc bạn có thể sử dụng giải pháp đã được thử nghiệm và sử dụng thời gian của mình để cải thiện nó, không phải phát minh lại. Tất cả các thư viện được liệt kê ở đây là mã nguồn mở, phần mềm miễn phí.


4
Làm thế nào chính xác một người nên sử dụng này? moment("whatever 123").isValid()trả lại true.
krivar

4
@krivar Tốt nhất nên sử dụng nó như thế này: moment("06/22/2015", "DD/MM/YYYY", true).isValid();với định dạng ngày dự kiến ​​được cung cấp rõ ràng và với một đối số truecó nghĩa là kiểm tra nghiêm ngặt. Tôi cập nhật câu trả lời của tôi với nhiều thông tin hơn và các ví dụ tốt hơn.
rsp

2
Mặc dù vậy, nhưng tôi đang xác thực đầu vào của người dùng và tôi không biết định dạng ngày dự kiến ​​...
Jan Van der Haegen

3
@JanVanderHaegen Nếu giả định có thể được thực hiện rằng 3/4/5 là một ngày hợp lệ và ngày 1 tháng 4 năm 2015 thì tôi khuyên bạn nên thêm các định dạng đó (và có khả năng nhiều hơn nữa) vào danh sách rõ ràng các định dạng được hỗ trợ. Lưu ý rằng 3/4/5 mà bạn đề cập là mơ hồ không có định dạng rõ ràng.
rsp

3
Đây có thể là câu trả lời tốt nhất và được duy trì tốt nhất mà tôi đã thấy trên SO
Phil3992

62

Đây là cách tôi giải quyết vấn đề này trong một ứng dụng tôi đang làm việc ngay bây giờ:

cập nhật dựa trên phản hồi từ krillgar:

var isDate = function(date) {
    return (new Date(date) !== "Invalid Date") && !isNaN(new Date(date));
}

5
Tôi cần phải trả lại (Ngày mới (ngày)). ToString ()! == "Ngày không hợp lệ" cho nút. Cũng lưu ý rằng? đúng: sai là dư thừa. chỉ cần trả lại biểu thức sẽ là đủ ở đây.
domenukk

Trong IE8, new Date(date)không cung cấp cho bạn 'Ngày không hợp lệ'.
krillgar

13
Đây không phải là một câu trả lời tốt. new Date(date) !== "Invalid Date"sẽ luôn trả về true vì biểu thức bên trái sẽ trả về một đối tượng Date có thời gian là NaN , không bao giờ có thể là ===một chuỗi. Sử dụng =="công trình" do chuyển đổi loại. Nhưng vì việc phân tích chuỗi ngày vẫn chủ yếu phụ thuộc vào việc triển khai, dựa vào nó để phân tích các định dạng ngẫu nhiên, chúng tôi rất thiếu sót.
RobG

4
Ngày mới ( "469") kết quả trong Tue 01 tháng 1 469 00:00:00 GMT + 0200 (EET)
Dan Ochiana

3
Điều này tương tự như câu trả lời đúng được chấp nhận sai. isDate('Mac OS X 10.14.2')trả về đúng ở đây
BradStell

24

new Date(date) === 'Invalid Date'chỉ hoạt động trong Firefox và Chrome. IE8 (cái tôi có trên máy dùng cho mục đích thử nghiệm) cung cấp cho NaN.

Như đã nêu với câu trả lời được chấp nhận, Date.parse(date)cũng sẽ làm việc cho các con số. Vì vậy, để giải quyết vấn đề đó, bạn cũng có thể kiểm tra xem đó có phải là số không (nếu đó là thứ bạn muốn xác nhận).

var parsedDate = Date.parse(date);

// You want to check again for !isNaN(parsedDate) here because Dates can be converted
// to numbers, but a failed Date parse will not.
if (isNaN(date) && !isNaN(parsedDate)) {
    /* do your work */
}

2
Tôi nhận ra rằng một vài năm sau đó, nhưng isNankhông phải là một chức năng; trường hợp không chính xác trong trường hợp đầu tiên.
Tim Lewis

Không hoạt động. Nếu dateFoostreet 1, điều kiện của bạn được đánh giá là đúng.
Fabian Picon

9

Còn những thứ như thế này thì sao? Nó sẽ kiểm tra xem đó là đối tượng Date hay chuỗi ngày:

function isDate(value) {
    var dateFormat;
    if (toString.call(value) === '[object Date]') {
        return true;
    }
    if (typeof value.replace === 'function') {
        value.replace(/^\s+|\s+$/gm, '');
    }
    dateFormat = /(^\d{1,4}[\.|\\/|-]\d{1,2}[\.|\\/|-]\d{1,4})(\s*(?:0?[1-9]:[0-5]|1(?=[012])\d:[0-5])\d\s*[ap]m)?$/;
    return dateFormat.test(value);
}

Tôi nên đề cập rằng điều này không kiểm tra các chuỗi được định dạng ISO nhưng với một chút công việc hơn đối với RegExp, bạn sẽ ổn.


7

Không có câu trả lời nào ở đây kiểm tra xem ngày đó có hợp lệ không, chẳng hạn như ngày 31 tháng 2. Hàm này giải quyết bằng cách kiểm tra xem tháng trả về có tương đương với tháng ban đầu hay không và đảm bảo rằng một năm hợp lệ đã được trình bày.

//expected input dd/mm/yyyy or dd.mm.yyyy or dd-mm-yyyy
function isValidDate(s) {
  var separators = ['\\.', '\\-', '\\/'];
  var bits = s.split(new RegExp(separators.join('|'), 'g'));
  var d = new Date(bits[2], bits[1] - 1, bits[0]);
  return d.getFullYear() == bits[2] && d.getMonth() + 1 == bits[1];
} 

Bởi vì câu hỏi không phải là để kiểm tra xem một chuỗi có phải là ngày 'hợp lệ' hay không, mà chỉ kiểm tra xem một chuỗi có đại diện cho định dạng ngày không.
Thizzer

@Thizzer điểm tốt. Tôi sẽ không khắc phục nhưng khi đọc lại câu hỏi của bạn, tôi đã bối rối vì bạn nói 10 không nên xác thực nhưng dấu thời gian đó nên được cho phép.
ykay nói Phục hồi lại

xD thậm chí không nhận thấy rằng, một câu hỏi từ những ngày trước của tôi với ngày / dấu thời gian. Tôi sẽ cố gắng để chỉnh sửa câu hỏi sau ngày hôm nay.
Thizzer

Tại sao tháng-1 rồi tháng + 1?
Kapil Raghuwanshi

@KapilRaghuwanshi ngày javascript sử dụng tháng dựa trên số không, vì vậy bạn cần trừ đi 1 để tạo ngày thích hợp và thêm 1 để kiểm tra xem nó có tương đương với tháng ban đầu hay không
ykay nói Phục hồi

5

Sử dụng biểu thức chính quy để xác nhận nó.

isDate('2018-08-01T18:30:00.000Z');

isDate(_date){
        const _regExp  = new RegExp('^(-?(?:[1-9][0-9]*)?[0-9]{4})-(1[0-2]|0[1-9])-(3[01]|0[1-9]|[12][0-9])T(2[0-3]|[01][0-9]):([0-5][0-9]):([0-5][0-9])(.[0-9]+)?(Z)?$');
        return _regExp.test(_date);
    }

4

Bằng cách tham khảo tất cả các ý kiến ​​trên, tôi đã đi đến một giải pháp.

Điều này hoạt động nếu Datethông qua ở định dạng ISO hoặc cần thao tác cho các định dạng khác.

var isISO = "2018-08-01T18:30:00.000Z";

if (new Date(isISO) !== "Invalid Date" && !isNaN(new Date(isISO))) {
    if(isISO == new Date(isISO).toISOString()) {
        console.log("Valid date");
    } else {
        console.log("Invalid date");
    }
} else {
    console.log("Invalid date");
}

Bạn có thể chơi ở đây trên JSFiddle.


1
Giải pháp này phù hợp nhất với tôi vì các chuỗi ngày mà ứng dụng của tôi hỗ trợ có định dạng YYYY-MM-DD, do đó, việc đính kèm T00:00:00.000Zvà sử dụng giải pháp này để kiểm tra các chuỗi hợp lệ là không quan trọng.
tăng tốc

cho javascript này đang hoạt động, nhưng làm thế nào để sử dụng nó trong bản in.?
Sae

3

Đây là một chức năng được cải thiện chỉ sử dụng Date.parse():

function isDate(s) {
    if(isNaN(s) && !isNaN(Date.parse(s)))
        return true;
    else return false;
}

Lưu ý: Date.parse () sẽ phân tích số: ví dụ: Date.parse(1)sẽ trả về một ngày. Vì vậy, ở đây chúng tôi kiểm tra nếu skhông phải là một số, nếu đó là một ngày.


1
điều này không hoạt động vì vượt qua 'thử nghiệm 2' sẽ vượt qua như một ngày thực sự. đã thử nghiệm trong phiên bản mới nhất của chrome
user1751287

2

Tôi sẽ làm điều này

var myDateStr= new Date("2015/5/2");

if( ! isNaN ( myDateStr.getMonth() )) {
    console.log("Valid date");
}
else {
    console.log("Invalid date");
}

Chơi ở đây


2
Điều này không hoạt động trong Chrome hiện tại, có thể các trình duyệt khác. Tôi đã thay đổi chuỗi được cung cấp EXAMPLE STRING 12345và nó trả về "Ngày hợp lệ".

1

Đây là một phiên bản tối giản.

var isDate = function (date) {
    return!!(function(d){return(d!=='Invalid Date'&&!isNaN(d))})(new Date(date));
}

1
Vẫn không hoạt động cho ví dụ của tôi:isDate("  1")
Tomas

@Tom Bạn nên kiểm tra xem giá trị có chứa các ký tự khoảng trắng hay không trước khi xác định xem đó có phải là ngày không. Vấn đề của bạn là một trường hợp đặc biệt cần được xử lý bằng logic điều khiển của bạn.
Ông Polywhirl

1
Không nên yêu cầu kiểm tra ký tự khoảng trắng vì chuỗi ngày 1 tháng 1 năm 2020 là ngày hợp lệ có chứa khoảng trắng. Phương pháp của bạn không tính đến điều này.
Kirstin Walsh

1

Hàm gọi được này hoạt động hoàn hảo, trả về true cho ngày hợp lệ. Đảm bảo gọi bằng ngày ở định dạng ISO (yyyy-mm-dd hoặc yyyy / mm / dd):

function validateDate(isoDate) {

    if (isNaN(Date.parse(isoDate))) {
        return false;
    } else {
        if (isoDate != (new Date(isoDate)).toISOString().substr(0,10)) {
            return false;
        }
    }
    return true;
}

1
Điều đó tốt, nhưng nó không trả lời hoàn toàn câu hỏi. Cụ thể, nó không hoạt động trong '2009-11-10T07: 00: 00 + 0000', một trong những ví dụ được đưa ra.
sáng

Đừng nghĩ điều này hoạt động vì nó sẽ xác nhận ngày ('2016-12-30T08: 00: 00.000Z') // false
Jose Browne

Bất kể điều này có hoạt động hay không, nó có thể được đơn giản hóa nhưreturn !isNaN(Date.parse(isoDate)) || isoDate == new Date(isoDate).toISOString().substr(0,10);
Michel Jung

1

Tôi biết đó là một câu hỏi cũ nhưng tôi đã đối mặt với cùng một vấn đề và thấy rằng không có câu trả lời nào hoạt động đúng - cụ thể là loại bỏ các con số (1.200.345, v.v.) từ ngày, đó là câu hỏi ban đầu. Đây là một phương pháp khá không chính thống mà tôi có thể nghĩ ra và nó dường như có hiệu quả. Vui lòng chỉ ra nếu có trường hợp nó sẽ thất bại.

if(sDate.toString() == parseInt(sDate).toString()) return false;

Đây là dòng để loại bỏ số. Do đó, toàn bộ chức năng có thể trông giống như:

function isDate(sDate) {  
  if(sDate.toString() == parseInt(sDate).toString()) return false; 
  var tryDate = new Date(sDate);
  return (tryDate && tryDate.toString() != "NaN" && tryDate != "Invalid Date");  
}

console.log("100", isDate(100));
console.log("234", isDate("234"));
console.log("hello", isDate("hello"));
console.log("25 Feb 2018", isDate("25 Feb 2018"));
console.log("2009-11-10T07:00:00+0000", isDate("2009-11-10T07:00:00+0000"));


1
console.log("hello 1 ", isDate("hello 1 "));trả về đúng
John

bạn đúng rồi! Bạn đã có một giải pháp? Cho đến bây giờ tôi nghĩ rằng không có câu trả lời nào ở đây thực sự giải quyết câu hỏi một cách thích hợp!
peekolo

"100%", tỷ lệ phần trăm, trả về giá trị đúng
chập chững vào

0

Có ổn không khi kiểm tra chức năng liên quan đến Ngày có sẵn cho đối tượng để tìm xem đó có phải là đối tượng Ngày hay không?

giống

var l = new Date();
var isDate = (l.getDate !== undefined) ? true; false;

0

Đây là cách tôi kết thúc việc đó. Điều này sẽ không bao gồm tất cả các định dạng. Bạn phải điều chỉnh cho phù hợp. Tôi có quyền kiểm soát định dạng, vì vậy nó hoạt động với tôi

function isValidDate(s) {
            var dt = "";
            var bits = [];
            if (s && s.length >= 6) {
                if (s.indexOf("/") > -1) {
                    bits = s.split("/");
                }
                else if (s.indexOf("-") > -1) {
                    bits = s.split("-");
                }
                else if (s.indexOf(".") > -1) {
                    bits = s.split(".");
                }
                try {
                    dt = new Date(bits[2], bits[0] - 1, bits[1]);
                } catch (e) {
                    return false;
                }
                return (dt.getMonth() + 1) === parseInt(bits[0]);
            } else {
                return false;
            }
        }

-1

Ok, đây là một câu hỏi cũ, nhưng tôi đã tìm thấy một giải pháp khác trong khi kiểm tra các giải pháp ở đây. Đối với tôi hoạt động để kiểm tra xem hàm getTime () có ở đối tượng ngày không:

const checkDate = new Date(dateString);

if (typeof checkDate.getTime !== 'function') {
  return;
}

-1

document.getElementById('r1').innerHTML = dayjs('sdsdsd').isValid()

document.getElementById('r2').innerHTML = dayjs('2/6/20').isValid()
<script src="https://unpkg.com/dayjs@1.8.21/dayjs.min.js"></script>

<p>'sdsdsd' is a date: <span id="r1"></span></p>
<p>'2/6/20' is a date: <span id="r2"></span></p>

Một thư viện trọng lượng nhẹ đã sẵn sàng cho bạn: Day.js


Đây về cơ bản là quảng cáo trên StackOverflow, không được làm điều đó.
c4sh

-4
SimpleDateFormat sdf = new SimpleDateFormat(dateFromat);
sdf.setLenient(false);

Theo mặc định, điều này được đặt thành TRUE. Vì vậy, ngay cả các chuỗi định dạng sai trả về giá trị tốt.

Tôi đã sử dụng nó một cái gì đó như thế này:

SimpleDateFormat formatter = new SimpleDateFormat("yyyy/MM/dd");
formatter.setLenient(false);
String value = "1990/13/23"; 

try {
      Date date = formatter.parse(value);
      System.out.println(date);
    }catch (ParseException e) 
  {
    System.out.println("its bad");
  }

5
... javascript?!
artparks

-5

Thử cái này:

if (var date = new Date(yourDateString)) {
    // if you get here then you have a valid date       
}

6
Điều này không làm việc cho tôi. Đầu tiên var trong điều kiện không phân tích cú pháp, nhưng nếu bạn loại bỏ điều đó và thử một cái gì đó như thế này: if (date = new Date ("rác")) {alert (date); } Ngay cả khi ngày là rác, cảnh báo vẫn sẽ thực thi vì chức năng Ngày sẽ trả về "Ngày không hợp lệ" (ít nhất là trên firefox) để điều kiện được đánh giá là đúng. Tôi đoán nếu một số trình duyệt trả về null vào ngày không hợp lệ, thì nó sẽ hoạt động trên các trình duyệt đó. Có thể có sự không nhất quán trình duyệt ở đây.
Cloudranger
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.