Các kiểu dữ liệu ngày, giờ và ngày giờ. Các kiểu dữ liệu ngày và giờ

Các kiểu DATETIME, DATE và TIMESTAMP là các kiểu dữ liệu có liên quan. Phần này mô tả các thuộc tính của chúng, đặc điểm chung và sự khác biệt.

Kiểu dữ liệu DATETIME được sử dụng cho các giá trị chứa cả thông tin ngày và giờ. MySQL truy xuất và hiển thị các giá trị DATETIME ở định dạng "YYYY-MM-DD HH:MM:SS". Phạm vi giá trị được hỗ trợ là từ "1000-01-01 00:00:00" đến "9999-12-31 23:59:59". ("được hỗ trợ" có nghĩa là mặc dù các giá trị có giá trị thời gian trước đó vẫn có thể hoạt động nhưng không có gì đảm bảo rằng chúng sẽ được lưu trữ và hiển thị chính xác).

Kiểu DATE được sử dụng cho các giá trị chỉ có thông tin ngày tháng, không có phần thời gian. MySQL truy xuất và hiển thị các giá trị DATE ở định dạng "YYYY-MM-DD". Phạm vi giá trị được hỗ trợ là từ "1000-01-01" đến "9999-12-31".

Kiểu cột TIMESTAMP cung cấp kiểu biểu diễn dữ liệu có thể được sử dụng để ghi âm tự động ngày và giờ hiện tại khi thực hiện các thao tác INSERT hoặc UPDATE. Nếu bạn có nhiều cột TIMESTAMP thì chỉ cột đầu tiên được cập nhật tự động.

Cột TIMESTAMP đầu tiên được cập nhật tự động khi bất kỳ điều kiện nào sau đây là đúng:

  • Cột này không được chỉ định rõ ràng trong lệnh INSERT hoặc LOAD DATA INFILE.
  • Cột này không được chỉ định rõ ràng trong lệnh UPDATE và nó thay đổi một giá trị trong một số cột khác (lưu ý rằng lệnh UPDATE đặt cột về cùng giá trị trước khi lệnh được thực thi sẽ không làm cho cột TIMESTAMP được cập nhật , vì lý do hiệu suất, MySQL bỏ qua các cập nhật như vậy khi đặt cột thành giá trị hiện tại).
  • Giá trị trong cột TIMESTAMP được đặt rõ ràng thành NULL.

Đối với các cột còn lại (ngoại trừ cột đầu tiên) thuộc loại TIMESTAMP, bạn cũng có thể đặt giá trị cho ngày và giờ hiện tại. Để thực hiện việc này, bạn chỉ cần đặt cột thành NULL hoặc NOW() .

Bất kỳ cột TIMESTAMP nào (kể cả cột đầu tiên thuộc loại này) có thể được đặt thành một giá trị khác với ngày và giờ hiện tại. Điều này được thực hiện bằng cách đặt nó thành giá trị mong muốn một cách rõ ràng. Tài sản này có thể được sử dụng, ví dụ: nếu bạn cần đặt cột TIMESTAMP thành ngày và giờ hiện tại khi tạo một hàng và sau đó khi bạn cập nhật hàng đó, giá trị của cột sẽ không thay đổi:

  • Để MySQL tự động đặt giá trị của cột TIMESTAMP khi tạo một hàng nhất định. Cột sẽ được đặt lại về ngày giờ hiện tại.
  • Khi bạn thực hiện các cập nhật tiếp theo cho các cột khác trong một hàng nhất định, bạn phải đặt rõ ràng cột TIMESTAMP thành giá trị hiện tại của nó.

Tuy nhiên, mặt khác, việc sử dụng cột DATETIME cho những mục đích này có thể dễ dàng hơn. Khi một hàng được tạo, nó phải được khởi tạo bằng hàm NOW() và để nguyên cho các lần cập nhật tiếp theo.

Giá trị TIMESTAMP có thể nằm trong khoảng từ đầu năm 1970 đến một giá trị nào đó vào năm 2037 với độ phân giải là một giây. Các đại lượng này được xuất ra dưới dạng giá trị số.

Định dạng dữ liệu mà MySQL truy xuất và hiển thị các giá trị TIMESTAMP tùy thuộc vào số lượng ký tự được hiển thị. Điều này được minh họa trong bảng dưới đây. Định dạng đầy đủ TIMESTAMP có 14 chữ số thập phân, nhưng bạn có thể tạo các cột TIMESTAMP với chuỗi đầu ra ngắn hơn:

Kiểu cột Định dạng đầu ra
DẤU THỜI GIAN(14)YYYYMMDDHHMMSS
DẤU THỜI GIAN(12)YYMMDDHHMMSS
DẤU THỜI GIAN(10)YYMMDDHHMM
DẤU THỜI GIAN(8)YYYYMMDD
DẤU THỜI GIAN(6)YYMMDD
DẤU THỜI GIAN(4)YYMM
DẤU THỜI GIAN(2)YY

Bất kể kích thước của giá trị đầu ra là bao nhiêu, kích thước của dữ liệu được lưu trữ trong cột TIMESTAMP luôn giống nhau. Định dạng đầu ra được sử dụng phổ biến nhất là 6, 8, 12 hoặc 14 chữ số thập phân. Khi tạo bảng, bạn có thể chỉ định kích thước tùy chỉnh cho các giá trị đầu ra, nhưng nếu bạn đặt kích thước thành 0 hoặc lớn hơn 14 thì giá trị 14 sẽ được sử dụng. Các giá trị kích thước lẻ trong phạm vi từ 1 đến 13 sẽ là được chia tỷ lệ thành số chẵn lớn hơn gần nhất.

Các giá trị DATETIME, DATE và TIMESTAMP có thể được chỉ định ở bất kỳ bộ định dạng tiêu chuẩn nào:

  • Là một chuỗi ở định dạng "YYYY-MM-DD HH:MM:SS" hoặc ở định dạng "YY-MM-DD HH:MM:SS" . Cho phép cú pháp "nhẹ" - bạn có thể sử dụng bất kỳ dấu chấm câu nào làm dấu phân cách giữa các phần của phần ngày hoặc giờ. Ví dụ: các giá trị "98-12-31 11:30:45" , "98.12.31 11+30+45" , "98/12/31 11*30*45" và "98@12@31 11^30^45" là tương đương.
  • Là một chuỗi ở định dạng "YYYY-MM-DD" hoặc ở định dạng "YY-MM-DD". Cú pháp "nhẹ" cũng được chấp nhận ở đây. Ví dụ: các giá trị "98-12-31", "98.12.31", "98/12/31" và "98@12@31" là tương đương.
  • Là một chuỗi không có dấu phân cách ở định dạng "YYYYMMDDHHMMSS" hoặc ở định dạng "YYMMDDHHMMSS", với điều kiện chuỗi đó được hiểu là một ngày. Ví dụ: các giá trị "19970523091528" và "970523091528" có thể được hiểu là "1997-05-23 09:15:28" nhưng giá trị "971122129015" không hợp lệ (giá trị phần phút là vô lý) và được chuyển đổi thành "0000-00-00 00:00:00" .
  • Là một chuỗi không có dấu phân cách ở định dạng "YYYYMMDD" hoặc ở định dạng "YYMMDD", miễn là chuỗi đó được hiểu là một ngày. Ví dụ: các giá trị "19970523" và "970523" có thể được hiểu là "1997-05-23", nhưng giá trị "971332" không hợp lệ (giá trị phần tháng và ngày là vô nghĩa) và được chuyển đổi thành " 0000-00-00".
  • Là một số ở định dạng YYYYMMDDHHMMSS hoặc ở định dạng YYMMDDHHMMSS, với điều kiện là số đó được hiểu là ngày. Ví dụ: các giá trị 19830905132800 và 830905132800 được hiểu là "1983-09-05 13:28:00" .
  • Là một số ở định dạng YYYYMMDD hoặc ở định dạng YYMMDD, miễn là số đó được hiểu là ngày. Ví dụ: các giá trị 19830905 và 830905 được hiểu là "1983-09-05".
  • Là kết quả của việc thực thi một hàm trả về giá trị được chấp nhận trong ngữ cảnh của các kiểu dữ liệu DATETIME, DATE hoặc TIMESTAMP (ví dụ: các hàm NOW() hoặc CURRENT_DATE).

