使用C#将DateTime格式转换为SQL格式

147

我想保存C#中的当前日期时间格式,并将其转换为SQL Server日期格式,例如yyyy-MM-dd HH:mm:ss,以便在我的UPDATE查询中使用。

这是我的第一份代码:

DateTime myDateTime = DateTime.Now;
string sqlFormattedDate = myDateTime.Date.ToString("yyyy-MM-dd HH:mm:ss");

日期的输出正常,但时间总是“12:00:00”,因此我将代码更改为以下内容:

string sqlFormattedDate = myDateTime.Date.ToString("yyyy-MM-dd") + " " + 
myDateTime.TimeOfDay.ToString("HH:mm:ss");

我遇到了编译错误:

未处理的FormatException

建议我进行解析。根据我在StackOverflow上的研究,我尝试对我的代码进行如下更改:

string sqlFormattedDate = myDateTime.Date.ToString("yyyy-MM-dd") + " " + 
myDateTime.Parse.TimeOfDay.ToString("HH:mm:ss");
或者
string sqlFormattedDate = myDateTime.Date.ToString("yyyy-MM-dd") + " " + 
myDateTime.tryParse.TimeOfDay.ToString("HH:mm:ss");

但告诉我这是一种不适用于给定情境的方法。我尝试寻找解决方案已经卡了两个小时了。我在C#上还有点新,请你帮帮我好吗?


你看过DateTime.TryParseExact吗? - Tim
https://dev59.com/xHI95IYBdhLWcg3wsQP9 - Kamil Budziewski
3
为什么不使用参数来更新DateTime,或者您是将其存储为字符串?ToStringDate上的使用会暗示时间始终为12:00:00 - V4Vendetta
3
你应该使用一个类型为 DATETIME 的参数化查询,这样就可以避免在字符串表示和日期格式之间来回转换的繁琐操作! - marc_s
5
就像其他人所说的,使用参数并将所有内容保持为 datetime 是一个不错的开始。更好的是,你为什么要传递服务器当前时间呢?它有一个 GETDATE() 函数可以完全在服务器端调用。 - Damien_The_Unbeliever
15个回答

300

尝试以下内容

DateTime myDateTime = DateTime.Now;
string sqlFormattedDate = myDateTime.ToString("yyyy-MM-dd HH:mm:ss.fff");

非常感谢,我正在尝试字符串sqlFormattedDate = myDateTime.DateTime...出于某种原因,这就是我想要实现的。 - Ace Caserya
我的stackoverflow搜索结果总是引用了一个错误的参考文献,尽管这个问题已经被回答了好几次,像我这样的新手也无法理解。对不起,我会尽快关闭这个问题。 - Ace Caserya
1
我认为C#中的“Sortable”格式做了同样的事情。因此,你只需执行myDateTime.ToString("s")即可。 - ProVega
3
是的,在CAST和CONVERT(Transact-SQL)的官方页面中,他们使用“ODBC规范”一词来表示日期与时间之间带有空格分隔符的形式,使用“ISO8601”一词来表示日期与时间之间带有"T"作为分隔符的形式。但是,这两种形式都可以隐式转换(并且正确地转换)为datetime类型。 - Jeppe Stig Nielsen
3
请使用 myDateTime.ToString("o"); 代替此答案,它比此答案的精度更高,并且在文档中被字面描述为“往返日期/时间模式”。请参见:https://learn.microsoft.com/en-us/dotnet/standard/base-types/standard-date-and-time-format-strings。 - Deantwo
显示剩余3条评论

59
使用标准的日期时间格式“s”也可以确保国际化兼容性(MM/dd与dd/MM):
myDateTime.ToString("s");

=> 2013-12-31T00:00:00

完整选项:(代码:示例结果)

d: 6/15/2008 
D: Sunday, June 15, 2008 
f: Sunday, June 15, 2008 9:15 PM 
F: Sunday, June 15, 2008 9:15:07 PM 
g: 6/15/2008 9:15 PM 
G: 6/15/2008 9:15:07 PM 
m: June 15 
o: 2008-06-15T21:15:07.0000000 
R: Sun, 15 Jun 2008 21:15:07 GMT 
s: 2008-06-15T21:15:07 
t: 9:15 PM 
T: 9:15:07 PM 
u: 2008-06-15 21:15:07Z 
U: Monday, June 16, 2008 4:15:07 AM 
y: June, 2008 

'h:mm:ss.ff t': 9:15:07.00 P 
'd MMM yyyy': 15 Jun 2008 
'HH:mm:ss.f': 21:15:07.0 
'dd MMM HH:mm:ss': 15 Jun 21:15:07 
'\Mon\t\h\: M': Month: 6 
'HH:mm:ss.ffffzzz': 21:15:07.0000-07:00

