วิธีการแปลงคอลัมน์เวลาประทับของ SQL Server เป็นรูปแบบวันที่และเวลา


93

เนื่องจาก SQL Server ส่งคืนการประทับเวลาเหมือน'Nov 14 2011 03:12:12:947PM'มีวิธีง่ายๆในการแปลงสตริงเป็นรูปแบบวันที่เช่น 'Ymd H: i: s'

จนถึงตอนนี้ฉันใช้

date('Y-m-d H:i:s',strtotime('Nov 14 2011 03:12:12:947PM'))

คำตอบ:


256

TIMESTAMPประเภทข้อมูลของ SQL Server ไม่มีส่วนเกี่ยวข้องกับวันที่และเวลา!

มันเป็นเพียงการแสดงเลขฐานสิบหกของจำนวนเต็ม 8 ไบต์ที่ต่อเนื่องกัน - เป็นการดีเท่านั้นที่จะทำให้แน่ใจว่าแถวนั้นไม่เปลี่ยนแปลงหลังจากอ่านแล้ว

คุณสามารถอ่านจำนวนเต็มฐานสิบหกหรือถ้าคุณต้องการBIGINT. ตัวอย่างเช่น:

SELECT CAST (0x0000000017E30D64 AS BIGINT)

ผลลัพธ์คือ

400756068

ในเวอร์ชันใหม่กว่าของ SQL Server จะมีการเรียกใช้RowVersion- เนื่องจากนั่นคือสิ่งที่เป็นจริง ดูเอกสาร MSDN ใน ROWVERSION :

เป็นชนิดข้อมูลที่แสดงเลขฐานสองที่สร้างขึ้นโดยอัตโนมัติภายในฐานข้อมูล rowversion โดยทั่วไปจะใช้เป็นกลไกในการปั๊มแถวของตาราง ชนิดข้อมูล rowversion เป็นเพียงตัวเลขที่เพิ่มขึ้นและไม่ได้รักษาวันที่หรือเวลา ในการบันทึกวันที่หรือเวลาให้ใช้ชนิดข้อมูล datetime2

ดังนั้นคุณจึงไม่สามารถแปลง SQL Server TIMESTAMPเป็นวันที่ / เวลาได้ - ไม่ใช่แค่วันที่ / เวลา

แต่ถ้าคุณพูดถึงการประทับเวลา แต่จริงๆแล้วคุณหมายถึงDATETIMEคอลัมน์คุณสามารถใช้รูปแบบวันที่ที่ถูกต้องตามที่อธิบายไว้ในหัวข้อแคสต์และแปลงในวิธีใช้ MSDN สิ่งเหล่านี้ถูกกำหนดและสนับสนุน "นอกกรอบ" โดย SQL Server สิ่งอื่นใดไม่ได้รับการสนับสนุนเช่นคุณต้องทำการแคสต์ด้วยตนเองและเชื่อมต่อกัน (ไม่แนะนำ)

รูปแบบที่คุณกำลังมองหามีลักษณะคล้ายกับODBC canonical (style = 121):

DECLARE @today DATETIME = SYSDATETIME()

SELECT CONVERT(VARCHAR(50), @today, 121)

ให้:

2011-11-14 10:29:00.470

ในที่สุด SQL Server 2012 จะมีFORMATฟังก์ชันในการจัดรูปแบบแบบกำหนดเอง ......


7
น่าจะเป็นความรู้สึกที่ยิ่งใหญ่ที่สุดของฉันกับ SQL Server ทำไมถึงเรียกมันว่าการประทับเวลาถ้าฉันไม่สามารถบอกเวลาได้
BelgoCanadian

1
@BelgoCanadian: ถาม Sybase - นั่นคือฟีเจอร์ที่อยู่ใน Sybase / SQL Server ตลอดไป .....
marc_s

1
@BelgoCanadian คุณควรดีใจที่รู้ว่าตอนนี้เรียกว่า rowversion docs.microsoft.com/en-us/sql/t-sql/data-types/…
Jason S

1
มีTIMESTAMPคอลัมน์ประเภท
Ghilteras

3

เพื่อนร่วมงานของฉันช่วยฉันในเรื่องนี้:

