C# 在执行datetime比较时,如何解释datetime缺少毫秒精度? 出身背景

C# 在执行datetime比较时,如何解释datetime缺少毫秒精度? 出身背景,c#,sql,sql-server,datetime,C#,Sql,Sql Server,Datetime,我最近才知道 鉴于这些数据: 创建表datetime\u test id int,my\u date datetime; 在datetime\u测试id中插入my\u日期值 0, '2020-12-11 17:14:07.000', 1, '2020-12-11 17:14:07.197', 2, '2020-12-11 17:14:07.198', 3, '2020-12-11 17:14:08.000'; 此查询将返回1、2、3,而不是预期的2、3: 从日期时间测试中选择id,其中我的日期>

我最近才知道

鉴于这些数据:

创建表datetime\u test id int,my\u date datetime; 在datetime\u测试id中插入my\u日期值 0, '2020-12-11 17:14:07.000', 1, '2020-12-11 17:14:07.197', 2, '2020-12-11 17:14:07.198', 3, '2020-12-11 17:14:08.000'; 此查询将返回1、2、3,而不是预期的2、3:

从日期时间测试中选择id,其中我的日期>='2020-12-11 17:14:07.198'; 原因是此日期时间的毫秒部分实际上存储为.197:

-结果:2020-12-1117:14:07.197 选择convertdatetime,“2020-12-1117:14:07.198”; 我的问题 我正在使用现有的c代码,该代码使用SQL通过>=比较日期时间。大概是这样的:

public Foo GetMyColumnDateTime inputDatetime { // ... } 选择my_列 从我的桌子上 其中my_datetime>=@inputDatetime 我正在尝试重用这个c方法来执行独占比较…相当于使用>。我该怎么做

我最初的尝试是在c中的datetime输入中添加一毫秒,但由于上面概述的精度问题,这将不起作用。我想我可以加3毫秒。那感觉像是一个黑客。但它能可靠地工作吗


注意:请假设我无法更改此SQL或方法。

您会发现windows时钟可能没有您需要的那么精确。 此外,您的服务器的时钟不是那么精确,这取决于负载,它可能会滞后,因此,我们在需要精确时间时使用带有GPS计时器的特殊硬件

此外,服务器上的时间和数据库服务器上的时间不需要匹配,如果您的要求很难满足,那么它们将/可能永远不会匹配。只有一块坏了的手表每天精确2倍

请注意,在数据库和代码中始终使用UTC日期时间,这样无论服务器托管在何处,都可以使用相同的时间。UTC日期时间在.net中有一个ToLocalTime,数据库在TSQL中有GetUtcDate,这样您就不必按时区关闭

using System;
using System.Runtime.InteropServices;
public static class HighResolutionDateTime 
{ 
    public static bool IsAvailable { get; private set; }
    [DllImport("Kernel32.dll", CallingConvention = CallingConvention.Winapi)] 
    private static extern void GetSystemTimePreciseAsFileTime(out long filetime); 
    public static DateTime UtcNow 
    {
        get { 
            if (!IsAvailable) 
            { 
                throw new InvalidOperationException("High resolution clock isn't available."); 
            } 
            long filetime; 
            GetSystemTimePreciseAsFileTime(out filetime); 
            return DateTime.FromFileTimeUtc(filetime); 
        } 
    } 
    static HighResolutionDateTime() 
    { 
        try 
        { 
            long filetime; 
            GetSystemTimePreciseAsFileTime(out filetime); 
            IsAvailable = true; 
        } 
        catch (EntryPointNotFoundException) 
        {             // Not running Windows 8 or higher.             
            IsAvailable = false;         
        }     
    } 
}
按注释编辑 至于比较日期时间,请在数据列中使用datetime27作为数据类型,这将与.net datetime一样准确,根据,datetime四舍五入为.000、.003或.007秒的增量。因此,c解决方法是按照该模式将DateTime输入四舍五入到下一个数字

大概是这样的:

私有日期时间RoundUpDateTime日期时间 { int最后毫秒位数; 做 { datetime=datetime.add毫秒1; LastMillistSecondDigit=日期时间。毫秒%10; }而lastmillseconddigit!=0&&lastmillseconddigit!=3&&lastmillseconddigit!=7; 返回日期时间; }
注:我知道这是一个大的黑客。注释中有更好的解决方案,例如将数据类型更改为datetime2。但是,如果您无法更改数据库或代码,我认为此解决方案可以解决问题。

这是一个很好的解决方案。“使用datetime2是一个很好的理由,它可以更好地控制精度。”GordonLinoff表示同意。但在本例中,我使用的是一个现有的代码库/数据库,更新起来会非常痛苦。所以我想知道是否有一个解决办法。我认为你的黑客攻击应该增加4毫秒,因为有时候加3只会得到相同的值。但是,我怀疑您可能能够在数据库中做一些工作,而不是在C代码中,这可能是最安全的方法。考虑行2——检索它的唯一方法是使用“>=197查询”或“等效”。存储日期时,查询日期也会发生相同的转换。无法仅修改该查询以根据基于日期时间的比较检索第2行和第3行。或者换一种说法.197和.198在数据库中是无法区分的。@Damien_不信者-对不起,我可以看出我的背景信息会多么混乱。我希望查询数据库中存在的数据,而不是像我编写insert语句那样。所以在这种情况下,我想要的答案是3。原始日期输入来自单独的数据库查询,因此我不认为我需要担心时钟不同步。请原谅,这里有我的问题的答案吗?我看到了一堆有趣的旁注,但没有直接解决我的问题。因此,请将数据保存在数据库中的DateTime27字段中,然后您将转到SQL Server时钟。我给了他一个精确的时间方法,他不喜欢that@WalterVehoeven我很感谢你的意见,但恕我直言,你没有回答我的问题。我的问题是如何使用现有代码/数据库实现变通方法。我同意datetime2是一个更好的选择,如果你可以像我在这个答案中提到的那样更改数据库,但这不是我的问题。你将不得不测量小于timespan difference DbTime local的差异 时间>时间跨度。你在比较双打时也有同样的结果