C# DateTime.TryParse->“鬼滴答声”
我有下面的单元测试,它在我们的一个开发人员的机器上失败了。他在结果变量中得到了一些刻度,而datetime变量为零刻度,但在其他机器上运行良好C# DateTime.TryParse->“鬼滴答声”,c#,.net,datetime,C#,.net,Datetime,我有下面的单元测试,它在我们的一个开发人员的机器上失败了。他在结果变量中得到了一些刻度,而datetime变量为零刻度,但在其他机器上运行良好 [TestMethod] public void DateTimeStringDateTimeMinCurrentCultureToNullableDateTimeSuccessTest() { var dateTime = new DateTime(1, 1, 1); string value =
[TestMethod]
public void DateTimeStringDateTimeMinCurrentCultureToNullableDateTimeSuccessTest()
{
var dateTime = new DateTime(1, 1, 1);
string value = dateTime.ToString();
var result = value.ToNullableDateTime();
Assert.AreEqual(dateTime, result);
}
下面是使用的扩展方法:
/// <summary>
/// Converts a string to a nullable DateTime. If the string is a invalid dateTime returns null.
/// Uses the current culture.
/// </summary>
public static DateTime? ToNullableDateTime(this string s)
{
//Don't use CultureInfo.CurrentCulture to override user changes of the cultureinfo.
return s.ToNullableDateTime(CultureInfo.GetCultureInfo(CultureInfo.CurrentCulture.Name));
}
/// <summary>
/// Converts a string to a nullable DateTime. If the string is a invalid dateTime returns null.
/// </summary>
public static DateTime? ToNullableDateTime(this string s, CultureInfo cultureInfo)
{
if (String.IsNullOrEmpty(s)) return null;
DateTime i;
if (DateTime.TryParse(s, cultureInfo, DateTimeStyles.None, out i)) return i;
return null;
}
我认为这可能与他使用的一些windows日期时间设置有关。理论上,ToNullableDateTimestring应该创建一个新的区域性信息,它与用户机器无关。GetCultureInfo应调用新的CultureInfo名称,false。我唯一能想到的是,有一个缓存的区域性信息,它在GetCultureInfoHelper中检查的s_NameCachedCultures中包含某种与用户机器相关的修改日期时间
我知道,CreateSpecificCulture方法可以返回用户修改的datetime,如果您使用与windows计算机相同的区域性调用它。但我一直认为,GetDateTime在任何情况下都会返回未修改的datetime
因此有两个问题:
是否可能将修改后的CultureInfo存储在内部缓存中?
如果是这样,手动调用new CultureInfoxy获取未修改的CultureInfo的唯一方法是false吗?
我猜,最有可能的是CultureInfo在缓存中。这在单元测试AreName中很容易检查 使用DateTime1、2、3代替DateTime1、1、1,并检查重影刻度。在绳子里的什么地方找到了吗?您是否在两台结果不同的机器上尝试了相同的区域性硬编码区域性名称 还要检查差异是否是您所在文化中UTC的偏移量
您可能可以使用TryParseExact。我想,最有可能的是CultureInfo在缓存中。这在单元测试AreName中很容易检查 使用DateTime1、2、3代替DateTime1、1、1,并检查重影刻度。在绳子里的什么地方找到了吗?您是否在两台结果不同的机器上尝试了相同的区域性硬编码区域性名称 还要检查差异是否是您所在文化中UTC的偏移量 您可能可以使用TryParseExact。当您这样做时 字符串值=dateTime.ToString 这将使用CultureInfo.CurrentCulture。然后尝试使用…解析此字符串 CultureInfo.GetCultureInfo.CurrentCulture.Name 因此,您专门使用一个区域性来解析字符串,该字符串与您创建字符串时使用的字符串不同。当然,在某些情况下,这是无法通过的 我认为这是大多数人的问题
Assert.AreEqual(CultureInfo.CurrentCulture, CultureInfo.GetCultureInfo(CultureInfo.CurrentCulture.Name));
会通过,但在有问题的机器上它不会,你的字符串也不会
我建议你可能想用。所以
当你这样做的时候
字符串值=dateTime.ToString
这将使用CultureInfo.CurrentCulture。然后尝试使用…解析此字符串
CultureInfo.GetCultureInfo.CurrentCulture.Name
因此,您专门使用一个区域性来解析字符串,该字符串与您创建字符串时使用的字符串不同。当然,在某些情况下,这是无法通过的
我认为这是大多数人的问题
Assert.AreEqual(CultureInfo.CurrentCulture, CultureInfo.GetCultureInfo(CultureInfo.CurrentCulture.Name));
会通过,但在有问题的机器上它不会,你的字符串也不会
我建议你可能想用。所以
我监督了一些细节。该问题与GetCultureInfo返回修改的datetime无关,该问题已从datetime.ToString开始;它使用Thread.CurrentThread.CultureInfo,该信息等于windows区域性,可以修改。开发者机器将DateTime1,1,1转换为01.01.01 00:00:00。在任何其他机器上,输出为01.01.0001 00:00:00。因此,使用了年份的缩写版本,在TryParse方法quick sidenode中,它似乎被解释为本世纪的第一年:因此,100岁以上的用户不可能用缩写版本告诉自己的生日。 这实际上是一种有趣的行为
for (int i = 0; i < 100; i++)
{
var year = 1900 + i;
DateTime date = new DateTime(year, 1, 1);
var parsedDate = DateTime.ParseExact(date.ToString("yy"), "yy", CultureInfo.InvariantCulture);
Console.WriteLine("{0}: {1}", year, parsedDate.ToString("yyyy"));
}
因此,对于86岁以上的人来说,缩短的出生日期将导致功能中的日期。。但这偏离了问题的背景
我认为除了告诉开发人员不要在UI字符串之外使用本地CultureInfo,也不要在输入中使用缩写日期之外,没有真正的解决方案
我们的代码本身没有这样的问题,因为我们使用CultureInfo.InvariantCulture处理所有内部内容。我只考虑单元测试。。我认为测试本身是正确的。它表明,该函数实际上不能正确处理缩写日期。如果识别出带有缩写年份的datetime字符串,我将更改TonulableDateTime的行为以引发异常。我已经了解了一些细节。该问题与GetCultureInfo返回修改的datetime无关,该问题已从datetime.ToString开始;它使用Thread.current hread.CultureInfo,它等于windows区域性,可以修改。开发者机器将DateTime1,1,1转换为01.01.01 00:00:00。在任何其他机器上,输出为01.01.0001 00:00:00。因此,使用了年份的缩写版本,在TryParse方法quick sidenode中,它似乎被解释为本世纪的第一年:因此,100岁以上的用户不可能用缩写版本告诉自己的生日。 这实际上是一种有趣的行为
for (int i = 0; i < 100; i++)
{
var year = 1900 + i;
DateTime date = new DateTime(year, 1, 1);
var parsedDate = DateTime.ParseExact(date.ToString("yy"), "yy", CultureInfo.InvariantCulture);
Console.WriteLine("{0}: {1}", year, parsedDate.ToString("yyyy"));
}
因此,对于86岁以上的人来说,缩短的出生日期将导致功能中的日期。。但这偏离了问题的背景
我认为除了告诉开发人员不要在UI字符串之外使用本地CultureInfo,也不要在输入中使用缩写日期之外,没有真正的解决方案
我们的代码本身没有这样的问题,因为我们使用CultureInfo.InvariantCulture处理所有内部内容。我只考虑单元测试。。我认为测试本身是正确的。它表明,该函数实际上不能正确处理缩写日期。如果识别到具有缩写年份的日期时间字符串,我将更改ToNullableDateTime的行为以引发异常。为什么选择在扩展方法的短重载中使用CultureInfo.GetCultureInfo?这说明了为什么我们更喜欢它而不是普通的实例构造函数new CultureInfo。。。是缓存导致的速度。了解测试失败的计算机上以及测试通过的计算机上的s和CultureInfo.CurrentCulture.Name将很有帮助。为什么在扩展方法的短重载中选择使用CultureInfo.GetCultureInfo?这说明了为什么我们更喜欢它而不是普通的实例构造函数new CultureInfo。。。是由于缓存而导致的速度。了解测试失败的计算机上以及测试通过的计算机上的s和CultureInfo.CurrentCulture.Name是很有帮助的。