Các giá trị giá trị DATETIME, DATE hoặc TIMESTAMP không hợp lệ được chuyển đổi thành giá trị "không" của loại giá trị tương ứng ("0000-00-00 00:00:00", "0000-00-00" hoặc 000000000000000).

Đối với các giá trị được biểu thị dưới dạng chuỗi chứa dấu phân cách giữa các phần ngày, không cần chỉ định hai chữ số cho giá trị tháng hoặc ngày nhỏ hơn 10. Do đó, giá trị "1979-6-9" tương đương với giá trị "1979-06-09". Tương tự, đối với các đại lượng được biểu thị dưới dạng chuỗi chứa dấu phân cách trong ký hiệu thời gian, không cần chỉ định hai chữ số cho các giá trị giờ, phút hoặc giây nhỏ hơn 10. Vì thế,

Các đại lượng được xác định là số phải có 6, 8, 12 hoặc 14 chữ số thập phân. Số 8 hoặc 14 bit được giả định có định dạng tương ứng là YYYYMMDD hoặc YYYYMMDDHHMMSS với năm ở bốn chữ số đầu tiên. Nếu độ dài của số là 6 hoặc 12 chữ số thì các định dạng sau được giả định: YYMMDD hoặc YYMMDDHHMMSS, trong đó năm được biểu thị bằng hai chữ số đầu tiên. Các số có độ dài không khớp với bất kỳ tùy chọn nào được mô tả sẽ được hiểu là được đệm bằng các số 0 theo độ dài được chỉ định gần nhất.

Các giá trị được biểu thị bằng chuỗi không có dấu phân cách được diễn giải dựa trên độ dài của chúng theo quy tắc bên dưới. Nếu độ dài chuỗi là 8 hoặc 14 ký tự thì năm được coi là được cung cấp bởi bốn ký tự đầu tiên. Ngược lại, năm được coi là được đưa ra bởi hai ký tự đầu tiên. Chuỗi được diễn giải từ trái sang phải, mang lại các giá trị cho năm, tháng, ngày, giờ, phút và giây cho tất cả các phần được biểu thị trong chuỗi. Điều này có nghĩa là không thể sử dụng chuỗi dài dưới 6 ký tự. Ví dụ: nếu bạn đặt một chuỗi như "9903" và cho rằng nó có nghĩa là tháng 3 năm 1999, MySQL sẽ chèn ngày "null" vào bảng. Năm và tháng trong mục này lần lượt là 99 và 03, nhưng phần ngày bị thiếu (giá trị bằng 0), vì vậy nhìn chung giá trị này không phải là giá trị ngày hợp lệ.

Khi các giá trị hợp lệ được lưu trữ trong các cột TIMESTAMP, độ chính xác đầy đủ được chỉ định khi chúng được chỉ định sẽ được sử dụng, bất kể số lượng ký tự đầu ra. Tính chất này có một số hậu quả:

  • Bạn phải luôn chỉ định năm, tháng và ngày, ngay cả đối với loại TIMESTAMP(4) hoặc TIMESTAMP(2). Nếu không, giá trị được chỉ định sẽ không phải là giá trị ngày hợp lệ và sẽ được lưu dưới dạng 0.
  • Việc tăng độ rộng của cột TIMESTAMP hẹp bằng cách sử dụng lệnh ALTER TABLE sẽ hiển thị thông tin "ẩn" trước đó.
  • Và tương tự, khi bạn thu hẹp cột TIMESTAMP, thông tin được lưu trữ sẽ không bị mất, trừ khi bạn tính đến việc sẽ xuất ra ít thông tin hơn khi xuất ra.
  • Mặc dù các giá trị TIMESTAMP được lưu trữ với độ chính xác hoàn toàn nhưng chỉ có hàm UNIX_TIMESTAMP() mới có thể hoạt động trực tiếp trên giá trị giá trị được lưu trữ ban đầu này. Các hàm còn lại hoạt động trên các giá trị được định dạng của giá trị được trích xuất. Điều này có nghĩa là các hàm như HOUR() hoặc SECOND() không thể được sử dụng cho đến khi phần tương ứng của giá trị TIMESTAMP được đưa vào giá trị được định dạng của nó. Ví dụ: phần HH của cột TIMESTAMP sẽ không được in cho đến khi số lượng ký tự cần in ít nhất là 10, vì vậy việc cố gắng sử dụng HOUR() trên các giá trị TIMESTAMP ngắn hơn sẽ tạo ra kết quả vô nghĩa.

Trong một số trường hợp, các giá trị của một loại ngày có thể được gán cho một đối tượng thuộc loại ngày khác. Tuy nhiên, một số thay đổi về giá trị hoặc mất thông tin có thể xảy ra:

  • Nếu bạn gán giá trị DATE cho đối tượng DATETIME hoặc TIMESTAMP, phần "thời gian" của giá trị kết quả sẽ được đặt thành "00:00:00" vì giá trị DATE không chứa thông tin về thời gian.
  • Nếu bạn chỉ định giá trị loại DATE, DATETIME hoặc TIMESTAMP cho đối tượng DATE, phần "thời gian" của giá trị kết quả sẽ bị xóa vì loại DATE không bao gồm thông tin thời gian.
  • Mặc dù tất cả các giá trị DATETIME, DATE và TIMESTAMP có thể được chỉ định bằng cách sử dụng cùng một bộ định dạng, nhưng hãy lưu ý rằng các loại được chỉ định có phạm vi giá trị hợp lệ khác nhau. Ví dụ: giá trị TIMESTAMP không thể có giá trị ngày sớm hơn năm 1970 hoặc muộn hơn năm 2037. Điều này có nghĩa là một ngày chẳng hạn như "1968-01-01" mặc dù hợp lệ đối với giá trị DATETIME hoặc DATE nhưng lại không hợp lệ đối với giá trị TIMESTAMP và sẽ được chuyển đổi thành 0 khi được gán cho đối tượng đó.

Khi đặt giá trị ngày, bạn nên ghi nhớ một số cạm bẫy:

  • Định dạng đơn giản hóa được phép cho các giá trị chuỗi có thể gây hiểu nhầm. Ví dụ: một giá trị như "10:11:12" có thể là giá trị thời gian nhờ dấu phân cách ://, nhưng khi được sử dụng trong ngữ cảnh ngày, nó sẽ được hiểu là năm "2010-11-12". Đồng thời, giá trị "10:45:15" sẽ được chuyển đổi thành "0000-00-00" do giá trị "45" không hợp lệ trong tháng.
  • Máy chủ MySQL chỉ thực hiện kiểm tra ban đầu về tính hợp lệ của ngày: ngày 00-31, tháng 00-12, năm 1000-9999. Bất kỳ ngày nào ngoài phạm vi này sẽ được chuyển đổi thành 0000-00-00. Tuy nhiên, cần lưu ý rằng không bị cấm lưu trữ ngày sai, chẳng hạn như 31-04-2002. Điều này cho phép các ứng dụng web lưu dữ liệu biểu mẫu mà không cần xác thực bổ sung. Để đảm bảo tính chính xác của ngày, việc kiểm tra được thực hiện trong chính ứng dụng.
  • Các giá trị của năm, được biểu thị bằng hai chữ số, cho phép giải thích mơ hồ vì không xác định được thế kỷ. MySQL diễn giải các giá trị năm có hai chữ số bằng các quy tắc sau:
    • Giá trị năm trong phạm vi 00-69 được chuyển đổi thành 2000-2069.
    • Giá trị năm trong phạm vi 70-99 được chuyển đổi thành 1970-1999.