select CONVERT(VARCHAR(10), <tms_column>, 112), count(*)
from table where <tms_column> > '2012-09-10'
group by CONVERT(VARCHAR(10), <tms_column>, 112);

หรือ

select CONVERT(DATE, <tms_column>, 112), count(*)
from table where <tms_column> > '2012-09-10'
group by CONVERT(DATE, <tms_column>, 112);

3

วิธีที่ง่ายที่สุดคือ:

SELECT id,name,FROM_UNIXTIME(registration_date) FROM `tbl_registration`;

สิ่งนี้ทำให้คอลัมน์วันที่อย่างน้อยที่สุดในรูปแบบที่อ่านได้ ต่อไปถ้าคุณต้องการที่จะเปลี่ยนรูปแบบเต้คลิกที่นี่


11
คำถามคือ SQLServer ไม่ใช่ MySQL
Mike M

3

การใช้แคสต์คุณจะได้รับวันที่จากช่องประทับเวลา:

SELECT CAST(timestamp_field AS DATE) FROM tbl_name

18
ดูเหมือนจะไม่ได้ผล:Explicit conversion from data type timestamp to date is not allowed.
jocull

ความคิดที่ไม่ดี ฟิลด์การประทับเวลาเป็นเพียงลำดับ คุณอาจโชคดีและได้เดท แต่วันที่นั้นจะไม่มีความหมาย คุณควรส่งไปที่ BIGINT หากคุณต้องการตัวเลขทศนิยมแทนที่จะเป็นเลขฐานสิบหก การประทับเวลาปัจจุบันเรียกว่า rowversion docs.microsoft.com/en-us/sql/t-sql/data-types/…
Jason S

3

ใช้งานได้ดียกเว้นข้อความนี้:

ไม่อนุญาตให้แปลงโดยนัยจาก varchar ชนิดข้อมูลเป็นการประทับเวลา ใช้ฟังก์ชัน CONVERT เพื่อเรียกใช้แบบสอบถามนี้

ใช่แล้วTIMESTAMP( RowVersion) ไม่ใช่วันที่ :)

พูดตามตรงฉันเล่นตัวเองอยู่นานพอสมควรเพื่อหาวิธีแปลงเป็นวันที่

วิธีที่ดีที่สุดคือการแปลงเป็นไฟล์ INTและเปรียบเทียบ นั่นคือสิ่งที่หมายถึงประเภทนี้

หากคุณต้องการวันที่ - เพียงเพิ่มDatetimeคอลัมน์และใช้ชีวิตอย่างมีความสุขตลอดไป :)

ไชโย mac


1
หรือ BIGINT เนื่องจากมีขนาด 8 ไบต์
Jason S

2

"คุณใช้คำนั้นต่อไปฉันไม่คิดว่ามันหมายความว่าอย่างที่คุณคิด" - อินิโกมอนโตย่า

การประทับเวลาไม่มีความสัมพันธ์กับเวลาอย่างแน่นอนตามที่ marc_s กล่าวไว้ในตอนแรก

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

สังเกตในเอาต์พุตว่า Ts (hex) จะเพิ่มขึ้นทีละรายการสำหรับแต่ละเร็กคอร์ด แต่เวลาจริงมีช่องว่าง 10 วินาที หากเกี่ยวข้องกับเวลาจะมีช่องว่างในการประทับเวลาเพื่อให้สอดคล้องกับความแตกต่างของเวลา


0

หลังจาก impelemtation ของการแปลงเป็นจำนวนเต็ม CONVERT (BIGINT, [timestamp]) เป็นเวลาประทับฉันได้ผลลัพธ์เช่น

446701117 446701118 446701119 446701120 446701121 446701122 446701123 446701124 446701125 446701126

ใช่นี่ไม่ใช่วันที่และเวลา แต่เป็นหมายเลขซีเรียล



0

ฉันมีปัญหาเดียวกันกับการประทับเวลาเช่น '29 -JUL-20 04.46.42.000000000 PM ' ฉันต้องการเปลี่ยนเป็นรูปแบบ 'yyyy-MM-dd' ทางออกที่ได้ผลที่สุดสำหรับฉันคือ

เลือก TO_CHAR (mytimestamp, 'YYYY-MM-DD') จาก mytable;


0

