DateTime.Parse(myString, CultureInfo.InvariantCulture)
很乐意解析以下明确的日期(假设当地时区是固定的):
2015-12-31T12:15:00
2015-12-31T12:15:00Z
2015-12-31T12:15:00+01:00
2015-12-31T12:15
2015-12-31
2015-12-31 12:15:00
2015-12-31 12:15:00Z
2015-12-31 12:15:00+01:00
2015-12-31 12:15
这很棒。我喜欢所有的灵活性。不幸的是,它还解析了以下含糊不清的日期:
4.3.2015 // The user intent could be March or April.
我知道我可以使用ParseExact,但是我必须提交一份包含可能提交给我的应用程序的所有明确日期格式的大型列表。
我能否以某种方式禁止含糊不清的日期格式而无需为ParseExact指定每种明确的格式?像DateTime.Parse(myString, IsoCulture)
?
答案 0 :(得分:-1)
我认为你不能通过提供单一格式选项来实现这一目标。
这是我的十人入门者,至少可以确保日期部分格式正确:
Public Function ParseUnAmbiguousDate(s As String, ByRef aDateTime As DateTime) As Boolean
'keep a track of how long the date portion is
Dim dateLength As Integer = 0
'there are only two valid date formats in ISO terms yyyy-MM-dd or yyyyMMdd so try these first
'is it too short?
If s.Length < 8 Then Return False
'try the yyyyMMdd format
If DateTime.TryParseExact(s.Substring(0, 8), "yyyyMMdd", CultureInfo.InvariantCulture, DateTimeStyles.None, aDateTime) Then
dateLength = 8
End If
'try the yyyy-MM-dd format if the first option failed
If dateLength = 0 Then
'is it too short for this format?
If s.Length < 12 Then Return False
If DateTime.TryParseExact(s.Substring(0, 10), "yyyy-MM-dd", CultureInfo.InvariantCulture, DateTimeStyles.None, aDateTime) Then
dateLength = 10
End If
End If
'if we get here then check we have found a format
If dateLength = 0 Then Return False
'now substitue our date for a known one to try and parse the time
Dim timePortion As Date
If DateTime.TryParse("2000-01-01" & s.Substring(dateLength), timePortion) Then
aDateTime = New DateTime(aDateTime.Year, aDateTime.Month, aDateTime.Day, timePortion.Hour, timePortion.Minute, timePortion.Second, timePortion.Kind)
Return True
Else
Return False
End If
End Function
答案 1 :(得分:-3)
可以使用此扩展程序完成:
using System;
using NUnit.Framework;
namespace UnitTestProject1
{
[TestFixture]
public class UnitTest1
{
[TestCase("2015-12-31", true)]
[TestCase("2015-01-01", true)]
[TestCase("2015-12-31 12:15:00+01:00", true)]
[TestCase("4.3.2015", false)]
[TestCase("4.13.2015", true)]
[TestCase("13.13.2015", false, ExpectedException = typeof(FormatException))]
public void TestMethod1(string input, bool expected)
{
Assert.AreEqual(expected, input.IsDateNotAmbigous());
}
}
public static class Extensions
{
public static bool IsDateNotAmbigous(this string stringDateTime)
{
DateTime parsed = DateTime.Parse(stringDateTime);
return parsed.Day == parsed.Month || parsed.Day>12;
}
}
}
<强>更新强>
我认为我必须在这方面与公众达成一致,即如果不了解传入的琴弦文化,这不是一个容易解决的问题。即使我们按照这样的方式迭代所有可用的文化:
public static bool IsDateNotAmbigous(this string stringDateTime)
{
return CultureInfo.GetCultures(CultureTypes.AllCultures).AsParallel().Select(ci =>
{
DateTime parsed = default(DateTime);
bool success = DateTime.TryParse(stringDateTime, ci, DateTimeStyles.AssumeLocal, out parsed);
bool test = parsed.Day > 12 || parsed.Day == parsed.Month;
Trace.WriteLine(String.Format("{0,12}:{1,5}:{2,5}:{3:O}", ci.Name, success, test, parsed));
if (!success)
return -1;
if (test)
return 1;
return 0;
}).Where(w=>w>=0).Select(s=>s==1).Aggregate((b, b1) => b || b1);
}
有些测试不会通过。但也许它会帮助某人为此提出一个优雅的解决方案。
无法停止思考
好的,所以我们无法确切地知道,如果不了解传入的文化,但这会让你更接近:
#region
using System;
using System.Globalization;
using System.Linq;
using NUnit.Framework;
#endregion
namespace UnitTestProject1
{
[TestFixture]
public class UnitTest1
{
[TestCase("2015-12-31", true)]
[TestCase("2015-01-01", true)]
[TestCase("2015-02-01", false)]
[TestCase("2015-12-31 12:15:00+01:00", true)]
[TestCase("4.3.2015", false)]
[TestCase("4.13.2015", true)]
[TestCase("13.13.2015", null, ExpectedException = typeof (InvalidOperationException))]
public void TestMethod1(string input, bool expected)
{
Assert.AreEqual(input.DateIsLikelyNotAmbigous(), expected);
}
}
public static class Extensions
{
public static bool DateIsLikelyNotAmbigous(this string stringDateTime)
{
return CultureInfo.GetCultures(CultureTypes.AllCultures).AsParallel().Select(ci =>
{
DateTime parsed = default(DateTime);
bool success = DateTime.TryParse(stringDateTime, ci, DateTimeStyles.AssumeLocal, out parsed);
if (!success)
return -1;
if (parsed.Day > 12 || parsed.Day == parsed.Month)
return 1;
return 0;
}).Where(w => w >= 0).Average(a => a) > 0.02;
}
}
}
很想听@hvd对此的看法。