C# 在执行datetime比较时,如何解释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,其中我的日期>='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毫秒。那感觉像是一个黑客。但它能可靠地工作吗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,其中我的日期>
注意:请假设我无法更改此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的差异 时间>时间跨度。你在比较双打时也有同样的结果