Nếu bạn có bất kỳ câu hỏi nào khác hoặc điều gì đó chưa rõ ràng - chào mừng bạn đến với chúng tôi

Ngày và giờ NĂM, THỜI GIAN, DẤU THỜI GIAN, NGÀY và DATETIME có khoảng thời gian riêng giá trị chấp nhận được, bao gồm giá trị “không”, được sử dụng khi người dùng nhập một giá trị thực sự không hợp lệ.

Lưu ý rằng MySQL có thể lưu trữ một số giá trị ngày không hoàn toàn đáng tin cậy, ví dụ: 1999-11-31. Lý do cho điều này là việc kiểm tra ngày phải được quản lý bởi ứng dụng cụ thể chứ không phải máy chủ SQL. Để tăng tốc độ xác thực ngày, MySQL kiểm tra xem tháng có nằm trong khoảng 0-12 và ngày nằm trong khoảng 0-31 hay không. Các khoảng này bắt đầu từ 0 để MySQL có thể lưu trữ ngày và tháng bằng 0 trong cột DATETIME hoặc DATE. Tùy chọn này rất hữu ích, chẳng hạn như đối với các ứng dụng yêu cầu lưu trữ ngày sinh khi không có tháng hoặc ngày sinh luôn được biết đến. Sau đó, ngày được lưu trữ ở dạng 1999-00-00 hoặc 1999-01-00 (đối với những ngày như vậy, hàm DATE_ADD hoặc DATE_SUB() có thể cho giá trị không chính xác).

MySQL diễn giải các giá trị theo một số định dạng, nhưng nó luôn mong đợi ngày theo thứ tự năm-tháng-ngày (ví dụ: "08-05-99"). Giá trị là loại ngày hoặc giờ được MySQL tự động chuyển đổi thành số khi giá trị được sử dụng dưới dạng số và ngược lại.

Giá trị thuộc loại ngày hoặc giờ và nằm ngoài phạm vi được chỉ định hoặc không hợp lệ đối với loại dữ liệu đã cho sẽ được MySQL chuyển thành null. Ngoại lệ là các giá trị THỜI GIAN vượt quá khoảng thời gian đã chỉ định và bị cắt cụt đến điểm biên khoảng thời gian xác định THỜI GIAN.

Bảng mô tả các định dạng cho giá trị “không” cho từng loại cột:

Số phát hành năm 2000 về các kiểu dữ liệu

MySQL có khả năng kháng Y2K nhưng một số giá trị đầu vào có thể dễ bị lỗi. Ví dụ: nếu bạn nhập giá trị năm có hai chữ số, nó sẽ được hiểu một cách mơ hồ, bởi vì thế kỷ không được xác định. Những giá trị như vậy phải được chuyển sang dạng 4 chữ số vì MySQL sử dụng 4 chữ số để biểu thị năm.

Những ngày có năm không rõ ràng trong MySQL đối với các loại YEAR, TIMESTAMP, DATE và DATETIME được diễn giải theo các quy tắc sau:

  • giá trị năm từ 00 đến 69 được chuyển thành 2000–2069;
  • giá trị năm từ 70 đến 99 được chuyển đổi thành 1970–1999.

loại DẤU THỜI GIAN

Loại DẤU THỜI GIAN tự động ghi lại ngày và giờ hiện tại khi sử dụng thao tác CHÈN hoặc CẬP NHẬT. Nếu nhiều cột TIMESTAMP được sử dụng thì chỉ cột đầu tiên được cập nhật tự động.

loại NGÀY

Loại DATE chứa các giá trị có thông tin ngày ở định dạng "YYYY-MM-DD". Đối với loại này, năm có thể thay đổi trong phạm vi 1000–9999 và giá trị tháng và ngày có thể thay đổi trong năm. Những thứ kia. dữ liệu được xử lý trong phạm vi "1000-01-01"–"9999-12-31".

loại NGÀY GIỜ

Loại DATETIME được sử dụng cho các giá trị chứa giá trị ngày và giờ. MySQL xử lý các giá trị ở định dạng "YYYY-MM-DD HH:MM:SS", tương ứng với phạm vi "1000-01-01 00:00:00" - "9999-12-31 23:59:59 ".

Nhập THỜI GIAN

MySQL xử lý các giá trị thuộc loại này theo định dạng "HH:MM:SS". Vì giá trị lớn giờ (khi chỉ định khoảng thời gian), định dạng "HHH:MM:SS" được sử dụng. giá trị THỜI GIAN phải nằm trong phạm vi từ "-838:59:59" đến "838:59:59".

Nhập NĂM

Kiểu dữ liệu NĂM là kiểu dữ liệu một byte chứa giá trị năm.

MySQL xử lý các giá trị ở định dạng YYYY và nằm trong khoảng từ 1901 đến 2155.

Giá trị NĂM không hợp lệ được chuyển đổi thành 0000.

Mục đích của bài viết này là giải thích chi tiết cụ thể khi làm việc với các loại DATETIME trong Máy chủ SQL, bao gồm những quan niệm sai lầm phổ biến và khuyến nghị chungđể vượt qua chúng. Nhờ Frank Kalis, bài viết này đã được dịch sang tiếng Đức.

Cảm ơn:

tôi muốn cảm ơn những người sau đây vì những gợi ý và đóng góp quý báu của họ cho bài viết này: Steve Kass, Aaron Bertrand, Jacco Schalkwijk, Klaus Oberdalhoff, Hugo Kornelis, Dan Guzman, và Erland Sommarskog.

Các phiên bản máy chủ SQL

Bài viết này áp dụng cho SQL Server 7.0, 2000, 2005 và 2008 trừ khi có ghi chú khác.

Các loại ngày và giờ trong SQL Server

Trước SQL Server 2008, SQL Server có hai loại dữ liệu để xử lý ngày và giờ. Vì chúng tôi sẽ thường xuyên đề cập đến các loại này trong bài viết này nên chúng tôi sẽ giới thiệu tên viết tắt cho từng loại trong hai bảng bên dưới (cột SC):

Tên

Tối thiểu. nghĩa

Tối đa. nghĩa

Sự chính xác

Bộ nhớ đã sử dụng

ngày nhỏ sdt 1900-01-01 00:00:00 2079-06-06 23:59:00 phút 4 byte
ngày giờ dt 1753-01-01 00:00:00.000 9999-12-31 23:59:59.997 3,33 mili giây 8 byte

Xin lưu ý rằng không có loại dữ liệu nào ở đây chỉ chứa ngày hoặc chỉ thời gian. Cả hai loại dữ liệu trên đều bao gồm các phần/phân đoạn như ngày và giờ.

Nếu bạn chỉ chỉ định phần ngày, SQL Server sẽ lưu trữ thời gian dưới dạng 00:00:00.000.
Và nếu bạn chỉ đặt giá trị thành thời gian, SQL Server sẽ lưu ngày là 01/01/1900.
Rất quan trọng. Đọc lại lần nữa.

LỰA CHỌN DÀN DIỄN VIÊN ('20041223'AS ngày giờ )

———————–
2004-12-23 00:00:00.000

LỰA CHỌN DÀN DIỄN VIÊN (’14:23:58′ NHƯ ngày giờ )

———————–
1900-01-01 14:23:58.000

