Vì SQL Server trả về dấu thời gian như vậy 'Nov 14 2011 03:12:12:947PM'
, có một số cách dễ dàng để chuyển đổi chuỗi sang định dạng ngày tháng như 'Ymd H: i: s'.
Cho đến nay tôi sử dụng
date('Y-m-d H:i:s',strtotime('Nov 14 2011 03:12:12:947PM'))
Câu trả lời:
TIMESTAMP
Kiểu dữ liệu của SQL Server không liên quan gì đến ngày và giờ!
Nó chỉ là một biểu diễn thập lục phân của một số nguyên 8 byte liên tiếp - nó chỉ tốt để đảm bảo một hàng không thay đổi kể từ khi nó được đọc.
Bạn có thể đọc số nguyên thập lục phân hoặc nếu bạn muốn a BIGINT
. Ví dụ:
SELECT CAST (0x0000000017E30D64 AS BIGINT)
Kết quả là
400756068
Trong các phiên bản SQL Server mới hơn, nó được gọi RowVersion
- vì đó thực sự là như vậy. Xem tài liệu MSDN trên ROWVERSION :
Là một kiểu dữ liệu hiển thị các số nhị phân được tạo tự động, duy nhất trong cơ sở dữ liệu. rowversion thường được sử dụng như một cơ chế cho các hàng trong bảng dập phiên bản. Kiểu dữ liệu chuyển đổi hàng chỉ là một số tăng dần và không bảo toàn ngày hoặc giờ . Để ghi ngày hoặc giờ, hãy sử dụng kiểu dữ liệu datetime2.
Vì vậy, bạn không thể chuyển đổi SQL Server TIMESTAMP
thành ngày / giờ - nó không phải là ngày / giờ.
Nhưng nếu bạn đang nói dấu thời gian nhưng thực sự ý bạn là một DATETIME
cột - thì bạn có thể sử dụng bất kỳ định dạng ngày hợp lệ nào được mô tả trong chủ đề CAST và CONVERT trong trợ giúp MSDN. Chúng được xác định và hỗ trợ "out of the box" bởi SQL Server. Bất kỳ thứ gì khác không được hỗ trợ, ví dụ như bạn phải thực hiện nhiều quá trình truyền và nối thủ công (không được khuyến khích).
Định dạng bạn đang tìm kiếm có vẻ giống với ODBC canonical (style = 121):
DECLARE @today DATETIME = SYSDATETIME()
SELECT CONVERT(VARCHAR(50), @today, 121)
cho:
2011-11-14 10:29:00.470
SQL Server 2012 cuối cùng sẽ có một FORMAT
chức năng để thực hiện định dạng tùy chỉnh ......
TIMESTAMP
cột loại
Sử dụng truyền, bạn có thể lấy ngày từ trường dấu thời gian:
SELECT CAST(timestamp_field AS DATE) FROM tbl_name
Explicit conversion from data type timestamp to date is not allowed.
Đồng nghiệp của tôi đã giúp tôi điều này:
select CONVERT(VARCHAR(10), <tms_column>, 112), count(*)
from table where <tms_column> > '2012-09-10'
group by CONVERT(VARCHAR(10), <tms_column>, 112);
hoặc là
select CONVERT(DATE, <tms_column>, 112), count(*)
from table where <tms_column> > '2012-09-10'
group by CONVERT(DATE, <tms_column>, 112);
Hoạt động tốt, ngoại trừ thông báo này:
Không cho phép chuyển đổi ngầm định từ kiểu dữ liệu varchar sang dấu thời gian. Sử dụng hàm CHUYỂN ĐỔI để chạy truy vấn này
Vì vậy, có, TIMESTAMP
( RowVersion
) KHÔNG PHẢI LÀ NGÀY :)
Thành thật mà nói, tôi đã lăn lộn khá lâu để tìm cách chuyển nó thành ngày tháng.
Cách tốt nhất là chuyển đổi nó sang INT
và so sánh. Đó là những gì loại này có nghĩa là.
Nếu bạn muốn có một ngày - chỉ cần thêm một Datetime
cột và sống hạnh phúc mãi mãi :)
cổ vũ mac
"Bạn tiếp tục sử dụng từ đó. Tôi không nghĩ nó có nghĩa như những gì bạn nghĩ." - Inigo Montoya
Dấu thời gian hoàn toàn không có mối quan hệ với thời gian như marc_s đã nói ban đầu.
declare @Test table (
TestId int identity(1,1) primary key clustered
,Ts timestamp
,CurrentDt datetime default getdate()
,Something varchar(max)
)
insert into @Test (Something)
select name from sys.tables
waitfor delay '00:00:10'
insert into @Test (Something)
select name from sys.tables
select * from @Test
Lưu ý trong đầu ra rằng Ts (hex) tăng một cho mỗi bản ghi, nhưng thời gian thực có khoảng cách là 10 giây. Nếu nó liên quan đến thời gian thì sẽ có một khoảng trống trong dấu thời gian để tương ứng với sự khác biệt về thời gian.
Sau khi thực hiện chuyển đổi thành CONVERT số nguyên (BIGINT, [timestamp]) dưới dạng Dấu thời gian, tôi đã nhận được kết quả như
446701117 446701118 446701119 446701120 446701121 446701122 446701123 446701124 446701125 446701126
Có, đây không phải là ngày và giờ, Đó là số sê-ri
đối với tôi hoạt động: TO_DATE ('19700101', 'yyyymmdd') + (TIME / 24/60/60) (oracle DB)
Tôi sẽ giả sử rằng bạn đã thực hiện một kết xuất dữ liệu dưới dạng các câu lệnh chèn và bạn (hoặc bất kỳ ai Google gửi điều này) đang cố gắng tìm ra ngày và giờ hoặc dịch nó để sử dụng ở nơi khác (ví dụ: để chuyển đổi sang chèn MySQL). Điều này thực sự dễ dàng trong bất kỳ ngôn ngữ lập trình nào.
Hãy làm việc với điều này:
CAST(0x0000A61300B1F1EB AS DateTime)
Biểu diễn Hex này thực sự là hai phần tử dữ liệu riêng biệt ... Ngày và Giờ. Bốn byte đầu tiên là ngày tháng, bốn byte thứ hai là thời gian.
Chuyển đổi cả hai phân đoạn thành số nguyên bằng cách sử dụng ngôn ngữ lập trình mà bạn chọn (đó là chuyển đổi trực tiếp hex sang số nguyên, được hỗ trợ trong mọi ngôn ngữ lập trình hiện đại, vì vậy, tôi sẽ không lãng phí dung lượng với mã có thể là ngôn ngữ lập trình hoặc có thể không bạn đang làm việc).
Bây giờ, phải làm gì với những số nguyên đó:
Ngày
Ngày kể từ ngày 01/01/1900 và được biểu thị dưới dạng ngày. Vì vậy, hãy thêm 42.515 ngày vào 01/01/1900, và kết quả của bạn là 27/05/2016.
Thời gian
Thời gian phức tạp hơn một chút. Lấy INT đó và làm như sau để tính thời gian của bạn tính bằng micro giây kể từ nửa đêm (mã giả):
TimeINT=Hex2Int(HexTime)
MicrosecondsTime = TimeINT*10000/3
Từ đó, sử dụng các lệnh gọi hàm yêu thích của ngôn ngữ của bạn để dịch micro giây (38872676666,7 µs trong ví dụ trên) thành thời gian.
Kết quả sẽ là 10: 47: 52,677
Một số trong số chúng thực sự ẩn đến một ngày-giờ từ SQL Server 2008 trở đi.
Hãy thử truy vấn SQL sau và bạn sẽ thấy:
SELECT CAST (0x00009CEF00A25634 AS datetime)
Ở trên sẽ dẫn đến 2009-12-30 09:51:03:000
nhưng tôi đã gặp những cái thực sự không liên kết với ngày-giờ.
Tại sao không thử FROM_UNIXTIME(unix_timestamp, format)
?
Không chắc liệu tôi có thiếu thứ gì đó ở đây hay không nhưng bạn không thể chỉ chuyển đổi dấu thời gian như thế này:
CONVERT(VARCHAR,CAST(ZEIT AS DATETIME), 110)