如何将 SQL Server 的时间戳列转换为日期时间格式

Posted

技术标签:

【中文标题】如何将 SQL Server 的时间戳列转换为日期时间格式【英文标题】:How to convert SQL Server's timestamp column to datetime format 【发布时间】:2011-12-28 11:54:36 【问题描述】:

由于 SQL Server 返回像 'Nov 14 2011 03:12:12:947PM' 这样的时间戳,有没有一些简单的方法可以将字符串转换为日期格式,如 'Y-m-d H:i:s'。

到目前为止我使用

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

【问题讨论】:

【参考方案1】:

SQL Server 的 TIMESTAMP 数据类型与日期和时间无关

它只是一个连续 8 字节整数的十六进制表示 - 它只有助于确保一行在被读取后没有发生变化。

您可以读取十六进制整数,或者如果您想要BIGINT。举个例子:

SELECT CAST (0x0000000017E30D64 AS BIGINT)

结果是

400756068

在较新版本的 SQL Server 中,它被称为 RowVersion - 因为它确实如此。见MSDN docs on ROWVERSION:

是一种在数据库中公开自动生成的唯一二进制数的数据类型。 rowversion 一般用作一种机制 用于版本标记表行。这 rowversion 数据类型只是一个递增的数字,而不是 保留日期或时间。要记录日期或时间,请使用 datetime2 数据类型。

所以您不能将 SQL Server TIMESTAMP 转换为日期/时间 - 它只是不是日期/时间。

但是,如果您说的是时间戳,但实际上是指 DATETIME 列 - 那么您可以使用 MSDN 帮助中 CAST and CONVERT 主题中描述的任何有效日期格式。这些是由 SQL Server “开箱即用”定义和支持的。不支持其他任何内容,例如您必须进行大量手动转换和连接(不推荐)。

您要查找的格式有点像 ODBC 规范(样式 = 121):

DECLARE @today DATETIME = SYSDATETIME()

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

给予:

2011-11-14 10:29:00.470

SQL Server 2012 will finally have a FORMAT function 进行自定义格式化......

【讨论】:

可能是我对 SQL Server 最大的不满。如果我不能用它来判断时间,为什么要称它为时间戳? @BelgoCanadian:询问 Sybase - 这是 Sybase/SQL Server 中一直存在的功能..... @BelgoCanadian 你应该很高兴知道它现在被称为 rowversion docs.microsoft.com/en-us/sql/t-sql/data-types/… TIMESTAMP类型的列【参考方案2】:

最简单的方法是:

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

这至少以可读的格式提供日期列。 进一步如果你想改变te格式点击here。

【讨论】:

问题是 SQLServer,而不是 mysql【参考方案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);

【讨论】:

【参考方案4】:

工作正常,除了这条消息:

不允许从数据类型 varchar 到时间戳的隐式转换。使用 CONVERT 函数运行此查询

所以是的,TIMESTAMP (RowVersion) 不是日期:)

说实话,我自己摆弄了很长时间才找到一种将其转换为日期的方法。

最好的方法是将其转换为INT 并进行比较。这就是这种类型的本意。

如果你想要一个日期 - 只需添加一个 Datetime 列,从此过上幸福的生活:)

干杯麦克

【讨论】:

或 BIGINT,因为它是 8 个字节【参考方案5】:

使用 cast 您可以从时间戳字段中获取日期:

SELECT CAST(timestamp_field AS DATE) FROM tbl_name

【讨论】:

这似乎不起作用:Explicit conversion from data type timestamp to date is not allowed. 坏主意。时间戳字段只是一个序列。你可能会很幸运并得到一个约会,但约会没有任何意义。如果你想要一个十进制数,而不是十六进制,你应该转换为 BIGINT。时间戳现在称为 rowversion docs.microsoft.com/en-us/sql/t-sql/data-types/…【参考方案6】:

“你一直用那个词。我不认为它意味着你认为它的意思。” — 伊尼戈·蒙托亚

正如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(十六进制)对于每条记录都会增加 1,但实际时间有 10 秒的间隔。如果与时间有关,那么时间戳就会有一个间隙来对应时间的差异。

【讨论】:

【参考方案7】:

