Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/268.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/ant/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# DateTimeOffset日期不包括具有结束日期的记录_C#_Sql Server 2016_Datetimeoffset - Fatal编程技术网

C# DateTimeOffset日期不包括具有结束日期的记录

C# DateTimeOffset日期不包括具有结束日期的记录,c#,sql-server-2016,datetimeoffset,C#,Sql Server 2016,Datetimeoffset,我想按日期范围获取数据库记录,包括包含结束日期范围的数据。数据库中的时间戳列是dateTime27的一种类型。日期和时间存储在UTC中。但是,我根据用户时区显示数据。为了实现这一点,我正在查找时区,然后将其转换为C.Ex.3/18/2020和3/29/2020中的BaseUtfOffset 然后,我在这里创建的DateTimeOffset参数的过程类型中传递开始日期和结束日期,以便在SQL中执行简单的select语句。返回的数据仅包括具有开始日期的记录 create table MyTable

我想按日期范围获取数据库记录,包括包含结束日期范围的数据。数据库中的时间戳列是dateTime27的一种类型。日期和时间存储在UTC中。但是,我根据用户时区显示数据。为了实现这一点,我正在查找时区,然后将其转换为C.Ex.3/18/2020和3/29/2020中的BaseUtfOffset

然后,我在这里创建的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, convert(datetime2(7), timestamp, 1)) <= '3/29/2020 12:00:00 AM -04:00'
在本例中使用:开始日期为2019年3月18日,结束日期为2020年3月29日。将日期转换为DateTimeOffset的C方法生成以下输出:

d1 = 3/18/2020 12:00:00 AM -04:00
d2 = 3/29/2020 12:00:00 AM -04:00

查询返回行的原因是因为这是正确的。您有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:00和2020-03-29 15:40:46.8500000-04:00都在2020-03-29T00:00:00-04:00之后,因此不显示


你得到的是1行,因为只有1行满足了那里的要求。

我相信你让它变得比需要的更困难了

在代码中:将TimeZoneInfo应用于用户提供的DateTime参数。由于数据被持久化为DateTime2,因此请使用在本例中匹配的参数类型System.DateTime。根据您的问题,您希望上限值包含日期,最简单的方法是在日期值中添加1,或者也可以接受24小时,并将查询更改为小于

请参阅下面的代码,您可以将其修改为存储过程。相反

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
            }
        }
    }
}

convertdatetime27,timestamp,1试图在这里实现什么?timestames已经是一个datetime2 s将其转换为一只会减慢查询速度。@Larnu,我不需要进行任何转换就得到了相同的结果。这是我最近一次尝试将日期时间转换为2020-03-29 19:40:46.8500000+00:00,这可能会奏效,但不可否认,不会。如果你想过滤一个包含日期的范围,那么你需要将时间也包括在你的上限范围内。最简单的方法是将1添加到日期,并将过滤器更改为刚好小于。示例:用户希望在日期3/18和3/29之间进行筛选。使where子句大于或等于2020-3-18,小于2020-3-30。此评论没有考虑时区,只是为了说明时间在where子句中很重要,而您目前没有对其进行说明。关于时区。如果将日期持久化为datetime2,并且日期信息为UTC,则需要将输入参数转换为UTC,然后根据这些参数进行过滤。2020-03-29 19:40:53.1000000+00:00在2020-03-29T00:00:00-04:00之后,因此convertdatetimeoffset,convertdatetime27,timestamp,1 ooo。我现在明白你刚才在评论中所指的了。所以我想我要找的是截止日期应该是2020年3月29日23:59:00 PM-04:00?我想,也许我没有解释清楚我的要求。我也会更新这个问题。我需要的是,如果用户的本地日期在日期范围内,我希望在不考虑时间的情况下包括该日期。因此,对于2020年3月18日和2020年3月29日,我希望所有记录都在该日期下,而不必担心时间。在这种情况下,我发现是我的转换导致了问题。如果您想要3月29日的所有日期,而不考虑时间,那么使用<2020-03-30T00:00:00-04:00,@smr5.Igor,您是对的。我把事情复杂化了。谢谢
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
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
            }
        }
    }
}