Sql server 2005 将.NET标记转换为SQL Server日期时间
我正在将数据库中的Sql server 2005 将.NET标记转换为SQL Server日期时间,sql-server-2005,nhibernate,datetime,timespan,Sql Server 2005,Nhibernate,Datetime,Timespan,我正在将数据库中的TimeSpan(来自.NET)值保存为SQL Server中的BIGINT(保存Ticks属性)。我想知道如何在SQL Server(而不是.NET)中将此BIGINT值转换为DATETIME值。有什么想法吗 干杯 编辑: 我正在使用NHibernate映射我拥有的TimeSpan属性,它将保留Ticks属性。我用它来控制某个日期的相对小时(或分钟) 系统内部一切正常,不需要进行这种转换。但是,在SQL Server中执行随机查询时,很难理解TimeSpan的持久形式。因此,
TimeSpan
(来自.NET)值保存为SQL Server中的BIGINT
(保存Ticks属性)。我想知道如何在SQL Server(而不是.NET)中将此BIGINT
值转换为DATETIME
值。有什么想法吗
干杯
编辑:
我正在使用NHibernate映射我拥有的TimeSpan
属性,它将保留Ticks属性。我用它来控制某个日期的相对小时(或分钟)
系统内部一切正常,不需要进行这种转换。但是,在SQL Server中执行随机查询时,很难理解
TimeSpan
的持久形式。因此,我传递Ticks
值并返回DateTime
的函数将给出TimeSpan
表示的小时、分钟和秒数。aTimeSpan
不是日期,这样保存它可能会在将来引起混乱
有什么原因不能简单地将记号保存到整数字段而不更改其含义吗?您应该能够使用SQL Server内置的函数
SELECT(CAST(CAST(CAST ('02/02/10' AS datetime) AS BIGINT) AS datetime))
您可以在.NET中获得2010-02-02 00:00:00.000获取
TimeSpan.TicksPerSecond
的值(只需写下来即可)
然后,在SQL中,您可以将滴答数除以该数字,得到秒数
然后你可以把它除以60分钟,以此类推。我自己算出了: 2880000000个刻度表示8小时,因此下面的
SELECT
返回一个指定小时数的虚拟日期
SELECT DATEADD(millisecond, 288000000000/10000, CAST('1900-01-01' AS DATETIME))
多亏了大家的努力。我不确定秒数的准确性,但您可以尝试以下方法:
Declare @TickValue bigint
Declare @Days float
Set @TickValue = 634024345696365272
Select @Days = @TickValue * POWER(10.00000000000,-7) / 60 / 60 / 24
Select DATEADD(d, Cast(@Days As int), Cast('0001-01-01' As DATE))
+ Cast( (@Days - FLOOR(@Days)) As DateTime)
实际上,在SQL2005中工作的另一种方法是注意从0001-01-01到1900-01-01的滴答数是5992660800000000。有了这些,你可以:
Declare @TickOf19000101 bigint
Declare @TickValue bigint
Declare @Minutes float
Set @TickOf19000101 = 599266080000000000
Set @TickValue = DATEDIFF(mi, 0 ,CURRENT_TIMESTAMP) * Cast(60 As BigInt)
* POWER(10.00000000000,7) + @TickOf19000101
Select @TickValue
Select @Minutes = (@TickValue - @TickOf19000101) * POWER(10.00000000000,-7) / 60
Select @Minutes
Select DATEADD(MI, @Minutes, '1900-01-01')
您可以使用此函数将64位整数转换为服务器本地时间内精度为毫秒的日期时间值:
CREATE FUNCTION NetFxUtcTicksToDateTime
(
@Ticks bigint
)
RETURNS datetime
AS
BEGIN
-- First, we will convert the ticks into a datetime value with UTC time
DECLARE @BaseDate datetime;
SET @BaseDate = '01/01/1900';
DECLARE @NetFxTicksFromBaseDate bigint;
SET @NetFxTicksFromBaseDate = @Ticks - 599266080000000000;
-- The numeric constant is the number of .Net Ticks between the System.DateTime.MinValue (01/01/0001) and the SQL Server datetime base date (01/01/1900)
DECLARE @DaysFromBaseDate int;
SET @DaysFromBaseDate = @NetFxTicksFromBaseDate / 864000000000;
-- The numeric constant is the number of .Net Ticks in a single day.
DECLARE @TimeOfDayInTicks bigint;
SET @TimeOfDayInTicks = @NetFxTicksFromBaseDate - @DaysFromBaseDate * 864000000000;
DECLARE @TimeOfDayInMilliseconds int;
SET @TimeOfDayInMilliseconds = @TimeOfDayInTicks / 10000;
-- A Tick equals to 100 nanoseconds which is 0.0001 milliseconds
DECLARE @UtcDate datetime;
SET @UtcDate = DATEADD(ms, @TimeOfDayInMilliseconds, DATEADD(d, @DaysFromBaseDate, @BaseDate));
-- The @UtcDate is already useful. If you need the time in UTC, just return this value.
-- Now, some magic to get the local time
RETURN @UtcDate + GETDATE() - GETUTCDATE();
END
GO
适合内联使用的替代代码:
DECLARE @Ticks bigint
set @Ticks = 634899090000000000
select DATEADD(ms, ((@Ticks - 599266080000000000) -
FLOOR((@Ticks - 599266080000000000) / 864000000000) * 864000000000) / 10000,
DATEADD(d, (@Ticks - 599266080000000000) / 864000000000, '01/01/1900')) +
GETDATE() - GETUTCDATE()
我不太了解SQL Server,但今天我的一位同事也遇到了同样的问题,我想我已经找到了这样的解决方案:
CAST(([ticks] - 599266080000000000) / 10000000 / 24 / 60 / 60 AS datetime)
其中5992660800000000是01/01/1900 00:00:00的刻度值。已授予。这需要SQL 2008及其日期数据类型。顺便说一句,还应注意刻度值从“0001-01-01”开始,而不是从“1900-01-01”开始。代码很好,但如果时间跨度仅表示小时而不是完整日期,结果日期太低,无法表示为datetime。但是代码是一个很好的开始,我将把它标记为答案并继续工作。非常感谢你!这对于查看我的quartz.net触发器非常有用:DATEADD(hour,@EST_offset_h,DATEADD(mi,(a.START_TIME-5992660800000000)*POWER(10.00000000000,-7)/60,'1900-01-01'))作为“StartDateTimeEST-4”,奇怪地从刻度开始使用select(CAST(CAST(CAST(633979266000000000作为BIGINT)作为datetime))给出算术溢出错误。请注意,对于相同的输入值,此函数可能返回相差几毫秒的日期时间。return语句进行两次不同的调用以获取当前日期时间,并且时间可能(有时)在这些调用之间移动。+1表示相当出色的UTC->Local转换。网上有一篇又一篇的文章告诉人们创建时区偏移表之类的,然后就是这个,非常简单,隐藏在一个看似无关的主题中。只有在比较的日期是最近的情况下,UTC->local转换才有用。如果您使用的日期不确定是否在夏令时(又称夏令时),则仍然需要进行一些比较以正确转换。这确实是对以前答案的重复,但我认为它有一些优点,因为它对我来说更简单。