Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sql-server-2005/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 2005 将.NET标记转换为SQL Server日期时间_Sql Server 2005_Nhibernate_Datetime_Timespan - Fatal编程技术网

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
表示的小时、分钟和秒数。

a
TimeSpan
不是日期,这样保存它可能会在将来引起混乱


有什么原因不能简单地将记号保存到整数字段而不更改其含义吗?

您应该能够使用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转换才有用。如果您使用的日期不确定是否在夏令时(又称夏令时),则仍然需要进行一些比较以正确转换。这确实是对以前答案的重复,但我认为它有一些优点,因为它对我来说更简单。