Với sự ra đời của SQL Server 2008, một số kiểu dữ liệu mới liên quan đến giá trị ngày và giờ đã được giới thiệu:

Tên

Tối thiểu. nghĩa

Tối đa. nghĩa

Sự chính xác

Bộ nhớ đã sử dụng

ngày giờ2 dt2 0001-01-01 00:00:00.0000000 9999-12-31 23:59:59.9999999 100 ns 6-8 byte
ngày d 0001-01-01 9999-12-31 ngày 3 byte
thời gian t 00:00:00.0000000 23:59:59.9999999 100 ns 3-5 byte
ngày giờ bù đắp dto 0001-01-01 00:00:00.0000000 9999-12-31 23:59:59.9999999 100 ns 8-10 byte
  • Như bạn có thể thấy, cuối cùng chúng ta đã có kiểu dữ liệu chỉ có ngày ( ngày) và chỉ trong thời gian ( thời gian).
  • Ngày giờ2đây là “DATETIME tốt nhất” vì một số lý do và không mất nhiều thời gian thêm bộ nhớ, Làm sao ngày giờ và thậm chí có thể ít hơn!
  • Đối với loại mới liên quan đến giá trị thời gian, bạn có thể chỉ định “độ chính xác phân số giây” bằng cách chỉ định thứ tự các chữ số được sử dụng tính bằng giây sau dấu thập phân. Vì vậy time(3) có thể lưu trữ các giá trị như 14:23:12.567, khi nhập là 14:23:12:5677 thì được làm tròn thành 14:23:12:568.
  • Kiểu mới ngày giờ bù đắp chứa một phần của phần bù múi giờ địa phương.

Định dạng ngày và giờ

Một quan niệm sai lầm phổ biến là SQL Server lưu trữ các loại dữ liệu này ở một số định dạng cụ thể có thể đọc được. Cái này sai. SQL Server lưu trữ các giá trị như vậy ở định dạng bên trong của nó (ví dụ: hai số nguyên cho ngày giờngày nhỏ). Điều đó đang được nói, khi sử dụng T-SQL để đặt giá trị (ví dụ: trong câu lệnh INSERT), bạn biểu thị nó dưới dạng chuỗi văn bản. Ngoài ra còn có các quy tắc giải thích của SQL Server định dạng khác nhau chuỗi ngày. Nhưng lưu ý rằng SQL Server sẽ không nhớ định dạng này trong mọi trường hợp.

Định dạng đầu vào cho ngày và giờ

Có nhiều định dạng có sẵn để chuyển đổi giá trị sang ngày/giờ/ngày giờ. Một số trong số chúng “tốt hơn” những cái khác, và sau này bạn sẽ hiểu tại sao “tốt hơn”. Đáng chú ý là tất cả các định dạng này đều có thể áp dụng cho tất cả các loại. Vì vậy, ngay cả định dạng “chỉ thời gian” cũng có thể áp dụng cho loại “chỉ ngày”, v.v. (Bài viết này bỏ qua phần bù múi giờ địa phương, phần này chỉ được sử dụng trong kiểu dữ liệu ngày giờ bù đắp– tìm hiểu thêm về điều đó trong Sách trực tuyến.)

Tên

Định dạng

THIẾT LẬP phụ thuộc DATEFORMAT

THIẾT LẬP phụ thuộc NGÔN NGỮ

Tính trung lập của ngôn ngữ

Không tách rời bạn ‘19980223 14:23:05’ KHÔNG KHÔNG cho tất cả
Ly thân S '23/02/1998 14:23:05' cho tất cả cho tất cả KHÔNG
ANSI SQL ansisql ‘1998-12-23 14:23:05’ sdt , dt sdt , dt không dành cho sdt dt
chữ cái Một '23 tháng 2 năm 1998 14:23:05' KHÔNG cho mọi người (tên tháng) KHÔNG
ngày giờ ODBC số lẻ (ts ‘1998-02-23 14:23:05’) KHÔNG KHÔNG cho tất cả
ngày ODBC (d '1998-02-23') KHÔNG KHÔNG cho tất cả
thời gian ODBC (t ’14:23:05′) KHÔNG KHÔNG cho tất cả
ISO 8601 iso ‘1998-02-23T14:23:05’ KHÔNG KHÔNG cho tất cả
Thời gian t '14:23:05'
‘2:23:05 chiều’
KHÔNG KHÔNG cho tất cả
  • Lưu ý rằng ANSI SQL thực sự chỉ trương hợp đặc biệtđịnh dạng phân cách Ly thân(gọi là “kỹ thuật số”), sử dụng dấu gạch ngang (-), dấu gạch chéo (/) và dấu chấm (.) làm dấu phân cách. Tuy nhiên, vì đây là định dạng duy nhất được xác định trong tiêu chuẩn ANSI SQL nên theo ý kiến ​​của tác giả, nó đáng được đề cập như một trường hợp đặc biệt.
  • Hầu hết các định dạng đều cho phép bạn xóa phần ngày và/hoặc thời gian và trong một số trường hợp, điều này có thể trông hơi... kỳ lạ. Ví dụ: có vẻ không hợp lý khi chỉ định '2008-08-25' làm loại thời gian ( thời gian), nhưng trong kết quả cuối cùngđiều này cũng giống như việc không thiết lập các giá trị trong chuỗi ngày giờ. Hãy xem xét dưới đây:
    LỰA CHỌN DÀN DIỄN VIÊN (BẰNG thời gian )
    LỰA CHỌN DÀN DIỄN VIÊN (‘25-08-2008’ NHƯ thời gian )

    Cả hai truy vấn đều tạo ra cùng một kết quả (thời gian 00:00:00).
  • Các định dạng ODBC ( Ngày giờ ODBC, ngày ODBC, thời gian ODBC) khác nhau ở chỗ chúng có mã thông báo (literal_type, t, d hoặc ts) phải được đặt chính xác tùy thuộc vào việc bạn đang nhận ngày và giờ, chỉ ngày hay chỉ thời gian.
  • Để áp dụng định dạng ISO 8601 một phân đoạn ngày và thời gian là bắt buộc.
  • SET DATEFORMAT kế thừa cài đặt của nó từ SET LANGUAGE (nhưng SET DATEFORMAT rõ ràng sẽ ghi đè SET LANGUAGE sau này). Cài đặt ngôn ngữ mặc định được đặt cho từng ngôn ngữ được sử dụng khi nhập thông tin đăng nhập. Ngôn ngữ đăng nhập mặc định được đặt bằng sp_configure.
  • Các quy tắc liên quan đến định dạng phần ngày tháng và các kiểu mới có thể gây nhầm lẫn. Microsoft cam kết cập nhật các loại dữ liệu liên quan mới ( ngày, datetime2 và datetimeoffset) ít phụ thuộc hơn vào cài đặt và thậm chí còn tuân thủ nhiều hơn với các yêu cầu của ANSI SQL. Và kết quả là, các loại ngôn ngữ trung lập mới giúp làm nổi bật các thành phần ngày giờ miễn là năm đến trước. Máy chủ SQL cần xác định phần này là năm nên cần có 4 vị trí tạo nên năm (yyyy, không phải yy). Nếu vậy, chuỗi sẽ được hiểu là đầu tiên là năm, sau đó là tháng và cuối cùng là ngày - bất kể cài đặt DATEFORMAT hoặc ngôn ngữ. Nếu tháng được chỉ định trước, thì cài đặt DATEFORMAT và ngôn ngữ sẽ được “tôn trọng”:
    BỘ NGÔN NGỮ Tiếng Anh –sử dụng dmy
    ĐI
    LỰA CHỌN DÀN DIỄN VIÊN (’23-02-1998 14:23:05′ BẰNG ngày ) -Lỗi
    ĐI
    LỰA CHỌN DÀN DIỄN VIÊN (‘2/23/1998 14:23:05’ BẰNG ngày ) -Lỗi
    ĐI
    LỰA CHỌN DÀN DIỄN VIÊN (‘1998-02-23 14:23:05’ BẰNG ngày ) -Được rồi
    ĐI
    LỰA CHỌN DÀN DIỄN VIÊN (‘1998.02.23 14:23:05’ BẰNG ngày ) -Được rồi
    ĐI
    LỰA CHỌN DÀN DIỄN VIÊN (‘1998/02/23 14:23:05’ BẰNG ngày) -Được rồi
    ĐI
    Đầu tiên
    hai truy vấn sai vì năm không ở vị trí đầu tiên (và không có 23 tháng trong năm 1998). Không có lỗi trong ba truy vấn tiếp theo vì các yêu cầu đều được đáp ứng và năm được liệt kê đầu tiên (và chúng tôi đang sử dụng một trong các kiểu loại ngày mới). Cực kỳ minh bạch phải không? 🙂

