使用DateTime.TryParseExact解析非标准日期格式

嗨我试图解析日期字符串,如“1012012”,“2012年1月1日”。

  1. 阅读Api它说使用d,%d,其中日期没有前导0.不能让它适用于像“1012012”这样的日期

  2. 试图用“d MMM YYYY”作为“2012年1月1日”,我怎么用’st’,’th’有效?

    using System; using System.IO; using System.Globalization; namespace test { class Script { static public void Main(string [] args) { //String dateString = "9022011"; // q1 String dateString = "9th February 2011"; //q2 System.DateTime date = DateTime.MinValue; string[] format = { "ddMMyyyy", "d MMM yyyy" }; // what would be the correct format strings? if (DateTime.TryParseExact(dateString,format,new CultureInfo("en-AU"),DateTimeStyles.None,out date)) { Console.Out.WriteLine(date.ToString()); } else { Console.Out.WriteLine("cant convert"); } } } } 

  1. 我不认为这可以做到。 解析器从左到右处理您的输入,因此如果它看到“1012012”,它会认为当天是10,然后解析失败,因为没有足够的字符,即使格式字符串是“dMMyyyy”。 它需要某种回溯来考虑当天是1的可能性,但不幸的是它似乎并没有这样做。

    但是,使用自定义正则表达式来解析此格式非常简单。 正则表达式解析器确实使用回溯,因此它将正确地考虑两个选项:

     string input = "1012012"; Match m = Regex.Match(input, @"^(?\d{1,2})(?\d{2})(?\d{4})$"); if( m.Success ) { DateTime d = new DateTime(Convert.ToInt32(m.Groups["year"].Value), Convert.ToInt32(m.Groups["month"].Value), Convert.ToInt32(m.Groups["day"].Value)); } 

    另一种选择是如果字符串的长度为7,则简单地添加前导零:

     string input = "1012012"; if( input.Length == 7 ) input = "0" + input; DateTime d = DateTime.ParseExact(input, "ddMMyyyy", CultureInfo.CurrentCulture); 
  2. 您可以使用已知字符串的确切格式这一事实,而不是像在其他答案中那样尝试进行多次查找和替换。 它以一个或两个数字开头,后跟两个字母,后跟月份和年份。 所以你可以像这样提取日期:

     string input = "1st January 2012"; int index = char.IsNumber(input, 1) ? 2 : 1; input = input.Substring(0, index) + input.Substring(index + 2); DateTime d = DateTime.ParseExact(input, "d MMMM yyyy", CultureInfo.InvariantCulture); 

    当然,这将接受在这些职位上纯粹胡说八道的日期,例如“1xx 2012年1月”,但我不确定这是否是您案件中的问题。

    如果输入可以包含非英语月份名称,也请务必传递相应的CultureInfo

如果你可以在不事先知道你得到的格式的情况下获得任何一种格式,你需要进行简单的检查,看看事先使用哪种方法。 第一种格式的字符串总是7或8个字符,第二种格式的字符串总是更长,所以这应该很容易测试。 另一种方法是检查字符串是否包含任何非数字字符(在这种情况下,它是长格式)。

 var dateString = "1st February 2011"; DateTime date; var replaced = dateString.Substring(0,4) .Replace("nd","") .Replace("th","") .Replace("rd","") .Replace("st","") + dateString.Substring(4); DateTime.TryParseExact(replaced, "d MMMM yyyy", new CultureInfo("en-us"), DateTimeStyles.AssumeLocal, out date); 

应该做的伎俩(对不起,’th’是讨厌的) – 你必须小心st(8月) – 只是从前几次出现删除它:

如果要解析特定于文化的日期字符串,则应使用匹配的文化。 CultureInfo.InvariantCulture不是一个好主意,因为它只适用于英文字符串。
但是,您尝试做的事情不仅仅是格式说明符,因为当天没有可以解析“th”,“st”等字符串。 您必须事先手动删除它们。