Câu trả lời:
Quyết định sử dụng ngày 1 tháng 1 năm 1753 ( 1753-01-01
) làm giá trị ngày tối thiểu cho thời gian trong SQL Server quay trở lại nguồn gốc Sybase của nó .
Tầm quan trọng của ngày tháng mặc dù có thể được quy cho người đàn ông này.
Philip Stanhope, Bá tước thứ 4 của Chesterfield. Ai đã chỉ đạo Đạo luật Lịch (Phong cách mới) năm 1750 thông qua Quốc hội Anh. Điều này đã được luật hóa cho việc thông qua lịch Gregorian cho Anh và các thuộc địa sau đó.
Có một số ngày bị thiếu (liên kết lưu trữ internet) trong lịch của Anh vào năm 1752 khi việc điều chỉnh cuối cùng đã được thực hiện từ lịch Julian. Ngày 3 tháng 9 năm 1752 đến ngày 13 tháng 9 năm 1752 bị mất.
Kalen Delaney giải thích sự lựa chọn theo cách này
Vì vậy, với 12 ngày bị mất, làm thế nào bạn có thể tính ngày? Ví dụ: làm thế nào bạn có thể tính số ngày trong khoảng thời gian từ ngày 12 tháng 10 năm 1492 đến ngày 4 tháng 7 năm 1776? Bạn có bao gồm những người mất tích 12 ngày? Để tránh phải giải quyết vấn đề này, các nhà phát triển Sybase SQL Server ban đầu đã quyết định không cho phép ngày trước năm 1753. Bạn có thể lưu trữ các ngày trước đó bằng cách sử dụng các trường ký tự, nhưng bạn không thể sử dụng bất kỳ hàm datetime nào với các ngày trước đó mà bạn lưu trữ trong ký tự lĩnh vực.
Sự lựa chọn năm 1753 có vẻ hơi thiên hướng tuy nhiên vì nhiều quốc gia công giáo ở châu Âu đã sử dụng lịch trong 170 năm trước khi Anh thực hiện (ban đầu bị trì hoãn do sự phản đối của nhà thờ ). Ngược lại, nhiều quốc gia đã không cải tổ lịch của họ cho đến sau này, 1918 ở Nga. Thật vậy, cuộc Cách mạng Tháng Mười năm 1917 bắt đầu vào ngày 7 tháng 11 theo lịch Gregorian.
Cả datetime
và datetime2
kiểu dữ liệu mới được đề cập trong câu trả lời của Joe đều không cố gắng tính đến những khác biệt cục bộ này và chỉ đơn giản là sử dụng Lịch Gregorian.
Vì vậy, với phạm vi lớn hơn của datetime2
SELECT CONVERT(VARCHAR, DATEADD(DAY,-5,CAST('1752-09-13' AS DATETIME2)),100)
Trả về
Sep 8 1752 12:00AM
Một điểm cuối cùng với datetime2
kiểu dữ liệu là nó sử dụng lịch Gregorian proleptic dự kiến ngược trước khi nó thực sự được phát minh nên được sử dụng hạn chế trong việc xử lý các ngày lịch sử.
Điều này trái ngược với các triển khai Phần mềm khác, chẳng hạn như lớp Lịch Gregorian Java , mặc định theo Lịch Julian cho các ngày cho đến ngày 4 tháng 10 năm 1582, sau đó nhảy sang ngày 15 tháng 10 năm 1582 trong lịch Gregorian mới. Nó xử lý chính xác mô hình Julian của năm nhuận trước ngày đó và mô hình Gregorian sau ngày đó. Ngày cắt có thể được thay đổi bởi người gọi bằng cách gọi setGregorianChange()
.
Một bài viết khá thú vị thảo luận về một số đặc thù hơn với việc thông qua lịch có thể được tìm thấy ở đây .
Ông cố tuyệt vời vĩ đại vĩ đại của bạn nên nâng cấp lên SQL Server 2008 và sử dụng kiểu dữ liệu DateTime2 , hỗ trợ các ngày trong phạm vi: 0001-01-01 đến 9999-12-31.
Năm 1752 là năm nước Anh chuyển từ lịch Julian sang lịch Gregorian. Tôi tin rằng hai tuần vào tháng 9 năm 1752 không bao giờ xảy ra như vậy, điều này có ý nghĩa đối với các ngày trong khu vực chung đó.
Giải thích: http://uneasysilence.com/archive/2007/08/12008/ ( phiên bản Lưu trữ Internet )
Đây là toàn bộ câu chuyện về vấn đề ngày tháng và cách các DBMS lớn xử lý các vấn đề này.
Trong khoảng thời gian từ 1 sau Công nguyên đến ngày nay, thế giới phương Tây đã thực sự sử dụng hai lịch chính: lịch Julian của Julius Caesar và lịch Gregorian của Giáo hoàng Gregory XIII. Hai lịch khác nhau chỉ liên quan đến một quy tắc: quy tắc để quyết định năm nhuận là gì. Trong lịch Julian, tất cả các năm chia hết cho bốn là năm nhuận. Trong lịch Gregorian, tất cả các năm chia hết cho bốn là năm nhuận, ngoại trừ năm chia hết cho 100 (nhưng không chia hết cho 400) không phải là năm nhuận. Do đó, những năm 1700, 1800 và 1900 là những năm nhuận trong lịch Julian nhưng không phải trong lịch Gregorian, trong khi những năm 1600 và 2000 là những năm nhuận trong cả hai lịch.
Khi Đức Giáo hoàng Grêgôriô XIII giới thiệu lịch của mình vào năm 1582, ông cũng nói rằng những ngày từ ngày 4 tháng 10 năm 1582 đến ngày 15 tháng 10 năm 1582 nên được bỏ qua, đó là ngày sau ngày 4 tháng 10 nên là ngày 15 tháng 10 trì hoãn thay đổi hơn, mặc dù. Anh và các thuộc địa của cô đã không chuyển từ Julian sang Gregorian tính đến năm 1752, vì vậy đối với họ, ngày bị bỏ qua là từ ngày 4 tháng 9 đến ngày 14 tháng 9 năm 1752. Các quốc gia khác chuyển sang thời điểm khác, nhưng 1582 và 1752 là ngày thích hợp cho DBMS mà chúng ta đang thảo luận.
Do đó, hai vấn đề phát sinh với số học ngày khi một năm trở lại. Đầu tiên là, nên nhảy năm trước khi chuyển đổi được tính theo quy tắc Julian hoặc Gregorian? Vấn đề thứ hai là, những ngày bị bỏ qua nên được xử lý khi nào và như thế nào?
Đây là cách các DBMS lớn xử lý các câu hỏi sau:
- Giả vờ không có công tắc. Đây là những gì mà Tiêu chuẩn SQL dường như yêu cầu, mặc dù tài liệu tiêu chuẩn không rõ ràng: Nó chỉ nói rằng ngày tháng bị "ràng buộc bởi các quy tắc tự nhiên đối với ngày sử dụng" quy tắc tự nhiên "lịch Gregorian. Đây là tùy chọn mà DB2 đã chọn. Khi có một giả vờ rằng các quy tắc của một lịch luôn luôn được áp dụng ngay cả khi không ai nghe nói về lịch, thuật ngữ kỹ thuật là lịch "proleptic" có hiệu lực. Vì vậy, ví dụ, chúng ta có thể nói rằng DB2 tuân theo lịch Gregorian nguyên sinh.
- Tránh vấn đề hoàn toàn. Microsoft và Sybase đặt giá trị ngày tối thiểu của họ vào ngày 1 tháng 1 năm 1753, qua thời gian mà Mỹ chuyển lịch. Điều này có thể bảo vệ được, nhưng thỉnh thoảng có hai khiếu nại rằng hai DBMS này thiếu chức năng hữu ích mà các DBMS khác có và Tiêu chuẩn SQL yêu cầu.
- Chọn 1582. Đây là những gì Oracle đã làm. Một người dùng Oracle sẽ thấy rằng biểu thức số học ngày 15 tháng 10 năm 1582 trừ ngày 4 tháng 10 năm 1582 mang lại giá trị là 1 ngày (vì ngày 5 tháng 1014 không tồn tại) và ngày 29 tháng 2 năm 1300 là hợp lệ (vì bước nhảy vọt của Julian- quy tắc năm áp dụng). Tại sao Oracle gặp rắc rối thêm khi Tiêu chuẩn SQL dường như không yêu cầu nó? Câu trả lời là người dùng có thể yêu cầu nó. Các nhà sử học và nhà thiên văn học sử dụng hệ thống lai này thay vì lịch Gregorian nguyên sinh. (Đây cũng là tùy chọn mặc định mà Sun đã chọn khi triển khai lớp GregorianCalWiki cho Java, mặc dù tên, GregorianCalWiki là một lịch lai.)
Ngẫu nhiên, Windows không còn biết cách chuyển đổi chính xác UTC sang giờ địa phương của Hoa Kỳ cho một số ngày nhất định vào tháng 3 / tháng 4 hoặc tháng 10 / tháng 11 của những năm trước. Dấu thời gian dựa trên UTC từ những ngày đó bây giờ hơi vô lý. Sẽ rất khó để HĐH đơn giản từ chối xử lý bất kỳ dấu thời gian nào trước bộ quy tắc DST mới nhất của chính phủ Hoa Kỳ, do đó, đơn giản là họ xử lý sai một số lỗi. SQL Server từ chối xử lý ngày trước năm 1753 vì rất nhiều logic đặc biệt sẽ được yêu cầu để xử lý chúng một cách chính xác và nó không muốn xử lý chúng sai.