DateTimeOffset日期不包括带有结束日期的记录

我想按日期范围(包括包含结束日期范围的数据)获取数据库记录。数据库中的TimeStamp列是dateTime2(7)的类型。日期和时间存储在UTC中。但是,我正在根据用户时区显示数据。为此,我要查找时区,然后将其转换为BaseUtfOffset中的C#。例如3/18/20203/29/2020

 var newOffSetDate = TimeZoneInfo.FindSystemTimeZoneById(timeZoneName);

 DateTimeOffset d1 = new DateTimeOffset(Convert.ToDateTime(date1),newOffSetDate.BaseUtcOffset);
 DateTimeOffset d2 = new DateTimeOffset(Convert.ToDateTime(date2),newOffSetDate.BaseUtcOffset);

然后我在此处创建的过程(DateTimeOffset参数的类型)中传递开始和结束日期,以在SQL中执行简单的select语句。返回的数据仅包括带有开始日期的记录。

create table MyTable
(
  Id int Primary Key Identity(1,1),[TimeStamp] datetime2(7) not null
)

insert into MyTable(TimeStamp) values('2020-03-29 19:40:46.8500000')
insert into MyTable(TimeStamp) values('2020-03-29 19:40:53.1000000')
insert into MyTable(TimeStamp) values('2020-03-18 17:15:48.2600000')

select * from MyTable
where
convert(datetimeoffset,convert(datetime2(7),timestamp,1)) >= '3/18/2020 12:00:00 AM -04:00' and 
convert(datetimeoffset,1)) <= '3/29/2020 12:00:00 AM -04:00'

例如,在上述情况下,我应该获得所有记录,但是我仅获得一条记录。

2020-03-18 17:15:48.2600000

DateTimeOffset中产生的C#的格式是否会影响结果?还是我遗漏了某些内容?

SQLFIDDLE

更新:

存储过程参数:

,@StartDate     DateTimeOffset  = NULL,@EndDate       DateTimeOffset  = NULL

在示例中使用:开始日期3/18/2019和结束日期3/29/2020。将日期转换为DateTimeOffset的C#方法产生以下输出:

d1 = 3/18/2020 12:00:00 AM -04:00
d2 = 3/29/2020 12:00:00 AM -04:00
vi324 回答:DateTimeOffset日期不包括带有结束日期的记录

我相信您正在使它变得更加困难。

在您的代码中:将TimeZoneInfo应用于用户提供的DateTime参数。由于数据以DateTime2的形式持久保存,因此请使用在这种情况下System.DateTime匹配的参数类型。根据您的问题,您希望上限值包含在内,使用Dates最简单的方法是在Date值上加上1(或者也可以使用24 Hours)并将查询更改为 less 比。

请参见下面的代码,您可以将其修改为存储的proc。代替。

public void Test(DateTime argStartDate,DateTime argEndDate)
{
    var newOffSetDate = System.TimeZoneInfo.FindSystemTimeZoneById("");

    DateTime startParam = new DateTimeOffset(argStartDate,newOffSetDate.GetUtcOffset(argStartDate)).UtcDateTime;
    DateTime endParam = new DateTimeOffset(argEndDate,newOffSetDate.GetUtcOffset(argEndDate)).UtcDateTime;

    endParam = endParam.AddDays(1);

    const string query = "SELECT [column1],[column2],... FROM [YourTable] WHERE [TimeStamp] >= @start AND [TimeStamp] < @end";
    using (var con = new System.Data.SqlClient.SqlConnection(""))
    using (var com = new System.Data.SqlClient.SqlCommand(query,con))
    {
        com.Parameters.Add("@start",SqlDbType.DateTime2).Value = startParam;
        com.Parameters.Add("@end",SqlDbType.DateTime2).Value = endParam;
        con.Open();
        using (var reader = com.ExecuteReader())
        {
            while (reader.Read())
            {
                // do stuff
            }
        }
    }
}
,

您的查询返回行的原因是因为这是正确的。您有3次,您说的是UTC:

2020-03-29 19:40:46.8500000+00:00
2020-03-29 19:40:53.1000000+00:00
2020-03-18 17:15:48.2600000+00:00

因此让我们将它们转换为-04:00(即EDT):

2020-03-29 15:40:46.8500000-04:00
2020-03-29 15:40:53.1000000-04:00
2020-03-18 13:15:48.2600000-04:00

然后您要查看时间是在 2020-03-18T00:00:00-04:00之后还是在之后 2020-03-29T00:00:00-04:00

2020-03-18 13:15:48.2600000-04:00既在2020-03-18T00:00:00-04:00之后,又在2020-03-29T00:00:00-04:00之前,因此被显示。另一方面, 2020-03-29 15:40:53.1000000-04:002020-03-29 15:40:46.8500000-04:00都在之后 2020-03-29T00:00:00-04:00,因此不会显示。

您将获得1行,因为其中只有1行满足WHERE

本文链接:https://www.f2er.com/2450100.html

大家都在问