Mô tả về các định dạng có sẵn có sẵn trong Sách Trực tuyến, do đó, không có ích gì khi đi sâu vào chi tiết cho từng định dạng.

Phát triển các ứng dụng cơ sở dữ liệu dựa trên thời gian trong SQL của Richard T. Snodgrass: chứa nhiều thông tin về cách biểu diễn thông tin dựa trên thời gian trong mô hình dữ liệu. Và tất nhiên, bạn có thể sử dụng thông tin bổ sung (lịch sử) này trong truy vấn SQL. Cuốn sách này đã hết bản in, nhưng trên trang web chính thức của Richard (www.cs.arizona.edu/people/rts), bạn có thể tải xuống miễn phí ở định dạng PDF.

Bản dịch: Vinchik Evgeniy

kiểu dữ liệu ngày và giờ: DATETIME, DATE, TIMESTAMP, TIME và NĂM. Mỗi giá trị này có một phạm vi giá trị hợp lệ cũng như giá trị "null", được sử dụng khi người dùng nhập một giá trị thực sự không hợp lệ. Lưu ý rằng MySQL cho phép bạn lưu trữ một số giá trị ngày không hoàn toàn đáng tin cậy, ví dụ: 1999-11-31. Lý do là việc quản lý việc xác nhận ngày tháng là trách nhiệm của ứng dụng cụ thể, không phải máy chủ SQL. Để tăng tốc độ xác thực ngày, MySQL chỉ kiểm tra xem tháng có nằm trong khoảng 0-12 và ngày nằm trong khoảng 0-31 hay không. Các khoảng thời gian này bắt đầu từ 0, điều này được thực hiện để cung cấp cho MySQL khả năng lưu trữ ngày trong đó ngày hoặc tháng nằm trong cột DATE hoặc DATETIME bằng 0. Tính năng này đặc biệt hữu ích cho các ứng dụng yêu cầu lưu trữ ngày sinh - ở đây ngày hoặc tháng sinh không phải lúc nào cũng được biết. Trong những trường hợp như vậy, ngày chỉ được lưu dưới dạng 1999-00-00 hoặc 1999-01-00 (nhưng bạn không nên mong đợi hàm DATE_SUB() hoặc DATE_ADD trả về giá trị chính xác cho những ngày đó).

MySQL chỉ truy xuất các giá trị cho một loại ngày hoặc giờ nhất định trong định dạng chuẩn, nhưng đồng thời cố gắng diễn giải nhiều định dạng khác nhau có thể đến từ người dùng (ví dụ: khi chỉ định một giá trị cần được gán loại ngày hoặc giờ hoặc so sánh với giá trị có một trong các loại này). Tuy nhiên, chỉ các định dạng được mô tả trong các phần sau mới được hỗ trợ. Người dùng phải nhập các giá trị hợp lệ cho số lượng, vì việc sử dụng số lượng ở các định dạng khác có thể tạo ra kết quả không thể đoán trước.

  • Mặc dù MySQL cố gắng diễn giải các giá trị theo nhiều định dạng, nhưng trong mọi trường hợp, phần giá trị ngày chứa năm sẽ nằm ở phía bên trái. Ngày phải được chỉ định theo thứ tự năm-tháng-ngày (ví dụ: "98-09-04") chứ không phải theo thứ tự tháng-ngày-năm hoặc ngày-tháng-năm, tức là. không phải cách chúng ta thường viết chúng (ví dụ: "09-04-98", "04-09-98").
  • MySQL tự động chuyển đổi giá trị ngày hoặc giờ thành số khi giá trị được sử dụng trong ngữ cảnh số và ngược lại.
  • Giá trị của loại ngày hoặc giờ nằm ​​ngoài khoảng thời gian được chỉ định hoặc không hợp lệ đối với loại dữ liệu đó (xem phần đầu của phần) được chuyển đổi thành giá trị "null" cho loại đó. (Ngoại lệ dành cho các giá trị thuộc loại TIME vượt quá ranh giới của khoảng thời gian đã chỉ định, được cắt ngắn đến điểm ranh giới tương ứng của khoảng thời gian đã chỉ định). Trong bảng 4.3. Dưới đây là các định dạng cho giá trị "null" cho từng loại cột:
  • Giá trị 0 là đặc biệt. Để lưu trữ hoặc tham chiếu đến chúng, bạn có thể sử dụng rõ ràng các giá trị được trình bày trong bảng hoặc bạn có thể sử dụng “0”, dễ viết hơn.
Các kiểu dữ liệu DATETIME, DATE và TIMESTAMP

Kiểu dữ liệu DATETIME được sử dụng cho các giá trị chứa cả thông tin ngày và giờ. MySQL truy xuất và hiển thị các giá trị DATETIME ở định dạng "YYYY-MM-DD HH:MM:SS". Phạm vi giá trị được hỗ trợ là từ "1000-01-01 00:00:00" đến "9999-12-31 23:59:59". ("được hỗ trợ" có nghĩa là mặc dù các giá trị có giá trị thời gian trước đó vẫn có thể hoạt động nhưng không có gì đảm bảo rằng chúng sẽ được lưu trữ và hiển thị chính xác).

Kiểu DATE được sử dụng cho các giá trị chỉ có thông tin ngày tháng, không có phần thời gian. MySQL truy xuất và hiển thị các giá trị DATE ở định dạng "YYYY-MM-DD". Phạm vi giá trị được hỗ trợ là từ "1000-01-01" đến "9999-12-31".

Loại cột TIMESTAMP cung cấp loại biểu diễn dữ liệu có thể được sử dụng để tự động ghi lại ngày và giờ hiện tại khi thực hiện thao tác CHÈN hoặc CẬP NHẬT. Nếu bạn có nhiều cột TIMESTAMP thì chỉ cột đầu tiên được cập nhật tự động.

Đối với các cột còn lại (ngoại trừ cột đầu tiên) thuộc loại TIMESTAMP, bạn cũng có thể đặt giá trị cho ngày và giờ hiện tại. Để thực hiện việc này, bạn chỉ cần đặt cột thành NULL hoặc NOW() .

Bất kỳ cột TIMESTAMP nào (ngay cả cột đầu tiên thuộc loại đó) đều có thể được đặt thành một giá trị khác với ngày và giờ hiện tại. Điều này được thực hiện bằng cách đặt nó thành giá trị mong muốn một cách rõ ràng. Thuộc tính này có thể được sử dụng, ví dụ: nếu bạn muốn đặt cột TIMESTAMP thành ngày và giờ hiện tại khi tạo một hàng và sau đó khi bạn cập nhật hàng đó, giá trị của cột sẽ không thay đổi.

