1 điểm bởi GN⁺ 2025-07-13 | 1 bình luận | Chia sẻ qua WhatsApp
  • Bài quiz này tập trung vào cách lớp Date của JavaScript hoạt động trong nhiều tình huống đầu vào khác nhau
  • Bao gồm các thử nghiệm về kết quả mà lớp Date trả về, có ném ngoại lệ hay không, cách xử lý nội bộ, v.v. khi nhận các giá trị đầu vào mà người dùng không ngờ tới (ví dụ: "wtf")
  • Thông qua bài quiz này, có thể dễ dàng nắm bắt các khoảnh khắc ngoại lệ của JavaScript Date, chiến lược phân tích cú pháp và các hành vi bất ngờ như không tuân thủ tiêu chuẩn
  • Mục đích là giúp lập trình viên JavaScript và người phụ trách kiểm thử nâng cao hiểu biết để giảm lỗi xử lý ngày tháng và sự bất định có thể phát sinh trong chương trình thực tế

1 bình luận

 
GN⁺ 2025-07-13
Ý kiến trên Hacker News
  • Trong console JS của firefox của tôi thì ra đáp án khác với bài quiz này
  • Mong là đừng chế giễu JavaScript. Ngày xưa người ta cũng làm vậy, rồi Node xuất hiện và giờ nó đã lan ra khắp thế giới
    • Tôi nghĩ TypeScript có lẽ là lựa chọn tốt nhất trong số các ngôn ngữ phải trả tiền để dùng
    • Tôi nhớ đến meme WAT mà suốt gần 10 năm mọi người coi undefined behaviour như bằng chứng mang tính quyết định cho sự vô nghĩa của công nghệ. Thật ra chỉ là mọi người hiểu sai khái niệm công nghệ thôi. Không thể dùng gạch để đựng nước thì chẳng có gì buồn cười cả, nhưng kỳ lạ là ai cũng kỳ vọng JavaScript sẽ bắt mọi ~lỗi~ thành lỗi thực sự hoặc tự sửa chúng. Đó là mục tiêu tốt, nhưng nếu không thể làm được thì cũng hơi kỳ khi lại xem đó là điều đáng tự hào. Tôi đã trải qua bầu không khí đó quá lâu rồi
  • Tôi thấy đây là bài quiz thú vị. Có nhiều hành vi gây bất ngờ. Nhưng trong thực tế thì phần lớn lại không quá quan trọng. Trong tình huống thực tế, tôi muốn mọi người trước hết hãy nghĩ xem mình có thật sự cần giờ địa phương không, và liệu dùng theo đơn vị instant có phù hợp không. Nếu dùng chuỗi UTC ISO 8601 hoặc Unix timestamp thì phần lớn độ phức tạp sẽ biến mất, hoặc ít nhất chỉ cần quan tâm ở một phần nào đó của phần mềm. Dĩ nhiên không phải lúc nào cũng vậy (có lần tôi phải xử lý thời gian nghỉ của người dùng phải bao gồm hai khoảng 1~5 giờ, và ở ranh giới DST thì đúng là ác mộng). Dù vậy, theo kinh nghiệm của tôi thì đa số trường hợp vẫn có thể tìm được cách giảm thiểu phạm vi phải bận tâm. Nếu đem nguyên xi dữ liệu người dùng nhập mà chưa hề kiểm tra nào đưa cho date parser thì đó là dùng sai cách
    • Vì cách chuyển dữ liệu người dùng nhập sang đúng định dạng chính là parsing, nên tôi nghĩ việc đưa nó cho date parser do ngôn ngữ cung cấp là hợp lý. Với lập trình viên JavaScript thì việc chuyện này không hoạt động tốt cũng không có gì đáng ngạc nhiên
    • Tôi hoàn toàn đồng ý với câu “không nên đưa dữ liệu người dùng nhập mà chưa kiểm tra vào date parser”. Nhưng khác biệt giữa API tốt và API tệ là: API tốt sẽ fail ngay khi có gì đó bất thường và báo cho bạn biết “bạn đang dùng sai”. Chỉ cần có gì hơi lạ là phải fail đúng cách, chứ không nên cố xử lý dữ liệu kỳ quặc bằng mọi giá. Tôi nghĩ vấn đề là nhiều API của JS được thiết kế để cứ phải chạy bằng được trong mọi trường hợp. Tôi không muốn ra NaN, cũng không muốn chuyển đổi chuỗi nửa vời
    • Mỗi lần nghe ai đó nói “chỉ cần dùng chuỗi UTC ISO 8601 hoặc Unix timestamp” là tôi lại thấy người đó chắc chỉ từng xử lý ngày tháng theo cách rất hạn hẹp. Hãy thử nghĩ đến chuyện áp dụng chiến lược đó cho ngày trong tương lai. Ví dụ một cuộc hẹn “gặp nhau lúc 7 giờ tối” thì điều quan trọng là vẫn gặp lúc 7 giờ, kể cả có đổi giờ mùa hè hay thay đổi múi giờ. Chuyện này ngoài đời xảy ra khá thường xuyên. Thực ra đây còn là vấn đề tinh tế hơn. Có những ứng dụng bắt buộc cần ngữ cảnh múi giờ. Ví dụ dịch vụ hiển thị đặt chỗ nhà hàng thì phải hiển thị theo giờ địa phương của nhà hàng, chứ không phải giờ địa phương của người dùng. Điều quan trọng là thời gian ở “đó”, không phải tôi đang ở đâu lúc này. Nói cách khác, GMT/UTC không phải thuốc chữa bách bệnh cho mọi vấn đề về ngày tháng. Với ngày trong quá khứ thì đây là giải pháp ổn, nhưng ngay cả khi đó việc lưu riêng giờ địa phương của người dùng hoặc múi giờ tại thời điểm sự kiện xảy ra vẫn thường hữu ích
    • Tôi cũng nghĩ cho thêm tùy chọn chỉ định rõ DST offset là cách hay. Tùy tình huống mà có thể rất hữu ích. Tôi cũng luôn thấy khó hiểu khi Excel không tự suy luận định dạng lúc dùng CSV
    • Tôi đồng ý với nội dung này. Đây là cái bẫy mà người mới rất dễ mắc phải, và tôi hy vọng bài quiz này sẽ khiến nhiều người suy nghĩ lại thêm một lần nữa
  • Có rất nhiều chỗ đáng ngạc nhiên! Tôi nghĩ mạch chung là parser đã cố quá mức để diễn giải đầu vào thành ngày tháng bằng mọi giá. Dù cách diễn giải đó rất thiếu nguyên tắc, thậm chí kỳ quặc đến mức ngay cả người dùng nhìn vào cũng khó đồng ý, nó vẫn cố ép ra ý nghĩa. Ngay cả trong những tình huống thật ra không thể diễn giải được thì dường như nó cũng không tích cực dùng các cách báo lỗi sẵn có. Dĩ nhiên cũng có thể những trường hợp kỳ cục đó đến từ các use case ngoài đời rất lạ
    • Tôi thấy kiểu hành vi này hoàn toàn không thể dự đoán. Nó gần như là nhiễu ngẫu nhiên. Chuỗi từ 32-49 thì ra những năm 2000, còn từ 50 trở đi lại bị hiểu là những năm 1900. Gặp kiểu này thì đúng là nên đập đi làm lại toàn bộ
    • Tôi hiểu cái thôi thúc muốn viết code sao cho lúc nào cũng trả ra kết quả hợp lệ. Nhưng phần lớn chúng ta đều kiềm chế được thôi thúc đó. Nên tôi thật sự thắc mắc tại sao những người thiết kế cái này lại không kiềm chế được
    • Đây là hiện tượng thường thấy ở các lập trình viên đã có vài năm kinh nghiệm. Junior thì chỉ lo sửa lỗi để cho chạy được. Mid-level thì ám ảnh với tư duy “giảm lỗi bằng mọi giá”, nên parser đưa ra quá nhiều giả định. Thế là sinh ra những thứ như lớp Date. Senior thì hiểu thấu đáo mức độ nguy hiểm của những lỗi kiểu này, nên sẽ thiết kế nhất quán và robust để đầu vào sai là báo lỗi ngay
  • Tôi được 17/28 điểm. Đúng là... những câu hỏi bị nguyền rủa! Có lẽ giờ cũng đến lúc tôi nên xem thử mấy thứ Temporal này
  • Tôi được 10/28. Không tệ lắm, nhưng tôi nghĩ kết quả có thể khác nhau tùy implementation: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/parse#non-standard_date_strings
    • Tôi ra 17/28 mà không biết nên tự hào hay xấu hổ. Chính tôi cũng thắc mắc sao mình lại biết mấy thứ này. Con trai tôi chẳng có chút kinh nghiệm nào với JS Date, vậy mà chỉ nhìn đáp án trước đó để suy luận cũng được 11/28. Tôi còn giải thích cho nó kiểu chuyển đổi type là gì nữa. Thành ra tôi thấy mình có khi đang cản trở con đi theo nghề IT
    • Đúng là implementation nào cũng khác. Tôi còn cố tình ghi ngay đầu bài quiz rằng đã kiểm tra trên một phiên bản Node cụ thể và một múi giờ cụ thể, vì cả hai đều ảnh hưởng quan trọng đến kết quả
    • Tôi thấy tác giả ghi rõ múi giờ chính xác của laptop mình ngay ở phần đầu bài quiz. Có vẻ một trong các câu tôi sai là vì không để ý chỗ đó. Tôi nghĩ đó rõ ràng là lời giải thích hợp lý. Chắc lẽ ra ngay từ đầu phải nhận ra đó sẽ là điểm mấu chốt
  • Trong JS thì tôi dùng chuỗi iso cho ngày tháng, vì có quá nhiều cái bẫy nguy hiểm. (Chỉ cần nhìn vài câu đầu của bài quiz là đủ thấy rồi.) Ngay cả các thư viện thay thế phổ biến như Moment cũng có những vấn đề nghiêm trọng tương tự ở nhiều mặt. Chúng trộn lẫn các khái niệm “date”, “time”, “datetime” với nhau và gây thêm hỗn loạn. Tôi còn từng nghe giải thích kiểu không nên tồn tại sự phân biệt giữa “time” và “date”, nhưng điều đó hoàn toàn không khớp với kinh nghiệm của tôi
    • Các thư viện nổi tiếng như Moment, Luxon, Day.js phạm sai lầm là xử lý những khái niệm thời gian khác nhau (thời gian tuyệt đối, thời gian dân sự, v.v.) bằng một đối tượng duy nhất. Chẳng lẽ thời gian tuyệt đối với thời gian dân sự lại là cùng một thứ sao? Họ cố gò chúng thành một
  • Điểm tôi nhận được là... ngày 28 tháng 11 năm 2000... thì phải
    • Tôi cười rất lâu khi thấy cái này
  • Điều tôi tò mò là tại sao mọi thứ lại thành ra thế này. Trông nó như kết quả của một đám tay mơ chắp vá vội vàng đủ thứ heuristic thiếu nhất quán, đến mức còn không thể phối hợp với nhau. Nhưng thực tế chắc không phải sản phẩm của người mới, nên tôi thắc mắc điều gì đã dẫn đến tình trạng này
    • Có người đã nhắc ở bình luận khác: Brendan Eich nói thẳng trên Twitter (liên kết) rằng họ chỉ sao chép hành vi của lớp Date trong Java. Với tôi thì bối cảnh lịch sử như vậy khá thú vị
    • Thực chất phần lớn vấn đề phát sinh khi cố ép parse những chuỗi kỳ quặc vốn chẳng liên quan gì đến ngày tháng. Gần như toàn edge case. Dĩ nhiên ở edge case thì tốt hơn vẫn là báo lỗi một cách nhất quán, nhưng nếu bạn không ném thẳng mọi chuỗi người dùng nhập vào Date.parse() thì cũng không phải vấn đề quá lớn. Trong thực tế rồi cũng sẽ dùng thư viện ngày tháng chuyên dụng. Vì ngay cả những phần ổn của Date cũng chẳng thật sự xuất sắc
    • Khi ngôn ngữ cho phép operator overriding hoặc không có static type, thì thường sẽ xảy ra chuyện một method phải hoạt động cho 10 mục đích hoàn toàn khác nhau. Java hay C++ cũng có khá nhiều API thiếu nhất quán kiểu này (dù không nghiêm trọng như JS)
  • Mấy bài quiz JS có cái vui là bấm vào để cười. Tôi dùng JS hơn 10 năm rồi mà chưa bao giờ parse chuỗi chưa qua regex validation thành Date
    • Vậy là bạn tạo ra thêm hai vấn đề
    • Tôi cũng đồng cảm tương tự. Tôi từng viết JS liên quan đến bảo mật suốt 10 năm. Đó là thời điểm tiêu chuẩn được cập nhật lớn. Hệ thống của chúng tôi chỉ dùng một phần cực nhỏ thực sự nhất quán và dự đoán được trên mọi trình duyệt. Sau khi tiêu chuẩn đổi, chúng tôi cũng chỉ thêm array.filterstructuredcopy, còn lại thì bỏ qua hết vì chẳng có lợi ích thực tế mà chỉ tăng bề mặt tấn công. Rồi TypeScript xuất hiện, và theo tôi đó là cơ hội bị bỏ lỡ lớn nhất trong lịch sử JS. Ngay cả bây giờ, viết code tử tế trong JS về bản chất vẫn là chỉ dùng cẩn thận 1% ngôn ngữ. Mà ngay cả phần đó cũng phải dùng rất thận trọng thôi