SQL Server插入带时区JSON DateTime报错:日期时间字符串转换失败
解决带时区的JSON DateTime插入SQL Server DATETIME字段的问题
你遇到的错误是因为SQL Server的DATETIME类型不直接支持带时区偏移的时间格式(比如2018-05-04T10:31:31.134+06:30里的+06:30和T分隔符),下面给你几种可靠的解决方法:
方法一:通过DATETIMEOFFSET中转转换
SQL Server的DATETIMEOFFSET类型原生支持带时区的时间格式,我们可以先把JSON里的时间字符串转成这个类型,再转换成DATETIME:
-- 单值转换示例 SELECT CONVERT(DATETIME, TRY_CONVERT(DATETIMEOFFSET, '2018-05-04T10:31:31.134+06:30')) AS ConvertedDateTime; -- 如果需要转成UTC时间再插入 SELECT CONVERT(DATETIME, SWITCHOFFSET(TRY_CONVERT(DATETIMEOFFSET, '2018-05-04T10:31:31.134+06:30'), '+00:00')) AS UtcDateTime;
TRY_CONVERT会尝试安全转换,避免转换失败时整个查询报错;SWITCHOFFSET可以把带时区的时间转换到指定时区(这里是UTC)。
方法二:处理JSON数组批量插入
如果是处理多对象JSON数组,用OPENJSON配合转换逻辑会更高效:
DECLARE @json NVARCHAR(MAX) = N'[ {"Id": 1, "EventTime": "2018-05-04T10:31:31.134+06:30"}, {"Id": 2, "EventTime": "2018-05-05T11:45:22.456-05:00"} ]'; -- 插入到目标表 INSERT INTO YourTargetTable (Id, EventTimeColumn) SELECT Id, -- 转成UTC后再插入DATETIME字段 CONVERT(DATETIME, SWITCHOFFSET(TRY_CONVERT(DATETIMEOFFSET, EventTime), '+00:00')) AS ConvertedTime FROM OPENJSON(@json) WITH ( Id INT, EventTime NVARCHAR(50) -- 先把JSON中的时间读取为字符串 );
方法三:按时区转换为本地时间(SQL Server 2016+)
如果需要把带时区的时间转换为服务器所在时区的时间,可以用AT TIME ZONE语法:
SELECT CAST(TRY_CONVERT(DATETIMEOFFSET, '2018-05-04T10:31:31.134+06:30') AT TIME ZONE 'China Standard Time' -- 替换成你需要的时区名称 AS DATETIME) AS LocalServerTime;
你可以通过查询sys.time_zone_info获取SQL Server支持的时区名称列表。
注意事项
- 尽量避免用字符串截取(比如
REPLACE/LEFT)的方式处理时间格式,这种方法兼容性差,遇到时间精度变化或时区格式异常时容易出错; - 如果你的SQL Server版本低于2012,
TRY_CONVERT不可用,可以改用CONVERT并指定格式代码127(ISO8601带时区格式):SELECT CONVERT(DATETIME, CONVERT(DATETIMEOFFSET, '2018-05-04T10:31:31.134+06:30', 127));
内容的提问来源于stack exchange,提问作者Raziel Naing
相关产品推荐
相关产品推荐

