从 SQL 服务器计时器获取报告时出现问题
Problem to get report from SQL Server timer
我们经常遇到的一个问题是如何更改服务器时间以使其与客户或用户的时区相匹配。不幸的是,答案是——你不能。网络服务器只能运行一个时区,所以其他39个时区的时间都将“关闭”。
解决此问题的方法是将服务器时间转换为本地时间。 .NET 通过内置的 TimeZoneInfo class 使这一过程变得简单,可用于将一个时区转换为另一个时区。
那么我的服务器时间将与我的当地时间相差 12.30 小时,即从我的当地时间减去 12 小时 30 分钟得到我的服务器时间。我需要从服务器时间获取本地时间。如何实现?
我尝试 class:
protected DateTime GetCurrentTime()
{
DateTime serverTime = DateTime.Now;
DateTime _localTime = TimeZoneInfo.ConvertTimeBySystemTimeZoneId(serverTime, TimeZoneInfo.Local.Id, "Arab Standard Time");
return _localTime;
}
这是在服务器上获取 TimeZoneId 的方法:
protected void Page_Load(object sender, EventArgs e)
{
foreach (TimeZoneInfo zoneID in TimeZoneInfo.GetSystemTimeZones())
{
Response.Write(zoneID.Id + "<br/>");
}
}
但我不知道我做错了什么,也不知道为什么要这么做。我所拥有的只是服务器上的一个数据库并与 c# windows 应用程序连接,我尝试使用此代码来获取我今天的报告 > DATEADD(d, - 1, GETDATE())
但它在 11:30 AM
之后工作
SQL 服务器系统的本地时区与用于时间戳记录数据的时区之间似乎存在差异。我建议检查最新记录的数据并将其与 SQL 服务器系统的本地时间进行比较;这应该揭示出这样的差异。
例如,如果记录的数据以 UTC 时间戳记,那么您可以在 DATEADD(d, -1, GETUTCDATE()) 和 GETUTCDATE() 之间的时间范围内检索最近 24 小时的数据。请注意,这不一定会为您提供当地时间的午夜至午夜报告;为此,您必须首先计算从当地午夜到午夜时间的 UTC 时间范围,然后查询计算出的 UTC 时间范围。
您不应该编写关心服务器时区的代码。相反,编写适用于 UTC 时间和特定时区的代码。
你的 C# 代码应该是这样的:
DateTime dt = TimeZoneInfo.ConvertTimeBySystemTimeZoneId(DateTime.UtcNow, "Arab Standard Time");
对于 SQL,通常您应该记录基于 UTC 的值,在这种情况下根本不需要转换。但是,如果你需要转换,因为你正在存储本地值,那么你可以使用系统的当前 UTC 时间和 AT TIME ZONE
函数,如下所示:
WHERE dt > (DATEADD(d, -1, GETUTCDATE() AT TIME ZONE 'Arab Standard Time')
在这两种情况下,时区标识符 'Arab Standard Time'
最好来自变量,而不是硬编码。
我们经常遇到的一个问题是如何更改服务器时间以使其与客户或用户的时区相匹配。不幸的是,答案是——你不能。网络服务器只能运行一个时区,所以其他39个时区的时间都将“关闭”。
解决此问题的方法是将服务器时间转换为本地时间。 .NET 通过内置的 TimeZoneInfo class 使这一过程变得简单,可用于将一个时区转换为另一个时区。
那么我的服务器时间将与我的当地时间相差 12.30 小时,即从我的当地时间减去 12 小时 30 分钟得到我的服务器时间。我需要从服务器时间获取本地时间。如何实现?
我尝试 class:
protected DateTime GetCurrentTime()
{
DateTime serverTime = DateTime.Now;
DateTime _localTime = TimeZoneInfo.ConvertTimeBySystemTimeZoneId(serverTime, TimeZoneInfo.Local.Id, "Arab Standard Time");
return _localTime;
}
这是在服务器上获取 TimeZoneId 的方法:
protected void Page_Load(object sender, EventArgs e)
{
foreach (TimeZoneInfo zoneID in TimeZoneInfo.GetSystemTimeZones())
{
Response.Write(zoneID.Id + "<br/>");
}
}
但我不知道我做错了什么,也不知道为什么要这么做。我所拥有的只是服务器上的一个数据库并与 c# windows 应用程序连接,我尝试使用此代码来获取我今天的报告 > DATEADD(d, - 1, GETDATE())
但它在 11:30 AM
SQL 服务器系统的本地时区与用于时间戳记录数据的时区之间似乎存在差异。我建议检查最新记录的数据并将其与 SQL 服务器系统的本地时间进行比较;这应该揭示出这样的差异。
例如,如果记录的数据以 UTC 时间戳记,那么您可以在 DATEADD(d, -1, GETUTCDATE()) 和 GETUTCDATE() 之间的时间范围内检索最近 24 小时的数据。请注意,这不一定会为您提供当地时间的午夜至午夜报告;为此,您必须首先计算从当地午夜到午夜时间的 UTC 时间范围,然后查询计算出的 UTC 时间范围。
您不应该编写关心服务器时区的代码。相反,编写适用于 UTC 时间和特定时区的代码。
你的 C# 代码应该是这样的:
DateTime dt = TimeZoneInfo.ConvertTimeBySystemTimeZoneId(DateTime.UtcNow, "Arab Standard Time");
对于 SQL,通常您应该记录基于 UTC 的值,在这种情况下根本不需要转换。但是,如果你需要转换,因为你正在存储本地值,那么你可以使用系统的当前 UTC 时间和 AT TIME ZONE
函数,如下所示:
WHERE dt > (DATEADD(d, -1, GETUTCDATE() AT TIME ZONE 'Arab Standard Time')
在这两种情况下,时区标识符 'Arab Standard Time'
最好来自变量,而不是硬编码。