如何在月份的日期解析带有后缀“th”,“st”或“nd”的日期?

时间:2013-01-29 12:47:56

标签: c# datetime

我在使用DateTime.Parse

时遇到问题

我正在处理各种日期格式,其中一些格式为January 11thFebruary 22nd,依此类推。

DateTime.Parse会在尝试解析这些日期时抛出异常。

我想知道在DateTime中是否存在我缺少的内置功能,就像我可以设置的标志,这将使Parse以更可接受的方式运行。

我知道这可以用一个相对简单的正则表达式解决,而且我已经有一个模糊匹配我写的日期的类,但是我想知道是否有内置的方法来执行这种提取因为从长远来看,维护它比重新发明轮子更容易。

3 个答案:

答案 0 :(得分:14)

.Net框架中没有内置任何内容来解析January 11th or February 22nd等格式的日期。您必须删除后缀字符,然后才能使用DateTime.TryParseExact

对于使用后缀stth的日期,您可以使用string.Replace删除该部分,然后使用DateTime.TryParseExact。喜欢。

string str = "1st February 2013";
DateTime dtObject;
string replacedStr =  str.Substring(0,4)
                         .Replace("nd","")
                         .Replace("th","")
                         .Replace("rd","")
                         .Replace("st","")
                         + str.Substring(4);


if (DateTime.TryParseExact(replacedStr, 
                            "dd MMMMM yyyy", 
                            CultureInfo.InstalledUICulture, 
                            DateTimeStyles.None, 
                            out dtObject))
{
 //valid date
}

对于多种格式,您可以在字符串数组中指定格式,稍后您可以使用它。它返回bool值,指示解析是否成功。

来自MSDN的示例:

string[] formats= {"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"};
string[] dateStrings = {"5/1/2009 6:32 PM", "05/01/2009 6:32:05 PM", 
                        "5/1/2009 6:32:00", "05/01/2009 06:32", 
                        "05/01/2009 06:32:00 PM", "05/01/2009 06:32:00"}; 
DateTime dateValue;

foreach (string dateString in dateStrings)
{
   if (DateTime.TryParseExact(dateString, formats, 
                              new CultureInfo("en-US"), 
                              DateTimeStyles.None, 
                              out dateValue))
      Console.WriteLine("Converted '{0}' to {1}.", dateString, dateValue);
   else
      Console.WriteLine("Unable to convert '{0}' to a date.", dateString);

答案 1 :(得分:13)

这是一个非常古老的问题,但对于仍然在研究复杂的自然语言日期解析的人,我建议使用nChronic,这是一个令人惊叹的(基于ruby的)慢性日期解析器的.NET端口。

它的来源是: nChronic Github

它也是Nuget的慢性病:Chronic in Nuget

使用此库的一些非常简单的示例代码如下:

using Chronic;
var parser = new Chronic.Parser ();
Span ParseObj;
DateTime ParsedDateTime;
ParseObj = parser.Parse ("January 11th");
ParsedDateTime = ParseObj.Start;

以下是一些可以处理的例子:

<强>简单

  • 星期四
  • 11月
  • 夏季
  • 星期五
  • 13:00
  • mon 2:35
  • 4pm
  • 10到8
  • 10月2日
  • 2点半
  • 早上6点
  • 周五下午1点
  • 晚上7点开始
  • 昨天
  • 今天
  • 明天
  • 上周
  • 下周
  • 本周二
  • 下个月
  • 去年冬天
  • 今天早上
  • 昨晚
  • 第二次
  • 昨天凌晨4点
  • 上周五20:00
  • 上周二周二
  • 明天下午6:45
  • 下午
  • 昨天
  • 星期四上周

<强>复合

  • 3年前
  • 一年前
  • 5个月前
  • 7小时前
  • 从现在起7天
  • 1周后
  • 在3小时内
  • 1年前的明天
  • 3个月前星期六下午5点
  • 明天中午前7小时
  • 11月3日星期三
  • 明年第3个月
  • 9月3日星期四
  • 上周第4天
  • 2010年6月14日晚上11点
  • 可能是97年7月7日凌晨三点。

具体日期

  • 1月5日
  • 6月22日
  • 2017年5月5日
  • 二月二十一日
  • dec 25
  • 5月27日
  • 2006年10月
  • oct 06
  • 2010年1月3日
  • 2004年2月14日
  • 2004年2月14日
  • 3月2000
  • 17年4月17日
  • 1979年5月27日
  • 27/5/1979
  • 05/06
  • 1979年5月27日
  • 星期五
  • 5
  • 4:00
  • 17:00
  • 0800

特定时间(上述许多内容增加了时间)

  • 1月5日晚上7点
  • 6月22日上午8点
  • 1979-05-27 05:00:00
  • 03/01/2012 07:25:09.234567

答案 2 :(得分:1)

我在这里遇到过类似的问题

  stringdate="August 19th 2000" 
  string pattern = @"\b(\d+)(?:st|nd|rd|th)\b";
  Regex rgx = new Regex(pattern);
  DateTime.Parse(String.Format("{0:MMMM,  d, yyyy}", rgx.Replace(stringdate, "$1"))  
  **result**    {19/08/2000 00:00:00}   System.DateTime

来自Microsoftregex to remove ordinals以及How can I visualize the way various DateTime formats will display?