支持 .NET Framework: 4.6、4.5、4、3.5、3.0、2.0、1.1、1.0
参考资料:DateTime.ToString 方法


2
这不够细致(缺少毫秒),在依赖日期排序的查询中会给你带来麻烦。 - reijerh
要同时获取小时和分钟,您可以使用以下转换:string sqlFormattedDate = YourDate.ToString("yyyy-MM-ddTHH:mm:ss", System.Globalization.CultureInfo.InvariantCulture); - netfed
2
请使用myDateTime.ToString("o");,它包含毫秒并在文档中被描述为“往返日期/时间模式”。 "s"仅被描述为“可排序日期/时间模式”,因此我不建议将其用于此。参见:https://learn.microsoft.com/en-us/dotnet/standard/base-types/standard-date-and-time-format-strings。 - Deantwo

13

让我们使用内置的SqlDateTime类

new SqlDateTime(DateTime.Now).ToSqlString()

但仍需检查空值。否则将抛出溢出异常。

new SqlDateTime(DateTime.MinValue).ToSqlString()

SqlDateTime溢出。 必须介于1753年1月1日上午12:00:00和9999年12月31日下午11:59:59之间。


我更喜欢这个解决方案能够为我工作,但是当我使用它时,出现了“将 nvarchar 数据类型转换为 datetime 数据类型导致超出范围的值”错误,所以我不得不采用 .ToString() 解决方案。 - Kadaj
有趣,我想试一下,你能把你用的输入日期值加入代码吗? - mkb

11

已经给出了正确答案“使用参数”。将日期格式化并将其作为字符串传递到SQL Server可能会导致错误,因为它取决于设置如何在服务器端解释日期。在欧洲,我们写'1.12.2012'表示2012年12月1日,而在其他国家,这可能被视为1月12日。

当直接在SSMS中发出语句时,我使用格式yyyymmdd,这似乎是相当通用的。到目前为止,在我所工作的各个安装中都没有遇到任何问题。

还有另一种很少使用的格式,有点奇怪,但适用于所有版本:

select { d '2013-10-01' }

将返回2013年10月的第一天。

select { ts '2013-10-01 13:45:01' }

将于10月1日下午1:45:01返回

我强烈建议使用参数,永远不要通过粘贴自己编写的格式化语句片段来格式化自己的SQL代码。这会导致SQL注入以及奇怪的错误(格式化浮点值是另一个潜在问题)。


6
您的问题出在“日期”属性上,它将 DateTime 截断为仅包含日期。 您可以将转换放在这里:
DateTime myDateTime = DateTime.Now;
string sqlFormattedDate = myDateTime.ToString("yyyy-MM-dd HH:mm:ss"); // <- No Date.ToString()!

4

您的第一段代码将通过以下方式工作

DateTime myDateTime = DateTime.Now;
string sqlFormattedDate = myDateTime.ToString("yyyy-MM-dd HH:mm:ss"); //Remove myDateTime.Date part 

3

如果你想在表中存储当前日期,可以使用以下方法:

GETDATE();

或将此函数作为参数传递,例如:

'update tblname set curdate=GETDATE() where colname=123'


它甚至作为SQL表上的默认值更有效。除非您使用的框架不允许使用默认值。 - Deantwo

1
我要找的答案是:


DateTime myDateTime = DateTime.Now;
string sqlFormattedDate = myDateTime.ToString("yyyy-MM-dd HH:mm:ss");

我还学到了另一种方法,可以这样做:

DateTime myDateTime = DateTime.Now;
string sqlFormattedDate = myDateTime.ToString(myCountryDateFormat);

其中myCountryDateFormat可以根据需求进行更改。

请注意,“此问题可能已经在这里有答案”的标记并没有真正回答问题,因为您可以看到它使用了“.Date”,而没有省略它。对于.NET的新程序员来说,这相当令人困惑。


1
为什么不完全跳过字符串呢:

(原文中的HTML标签已被保留)
SqlDateTime myDateTime = DateTime.Now;

1
你的问题在于 Date 属性只保留了日期部分而舍弃了时间部分。你可以按照以下方式进行转换:
DateTime myDateTime = DateTime.Now;

string sqlFormattedDate = myDateTime.ToString("yyyy-MM-dd HH:mm:ss");

谢谢。正是我想要的 ;) 惊讶微软没有添加一个标志或命令来更简洁地完成这个任务。 - Zeek2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接