ฉันจะถือว่าคุณได้ทำการถ่ายโอนข้อมูลเป็นคำสั่งแทรกและคุณ (หรือใครก็ตามที่ Googles สิ่งนี้) กำลังพยายามหาวันที่และเวลาหรือแปลเพื่อใช้ที่อื่น (เช่นแปลงเป็น MySQL inserts) นี่เป็นเรื่องง่ายในภาษาโปรแกรมใด ๆ

มาทำงานกับสิ่งนี้:

CAST(0x0000A61300B1F1EB AS DateTime)

การแทนค่าฐานสิบหกนี้เป็นองค์ประกอบข้อมูลสององค์ประกอบที่แยกจากกัน ... วันที่และเวลา สี่ไบต์แรกคือวันที่สี่ไบต์ที่สองคือเวลา

  • วันที่คือ 0x0000A613
  • เวลาคือ 0x00B1F1EB

แปลงทั้งสองส่วนเป็นจำนวนเต็มโดยใช้ภาษาโปรแกรมที่คุณเลือก (เป็นการแปลงเลขฐานสิบหกเป็นจำนวนเต็มโดยตรงซึ่งได้รับการสนับสนุนในทุกภาษาการเขียนโปรแกรมสมัยใหม่ดังนั้นฉันจะไม่เสียพื้นที่ไปกับรหัสที่อาจเป็นหรือไม่ใช่ภาษาโปรแกรม คุณกำลังทำงานอยู่)

  • วันที่ 0x0000A613 กลายเป็น 42515
  • เวลาของ 0x00B1F1EB กลายเป็น 11661803

ทีนี้จะทำอย่างไรกับจำนวนเต็มเหล่านั้น:

วันที่

วันที่คือตั้งแต่ 01/01/1900 และแสดงเป็นวัน ดังนั้นเพิ่ม 42,515 วันในวันที่ 01/01/1900 และผลลัพธ์ของคุณคือ 27/09/2016

เวลา

เวลามีความซับซ้อนขึ้นเล็กน้อย ใช้ INT นั้นและทำสิ่งต่อไปนี้เพื่อรับเวลาของคุณเป็นไมโครวินาทีตั้งแต่เที่ยงคืน (รหัสเทียม):

TimeINT=Hex2Int(HexTime)
MicrosecondsTime = TimeINT*10000/3

จากนั้นใช้การเรียกใช้ฟังก์ชันโปรดในภาษาของคุณเพื่อแปลไมโครวินาที (38872676666.7 วินาทีในตัวอย่างด้านบน) เป็นเวลา

ผลลัพธ์จะเป็น 10: 47: 52.677


-1

บางคนแอบแฝงไปถึงวันที่ - เวลาตั้งแต่SQL Server 2008เป็นต้นไป

ลองใช้แบบสอบถาม SQL ต่อไปนี้แล้วคุณจะเห็นเอง:

SELECT CAST (0x00009CEF00A25634 AS datetime)

ข้างต้นจะส่งผลให้2009-12-30 09:51:03:000แต่ฉันพบสิ่งที่ไม่ได้จับคู่กับวันที่ - เวลา


1
อย่าทำอย่างนั้น คุณอาจโชคดีและได้รับการเปลี่ยนใจเลื่อมใส แต่วันเวลาจะไม่มีความหมายและทำให้เข้าใจผิด การประทับเวลาเป็นเพียงหมายเลขลำดับและตอนนี้จะเรียกว่ารุ่นแถวdocs.microsoft.com/en-us/sql/t-sql/data-types/... หากคุณต้องการตัวเลขทศนิยมเพียงแค่ส่งไปที่ BIGINT
Jason S


-3

ไม่แน่ใจว่าฉันพลาดอะไรบางอย่างที่นี่ แต่คุณแปลงเวลาเป็นแบบนี้ไม่ได้:

CONVERT(VARCHAR,CAST(ZEIT AS DATETIME), 110)

ลองทำดูไหม TIMESTAMP ไม่มีความสัมพันธ์กับ DATE
Sean Pearce

ฉันใช้มันบน SQL Server 2008
Daniel

อย่าพยายามส่งไปยังวันที่และเวลา มันเป็นเพียงลำดับจำนวนเต็มในรูปเลขฐานสิบหก เพียงแค่ส่งไปที่ BIGINT
Jason S
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.