c# - 在执行日期时间比较时,如何解决日期时间缺乏毫秒精度的问题?
问题描述
背景
我最近了解到SQL Server 的 datetime 类型只存储大约 1/300 秒的时间。
因此,鉴于这些数据:
create table datetime_test (id int, my_date datetime);
insert into datetime_test (id, my_date) values
(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)
像预期的那样:
select id from datetime_test where my_date >= '2020-12-11 17:14:07.198';
原因是该日期时间的毫秒部分实际上存储为.197
:
-- Result: 2020-12-11 17:14:07.197
select convert(datetime, '2020-12-11 17:14:07.198');
我的问题
我正在处理使用 SQL 来比较日期时间的现有 c# 代码>=
。像这样的东西:
public Foo GetMyColumn(DateTime inputDatetime)
{
// ...
}
select my_column
from my_table
where my_datetime >= @inputDatetime
我正在尝试重用此 c# 方法来执行排他比较...相当于 using >
. 我怎样才能做到这一点?
我最初的尝试是向日期时间输入(在 c# 中)添加一个毫秒,但由于上述精度问题,这将不起作用。我想我可以增加 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;
}
}
}
#edit 根据评论 比较日期时间,使用 datetime2(7) 作为数据列中的数据类型,这将与 .net datetime 一样准确
推荐阅读
- c# - Vb.Net:用户控件Datagridview列不序列化
- r - 带标准差的线图
- postgresql - PostgreSQL lower() 和 upper() 不适用于某些土耳其语字符
- c++ - 如何将 R 中的函数转换为 Rcpp?
- java - 无法使用“CsvParser”抽象类映射解析 CSV,但可以使用 JSON 映射器
- pine-script - 如何正确绘制 Renko 条?
- winapi - Winapi 消息框图标位图
- python - 如果满足条件,如何删除熊猫数据框中的特定行
- javascript - 在尝试记录 this.state 更新值之后,刚刚在 console.log 中评估了下面的值
- loops - Cypher - 如何在循环中多次调用一个过程?