日期时间格式无效。[...]将 nvarchar 数据类型转换为 datetime 数据类型会导致值超出范围

Invalid datetime format. [...] The conversion of a nvarchar data type to a datetime data type resulted in an out-of-range value

提问人:crazyTech 提问时间:11/2/2023 最后编辑:Dale KcrazyTech 更新时间:11/3/2023 访问量:60

问:

以下是有关我们的技术开发环境的信息:

• .NET 6 • C# 10 • Hasura GraphQL v2.6.2-pro.1 • Micrsoft SQL Server 2019 • Visual Studio 2022 • “GraphQL” version=“7.3.1” 代理 • “GraphQL.Client” version=“5.1.1” 代理




• “GraphQL.Client.Serializer.Newtonsoft” version=“5.1.1” 代理

我有应用程序代码

  1. 将基于整数的 Unix 时间戳转换为 C# DateTimeOffset
  2. 我将所述 C# DateTimeOffset 转换为 C# DateTime
  3. C# DateTime 值将转换为基于字符串的 DateTime 格式

下面是有问题的代码:

_DateCreated = DateTimeOffset
    .FromUnixTimeMilliseconds(emailEvent.TimeStamp)
    .DateTime
    .ToString("dd-MMM-yyyy hh:mm:ss tt");

不幸的是,当我运行上述代码时,出现以下错误:

{“错误 (1)\r\n1:数据异常。日期时间格式无效。 [Microsoft][适用于 SQL Server 的 ODBC 驱动程序 18][SQL 服务器]转换 的 nvarchar 数据类型转换为 datetime 数据类型,导致 超出范围的值。\r\n“}

我在互联网上搜索了一下,看到了这个帖子:

https://stackoverflow.com/a/2307624/1338998

在上述帖子中,其中一位评论者陈述如下:

我习惯过的从 .net 到 sql 的最安全的“日期时间”格式 date 为“yyyy-MM-dd HH:mm:ss.fff”。PK :-)

因此,我更改了代码,使日期时间的字符串格式与以下重构代码中不同:

_DateCreated = DateTimeOffset
    .FromUnixTimeMilliseconds(emailEvent.TimeStamp)
    .DateTime
    .ToString("yyyy-MM-dd HH:mm:ss.fff");

从本质上讲,我将字符串的日期时间格式从:

..............DateTime.ToString(“dd-MMM-yyyy hh:mm:ss tt”)

......................DateTime.ToString(“yyyy-MM-dd HH:mm:ss.fff”),

我不再收到错误。
但是,我担心的是抛出的错误是否真的取决于托管我的应用程序的服务器的区域日期和时间设置。

详细地说,我当前托管应用程序的服务器具有以下区域日期和时间设置:

enter image description here

因此,如果有人在主机服务器上更改了所述日期和时间格式设置,则无论我在应用程序代码中使用哪种 C# 日期时间格式,错误都可能再次出现。

因此,我想知道如果更改主机服务器的日期和时间格式设置,我的 C# 日期时间格式是否会徒劳无功。

如何对 C# 日期时间格式设置代码进行更改,使其更可靠/容错,以便无论主机服务器上的日期和时间格式设置如何,它都能正常工作?

sql-server 日期时间

评论

0赞 siggemannen 11/2/2023
你确定这是出错的实际代码吗?因为错误来自 sql server,而您的代码看起来很简单 c#
0赞 crazyTech 11/2/2023
当我将格式化 DateTime String 值的 C# 代码更改为“yyyy-MM-dd HH:mm:ss.fff”时,错误消失了。这就是我所知道的。
1赞 Thom A 11/2/2023
您的错误表明 SQL Server,但您的问题表明是 PostgreSQL。它是什么?
3赞 Thom A 11/2/2023
将日期时间值传递给 SQL 查询,而不是字符串。如果该值是日期时间,则不能出现日期时间的转换错误。
1赞 Thom A 11/2/2023
顺便说一句,设备上用户的区域设置与 SQL Server 解释文本字符串的方式无关;这由会话日期格式设置定义,该设置通常与 S 语言设置相关联。LOGIN

答:

1赞 Zohar Peled 11/2/2023 #1

TL;博士;- 如果您正在使用或在您的数据库中,则此答案的其余部分不适用于您。DateTime2DateTimeOffset

但是,如果使用 SQL Server 的 DateTime 数据类型并使用值的字符串表示形式,则应使用 ISO 8601 人类可读格式,
即 .
DateTimeyyyy-MM-ddTHH:mm:ss

使用 Odbc 格式(与 ISO 8601 几乎相同,但日期和时间部分之间使用空格而不是 T 作为分隔符)可能会导致错误或最糟糕的错误数据,因为 SQL Server 将其转换为的方式取决于登录名* 日期格式(如果直接在查询批处理中使用 、 或隐式使用 )。yyyy-MM-dd HH:mm:ssDateTimeSET DATEFORMATSET LANGUAGE

*login 表示执行查询的 SQL Server 登录名。

这里有一些代码来说明我的意思:

DECLARE @Iso varchar(20) = '2023-09-13T16:18:32',
        @Odbc varchar(16) ='2023-09-13 16:18:32';

SELECT TRY_CAST(@Iso As DateTime) As Iso,
       TRY_CAST(@Odbc As DateTime) As Compact;

SET DateFormat YMD;

SELECT TRY_CAST(@Iso As DateTime) As Iso,
       TRY_CAST(@Odbc As DateTime) As Compact;

SET DateFormat YDM;

SELECT TRY_CAST(@Iso As DateTime) As Iso,
       TRY_CAST(@Odbc As DateTime) As Compact;

其结果是:

ISO系列 紧凑的
2023-09-13 16:18:32.000 2023-09-13 16:18:00.000

(日期格式 YMD)

ISO系列 紧凑的
2023-09-13 16:18:32.000 2023-09-13 16:18:00.000

(日期格式 YDM)

ISO系列 紧凑的
2023-09-13 16:18:32.000

您可以在 db<>fiddle 上观看现场演示