我已经日期和时间在一个字符串格式化像一个:解析字符串的DateTime在C#
"2011-03-21 13:26" //year-month-day hour:minute
如何可以解析它System.DateTime
?
如果可能,我想使用DateTime.Parse()
或DateTime.ParseExact()
等功能,以便能够手动指定日期格式。
我已经日期和时间在一个字符串格式化像一个:解析字符串的DateTime在C#
"2011-03-21 13:26" //year-month-day hour:minute
如何可以解析它System.DateTime
?
如果可能,我想使用DateTime.Parse()
或DateTime.ParseExact()
等功能,以便能够手动指定日期格式。
DateTime.Parse()
将尝试找出给定日期的格式,它通常会做得很好。如果你能保证日期总是会在一个给定的格式,那么你可以使用ParseExact()
:
string s = "2011-03-21 13:26";
DateTime dt =
DateTime.ParseExact(s, "yyyy-MM-dd HH:mm", CultureInfo.InvariantCulture);
(但是请注意,它通常是使用更安全的的TryParse方法之一,以防日期不是预期的格式)
构建格式化字符串时一定要检查Custom Date and Time Format Strings,尤其要注意字母和大小写(即“MM”和“mm”意思是非常不同的东西)。
对于C#格式化字符串另一个有用的资源是String Formatting in C#
var dateStr = @"2011-03-21 13:26";
var dateTime = DateTime.ParseExact(dateStr, "yyyy-MM-dd HH:mm", CultureInfo.CurrentCulture);
看看这个link其他格式字符串!
HH =小时,ss =秒...... – 2011-03-20 02:10:18
DateTime.Parse()应该适用于该字符串格式。参考:
http://msdn.microsoft.com/en-us/library/1k1skd40.aspx#Y1240
是它抛出一个出现FormatException你吗?
把一个人类可读的字符串的值到.NET的DateTime有这样的代码:
DateTime.ParseExact("April 16, 2011 4:27 pm", "MMMM d, yyyy h:mm tt", null);
由于我后来解释,我总是会青睐TryParse
和TryParseExact
方法。因为他们是有点笨重的使用,我写了扩展方法这使得解析容易得多:
var dtStr = "2011-03-21 13:26";
DateTime? dt = dtStr.toDate("yyyy-MM-dd HH:mm");
不像Parse
,ParseExact
等它不会抛出异常,并允许您通过
if (dt.HasValue) { // continue processing } else { // do error handling }
转换是否成功(在这种情况下dt
有您可以通过dt.Value
访问的值)或者没有(在这种情况下,它是null
)。
,即使允许使用快捷键优雅像“猫王” - 运算符?.
,例如:
int? year = dtStr?.toDate("yyyy-MM-dd HH:mm")?.Year;
在这里,你还可以使用year.HasValue
检查,如果转换成功,如果没有成功,则year
将包含null
,否则为该日期的年份部分。如果转换失败,则不会抛出异常。
public static class Extensions
{
public static DateTime? toDate(this string dateTimeStr, string[] dateFmt)
{
// example: var dt = "2011-03-21 13:26".toDate(new string[]{"yyyy-MM-dd HH:mm",
// "M/d/yyyy h:mm:ss tt"});
const DateTimeStyles style = DateTimeStyles.AllowWhiteSpaces;
if (dateFmt == null)
{
var dateInfo = System.Threading.Thread.CurrentThread.CurrentCulture.DateTimeFormat;
dateFmt=dateInfo.GetAllDateTimePatterns();
}
DateTime? result = null;
DateTime dt;
if (DateTime.TryParseExact(dateTimeStr, dateFmt,
CultureInfo.InvariantCulture, style, out dt)) result = dt;
return result;
}
public static DateTime? toDate(this string dateTimeStr, string dateFmt=null)
{
// example: var dt="2011-03-21 13:26".toDate("yyyy-MM-dd HH:mm");
// or simply var dt="2011-03-21 13:26".toDate();
// call overloaded function with string array param
string[] dateFmtArr = dateFmt == null ? null : new string[] { dateFmt };
return toDate(dateTimeStr, dateFmtArr);
}
}
更新:.toDate()
(不带参数)现在默认线程的当前文化的所有常见的日期/时间模式。
注意我们需要result
和dt
在一起,因为TryParseExact
不允许使用我们打算返回的DateTime?
。 在C#7版你可以简化toDate
功能的位,如下所示:
// in C#7 only: "DateTime dt;" - no longer required, declare implicitly
if (DateTime.TryParseExact(dateTimeStr, dateFmt,
CultureInfo.InvariantCulture, style, out var dt)) result = dt;
(这也将被允许写out DateTime dt
代替out var dt
。)
实施例:
var dtStr="2011-03-21 13:26";
var dt=dtStr.toDate("yyyy-MM-dd HH:mm");
if (dt.HasValue)
{
Console.WriteLine("Successful!");
// ... dt.Value now contains the converted DateTime ...
}
else
{
Console.WriteLine("Invalid date format!");
}
正如你所看到的,这个例子只是查询dt.HasValue
来查看转换成功与否。作为额外的奖励,TryParseExact允许指定严格的DateTimeStyles
,以便您确切知道是否已传递适当的日期/时间字符串。
N.B.重载函数允许您传递有效格式数组,用于解析/转换日期,如here(TryParseExact
直接支持这个)。
string[] dateFmt = {"M/d/yyyy h:mm:ss tt", "M/d/yyyy h:mm tt",
"MM/dd/yyyy hh:mm:ss", "M/d/yyyy h:mm:ss",
"M/d/yyyy hh:mm tt", "M/d/yyyy hh tt",
"M/d/yyyy h:mm", "M/d/yyyy h:mm",
"MM/dd/yyyy hh:mm", "M/dd/yyyy hh:mm"};
var dtStr="5/1/2009 6:32 PM";
var dt=dtStr.toDate(dateFmt);
然而,为了保持代码的短,我只用TryParseExact的字符串数组超载,因为它没有一个通用的参数工作。
高级例如:
可以使用??
运营商默认为自动防故障的格式,例如
var dtStr = "2017-12-30 11:37:00";
var dt = (dtStr.toDate()) ?? dtStr.toDate("yyyy-MM-dd HH:mm:ss");
在这种情况下,.toDate()
将使用共同的地方文化的日期格式,如果所有这些失败,它会尝试使用ISO standard格式"yyyy-MM-dd HH:mm:ss"
作为后备。这样,扩展功能可以轻松“链接”不同的后备格式。
最后,下面是关于背景的一些评论。为什么我这样写它的原因):我在此扩展方法宁愿TryParseExact
,因为你避免异常处理 - 你可以read in Eric Lippert's article about exceptions为什么你应该使用的TryParse而不是解析,我引用了他有关该主题:2)
这不幸设计决策1) [注释:到 让Parse方法抛出异常]是如此令人烦恼的是当然 框架团队不久之后实施了TryParse这是正确的事情。
确实如此,但TryParse
和TryParseExact
都还比舒适的少了很多使用方法:他们强迫你使用一个未初始化的变量作为out
参数,不能可为空并且当你转换你需要评估布尔返回值 - 要么立即使用if
语句,要么必须将返回值存储在其他布尔变量中,以便稍后执行检查。如果不知道转换是否成功,您不能只使用目标变量。
你只是想知道转换是否成功与否(当然如果值是成功的)大多数情况下,这样一个为空的目标变量这使所有的信息将是可取的,多更优雅 - 因为整个信息只是存储在一个地方:这是一致的,易于使用,而且更不容易出错。
我写的扩展方法确实如此(它也显示了如果你不打算使用它,你每次都要写什么样的代码)。
我认为.toDate(strDateFormat)
的好处是它看起来简单而干净 - 像原来的DateTime.Parse
一样简单 - 但能够检查转换是否成功,并且不会抛出异常。
1)这是怎么意思是异常处理(即try { ... } catch(Exception ex) { ...}
块) - 当你使用解析,因为如果无效的字符串被解析它会抛出一个异常,是必要的 - 在这种情况下不仅是不必要的,而且令人讨厌,并且使代码复杂化。 TryParse避免了所有这些,因为我提供的代码示例正在显示。
2)埃里克利珀是著名StackOverflow fellow,在微软工作作为对C#编译器团队主要开发了几年。
您还可以使用XmlConvert.ToDateString
VAR dateStr = “2011-03-21 13:26”; var parsedDate = XmlConvert。ToDateTime(dateStr,“yyyy-MM-dd hh:mm”);
这是好事,指定的日期种类,像
变种anotherParsedDate = DateTime.ParseExact(dateStr, “YYYY-MM-DD HH:MM”,CultureInfo.InvariantCulture,DateTimeStyles.AssumeUniversal);
关于不同解析选项的更多细节http://amir-shenodua.blogspot.ie/2017/06/datetime-parsing-in-net.html
那么,为什么你不使用DateTime.Parse? – 2011-03-20 02:06:22
我是downvoters之一。这是因为你原来的问题(http://stackoverflow.com/revisions/3c6789f2-8a6b-4557-bafc-1b8eb4d5f8c4/view-source)表示你想使用DateTime.Parse(),但你没有说明为什么你无法使用它。这使得它看起来像是一个无稽之谈,特别是因为一个简单的检查会清楚地表明cacois是正确的:你的字符串“2011-03-21 13:26”对于DateTime.Parse()不是问题。最后,您在原始问题中没有提及ParseExact()。你一直等到* Mitch的回答之后,在编辑中添加这个。 – anon 2011-03-20 04:31:41
我只是喜欢那些没有给出任何理由的评论性问题。 – Hooch 2015-04-21 11:46:41