Tại sao không có kiểu dữ liệu Ngày-Chỉ thực sự của Nhật Bản?


24

Tôi rất nản lòng khi phải sử dụng các giá trị DateTime cho các tập dữ liệu thực sự "chỉ là một ngày". Sinh nhật là ví dụ phổ biến nhất, nhưng điều này xuất hiện trong các ứng dụng kinh doanh mọi lúc.

Tôi đã quen với việc chỉ đặt phần Thời gian của các bản ghi "chỉ ngày" thành "buổi trưa" (giúp tránh ngày thay đổi bất kể múi giờ). Điều này có vẻ như là một hack, và tôi mãi mãi tìm thấy lỗi từ các nhà phát triển cơ sở gặp phải vấn đề này.

Thời gian luôn luôn tương đối với một điểm cố định. 4 giờ chiều là 4 giờ đăng kinh tuyến, hoặc buổi trưa. Điểm cao nhất của mặt trời trong quá cảnh là có thể quan sát được và cho phép chúng ta thiết lập một hệ tọa độ. 3 giờ trước buổi trưa (Ante Meridian), 2 giờ sau buổi trưa, 1441899402938 mili giây kể từ ngày 1 tháng 1 năm 1970. Đối với những người được nuôi dưỡng trong một thế giới Cartesian, đây là bản chất thứ hai.

Nhưng Lịch của chúng tôi có trước Descartes. Lập luận của tôi là nó được suy nghĩ đúng đắn hơn như là một phép liệt kê mà chức năng modulo được áp dụng. Thứ Hai sau Chủ Nhật, và cứ thế cho đến khi bạn nhận ra thực tế là Chủ Nhật sau Thứ Bảy. Không có tích cực và tiêu cực, nó là một mô-đun, hoặc giá trị tuyệt đối.

Tương tự với nhiều năm lặp lại. Cứ sau 365 ngày, có một vài ngày đặc biệt đối với tôi: sinh nhật, ngày kỷ niệm, sinh nhật của trẻ em, v.v. Các ứng dụng lên lịch kinh doanh đầy rẫy với các ví dụ về các cuộc họp cứ sau bảy ngày, thứ ba đầu tiên của tháng, v.v ... Chỉ vì chúng ta CÓ THỂ ánh xạ số này lên một số dấu phẩy động và trong thực tế, ánh xạ nó vào số đã nói sẽ giải quyết RẤT NHIỀU vấn đề thực sự khó khăn theo cách cũ, nhưng điều đó không có nghĩa là cách duy nhất để làm điều đó.

Nhận thức và hiểu biết về bản chất "chốt vuông trong lỗ tròn" của việc sử dụng DateTimes để lưu trữ Ngày làm cho bạn trở thành một lập trình viên tốt hơn theo quan điểm của tôi.

Có giá trị nào trong một ứng dụng được dự định rõ ràng là một ứng dụng lập lịch trong việc xác định lớp Ngày hay là "đặt tất cả thời gian đến trưa" là cách tiếp cận tốt nhất? Có vấn đề gì với việc sử dụng DateTime và đặt thành phần Thời gian thành Buổi trưa? Sự dịch chuyển múi giờ có thể được tính theo cách tiếp cận như vậy không? Tôi đã sử dụng MomentJS, nhưng tôi nghĩ đó chỉ là một lớp Date tốt hơn.


7
Đây là một câu hỏi khá thú vị tôi nghĩ. Lấy ví dụ về sinh nhật, nó chỉ thực sự có ý nghĩa ở con người, tôi đang sống ở một nơi và mọi người thức dậy cùng một lúc, một cách thức. ngay khi bạn cần diễn đạt nó một cách toán học, nó trở nên rất phức tạp. Tương tự với những thứ như thời gian bắt đầu / kết thúc ca làm việc, v.v. họ không có 'thời gian' họ là 'giờ trong ngày trong múi giờ mà bạn đang làm việc'
Ewan

