任何文化的DateTime.TryParse

3

有很多关于这个问题的帖子,但我仍然卡在以下问题上:

我有什么:

我正在尝试构建一个 Windows Phone 应用程序,该应用程序将选择个人的出生日期

后台代码:

string dateString = "";

  DateTime dt = DateTime.Now;
     if (value != null && DateTime.TryParse(value.ToString(),  culture, DateTimeStyles.None, out dt))
  {
    if (dt.Equals(DateTime.MinValue))
    {
      //dateString = "mm/dd/yyyy";
      return "";
    }
    else
      return dt.ToShortDateString();
  }
  else
    return dateString;
}

我需要:

我希望它能解析任何日期格式,应该是与文化无关的。

我尝试过:

1. 我尝试使用CultureInfo.InvariantCultute、CultureInfo.CurrentCulture。

2. 尝试使用ExactParser,如下所示:

string[] formats = {"M/d/yyyy h:mm:ss tt", "M/d/yyyy h:mm tt", "d/M/yyyy hh:mm:ss tt", "dd/MM/yyyy hh:mm:ss tt", "d/M/yyyy" , "dd/MM/yyyy" , "M/d/yyyy" ,"MM/dd/yyyy", 
               "MM/dd/yyyy hh:mm:ss", "M/d/yyyy h:mm:ss",   "dd/MM/yyyy hh:mm:ss", "d/M/yyyy h:mm:ss",
               "M/d/yyyy hh:mm tt", "M/d/yyyy hh tt",  "d/M/yyyy hh:mm tt", "d/M/yyyy hh tt",
               "M/d/yyyy h:mm", "M/d/yyyy h:mm", "d/M/yyyy h:mm", "d/M/yyyy h:mm",
               "MM/dd/yyyy hh:mm", "M/dd/yyyy hh:mm","dd/MM/yyyy hh:mm", "dd/M/yyyy hh:mm"};


 if (value != null && DateTime.TryParseExact(value.ToString(), format, CultureInfo.InvariantCulture, DateTimeStyles.None, out dt))

但这种方法太过硬编码,无法覆盖多种情况。

是否有任何方法可以以任何格式选择出生日期?

非常感谢您的帮助!谢谢!!


5
不行,因为日期格式甚至可能相互矛盾,我认为这是不可能/不可行的... - Yahia
2
同意 @Yahia 的观点:10/12/2013 可能是美国的十月十二日,也可能是法国的十二月十日。 - Kek
我同意Yahia的观点:你需要定义支持的日期格式。考虑一个简单的例子,比如2013年8月9日。当使用英国格式解析时,它是2013年9月8日;而当使用美国格式解析时,它是2013年8月9日。 - Daniel Hilgarth
2
回应其他评论 - 如果有一种简单的方法可以将任何字符串明确解码为DateTime值,你难道不认为这会是框架中公开的一个方法吗? - Damien_The_Unbeliever
1
那么另一个选择可能是,我应该询问文化,并尝试相应地设置CultureInfo。我说得对吗? - Ankush Dubey
显示剩余2条评论
3个回答

15

并非如此,因为每个人都有自己的日期格式。

Also, this!

您基本上正在尝试从上面这个 XKCD 漫画 的下半部分神奇地推断出日期。;)

话虽如此,您唯一可以尝试做到这一点的方法是使用您认为可能存在的每种格式解析字符串,然后在每种成功解析的情况下进行合理性检查。然而,这种合理性检查将会很困难……11-02是否表示2月11日还是11月2日?您需要某种上下文。


1
你需要一些上下文。- 这就是 CultureInfo ;-) - Christian.K
假设你拥有相关的 CultureInfo。如果我只告诉你解析这个日期 2012-01-02,你知道我指的是什么吗?至少,这是我从问题中得出的结论。当然,你可以尝试使用 CurrentCulture 设置,但我假设这对于提问者来说不够。否则...为什么要一开始就尝试解析每种格式呢? - MBender
@Shaamaan - 幸运的是,当一个四位数的数字首先出现时,我们可以推断其格式为YYYY-MM-DD。据我所知,没有任何地方使用YYYY-DD-MM格式(维基百科也支持这一观点)。但你对其他观点都是正确的。还有一个加分给xkcd! - Matt Johnson-Pint
@MattJohnson 我确信一些美国人,由于他们令人讨厌的习惯把日期和月份混淆起来,可能会以这种方式书写——即使不是正式地,也可以说是非正式地。:P - MBender

7
抱歉,由于日期时间可能存在歧义,因此似乎不可能实现,这也是为什么会被误解的原因。例如:"01/02/03"
01 Feb 2003 (Russia)

02 Jan 2003 (USA)

03 Feb 2001 (China)

请查看http://en.wikipedia.org/wiki/Date_format_by_country以了解各国日期格式。


4
这将尝试所有文化:
public static bool TryParseAnyDate(string dateValue, out DateTime result)
{
  result = DateTime.MinValue;
  foreach (CultureInfo cultureInfo in CultureInfo.GetCultures(CultureTypes.AllCultures))
  {
    if (DateTime.TryParse(dateValue, cultureInfo, DateTimeStyles.None, out result))
    {
      return true;
    }
  }
  return false;
}

5
“First one wins” 不是这个问题的很好策略。 - Matt Johnson-Pint
1
对于你的问题,没有一个好的解决方案。如果你不强制用户使用某种格式,你无法确定用户在输入日期时的“意图”。例如,根据用户所在的国家和智商,这个字符串可能代表很多不同的日期:“05/06/07”(2007年6月5日,2007年5月6日,2005年6月7日等等)。最好的解决方案是使用日期选择器,而不是让用户在文本框中自由输入。 - Péter
+1 因为在现实世界中,并不总是可以控制序列化日期时间的方式。使用一个精心选择的格式字符串列表来“猜测”是一个很好的解决方案(即使知道存在模糊的情况)。 - Askolein

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