Giá trị TIMESTAMP có thể nằm trong khoảng từ đầu năm 1970 đến một giá trị nào đó vào năm 2037 với độ phân giải là một giây. Các đại lượng này được xuất ra dưới dạng giá trị số.

Định dạng dữ liệu mà MySQL truy xuất và hiển thị các giá trị TIMESTAMP tùy thuộc vào số lượng ký tự được hiển thị. Điều này được minh họa trong Bảng 4.4. Định dạng TIMESTAMP đầy đủ là 14 chữ số thập phân, nhưng bạn có thể tạo các cột TIMESTAMP với chuỗi đầu ra ngắn hơn:

Bảng 4.4. Định dạng dữ liệu TIMESTAMP tùy thuộc vào số chữ số được trích xuất
Kiểu cột Định dạng đầu ra
DẤU THỜI GIAN(14) YYYYMMDDHHMMSS
DẤU THỜI GIAN(12) YYMMDDHHMMSS
DẤU THỜI GIAN(10) YYMMDDHHMM
DẤU THỜI GIAN(8) YYYYMMDD
DẤU THỜI GIAN(6) YYMMDD
DẤU THỜI GIAN(4) YYMM
DẤU THỜI GIAN(2) YY

Các giá trị DATETIME, DATE và TIMESTAMP có thể được đặt thành bất kỳ bộ tiêu chuẩnđịnh dạng:

  • Là một chuỗi ở định dạng "YYYY-MM-DD HH:MM:SS" hoặc ở định dạng "YY-MM-DD HH:MM:SS". Cho phép cú pháp "nhẹ" - bạn có thể sử dụng bất kỳ dấu chấm câu nào làm dấu phân cách giữa các phần của phần ngày hoặc giờ. Ví dụ: các giá trị "98-12-31 11:30:45", "98.12.31 11+30+45", "98/12/31 11*30*45" và "98@12@31 11^30^45" là tương đương.
  • Là một chuỗi ở định dạng "YYYY-MM-DD" hoặc ở định dạng "YY-MM-DD". Cú pháp "nhẹ" cũng được chấp nhận ở đây. Ví dụ: các giá trị "98-12-31", "98.12.31", "98/12/31" và "98@12@31" là tương đương.
  • Là một chuỗi không có dấu phân cách ở định dạng "YYYYMMDDHHMMSS" hoặc ở định dạng "YYMMDDHHMMSS", với điều kiện chuỗi đó được hiểu là một ngày. Ví dụ: các giá trị "19970523091528" và "970523091528" có thể được hiểu là "1997-05-23 09:15:28", nhưng giá trị "971122129015" không hợp lệ (giá trị phần phút là vô lý) và được chuyển đổi đến "0000-00-00 00:00:00."
  • Là một chuỗi không có dấu phân cách ở định dạng "YYYYMMDD" hoặc ở định dạng "YYMMDD", miễn là chuỗi đó được hiểu là một ngày. Ví dụ: các giá trị "19970523" và "970523" có thể được hiểu là "1997-05-23", nhưng giá trị "971332" không hợp lệ (giá trị phần tháng và ngày là vô nghĩa) và được chuyển đổi thành " 0000-00-00".
  • Là một số ở định dạng YYYYMMDDHHMMSS hoặc ở định dạng YYMMDDHHMMSS, với điều kiện là số đó được hiểu là ngày. Ví dụ: các giá trị 19830905132800 và 830905132800 được hiểu là "1983-09-05 13:28:00".
  • Là một số ở định dạng YYYYMMDD hoặc ở định dạng YYMMDD, miễn là số đó được hiểu là ngày. Ví dụ: các giá trị 19830905 và 830905 được hiểu là "1983-09-05".
  • Là kết quả của việc thực thi một hàm trả về giá trị được chấp nhận trong ngữ cảnh của các kiểu dữ liệu DATETIME, DATE hoặc TIMESTAMP (ví dụ: các hàm NOW() hoặc CURRENT_DATE()).
Kiểu dữ liệu THỜI GIAN

MySQL truy xuất và hiển thị các giá trị TIME ở định dạng "HH:MM:SS" (hoặc ở định dạng "HHH:MM:SS" cho các giá trị giờ lớn hơn). Giá trị THỜI GIAN có thể thay đổi từ "-838:59:59" đến "838:59:59". Lý do mà phần "giờ" của một giá trị có thể lớn đến vậy là vì loại TIME có thể được sử dụng không chỉ để biểu thị thời gian trong ngày (phải nhỏ hơn 24 giờ) mà còn để biểu thị tổng thời gian đã trôi qua hoặc khoảng thời gian giữa hai sự kiện (có thể dài hơn đáng kể hơn 24 giờ hoặc thậm chí âm).

Giá trị THỜI GIAN có thể được chỉ định theo nhiều định dạng khác nhau:

Là một chuỗi ở định dạng "D HH:MM:SS.phần phân số" (lưu ý rằng MySQL chưa hỗ trợ lưu trữ phần phân số của một giá trị trong một cột thuộc loại được đề cập). Bạn cũng có thể sử dụng một trong các chế độ xem "nhẹ" sau: HH:MM:SS.phần phân số, HH:MM:SS , HH:MM , D HH:MM:SS , D HH:MM , D HH hoặc SS . Ở đây D là số ngày trong phạm vi giá trị 0-33.

  • Là một chuỗi không có dấu phân cách ở định dạng "HHMMSS", với điều kiện chuỗi đó được hiểu là ngày tháng. Ví dụ: giá trị “101112” được hiểu là “10:11:12”, nhưng giá trị “109712” sẽ không hợp lệ (giá trị phần phút là vô lý) và sẽ được chuyển thành “00:00:00”.
  • Là một số ở định dạng HHMMSS, với điều kiện chuỗi đó được hiểu là ngày tháng. Ví dụ: giá trị 101112 được hiểu là “10:11:12”. MySQL cũng hiểu các định dạng thay thế sau: SS
  • Là số có bốn chữ số trong khoảng từ 1901 đến 2155.
  • Là một chuỗi hai ký tự trong phạm vi giá trị từ "00" đến "99". Các giá trị trong khoảng từ "00" đến "69" và từ "70" đến "99" sau đó được chuyển đổi thành giá trị NĂM trong các khoảng tương ứng từ 2000 đến 2069 và từ 1970 đến 1999.
  • Là một số có hai chữ số trong phạm vi từ 1 đến 99. Các giá trị trong phạm vi từ 1 đến 69 và từ 70 đến 99 sau đó được chuyển đổi thành giá trị NĂM trong phạm vi từ 2001 đến 2069 và từ 1970 đến 1999, tương ứng. Xin lưu ý rằng khoảng cách cho các số có hai chữ số và chuỗi có hai chữ số hơi khác một chút vì bạn không thể chỉ định trực tiếp "số 0" dưới dạng số và hiểu nó là 2000. Bạn phải chỉ định nó dưới dạng chuỗi "0" hoặc "00" hoặc nó sẽ được hiểu như 0000.
  • Là kết quả của việc thực thi một hàm trả về giá trị được chấp nhận trong ngữ cảnh của kiểu dữ liệu YEAR (chẳng hạn như NOW() ).

Giá trị NĂM không hợp lệ được chuyển đổi thành 0000.

Các loại DATETIME, DATE và TIMESTAMP

