我们使用 SQL Server 作为 Quartz.net 的持久数据存储。我想编写一些查询@时间值。具体来说 - Qrtz_Fired_Triggers.Fired_Time、Qrtz_Triggers.Next_fire_time、Prev_fire_time。
在我的一生中,我找不到任何东西来说明这个数据是什么——滴答声、毫秒、微秒、纳秒。我猜测了一些事情,但事实证明它们都是错误的。
最好的答案将包括将大整数转换为日期时间的数学,甚至可能是我应该找到的页面/文档的链接 - 解释这些字段中数据的含义。
如果您有关于使用 Quartz .Net 库查看此信息的具体说明,我们将不胜感激,但是,我确实有 2 个目标 - 理解所存储的日期/时间数据的含义并将其保留在 T-SQL 中。如果我得到了这个,我就能弄清楚 T-SQL 或出来。
在 SQL 端,您可以使用以下命令将 Quartz.NET BIGINT 时间转换为 UTC 时间的 DateTime:
SELECT CAST(NEXT_FIRE_TIME/864000000000.0 - 693595.0 AS DATETIME) FROM QRTZ_TRIGGERS
列中存储的值是 .NET
DateTime.MinValue
中 UTC 时间的刻度数。每毫秒有 10000 个刻度。
864000000000.0
代表一天内的刻度数。您可以使用 来验证这一点
SELECT DATEDIFF(ms,'19000101','19000102')*10000.0
现在,如果我们以 2013 年 3 月 13 日午夜为例,.NET 将返回
634987296000000000
作为刻度数。
var ticks = new DateTime(2013, 3, 13).Ticks;
要获得浮点数,其中整数代表天数,小数代表时间,我们将刻度除以每天的刻度数(在我们的示例中给出
734939.0
)
SELECT 634987296000000000/(DATEDIFF(ms,'19000101','19000102')*10000.0)
如果我们将日期放入 SQL 中并转换为浮点数,我们会得到不同的数字:
41344.0
SELECT CAST(CAST('March 13, 2013 0:00' AS DATETIME) AS FLOAT)
因此,我们需要为 .NET 到 SQL 生成一个转换因子。 SQL 最小日期是 1900 年 1 月 1 日 0:00,因此可以通过将该时间的刻度数 (
599266080000000000
) 除以每天的刻度数来计算校正因子,得到 693595.0
SELECT 599266080000000000/(DATEDIFF(ms,'19000101','19000102')*10000.0)
因此,要计算 Quartz.NET 日期的 DateTime:
SELECT CAST([Column]/864000000000.0 - 693595.0 AS DATETIME)
数据库中存储的值是DateTime.Ticks值。来自 MSDN:
一个勾代表一百 纳秒或万分之一 第二。有 10,000 个蜱虫 毫秒。
该属性的值代表 100 纳秒间隔的数量 自 12:00:00 以来已过去的时间 0001 年 1 月 1 日午夜, 表示 DateTime.MinValue。确实如此 不包括刻度数 归因于闰秒。
所以,除非我错过了一些东西并且让事情变得太复杂,否则我无法让 Ms Sql Server 2008 中的 dateadd 函数来处理如此大的值,并且我不断收到溢出错误。我在 Ms Sql Server 中采取的方法是这样的: a) 找到比 0001.01.01 更接近现在的日期及其刻度值 b) 使用函数给我一个 DateTime 值。
注意事项: * 对于我的应用程序 - 秒就足够了。 * 我还没有对此进行广泛的测试,但到目前为止,它对我来说效果很好。
功能:
CREATE FUNCTION [dbo].[net_ticks_to_date_time]
(
@net_ticks BIGINT
)
RETURNS DATETIME
AS
BEGIN
DECLARE
@dt_2010_11_01 AS DATETIME = '2010-11-01'
, @bi_ticks_for_2010_11_01 AS BIGINT = 634241664000000000
, @bi_ticks_in_a_second AS BIGINT = 10000000
RETURN
(
DATEADD(SECOND , ( ( @net_ticks - @bi_ticks_for_2010_11_01 ) / @bi_ticks_in_a_second ) , @dt_2010_11_01)
);
END
GO
DECLARE
@dt2_dot_net_min AS DATETIME2 = '01/01/0001'
, @dt2_first_date AS DATETIME2
, @dt2_next_date AS DATETIME2
, @bi_seconds_since_0101001 BIGINT = 0
SET @dt2_first_date = @dt2_dot_net_min;
SET @dt2_next_date = DATEADD ( DAY, 1, @dt2_first_date )
WHILE ( @dt2_first_date < '11/01/2010' )
BEGIN
SELECT @bi_seconds_since_0101001 = DATEDIFF(SECOND, @dt2_first_date, @dt2_next_date ) + @bi_seconds_since_0101001
PRINT 'seconds 01/01/0001 to ' + CONVERT ( VARCHAR, @dt2_next_date, 101) + ' = ' + CONVERT ( VARCHAR, CAST ( @bi_seconds_since_0101001 AS MONEY ), 1)
SET @dt2_first_date = DATEADD ( DAY, 1, @dt2_first_date );
SET @dt2_next_date = DATEADD ( DAY, 1, @dt2_first_date )
END
数据库中存储的值是DateTime.Ticks值。对于 postgresql
Select to_timestamp(((NEXT_FIRE_TIME - 621355968000000000) / 10000000)) FROM qrtz_triggers