Robert Mauro 的评论是正确的。对于那些知道 Sybase 起源的人来说,datetime 实际上是两个单独的整数,一个代表日期,一个代表时间,因此时间戳(也称为 rowversion)可以被视为从服务器捕获的原始值。更快。

【讨论】:

可能值得在您的答案中链接评论:) 这没有提供问题的答案。一旦你有足够的reputation,你就可以comment on any post;相反,provide answers that don't require clarification from the asker。 - From Review【参考方案8】:

在转换为整数之后 CONVERT(BIGINT, [timestamp]) 作为时间戳 我得到了类似的结果

446701117 446701118 446701119 446701120 446701121 446701122 446701123 446701124 446701125 446701126

是的,这不是日期和时间,而是序列号

【讨论】:

【参考方案9】:

对我来说有效: TO_DATE('19700101', 'yyyymmdd') + (TIME / 24 / 60 / 60) (甲骨文数据库)

【讨论】:

【参考方案10】:

其中一些实际上确实从 SQL Server 2008 开始转换为日期时间。

试试下面的 SQL 查询,你会亲眼看到:

SELECT CAST (0x00009CEF00A25634 AS datetime)

以上将导致2009-12-30 09:51:03:000,但我遇到了实际上不映射到日期时间的。

【讨论】:

不要那样做。您可能会很幸运并获得转换,但日期时间将毫无意义且具有误导性。时间戳只是一个序列号,现在称为行版本docs.microsoft.com/en-us/sql/t-sql/data-types/…。如果你想要一个十进制数,只需转换为 BIGINT【参考方案11】:

我在时间戳上遇到了同样的问题,例如:'29-JUL-20 04.46.42.000000000 PM'。我想把它变成'yyyy-MM-dd'格式。最终对我有用的解决方案是

SELECT TO_CHAR(mytimestamp, 'YYYY-MM-DD') FROM mytable;

【讨论】:

【参考方案12】:

我假设您已将数据转储为插入语句,并且您(或任何 Google 搜索的人)正试图找出日期和时间,或将其转换为在其他地方使用(例如:转换为 MySQL 插入)。这实际上在任何编程语言中都很容易。

让我们来解决这个问题:

CAST(0x0000A61300B1F1EB AS DateTime)

这个十六进制表示实际上是两个独立的数据元素...日期和时间。前四个字节是日期,后四个字节是时间。

日期为0x0000A613 时间为0x00B1F1EB

使用您选择的编程语言将两个段转换为整数(这是一种直接的十六进制到整数的转换,每种现代编程语言都支持,因此,我不会用可能或不可能的代码浪费空间您正在使用的编程语言)。

0x0000A613的日期变成42515 0x00B1F1EB的时间变成11661803

现在,如何处理这些整数:

日期

日期自 1900 年 1 月 1 日起,以天数表示。因此,将 42,515 天添加到 01/01/1900,您的结果是 05/27/2016。

时间

时间有点复杂。获取该 INT 并执行以下操作以获取自午夜以来的微秒时间(伪代码):

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

从那里,使用您的语言最喜欢的函数调用将微秒(上例中为 38872676666.7 µs)转换为时间。

结果将是 10:47:52.677

【讨论】:

【参考方案13】:

为什么不试试FROM_UNIXTIME(unix_timestamp, format)

【讨论】:

因为这个问题指的是微软的SQL,而不是MySQL。【参考方案14】:

不确定我是否在这里遗漏了什么,但你不能像这样转换时间戳:

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

【讨论】:

你试过了吗? TIMESTAMP 与 DATE 无关。 我在 SQL Server 2008 上使用它 再一次,不要尝试转换为日期时间。它只是一个十六进制形式的整数序列。只需投射到 BIGINT。

以上是关于如何将 SQL Server 的时间戳列转换为日期时间格式的主要内容,如果未能解决你的问题,请参考以下文章

如何从 parquet 文件中选择 13 位时间戳列,将其转换为日期并存储为数据框?

sql server2000如何将数字转换为日期时间

Pandas 将时间戳列转换为日期时间

将纪元时间戳列转换为带有时区的日期时间

Pyspark 将字符串转换为日期时间戳列,包含两种不同的格式

如何将包含时区的字符串转换为日期时间 sql server