Các loại DATETIME, DATE và TIMESTAMP có liên quan với nhau. Phần này mô tả các đặc điểm của chúng, chúng giống nhau như thế nào và khác nhau như thế nào.
Loại DATETIME được sử dụng khi bạn cần có các giá trị bao gồm cả ngày và giờ. MySQL truy xuất và hiển thị các giá trị DATETIME ở định dạng TGGT-MM-DD HH:MM:SS". Phạm vi giá trị được hỗ trợ cho các giá trị này là từ "1000-01-01 00:00:00" đến "9999- 12-31 23:59 :59" (Được hỗ trợ có nghĩa là các giá trị trước đó có thể hoạt động nhưng không được đảm bảo.)
Loại DATE được sử dụng khi bạn cần có các giá trị chỉ bao gồm ngày mà không có thời gian. MySQL truy xuất và hiển thị các giá trị DATETIME ở định dạng "YYYY-MM-DD". Phạm vi được hỗ trợ là từ CH000-01-0G đến "9999-12-31".
Loại cột TIMESTAMP có một số thuộc tính phụ thuộc vào phiên bản MySQL và chế độ SQL mà máy chủ đang chạy. Các thuộc tính này được mô tả sau trong phần này.
Bạn có thể chỉ định các giá trị của loại DATETIME, DATE và TIMESTAMP bằng cách sử dụng bất kỳ bộ định dạng nào được chấp nhận chung:

  1. Là một chuỗi có định dạng "YYYY-MM-DD HH:MM:SS" hoặc "YY-MM-DD HH:MM:SS. Cho phép cú pháp thoải mái: bất kỳ ký tự dấu chấm câu nào cũng có thể được sử dụng làm dấu phân cách giữa ngày và giờ. Ví dụ: "98-12-31 11:30:45", "98.12.31 11+30+45", "98/12/31 11*30*45" và "98012031 11Л30Л45" là tương đương.
  2. Là một chuỗi có định dạng "YYYY-MM-DD" hoặc "YY-MM-DD". Cú pháp thoải mái cũng được cho phép. Ví dụ: các giá trị sau tương đương: "98-12-31","98.12.31","98/12/31" và "98012031".
  3. Là một chuỗi không có dấu phân cách ở định dạng "YYYYMMDDHHMMSS" hoặc "YYMMDDDHHMSS", giả sử rằng chuỗi đó có ý nghĩa như một ngày. Ví dụ: "19970523091528" và "970523091528" được hiểu là "1997-0 5-23 09:15:28", nhưng "971122129015" không chính xác (vì nó có giá trị phút vô nghĩa) và trở thành "0000-00-00 00:00": 00".
  4. Là một chuỗi không giới hạn ở định dạng "YYYYMMDD" hoặc TGMMDD", giả sử rằng chuỗi này có ý nghĩa như một ngày. Ví dụ: "19970523" và "980523" được hiểu là "1997-05-23", nhưng "971332" là không đúng ( giá trị không chính xác tháng và ngày) và trở thành "0000-00-00".
  5. Là một số có định dạng YYYYMMDDDHHMSS hoặc YYMMDDDHHMMSS, giả sử số này có ý nghĩa như một ngày. Ví dụ: 19830905132800 và 830905132800 được hiểu là "1983-09-05 13:28:00".
  6. Là một số có định dạng YYYYMMDD hoặc YYMMDD, giả sử số này có ý nghĩa là ngày. Ví dụ: 19830905 và 830905 được hiểu là "1983-09-05".
  7. Là kết quả của hàm trả về giá trị được chấp nhận trong ngữ cảnh DATETIME, DATE hoặc TIMESTAMP, chẳng hạn như NOW() hoặc CURRENT_DATE.

Các giá trị DATETIME, DATE hoặc TIMESTAMP không hợp lệ được chuyển đổi thành giá trị null của loại thích hợp ("0000-00-00 00:00:00", "0000-00-00" hoặc 000000000000000).
Đối với các giá trị được chỉ định dưới dạng chuỗi bao gồm dấu phân cách ngày, không cần chỉ định hai chữ số cho tháng hoặc ngày nhỏ hơn 10. "1976-6-9" giống như "1976-06-09" . Tương tự, đối với các giá trị được chỉ định dưới dạng chuỗi bao gồm dấu phân cách thời gian, bạn không cần chỉ định hai chữ số cho giờ, phút và giây nhỏ hơn 10. "1979-10-30 1:2:3" là giống như "1979-10-30 01:02:03".


Các giá trị được chỉ định dưới dạng số phải có độ dài 6, 8, 12 hoặc 14 chữ số. Nếu một số dài 8 hoặc 14 chữ số, nó được giả định chỉ định một giá trị ở định dạng YYYYMMDD hoặc YYYYMMDDDHHMSS và năm được chỉ định bằng bốn chữ số. Nếu số có độ dài 6 hoặc 12, nó được giả sử chỉ định một giá trị ở định dạng YYMMDD hoặc YYMMDDDHHMSS và năm được chỉ định bằng hai chữ số. Các số có độ dài khác nhau từ 6, 8, 12 và 14 được đệm bằng các số 0 đứng đầu đến số chữ số gần nhất trong chuỗi được chỉ định.

Các giá trị được chỉ định là chuỗi không giới hạn được diễn giải bằng cách sử dụng độ dài của chúng như mô tả ở trên. Nếu chuỗi dài 8 hoặc 14 ký tự thì giả sử năm ở định dạng 4 chữ số. Ngược lại, giả định rằng năm được cho bởi hai chữ số đầu tiên. Chuỗi được diễn giải từ trái sang phải để trích xuất các giá trị năm, tháng, ngày, giờ, phút và giây. Điều này có nghĩa là bạn không nên sử dụng các dòng dài dưới 6 ký tự. Ví dụ: nếu bạn chỉ định "9903" nghĩa là tháng 3 năm 1999, bạn sẽ thấy rằng MySQL sẽ chèn ngày rỗng vào bảng. Điều này xảy ra vì giá trị năm và tháng là 99 và 03, nhưng phần ngày bị thiếu hoàn toàn, nghĩa là giá trị này không đặt ngày chính xác. Tuy nhiên, kể từ MySQL 3.23, bạn có thể chỉ định rõ ràng giá trị null tháng hoặc ngày. Ví dụ: bạn có thể chỉ định "990300" để chèn giá trị "1999-03-00" vào bảng.
Trong giới hạn nhất định, bạn có thể gán giá trị của một loại cho các đối tượng thuộc loại khác. Tuy nhiên, có thể xảy ra một số biến dạng do mất thông tin:

  1. Nếu bạn gán giá trị loại DATE cho đối tượng thuộc loại DATETIME hoặc TIMESTAMP, phần thời gian của giá trị được giả sử là "00:00:00" vì giá trị DATE không chứa thông tin thời gian.
  2. Nếu bạn gán giá trị loại DATETIME hoặc tiMesTAMP cho đối tượng loại DATE, phần thời gian của giá trị sẽ bị mất vì DATE không thể bao gồm nó.
  3. Hãy nhớ rằng, mặc dù các giá trị DATETIME, DATE và TIMESTAMP có thể được chỉ định bằng cách sử dụng cùng một bộ định dạng, nhưng phạm vi hợp lệ của chúng sẽ khác nhau. Ví dụ: giá trị TIMESTAMP không thể sớm hơn năm 1970 hoặc muộn hơn năm 2037. Điều này có nghĩa là một ngày như "1968-01-10", được coi là giá trị DATETIME hoặc DATE, không chính xác dưới dạng TIMESTAMP và sẽ được chuyển đổi thành 0 khi được gán cho đối tượng đó.

