【问题标题】:Wrong column date format in SQL ServerSQL Server 中的列日期格式错误
【发布时间】:2025-12-21 02:40:12
【问题描述】:

我正在将我的 C# 程序中的一些数据插入 SQL Server 2012。我的表中有 datetime 类型的列。我的 C# 代码:

string date = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");
// returns 2016-04-11 11:47:05.535

当我调试我的应用程序时,我可以看到日期格式正确(与上面相同)。但是当我查看我的数据库时,这个日期是:

2016-11-04 11:47:05.537

交换月份和日期。为什么会这样?

【问题讨论】:

  • Sql server does not store date display format. 当您使用 SSMS 选择日期时间值时,它将以数据库的默认显示格式显示为字符串。试试这个SELECT DATENAME(MONTH, YourDateTimeColumn),看看你得到的月份是否正确。
  • 停止使用字符串。它们是您的格式问题的原因。在 C# 中使用 DateTime,在 SQL Server 中使用 datetime(或 datetime2)。从 C# -> SQL Server 发送数据时使用参数。只要确保您始终使用日期时间数据类型,您就不会遇到格式问题。
  • @L-Three - 但他们在 C# 中使用 string。一旦转换为字符串(在 C# SQL 中),您就会面临格式问题。
  • @L-Three - 但这里的问题是,我保证,非常好 .NET DateTime 值和 SQL Server datetime 值之间存在字符串转换.如果没有该字符串转换,OP 将不会报告“SQL”已切换日/月值。你似乎是唯一一个提到显示的人。
  • @L-Three - 不,它不会。 .NET 的 datetime 类型存储自过去某个固定点以来的 100 纳秒间隔的单个计数。它不包含格式或文化信息。 SQL Server 的 datetime 类型存储自 1900 年 1 月 1 日以来的(小数)天数,没有格式或区域性信息。 ADO.NET 了解如何在这两者之间进行转换,并且不使用任何文化或格式信息。如果您(程序员)开始将值转换成字符串或从字符串转换出,您可以引入问题。

标签: c# sql-server datetime


【解决方案1】:

你有一个坏习惯被踢成choosing the wrong data type

您应该永远将您的DateTime 值与其字符串表示形式一起存储。 SQL Server 的 datetime 类型 mapped with System.DateTime 在 .NET Framework 端。这就是为什么你应该用parameterized query直接插入你的DateTime.Now值。

但也要注意The case against DateTime.Now

另一方面,让我们分析一下你的例子..

2016-04-11 11:47:05.535
2016-11-04 11:47:05.537

忽略 datetime 类型会将毫秒部分舍入为 .000.003.007,我们能否 %100 确定这些值完全相同基于只是他们的陈述?

不,我们不能

这些表示取决于 sql server 的排序规则和区域性设置。这就是为什么你的2016-11-04 11:47:05.537可能甚至是 11 月 4 日,而不是 4 月 11 日。

【讨论】:

  • 你认为他为什么将它存储为字符串?数据库中的数据类型是 DateTime。这是文化问题,而不是数据存储问题。
  • @L-Three - 不,这是一个“在某些时候一切都必须是字符串”的问题。让 OP 摆脱那种的心态,这将解决问题。
  • @L-Three 由于 OP 在他的代码中写入了date 变量,我认为这是插入的值string。看起来 OP 的字符串具有有效格式,可以在 SQL Server 中插入 datetime 类型。但我们无法知道将插入哪个值,因为“格式”概念可能会针对不同的排序规则/文化设置生成不同的结果。这似乎不是CultureInfo 问题,因为 OP 的“格式”和结果值具有相同的格式。你不能确定这个2016-11-04的值是4th of November11th of April只是基于它的表示。
  • 如果您需要将其格式化为要在 UI 中显示的字符串,这没有问题。例如,如果在视图中使用日期,我在这里本身并没有看到错误的心态。但是你必须考虑到文化。
【解决方案2】:

我不相信这里存在实际问题,发生这种情况的原因是不同国家/地区的日期显示方式不同。尝试插入一个如果值被切换则无效的日期,例如2015 年 11 月 22 日。

在 .NET 中,您可以使用 CultureInfo MSDN Link 管理此显示,以实现英国日期/时间格式作为标准行为,您可以像这样使用它:

CultureInfo en = new CultureInfo("en-GB");

希望这会有所帮助。

【讨论】:

  • 问题不是 C# 中的日期格式,而是 SQL Server 中的问题。
  • 这就是我想说的,我不相信存在实际问题。 SQL 以美国格式存储日期,而您以 GB 格式显示日期。 SQL 并非设计为表示层,这应该在您的应用程序中处理。
  • 要测试我的理论,在您的数据库中运行此语句,您将看到正确显示的日期。 - DECLARE @d DATETIME = '04/11/2016'; SELECT FORMAT ( @d, 'd', 'en-GB' ) AS 'GB English Result'
  • 其实,“不同国家的日期存储方式不同”是完全错误的。 不同国家的日期显示方式不同,但无论本地设置如何,它们的存储方式都是一样的。