3
NodaTime (thư viện C # cho Ngày & Giờ) có một loại ngày.
CodeInChaos

5
Lưu trữ thời gian của bạn dưới dạng UTC, không có vấn đề ngày, không có vấn đề múi giờ.
Loren Pechtel

3
"Nhưng Chúa ơi điều này có vẻ giống như một vụ hack, và tôi mãi mãi tìm thấy lỗi từ các nhà phát triển cơ sở gặp phải vấn đề này." - tại sao bạn không tạo lớp DateOnly của riêng bạn hoặc bất cứ điều gì và gọi nó là một ngày.
Brandin

5
@MichaelBlackburn Tôi nghiêm túc. Lời giải thích của bạn nghe chính xác tình huống đối với loại dữ liệu riêng thực thi quy tắc kinh doanh (chỉ ngày, ví dụ: bạn có thể lưu trữ dưới dạng "DateTime" bên trong với phần thời gian được đặt thành buổi trưa), nhưng sau đó chỉ hiển thị các phần bạn muốn (tháng , ngày, vv năm / không năm).
Brandin

Câu trả lời:


15

Trước hết, chúng ta hãy hiểu một điều: sinh nhật là một chuyện, ngày sinh là chuyện khác. Một sinh nhật là một kiểu dữ liệu kỳ lạ bởi vì nó thiếu không chỉ các thành phần của giờ, phút vv nhưng nó cũng thiếu các thành phần năm. Nếu bạn thực sự muốn đối phó với ngày sinh nhật, tôi khuyên bạn nên phát minh ra kiểu dữ liệu của riêng bạn, không chứa gì ngoài số tháng và số ngày và không liên quan đến bất kỳ loại dữ liệu ngày giờ tích hợp nào.

Mặt khác, nếu bạn cũng muốn theo dõi năm sinh, thì những gì bạn có không phải là ngày sinh nhật, đó là ngày sinh . Vì vậy, câu hỏi bây giờ trở thành lý do tại sao không có loại dữ liệu chỉ có ngày, để bạn có thể biểu thị ngày sinh một cách thuận tiện và thay vào đó, các ngôn ngữ phổ biến dường như buộc bạn phải sử dụng một số loại cũng bao gồm thành phần thời gian.

Hãy để tôi đề cập ngắn gọn rằng không phải tất cả các ngôn ngữ lập trình chỉ cung cấp các loại dữ liệu tạm thời bao gồm một thành phần thời gian. Tôi đã bắt gặp các kiểu dữ liệu chỉ có ngày trong RDBMS và trong các phương ngữ SQL tương ứng của chúng. Nhưng điều đó không liên quan: thực tế là các loại dữ liệu này tồn tại không có nghĩa là chúng là một thứ tốt để có và RDBMS có một lịch sử lâu dài về việc lưu trữ nhầm lẫn với biểu diễn.

Bạn sẽ hiểu tại sao nên có các kiểu dữ liệu chỉ có ngày như vậy vào thời điểm bạn nhận ra rằng thời gian là tọa độ. Hầu hết mọi người có một ý tưởng rất mơ hồ về thời gian là gì và ý tưởng này chứa đựng những quan niệm văn hóa phức tạp như năm, tháng và ngày, mà không nhận ra rằng những khái niệm này chỉ mang tính đại diện : Chúng chỉ hữu ích để đại diện cho thời gian cho con người và để nhận thời gian như đầu vào từ một con người. Tại bất kỳ lớp nào bên dưới điều khiển GUI nhập thời gian thực tế, thời gian nên và thường được biểu diễn dưới dạng tọa độ thời gian, là một số đơn vị thời gian duy nhất kể từ một số gốc.

Ví dụ: trong DateTimekiểu dữ liệu của Microsoft Dotnet, đơn vị thời gian là 100 nano giây và nguồn gốc của thời gian là 12:00 nửa đêm, ngày 1 tháng 1, 0001 CE

Một ví dụ khác về một ký hiệu đại diện, độc quyền là các phép đo góc sử dụng độ, phút của độ và giây của độ. Tất nhiên, để thực hiện bất kỳ phép tính hữu ích nào, bạn phải sử dụng nội bộ radian và nếu cần, hãy chuyển đổi sang và từ độ khi tương tác với người dùng.

Vì vậy, đừng nhầm lẫn giữa biểu diễn có thể đọc được của con người với phép đo với bản chất thực tế của phép đo. Thông thường, phương pháp lý tưởng để thực hiện phép đo, phù hợp nhất với bản chất của phép đo, rất khác so với cách biểu thị có thể đọc được của con người đối với phép đo đó.

Xét về tất cả những điều này, yêu cầu của bạn về kiểu dữ liệu tạm thời chỉ đại diện cho ngày giống với yêu cầu về kiểu dữ liệu góc chỉ có khả năng biểu thị độ, ngăn chặn rõ ràng bất kỳ độ chính xác nào. Kiểu dữ liệu như vậy sẽ khá hạn chế và cuối cùng là vô dụng, vì dù sao bạn cũng phải chuyển đổi nó sang và từ radian để có được bất cứ điều gì hữu ích với nó.

Vấn đề của bạn với ngày sinh là bạn có tọa độ thời gian không chính xác : người đó, tất nhiên, được sinh ra vào một thời điểm cụ thể, nhưng giờ và phút không được bệnh viện ghi lại, hoặc chúng tôi không quan tâm đến họ. Vì vậy, điều thực sự xảy ra là tọa độ thời gian ngày sinh của bạn có một lỗi sai, dung sai hoặc không chắc chắn nếu bạn muốn, và tốt nhất là xử lý nó như vậy: đặt nó ở chính xác ở giữa trong ngày và xem xét mức độ không chắc chắn +12 -12 giờ ngụ ý. Và đó chính xác là giải pháp mà bạn đã trực giác tìm đến.


4
Điều này không đúng với "Ngày", một khái niệm thậm chí còn cũ hơn Thời gian. Chúng được coi là đúng nhất như một bảng liệt kê, hoặc một mô-đun. Chủ nhật sau thứ Hai, vv cho đến khi chúng tôi trở lại vào Chủ nhật, sau thứ Bảy. Đó thực sự là một điều khác biệt.
Michael Blackburn

10
Tất nhiên , bệnh viện đã ghi lại thời gian sinh - đó là tiêu chuẩn thực hành ở hầu hết các bệnh viện. Đó hoàn toàn không phải là vấn đề. Vấn đề là vì mục đích kỷ niệm các sự kiện (sinh nhật, ngày lễ, ngày kỷ niệm, v.v.) mọi người không sử dụng hoặc muốn giải quyết đó là tốt hơn 1 ngày. Hãy hỏi người đầu tiên bạn nhìn thấy khi sinh nhật của họ, và họ sẽ cho bạn một tháng và một ngày, nhưng không bao giờ một giờ và phút. Ngoài ra: chúng tôi sử dụng các đơn vị bao gồm quy mô mọi lúc: milimet, kilôgam, megawatt, và thực sự, microfarad.
Caleb

4
-1: Không phải tất cả việc sử dụng thời gian là để biểu thị một khoảnh khắc trong thời gian. Sinh nhật là một ý tưởng khác nhau, được thể hiện bằng một tháng và ngày trong lịch Gregorian. Thật ý nghĩa khi hỏi "hôm nay là sinh nhật của Kevin phải không?" Câu trả lời là phụ thuộc vào vị trí. Nếu tôi ở Sydney thì đó có thể là sinh nhật của tôi, nhưng nếu tôi ở Honolulu, thì sẽ không được vài giờ nữa.
kevin cline

6
@MikeNakis Kết quả sẽ là microamp, không vô nghĩa. Quan trọng hơn: khi bạn sử dụng một ngày thay vì một giây hoặc một phần nghìn giây, bạn thường nói về cả ngày - một khoảng thời gian - chứ không phải là một thời gian cụ thể và tùy thuộc vào ngữ cảnh, đó có thể là một sự kiện lặp lại.
Caleb

4
OP đã nói về ngày sinh nhật, được đại diện chính xác bởi java.util.MonthDay. Sinh nhật không phải là một phép đo, đó là quan niệm của con người về một ngày lặp lại hàng năm. Có rất nhiều ý tưởng của con người về thời gian không được đại diện bởi một điểm duy nhất trong thời gian.
kevin cline

9

Ngày và thời gian là nhiều thứ khác nhau tùy thuộc vào ngữ cảnh và bạn cần nhiều loại riêng biệt để bao gồm tất cả các trường hợp sử dụng.

Các DateTimeloại hiện diện trong nhiều ngôn ngữ đại diện cho một điểm chính xác trong thời gian ( "thời gian tức thời"). Ngoài ra, chúng ta có một số khái niệm thời gian và thời gian tương đối hoặc "con người" như ngày dương lịch, ngày định kỳ, tháng, năm, v.v ... trong nhiều trường hợp phụ thuộc mơ hồ và bối cảnh. Các loại này không hữu dụng chung, nhưng cần thiết trong các lĩnh vực ứng dụng cụ thể như lịch, công cụ lập lịch và các ứng dụng khác tương tác với các khái niệm về thời gian của con người.

Nếu bạn đang viết một cái gì đó giống như một ứng dụng lịch, bạn chắc chắn sẽ được hưởng lợi từ việc sử dụng một thư viện như Joda-time cung cấp một tập hợp các loại thời gian phong phú hơn. Ví dụ LocalDate, một ngày không có thời gian. Điều này có ngữ nghĩa khác với thông thường DateTimevới phần thời gian được đặt thành 0, vì DateTimevẫn chỉ ra một thời điểm cụ thể (nửa đêm trong múi giờ cụ thể), trong khi LocalDatechỉ ra cả ngày và không bị ràng buộc với múi giờ cụ thể. Điều này cũng có nghĩa là bạn không thể dịch trực tiếp cái này sang cái kia.

LocalDatechắc chắn là đơn giản hơn DateTimevì không cần phải xem xét các múi giờ, nhưng bạn nên chú ý đến các vấn đề khác, ví dụ: ngày hiện tại có thể thực sự quay ngược khi bạn vượt qua múi giờ và cùng thời điểm đó có thể tương ứng với các ngày khác nhau trong các múi giờ khác nhau. Nếu bạn đang sử dụng ngày địa phương trong các ứng dụng mạng hoặc ứng dụng web, bạn nên rất cẩn thận về những vấn đề này. Loại bỏ phần thời gian từ một ngày không giải quyết được vấn đề cơ bản của múi giờ! Và nếu bạn xem xét các ngày lịch sử và các nền văn hóa khác nhau, nó thậm chí còn phức tạp hơn, vì cùng một ngày có thể tương ứng với các trường hợp khác nhau theo thời gian trong lịch sử nói Julian so với lịch Gregorian.

Bây giờ bạn hỏi tại sao ngôn ngữ không có thứ gì đó như tích LocalDate hợp . Trước hết, một số ngôn ngữ như SQL và Visual Basic có kiểu ngày không có phần thời gian. Và Java cũng đã thêm một LocalDatetrong phiên bản gần đây. Nhưng các nền tảng khác như .Net thì không. Chỉ các nhà thiết kế ngôn ngữ thực sự có thể trả lời tại sao điều này không được bao gồm trong thư viện tiêu chuẩn, nhưng tôi đoán là "thời gian tức thời" về mặt khái niệm đơn giản và phổ biến, trong khi các khái niệm thời gian khác chỉ hữu ích cho các miền ứng dụng cụ thể (như lịch, v.v. .). Vì vậy, thật hợp lý khi để nhà phát triển ứng dụng viết các loại tùy chỉnh để xử lý các trường hợp sử dụng phức tạp hơn hoặc để nó được xử lý bởi thư viện của bên thứ ba (như Joda-time).


5

Tôi rất nản lòng khi phải sử dụng các giá trị DateTime cho các tập dữ liệu thực sự "chỉ là một ngày". Sinh nhật là ví dụ phổ biến nhất, nhưng điều này xuất hiện trong các ứng dụng kinh doanh mọi lúc.

Điều này có lẽ là do lịch phức tạp và được sử dụng theo nhiều cách khác nhau mà không ai có thể tìm ra một lớp đơn giản nhưng đủ chung để có ích trong nhiều lĩnh vực.

Loại ngày thường được tìm thấy trong các ngôn ngữ lập trình có thể được sử dụng để xác định ngày giao dịch chính xác trong hệ thống máy tính. Các trường hợp sử dụng khác có thể yêu cầu một thư viện tùy chỉnh.

Dưới đây là một danh sách ngắn các sự thật về lịch, thể hiện sự phức tạp của chúng - hầu hết chúng là lịch sử, vì vậy nếu bạn hạn chế sự chú ý của mình vào ngày sau 1.1.1970, bạn sẽ không bị ảnh hưởng bởi điều này. Tuy nhiên, nếu ứng dụng của bạn cần hoạt động với ngày xảy ra trước cuối thế kỷ 19, thì những sự thật này sẽ có vấn đề. Các trường hợp sử dụng có thể là cơ sở dữ liệu lịch sử của tất cả các loại (sách, phả hệ) nhưng cũng là tài sản của các công ty hoặc tổ chức lớn vẫn còn hoạt động ngày nay.

Tất cả những sự thật này được trích dẫn từ Câu hỏi thường gặp xuất sắc được tìm thấy trong thư viện lịch cho OCaml được viết bởi Julien Signolles.

  1. Lịch Julian được giới thiệu bởi Julius Caesar vào năm 45 trước Công nguyên. Nó được sử dụng phổ biến cho đến những năm 1500, khi các quốc gia bắt đầu đổi sang lịch Gregorian (phần 2.2). Tuy nhiên, một số quốc gia (ví dụ Hy Lạp và Nga) đã sử dụng nó vào những năm 1900 và nhà thờ Chính thống ở Nga vẫn sử dụng nó, cũng như một số nhà thờ Chính thống khác.

  2. Chuyển từ lịch Julian sang lịch Gregorian không xảy ra thống nhất và tùy thuộc vào năm thay đổi, 10 đến 13 ngày đã bị loại bỏ. Ví dụ ở Pháp ngày 9 tháng 12 năm 1582 được theo sau bởi ngày 20 tháng 12 năm 1582 và tại Hy Lạp ngày 9 tháng 3 năm 1924 tiếp theo là ngày 23 tháng 3 năm 1924.

  3. Ngay cả trong thời kỳ hiện đại, nhiều lịch khác nhau được sử dụng (Gregorian, Chính thống giáo, Hồi giáo và Trung Quốc) để trích dẫn một số, tất cả đều sử dụng các cách khác nhau để tính toán năm và ngày kỷ niệm hoặc ngày kỷ niệm tôn giáo.

Bây giờ bạn hy vọng cho một loại ngày được đóng gói với các hoạt động hữu ích cho các hoạt động kinh doanh nói chung. Tôi đoán không có những thứ như hoạt động kinh doanh nói chung. Chẳng hạn, trong thế giới tài chính, chúng ta cần tính toán:

  1. Phân số năm (như Sáu tháng 6 tháng, tương ứng với Số 0,5 0,5), được sử dụng cùng với lãi suất để tính lãi thực tế cho khoản vay trong một thời hạn nhất định. Có 6 đến 10 công thức để tính các phân số này, mỗi cách khác nhau về cách chúng xử lý độ dài của một năm nhuận, vị trí của khoảng thời gian liên quan đến ngày cuối cùng của tháng 2 và thời gian của một tháng.

  2. Ngày lăn, khi tính toán ngày kỷ niệm, chúng tôi sử dụng lịch kinh doanh và quy tắc (được chọn từ một bộ gồm hơn 6 quy tắc khác nhau) để chuyển ngày kỷ niệm từ ngày nghỉ sang ngày làm việc.

Đối với những người làm việc trong ngành tài chính, bất kỳ loại lịch nào không thực hiện tất cả các chức năng và quy tắc này đều vô dụng. Có khả năng nhiều ngành công nghiệp khác có các loại thói quen và quy ước khác yêu cầu tính toán tùy chỉnh trên lịch.

Có giá trị nào trong một ứng dụng được dự định rõ ràng là một ứng dụng lập lịch trong việc xác định lớp Ngày hay là "đặt tất cả thời gian đến trưa" là cách tiếp cận tốt nhất? Có vấn đề gì với việc sử dụng DateTime và đặt thành phần Thời gian thành Buổi trưa? Sự dịch chuyển múi giờ có thể được tính theo cách tiếp cận như vậy không? Tôi đã sử dụng MomentJS, nhưng tôi nghĩ đó chỉ là một lớp Date tốt hơn.

Nếu bạn cần theo dõi một ngày theo lịch, cách tốt nhất có lẽ là sử dụng một số nguyên lớn đại diện cho ngày Julian của ngày đó. Các thuật toán để chuyển đổi qua lại từ ngày Julian sang ngày dương lịch - được mô tả bằng năm, tháng và lịch - được biết đến rộng rãi và được kiểm tra kỹ lưỡng, để bạn có thể dễ dàng thực hiện chúng trong ứng dụng của mình - và tìm ra bất kỳ quy tắc nào phù hợp trong bạn trường hợp để tính ngày kỷ niệm của một sự kiện xảy ra vào một số Februray thứ 29.


2

Tôi nghĩ Mike Nakis trong câu trả lời của mình ở trên thực hiện công việc tốt hơn tôi có thể giải thích thời gian nói chung là tọa độ được đo tuyệt đối và bất kỳ giao tiếp nào khác, trạng thái giả định hoặc sự tồn tại của tọa độ thời gian đó chỉ là một đại diện trừu tượng của tọa độ thời gian đã nói.

Bạn nói với các đại diện như vậy khi đề cập đến Ngày trong tuần chỉ là một dạng đại diện mô-đun của một thời điểm thực tế. Trong thực tế nó có phần phức tạp hơn thế. Nếu bạn được giao nhiệm vụ viết một hàm sẽ trả về Ngày trong tuần cho một thời điểm nhất định, hãy xem xét các thông tin sau mà bạn sẽ cần làm đầu vào cho thuật toán đó. Bạn sẽ yêu cầu thời điểm, Lịch, múi giờ để xem xét (Hãy nhớ rằng, múi giờ thay đổi TẤT CẢ THỜI GIAN để bạn cần biết khi nào múi giờ hiệu quả bắt đầu khi nó kết thúc ở tọa độ thời gian cụ thể. đã thay đổi ví dụ của họ!) và nếu thời gian Tiết kiệm ánh sáng có hiệu lực, điều này cũng thay đổi theo thời gian. Bây giờ hãy xem xét nếu bạn đã được cung cấp DateTime theo múi giờ địa phương,

Bạn có thể thấy câu hỏi có vẻ đơn giản này thực sự phức tạp đến mức nào.

Tôi biết nỗi đau mà bạn đang cảm thấy khi tôi ở trong đôi giày của bạn tại một thời điểm sửa tất cả các lỗi trong ứng dụng lập lịch truy cập cho một sản phẩm được viết bởi các nhà phát triển thiếu kinh nghiệm. Toàn bộ điều phải được loại bỏ.

Thời gian thực sự là một tọa độ, nhưng bên cạnh một Ngày đơn thuần, hãy xem xét các dữ liệu nhạy cảm về thời gian khác có thể cần thiết như:

Thời lượng: Một khoảng thời gian tính bằng mili giây có thể xảy ra biểu thị độ dài hoặc thời gian trôi qua mà không có tọa độ thời gian cụ thể được chỉ định. Một trường hợp sử dụng có thể là,

Là người dùng, tôi muốn nhiệm vụ này được thực hiện 15 giây sau khi hoàn thành công việc nửa đêm vào mỗi thứ tư khác.

Khoảng thời gian: Một phạm vi thời gian giữa hai tọa độ thời gian cụ thể. Một trường hợp sử dụng mà bạn có thể muốn xem xét một khoảng.

Là người dùng, tôi cần xem tất cả các Ngày trong Tháng trong một khoảng thời gian xác định.

Một điểm nhanh khác tôi muốn đưa ra là bạn đã nhận xét về các số Dấu phẩy động cho dữ liệu dựa trên thời gian và tôi khuyên bạn nên chống lại nó. Số học dấu phẩy động chắc chắn dẫn đến các lỗi làm tròn có thể không cung cấp cho bạn một phép đo chính xác khi cần thiết cho thời gian.

Vì vậy, trong kết luận, tất cả các thông tin này chắc chắn dẫn đến các cân nhắc thiết kế sau đây:

  • Các điểm hoặc phạm vi thời gian cụ thể cần được duy trì trong UTC hoặc một số kiểu dữ liệu chứa đủ thông tin để dễ dàng được trừu tượng hóa trở lại UTC khi cần
  • Logic ứng dụng nên được viết để định dạng UTC hoặc một phạm vi tọa độ UTC thành trạng thái dữ liệu đại diện dễ tiêu hóa hơn cho người dùng cuối.
  • Thời lượng quan trọng nên được duy trì trong một phần nghìn giây
  • Tùy chọn địa phương cụ thể hoặc người dùng cuối trên màn hình hiển thị của bất kỳ dữ liệu nào theo thời gian nên được duy trì dưới dạng dữ liệu bổ sung và được coi như một tùy chọn hiển thị. (Ví dụ: Kiốt A, Múi giờ miền Trung, định dạng Giờ quân sự hoặc tùy chọn của người dùng B, Giờ chuẩn ở múi giờ Tel Aviv (GMT + 7: 00), v.v ...)
  • Tránh số FP

1
Không ai trong số này là "không thể tránh khỏi". Nó có thể phổ biến cho nhiều ứng dụng, nhưng Máy Va chạm Hadron Lớn xử lý các sự kiện ở quy mô nano giây. Thời gian hệ thống đã chuyển sang micro giây vì mili giây không có đủ độ chính xác. Các ứng dụng lịch cần có khái niệm về một ngày diễn ra vào một ngày theo lịch địa phương cho dù bạn có ở cùng múi giờ bạn đã tạo sự kiện hay không.
Alan Shutko

1
@AlanShutko Và vâng, "dữ liệu bổ sung" cần thiết là những thứ như múi giờ địa phương và Ngày và bất kỳ dữ liệu quan trọng nào khác phải được ghi lại. Tất cả chỉ là trừu tượng tuy nhiên đến một thời điểm duy nhất, ngay cả khi thời điểm đó không quan trọng đối với thuật toán của bạn. Theo như tỷ lệ nano giây và thậm chí là micro giây, câu trả lời của tôi hướng nhiều hơn đến phần mềm loại web và LOB. Tôi nghi ngờ rằng ngôn ngữ LHC được lựa chọn là C # hoặc Javascript.
maple_shaft

1
Milliseconds là tuyệt vời cho các quá trình vật lý lặp lại. Đối với hoạt động của con người, đôi khi đơn vị thích hợp là ngày danh nghĩa, ví dụ: nếu được vận chuyển vào cuối ngày, nó sẽ có sẵn để sử dụng tại điểm đến ba ngày sau đó.
kevin cline

Trước đây tôi đã từng cân nhắc sử dụng số dấu phẩy động 64 bit cho tọa độ thời gian và quan trọng hơn là kéo dài thời gian, bởi vì chúng cho phép bạn thể hiện số lượng nhỏ với độ chính xác cao, cũng như số lượng lớn, trong đó việc mất độ chính xác không thực sự quan trọng . (Vậy điều gì sẽ xảy ra nếu Khủng long chết 65 triệu năm trước cho hoặc mất vài năm?) Vậy, tại sao bạn lại nói rằng chúng nên tránh?
Mike Nakis

Mike, tôi nghĩ rằng mối quan tâm của anh ấy là với toán học FP chắc chắn làm tròn khi nó chuyển đổi từ giá trị thập phân sang giá trị nhị phân. Ví dụ: 0,3 là số thập phân lặp lại khi được biểu thị dưới dạng số FP nhị phân và do đó không thể được biểu diễn chính xác. Không phải là bạn thiếu năng lực, mà là bạn thiếu độ chính xác.
Michael Blackburn

2

Nói tóm lại, vì hầu hết các loại thời gian dựa trên máy tính đều tập trung vào xử lý vấn đề múi giờ và múi giờ đúng cách.

Có 2 trường hợp cạnh không được phục vụ tốt theo cách tiếp cận thông thường. Đặt điểm thời gian ở phía bên kia của thay đổi tiết kiệm ánh sáng ban ngày bằng giờ địa phương, sau đó được chuyển đổi trong UTC bằng lớp trừu tượng thấp hơn và sau đó khiến bạn đến sớm 1 giờ / trễ cho cuộc họp.

Một cái khác là (theo câu hỏi) mô hình hóa thông tin ngày tùy ý, chẳng hạn như ghi ngày sinh của một người. Hãy tưởng tượng trường hợp hai người được sinh ra cùng một lúc, một người ở New Zealand, người kia ở Hawaii. Xác suất là họ sẽ có ngày sinh khác nhau trên hộ chiếu và nếu người sinh ra ở Hawaii chuyển đến New Zealand, họ sẽ được coi là một ngày lớn hơn người sinh ra ở New Zealand, mặc dù đã sống cùng thời gian.

Gợi ý trong câu hỏi là đặt ngày để có thời gian giữa trưa, UTC sẽ hoạt động, CÒN ở khắp mọi nơi. Độ lệch của UTC nằm trong khoảng từ -12 đến +14, do đó, có một vài nơi ở Thái Bình Dương nơi phương pháp này sẽ thất bại. Tôi có xu hướng coi các loại dữ liệu này là các chuỗi, theo định dạng yyyymmdd và nếu tôi phải so sánh các phép tính giữa hai ngày, điều này có thể được thực hiện một cách an toàn khi so sánh chuỗi. Khi thực hiện so sánh delta (ví dụ giữa ngày và bây giờ hoặc bao lâu đến tuổi X), bạn cần đảm bảo rằng tất cả các ngày được tạo trong cùng một độ lệch UTC, và sau đó có thể sử dụng các hàm thời gian tiêu chuẩn để thực hiện công việc.


3
" Tôi có xu hướng coi các loại dữ liệu này là các chuỗi, ở định dạng yyyymmdd và nếu tôi phải so sánh các phép tính giữa hai ngày, điều này có thể được thực hiện một cách an toàn như so sánh chuỗi. " Điều đó chắc chắn giống như một Datekiểu dữ liệu, chỉ cần được thực hiện aString
Ross Patterson

Như bạn nói, đó là một chuỗi đại diện cho một ngày và không giống như poster gốc, ngày đó không bị thay đổi khi ở trong múi giờ UTC + 13.
Michael Shaw

2

Tại sao không có kiểu dữ liệu Ngày-Chỉ thực sự của Nhật Bản?

Vì những lý do tương tự, tôi nghĩ rằng các giá trị DateTime thường được chỉ định trong UTC: tính đơn giảnđộ tin cậy . Điểm của giá trị DateTime là chỉ định một thời điểm duy nhất không bị ảnh hưởng bởi múi giờ, tiết kiệm ánh sáng ban ngày, lịch và các điều chỉnh cục bộ khác. Giá trị DateTime chỉ định một tức thời (tối đa giới hạn độ phân giải của loại), không phải là khoảng thời gian hoặc tập hợp thời gian. Những hạn chế này cho phép so sánh các giá trị DateTime theo cách đáng tin cậy, có thể dự đoán được, không phức tạp.

Cố gắng chỉ định một ngày có giá trị DateTime giống như cố gắng sử dụng một điểm để chỉ định một khu vực.Bạn có thể thực hiện công việc đó bằng cách sử dụng một quy ước, như "điểm này đại diện cho tâm của vòng tròn có bán kính 100m", nhưng có rất nhiều vấn đề ở đó: mọi người cần sử dụng cùng một quy ước, bạn cần viết một bó mã hỗ trợ để làm việc với loại sai ít gây đau đớn hơn và khá chắc chắn rằng đến một lúc nào đó bạn sẽ cần chỉ định một khu vực lớn hơn hoặc nhỏ hơn khu vực thông thường. Vì vậy, đó là với ngày: bạn có thể sử dụng 'buổi trưa' là thời gian thông thường để chỉ định ngày, nhưng sau đó bạn đi vào múi giờ vì mọi người mong đợi chỉ định ngày theo giờ địa phương thay vì UTC. Và ngay cả khi bạn đưa ra một cách thỏa đáng để sử dụng DateTime để chỉ định ngày, bạn sẽ cần thêm thông tin để biết đó là ngày tuyệt đối hay ngày tương đối: đó là ngày 4 tháng 7, 1776 hay mỗi 4 tháng 7? Điều gì nếu bạn muốn lặp lại sử dụng một số giai đoạn khác? Và lịch có tất cả các vấn đề điên rồ: một số tháng dài hơn những năm khác, một số năm dài hơn những ngày khác, một số ngày thậm chí dài hơn những ngày khác và một số lịch có những khoảng trống trong đó. Bạn sẽ không muốn giải quyết những vấn đề này trong cả ngày, bởi vì những vấn đề tương tự xuất hiện trong thời gian ngắn hơn: bạn có thể muốn viết mã thể hiện "uống 1 viên thuốc mỗi 4 giờ" một cách dễ dàng như " nhóm họp vào thứ Sáu hàng tuần. "

Vì vậy, có rất nhiều sự phức tạp liên quan đến việc làm việc với ngày. Thật dễ dàng (không có ý định chơi chữ) dễ dàng cung cấp một loại chỉ định thời điểm và làm việc với nó như bạn muốn, nhưng cực kỳ khó để cung cấp một loại giải quyết tất cả các cách sử dụng ngày.

Như những người khác đã chỉ ra, có những ngôn ngữ và thư viện hỗ trợ tốt cho ngày tháng và thường nên sử dụng chúng vì thật khó để có được mã liên quan đến ngày chính xác.


2
"Khó có thể cung cấp một loại giải quyết tất cả các cách mà ngày được sử dụng." Đúng, đó là lý do tại sao đó là một ý tưởng khủng khiếp để cố gắng cung cấp một loại duy nhất để làm tất cả. Các bản phát hành Java đầu tiên chỉ cung cấp java.util.Date và kết quả thật kinh khủng. Sau đó, họ đã thêm một hệ thống phân cấp java.util.CalWiki phức tạp và nó không trở nên tốt hơn nhiều.
kevin cline

1
@kevincline Hoàn toàn đồng ý. OP đã không chỉ định một ngôn ngữ, vì vậy tôi đã nhắm đến tính tổng quát.
Caleb

" Vì những lý do tương tự, tôi nghĩ rằng các giá trị DateTime thường được chỉ định trong UTC " ... Ồ, điều đó có đúng không. Đó là năm 2015, và vẫn còn rất nhiều mã được viết bằng múi giờ tại nhà của tác giả :-(
Ross Patterson

1
Tôi đã thực sự tự hỏi tại sao không có một hội nghị thường được chấp nhận xung quanh ngày. Việc "sử dụng một điểm để thể hiện một khu vực" của bạn hoàn toàn gói gọn sự thất vọng của tôi.
Michael Blackburn

2

Tại sao không có kiểu dữ liệu Ngày-Chỉ thực sự của Nhật Bản?

Có nhiều loại như vậy trong các thư viện khác nhau cho các ngôn ngữ khác nhau. Gần như chắc chắn có một cho ngôn ngữ hiện tại của bạn. Gói Java sử dụng đã có một API khủng khiếp để tính toán thời gian, nhưng việc giới thiệu gói java.time đã giúp cuộc sống tốt hơn nhiều. Xem java.time.LocalDate, chứa giá trị năm tháng hoặc java.time.MonthDay, chỉ chứa số tháng và ngày.


1

Thao tác theo lịch là một trong những khía cạnh kém hiểu biết nhất của điện toán. Toàn bộ cuốn sách đã được viết về chủ đề này. @MichealBlackburn hoàn toàn đúng khi yêu cầu một kiểu dữ liệu chỉ có ngày, một kiểu dữ liệu không giải quyết đến một điểm trên dòng thời gian, có thể giải thích lại. Trong lịch sử, đã có những tranh chấp chính đáng về ý nghĩa của một ngày. Người ta không cần nhìn xa hơn việc thông qua lịch Gregorian để tìm hiểu mức độ phức tạp của nó. Hơn nữa, nhiều năm không phải lúc nào cũng bắt đầu vào ngày 1 tháng 1, ngay cả ở Tây Âu và các thuộc địa của nó ( ví dụ: Anh và Anh Mỹ bắt đầu năm vào ngày 25 tháng 3).


1
Đúng rồi đó. Câu hỏi thường gặp về lịch mà tôi trích dẫn trong câu trả lời của mình là một nguồn tài nguyên tuyệt vời để khám phá sự phức tạp và sự tinh tế của các thao tác clandar
Michael Le Barbier Grünewald

-2

Trong câu trả lời:

Chà, thật lòng tôi muốn biết tại sao hầu hết mọi ngôn ngữ chỉ có một kiểu dữ liệu cho việc này.

Lý do phổ biến nhất có thể là "vì nó không cần thiết". Nếu bạn muốn thời gian ngày không quan tâm đến giờ, phút, giây, v.v., thì bạn chỉ cần khởi tạo nó như thế này:

date = new DateTime(year, month, day, 0, 0, 0);

Nếu bạn muốn, bạn có thể tự gia hạn DateTime:

public class Date extends DateTime {
    ...
    public Date(int year, int month, int day) {
        this(year, month, day, 0, 0, 0);
    }
}

Lưu ý: Tôi cố tình bỏ qua thời gian và múi giờ mặc định. Việc bạn đặt chúng vào thực sự không quan trọng, miễn là chúng giống nhau cho tất cả mọi người Date. Bạn có thể làm một trường hợp cho UTC. Bạn có thể tạo ra một trường hợp để sử dụng múi giờ mà máy chủ của bạn nằm trong - theo cách tôi không nghĩ nó quan trọng để thể hiện một giá trị không chính xác như thế nào Date. Tương tự với thời gian mặc định - bạn có thể làm cho nó 0, bạn có thể làm cho nó buổi trưa. Nó không thành vấn đề. Nếu Facebook gửi cho tôi thông báo sinh nhật vào lúc 00:01 nhưng tôi sinh vào lúc 23:59 tôi không thực sự quan tâm và tôi sẽ không bị xúc phạm rằng họ đã nghỉ hơn 12 giờ.

Ở trên là trong Java nhưng sẽ hoạt động tương tự trong bất kỳ ngôn ngữ nào có a DateTimevà thừa kế. Java thực sự có rất nhiều cách để giải quyết vấn đề này và những điều trên không được chấp nhận (họ muốn bạn sử dụng Calendarngay bây giờ). Nhưng như những người khác đã đăng trong các ý kiến, một số ngôn ngữ thực sự làm cung cấp một Datelớp, có lẽ chỉ vì lý do này.

Trong tất cả khả năng, mọi Datetriển khai có lẽ chỉ là một trình bao bọc cho ngôn ngữ DateTimevà nó không thay đổi thời gian. Nếu không, bạn sẽ cần mã trùng lặp để giải quyết các vấn đề như số ngày giữa hai Ngày / Ngày, hoặc liệu hai Dategiây có bằng nhau không (về ngày 29 tháng 2 và ngày 1 tháng 3?). Những thứ đó thường được giải trong DateTimelớp. Nó có ý nghĩa để sử dụng lại cùng một mã cho a Date.


4
-1: Sử dụng LocalDate nếu bạn muốn chỉ năm + tháng + ngày. Sử dụng DateTime cho mục đích đó sẽ dẫn đến lỗi khi một số lập trình viên khác nhìn thấy DateTime và cho rằng nó đại diện cho một thời điểm.
kevin cline

@kevincline Tôi không cảm thấy cần thiết vì câu hỏi này không liên quan đến ngôn ngữ. Tôi cũng sẽ nghĩ rõ ràng rằng việc sử dụng mã có nhãn "Không dùng nữa" là một tình huống rủi ro sử dụng của chính bạn. Quan trọng hơn, tôi chỉ sử dụng nó như một ví dụ về những điều bạn có thể làm trong một tình huống trong đó một ngôn ngữ khôngLocalDatehoặc Dateloại lớp và bạn phải 'tự mình làm'.
Shaz

1
Nhưng "nó là cần thiết" cho mã ngắn gọn và chính xác rõ ràng liên quan đến các quy tắc kinh doanh về thời gian (trái ngược với thời gian vật lý). nếu thư viện không cung cấp các loại cho thời gian danh nghĩa, thì lập trình viên sẽ cần thiết để phát minh ra chúng và cách để làm điều đó không bắt đầu với "DateTime".
kevin cline

@kevincline Tôi không thấy mã sẽ rõ ràng hay súc tích như thế nào. Sự khác biệt từ quan điểm của một lập trình viên giữa new Date(2000, 1, 1);và là new Date(2000, 1, 1);gì? Bạn có thể biết cái nào có giờ trống, phút và giây bên dưới không? Nếu bạn đang lo lắng về chức năng bổ sung hiển thị (như setMinutes ()), sau đó bạn có thể đi con đường của việc có Datebọc DateTimethay vì kế thừa từ nó, và sau đó bạn chỉ phơi bày setYear, setMonth, setDay, vv Và nó chắc chắn không kém chính xác hơn DateTime của thư viện mà bạn đang sử dụng.
Shaz

Nền tảng của tôi chủ yếu là C #, không có cấu trúc tương tự LocalDate. Chúng tôi chỉ cần DateTime và lướt qua, rõ ràng.
Michael Blackburn
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.