Bạn cũng nên lưu ý một số cạm bẫy khi chỉ định giá trị ngày:

  1. Định dạng thoải mái của các giá trị được đưa ra dưới dạng chuỗi có thể gây hiểu nhầm. Ví dụ: một giá trị như "10:11:12" có thể xuất hiện là thời gian vì nó sử dụng dấu phân cách ://, nhưng nếu được sử dụng trong ngữ cảnh ngày thì nó sẽ được hiểu là "2010-11-12". Đồng thời giá trị "10:45:15"
    sẽ được chuyển đổi thành "0000-00-00" vì "45" không phải là tháng hợp lệ.
  2. Máy chủ MySQL chỉ thực thi kiểm tra cơ bản hiệu lực của ngày: phạm vi cho năm, tháng và ngày lần lượt là 1000 đến 9999, 00 đến 12 và 00 đến 31. Bất kỳ ngày nào chứa các phần nằm ngoài các phạm vi này đều có thể được chuyển đổi thành "0000-00-00". Xin lưu ý rằng điều này cho phép bạn lưu trữ các ngày không hợp lệ như "2002-04-31". Để đảm bảo ngày chính xác, hãy kiểm tra trong ứng dụng.
  • Ngày tháng chứa năm có hai chữ số không rõ ràng vì không xác định được thế kỷ. MySQL diễn giải các năm có hai chữ số như sau: * Một năm trong khoảng 00-69 được chuyển đổi thành 2000-2069.
  • Một năm trong khoảng 70-99 được chuyển đổi thành 1970-1999.
Thuộc tính TIMESTAMP trong các phiên bản MySQL cũ hơn 4.1
DẤU THỜI GIAN là loại cột có thể được sử dụng để tự động đóng dấu ngày và giờ hiện tại khi thực hiện thao tác CẬP NHẬT hoặc CHÈN. Nếu có nhiều cột TIMESTAMP trong một bảng thì chỉ cột đầu tiên được cập nhật tự động.
Cột TIMESTAMP đầu tiên trong bảng được cập nhật tự động khi xảy ra một trong các điều kiện sau:
  1. Khi gán rõ ràng cho nó giá trị NULL.
  2. Cột này không được chỉ định rõ ràng trong câu lệnh INSERT hoặc LOAD DATA INFILE.
  3. Cột này không được chỉ định rõ ràng trong câu lệnh UPDATE, nhưng giá trị của một số cột khác bị thay đổi. Câu lệnh CẬP NHẬT đặt một cột thành cùng giá trị như trước đó không cập nhật cột TIMESTAMP. Nếu bạn gán một giá trị cũ, MySQL sẽ bỏ qua nó vì lý do hiệu quả.

Các cột TIMESTAMP cũng có thể được cập nhật theo ngày và giờ hiện tại nếu chúng được đặt rõ ràng thành giá trị mong muốn. Điều này đúng ngay cả với cột TIMESTAMP đầu tiên. Bạn có thể sử dụng thuộc tính này chẳng hạn nếu bạn muốn đặt giá trị của một cột thành ngay hiện tại và thời gian khi tạo hàng, nhưng không thay đổi nó trong các lần cập nhật tiếp theo cho hàng:

  1. Để MySQL đặt giá trị của cột khi tạo hàng. Điều này khởi tạo nó với giá trị ngày và giờ hiện tại.
  2. Khi thực hiện các cập nhật tiếp theo cho các cột hàng khác, hãy đặt cột TIMESTAMP thành giá trị hiện tại:

CẬP NHẬT tên_bảng
BỘ cột_ imes tamp- cột_Ytestamp, other_column1 = new_value1, other_column2= new_objection2, ...
Một cách khác để duy trì một cột ghi lại thời gian tạo một hàng là sử dụng cột DATETIME được khởi tạo thành NOW() khi hàng được tạo và không được sửa đổi sau đó.
Giá trị TIMESTAMP có thể nằm trong khoảng từ đầu năm 1970 đến một phần của năm 2037 với độ phân giải một giây. Các giá trị được hiển thị dưới dạng số.
Định dạng mà MySQL truy xuất và hiển thị các giá trị TIMESTAMP phụ thuộc vào độ rộng hiển thị, như được minh họa trong Bảng 1. 4.3. Định dạng TIMESTAMP đầy đủ dài 14 bit, nhưng các cột TIMESTAMP có thể được xác định ở định dạng hiển thị ngắn hơn.

Bảng Sự phụ thuộc của định dạng hiển thị vào chiều rộng

Tất cả các cột TIMESTAMP đều có cùng kích thước lưu trữ, bất kể định dạng hiển thị. Các định dạng được sử dụng phổ biến nhất là 6, 8, 12 và 14 ký tự. Bạn có thể chỉ định kích thước hiển thị tùy chỉnh khi tạo bảng, nhưng các giá trị 0 và lớn hơn 14 được chia tỷ lệ thành 14. Các giá trị lẻ từ 1 đến 13 được chia tỷ lệ thành số chẵn gần nhất.
Các cột TIMESTAMP lưu trữ các giá trị hợp lệ bằng cách sử dụng độ chính xác hoàn toàn mà chúng được chỉ định, bất kể chiều rộng hiển thị. Tuy nhiên, có một số hạn chế liên quan đến điều này:

  1. Bạn phải luôn chỉ định năm, tháng và ngày, ngay cả khi cột được khai báo là TIMESTAMP(4) hoặc TIMESTAMP(2). Nếu không, giá trị được coi là không chính xác và được lưu ở mức 0.
  2. Nếu bạn sử dụng bảng ALTER để mở rộng cột TIMESTAMP, thông tin bị ẩn trước đó sẽ được đánh dấu.
  3. Tương tự như vậy, khi bạn thu hẹp cột DẤU THỜI GIAN, không có thông tin nào bị mất, ngoại trừ nghĩa là sẽ có ít thông tin được xuất ra hơn trước.
  4. Mặc dù các cột TIMESTAMP được lưu trữ với độ chính xác hoàn toàn, hàm duy nhất hoạt động với toàn bộ lượng thông tin được lưu trữ trong đó là UNIX_TIMESTAMP(). Tất cả các hàm khác hoạt động trên giá trị được trích xuất được định dạng. Điều này có nghĩa là bạn không thể sử dụng hàm như HOUR() hoặc SECOND() trừ khi phần tương ứng được bao gồm trong giá trị được định dạng của cột. Ví dụ: phần HH của cột TIMESTAMP sẽ không được hiển thị trừ khi chiều rộng hiển thị của nó ít nhất là 10, do đó việc áp dụng HOURO cho các giá trị TIMESTAMP ngắn hơn sẽ tạo ra kết quả vô nghĩa.
Thuộc tính TIMESTAMP trong MySQL phiên bản 4.1 trở lên
Bắt đầu với MySQL 4.1, các thuộc tính TIMESTAMP khác với các thuộc tính trong bản phát hành trước: cột TIMESTAMP được hiển thị ở cùng định dạng với cột DATETIME.
  • Chiều rộng hiển thị không còn được hỗ trợ như mô tả trước đây. Nói cách khác, bạn không còn có thể sử dụng TIMESTAMP(4) hoặc TIMESTAMP(2). Ngoài ra, nếu máy chủ MySQLđược khởi chạy ở chế độ MAXDB, loại TIMESTAMP giống hệt với datetime. Nghĩa là, nếu máy chủ đang chạy ở chế độ MAXDB tại thời điểm bảng được tạo thì mọi cột TIMESTAMP sẽ được tạo dưới dạng DATETIME. Kết quả là các cột này sử dụng định dạng hiển thị DATETIME, có cùng phạm vi giá trị hợp lệ và không có cập nhật tự động không xảy ra.
Ở chế độ MAXDB, máy chủ MySQL có thể được khởi chạy bắt đầu từ phiên bản 4.1.1. Để bật chế độ này, hãy chỉ định tùy chọn -sql-mode=MAXDB khi khởi động máy chủ hoặc đặt giá trị của biến toàn cục sqljnode khi chạy:
mysql THIẾT LẬP TOÀN CẦU sql_mode=MAXDB;
Máy khách có thể buộc máy chủ chạy ở chế độ MAXDB cho phiên riêng của nó bằng lệnh:
mysql THIẾT LẬP PHIÊN sql_mode=MAXDB;