DateTime.TryParse将十进制转换为日期时间

6
以下代码行返回true(实际上不应该),并将1.0228转换为日期时间格式...
DateTime.TryParse(1.0228,out temporaryDateTimeValue)

有人能帮我吗?


2
"1.0228" 不是小数,它是一个双精度浮点数。 - CodesInChaos
1
你使用的是哪个.NET平台的实现?DateTime.TryParse()只应该有两个重载,而且这两个重载都不会将double作为它们的第一个参数。 - Frédéric Hamidi
@Anish,你可能有一个实现了DateTime.TryParse(double, out DateTime)的扩展方法在作用域内。Intellisense列出了多少个TryParse()的重载? - Frédéric Hamidi
1
@Frédéric Hamidi:假设他也有一个“using System;”声明,那么他就不需要使用大写的DateTime - jason
@Jason,糟糕,你是对的,我太傻了。 - Frédéric Hamidi
显示剩余4条评论
2个回答

10

以下代码返回 true(不应该),并将 1.0228 转换为日期时间...

DateTime.TryParse(1.0228,out temporaryDateTimeValue)

这段代码无法编译。

然而,如果你将其用引号括起来(并进行一些清理),

bool success = DateTime.TryParse("1.0228", out temporaryDateTimeValue);

那么,是的,你会得到true。你需要阅读文档来理解为什么,但基本上有许多不同的日期格式方式,而你可能碰巧在其中一种格式(也许是M.yyyy)上犯了错。

如果你不想对其进行解析,我可以建议

bool success = DateTime.TryParseExact(
                   "1.0228",
                   "yyyyMMdd", 
                   CultureInfo.InvariantCulture,
                   DateTimeStyles.None,
                   out temporaryDateTimeValue
               );

然后successfalse

我从文档的注释中注意到:

使用当前线程区域性隐式提供的当前DateTimeFormatInfo对象中的格式信息解析字符串s

如果可能,此方法尝试忽略无法识别的数据,并使用当前日期填充缺少的月份、日期和年份信息。如果s仅包含日期而没有时间,则此方法假定时间为午夜12:00。在s中任何前导、内部或尾随的空格字符都会被忽略。日期和时间可以用一对前导和尾随数字标记字符('#',U + 0023)括起来,并且可以在其后跟随一个或多个NULL字符(U + 0000)。

由于DateTime.TryParse(String, DateTime)方法尝试使用当前区域性的格式规则解析日期和时间的string表示形式,因此尝试在不同的区域性中解析特定的string可能会失败或返回不同的结果。如果将在不同的语言环境中解析特定的日期和时间格式,请使用DateTime.TryParse(String, IFormatProvider, DateTimeStyles, DateTime)方法或TryParseExact方法的其中一个重载,并提供格式说明符。

基本上,TryParse非常努力地尝试解析您提供的字符串(虽然“Try”实际上是指该方法返回了一个布尔值表示成功/失败的指示)。


如果我使用其他DateTime.TryParse重载函数,带有文化信息的话,我需要提供什么文化信息和日期时间样式? - Relativity

4

不,那段代码并没有返回 true - 它甚至无法编译:

using System;

class Program
{

    static void Main(string[] args)
    {
        DateTime dt;
        Console.WriteLine(DateTime.TryParse(1.0228, out dt));
    }
}

错误:

Test.cs(9,27): error CS1502: The best overloaded method match for
        'System.DateTime.TryParse(string, out System.DateTime)' has some invalid
        arguments
Test.cs(9,45): error CS1503: Argument 1: cannot convert from 'double' to
        'string'

如果你将它更改为"1.0228",是可以返回true的。看起来它使用的格式是"M.yyyy",这对某些文化来说无疑是有效的......也凸显了在我看来使用DateTime.TryParse的坏处。如果你有特定的格式(或一组格式)在心中,你应该使用DateTime.TryParseExact来指定格式。
我通常发现指定精确格式是一个好主意,并且除非日期直接来自用户(在我的经验中很少见),否则我通常还会指定CultureInfo.InvariantCulture。

我猜它可能会返回“公元228年1月1日”,因为有些文化使用点作为日期分隔符。 - Frédéric Hamidi
1
@Frédéric Hamidi:是的,看起来这似乎是它得出的日期。就我个人而言,我真的很讨厌DateTime.TryParse默认的“我们将尝试以数百种方式解析它”的方法。 - Jon Skeet
显然它匹配M.yyyy - Yuriy Faktorovich
@Jon,嗯,那个策略确实可以提高单元测试中的代码覆盖率 ;) - Frédéric Hamidi

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