15

我们使用 sql server 作为 Quartz.net 的持久数据存储。我想写一些查询@时间值。具体来说 - Qrtz_Fired_Triggers.Fired_Time、Qrtz_Triggers.Next_fire_time、Prev_fire_time。

在我的一生中,我找不到任何能说明这些数据是什么的东西——滴答声、毫秒、微秒、纳秒。我猜到了几件事,但都被证明是错误的。

最好的答案将包括将大整数转换为日期时间的数学,甚至可能是我应该找到的页面/文档的链接 - 解释这些字段中数据的含义。

如果您有关于使用 Quartz .Net 库查看此信息的具体说明,那将不胜感激,但是,我确实有两个目标 - 了解所存储的日期/时间数据的含义并将其保存在 T-SQL 中。如果我得到一个,我可以找出 T-SQL 或找出。

4

3 回答 3

37

在 SQL 方面,您可以使用以下方法将 Quartz.NET BIGINT 时间转换为 UTC 时间的 DateTime:

SELECT CAST(NEXT_FIRE_TIME/864000000000.0 - 693595.0 AS DATETIME) FROM QRTZ_TRIGGERS

数字解释

该列中存储的值是来自 .NETDateTime.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)
于 2013-03-13T15:16:53.603 回答
4

存储在数据库中的值是 DateTime.Ticks 值。来自 MSDN:

一个滴答表示一百纳秒或百万分之一秒。一毫秒内有 10,000 个滴答声。

此属性的值表示自 0001 年 1 月 1 日午夜 12:00:00 以来经过的 100 纳秒间隔数,它表示 DateTime.MinValue。它不包括可归因于闰秒的滴答数。

于 2010-11-20T11:29:20.480 回答
1

所以,除非我遗漏了一些东西并且把它弄得太复杂了,否则我无法在 Ms Sql Server 2008 中使用 dateadd 函数来处理如此大的值,并且我不断收到溢出错误。我在 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
于 2010-11-24T17:57:17.873 回答