如何在c#中复制c#日期时间整数值

本文关键字:时间 整数 日期 复制 | 更新日期: 2023-09-27 18:12:15

有没有办法在c#中复制这个整数值?

select cast(getdate() as int)
-->
41827

我尝试了这个,但它与sql日期不一致:

public string SqlDate { 
    get 
    {
        double x = (DateTime.Now - DateTime.FromOADate(0)).TotalDays;
        return Math.Floor(x).ToString();
    } 
}

如何在c#中复制c#日期时间整数值

SQL Server datetime值在内部是一个元组,包含2个有符号的32位整数:

  • 高阶整数是SQL Server日历历元(零点)的偏移量,以全天为单位,恰好是1 Jan 1900 00:00:00.000

  • 低阶整数是从一天开始的偏移量,不是以毫秒为单位,而是以"刻度"为单位,大约为1/300秒。

getdate()返回当前日期和时间作为datetime值。表达式cast( getdate() as int )完全等价于

datediff(day,'1 Jan 1900 00:00:00.000',getdate())
这个查询

declare @epoch datetime = '4 July 2014 00:00:01.000'
select [raw]            = @epoch ,
       [cast]           = cast(@epoch as int) ,
       [datediff]       = datediff(day,'1 Jan 1900',@epoch) ,
       [highorder-word] = convert(int,substring( convert(varbinary(8),@epoch),1,4) ) ,
       [low-order-word] = convert(int,substring( convert(varbinary(8),@epoch),4,8) )

产生以下结果:

raw                     cast  datediff highorder-word low-order-word
----------------------- ----- -------- -------------- --------------
2014-07-04 00:00:01.000 41822 41822         41822           300

[你会注意到1秒正好是300个滴答。SQL Server以这种奇怪的方式计算时间是有历史原因的。根据我的理解,这可以追溯到Sybase SQL Server的时代,以及早期Windows和OS/2盒子上糟糕的时钟分辨率。

给定所有这些,您可以在c#中获得相同的计数(自1900年以来的天数):

public string SqlDate
{
  get { return DaysSince1900( DateTime.Now ).ToString() ; }
}
private int DaysSince1900( DateTime now )
{
  TimeSpan period = now.Date - SqlServerEpoch ;
  return period.Days ;
}
static readonly DateTime SqlServerEpoch = new DateTime( 1900 , 1 , 1 ) ;

有点像随机代码,但是这样做了:

void Main()
{
    int n = NumberOfDays(DateTime.Now);
    Console.WriteLine(n);
}
static int NumberOfDays(DateTime date)
{
  DateTime start = DateTime.Parse("12/31/1899");
  TimeSpan t = date - start;
  return (int)t.TotalDays;
}

基本上,转换为int似乎给出了从12/31/1899开始的天数。

作为旁注,这似乎不是一个依赖或使用的好东西。

在t-sql中GetDate()返回一个datetime,它将日期存储为自1753年1月1日以来的天数,时间存储为一天的小数部分。

因此Select Cast(GetDate() as int)将返回自1900年1月1日以来的天数

相反,c#结构将datetime存储为自01/01/0001以来的天数加上时间作为一天的小数部分。

因此,为了在两者之间进行转换,您只需要考虑01/01/0001和01/01/1900之间的偏移天数

或者,如果你不想用偏移量工作,你正在使用SQL Server 2008或更高版本,那么你可以用SYSDATETIME()函数替换GETDATE()函数,它返回一个datetime2,它也用作参考01/01/0001,所以c#日期和t-sql日期将被引用到相同的数据,所以当转换为int时,它们给出相同日期的相同数字。