提问人:crazyTech 提问时间:11/2/2023 最后编辑:Dale KcrazyTech 更新时间:11/3/2023 访问量:60
日期时间格式无效。[...]将 nvarchar 数据类型转换为 datetime 数据类型会导致值超出范围
Invalid datetime format. [...] The conversion of a nvarchar data type to a datetime data type resulted in an out-of-range value
问:
以下是有关我们的技术开发环境的信息:
• .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” 代理
我有应用程序代码
- 将基于整数的 Unix 时间戳转换为 C# DateTimeOffset
- 我将所述 C# DateTimeOffset 转换为 C# DateTime
- 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”),
我不再收到错误。
但是,我担心的是抛出的错误是否真的取决于托管我的应用程序的服务器的区域日期和时间设置。
详细地说,我当前托管应用程序的服务器具有以下区域日期和时间设置:
因此,如果有人在主机服务器上更改了所述日期和时间格式设置,则无论我在应用程序代码中使用哪种 C# 日期时间格式,错误都可能再次出现。
因此,我想知道如果更改主机服务器的日期和时间格式设置,我的 C# 日期时间格式是否会徒劳无功。
如何对 C# 日期时间格式设置代码进行更改,使其更可靠/容错,以便无论主机服务器上的日期和时间格式设置如何,它都能正常工作?
答:
TL;博士;- 如果您正在使用或在您的数据库中,则此答案的其余部分不适用于您。DateTime2
DateTimeOffset
但是,如果使用 SQL Server 的 DateTime
数据类型并使用值的字符串表示形式,则应使用 ISO 8601 人类可读格式,
即 .DateTime
yyyy-MM-ddTHH:mm:ss
使用 Odbc 格式(与 ISO 8601 几乎相同,但日期和时间部分之间使用空格而不是 T 作为分隔符)可能会导致错误或最糟糕的错误数据,因为 SQL Server 将其转换为的方式取决于登录名* 日期格式(如果直接在查询批处理中使用 、 或隐式使用 )。yyyy-MM-dd HH:mm:ss
DateTime
SET DATEFORMAT
SET 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 上观看现场演示
评论
LOGIN