Convert.ToDateTime() 的意外行为

3

考虑以下代码片段:

DateTime dt = Convert.ToDateTime("06/16/2014 -0:10");
Console.Write (dt.ToString());
Console.ReadKey();

输出结果为6/15/2014 8:10:00 PM
这是在测试允许手动输入日期、小时和分钟(分别在ASP.Net文本框控件中)的Web应用程序时出现的,最初字符并没有被限制为仅数字(ASP .net验证器控件接受“-0”作为0..23范围内的整数)。
有人能解释一下这个字符串是如何转换成这个日期/时间的逻辑吗?我本来期望会抛出异常或者得到"6/16/2014 12:10:00 AM",因为"-0"和"0"是一样的("06/16/2014 0:10"转换为"6/16/2014 12:10:00 AM",正如我们所期望的那样)。

1
不要让用户以自由文本的形式插入日期,或者至少针对一个非常明确定义的格式进行验证。有大约200万种冲突的时间和日期表示方式,您不希望开始弄清楚用户输入了什么。 01/02/2014 - 这是二月二日还是一月一日? - AK_
大家都说得对,-0:10 被视为时区偏移量。如果输入字符串为 06/16/2014 00:00 -0:10 ,输出结果也相同。它将 06/16/2014 视为日期,假设时间为午夜,因为没有具体指定时间(所有时间都是在 UTC 上)。然后它使用我的本地时间(UTC-4)并通过 -0:10 进行时区调整。 - Joe Schmoe
AK_: 我同意你所说的。顺便提一下,日期并不是以自由文本形式输入的,日期部分的文本框被设置为只读,值是从jQuery日期选择器控件中捕获的。 - Joe Schmoe
3个回答

4

根据MSDN的说法,我认为您已经将时区设置为提前10分钟。

dateString = "2009-05-01T07:54:59.9843750-04:00";
Convert.ToDateTime(dateString);
//    '2009-05-01T07:54:59.9843750-04:00' converts to 5/1/2009 4:54:59 AM Local time.

2

正如@LIUFA所指出的那样,这是首先解析字符串然后转换为本地时间的结果。 -0:10 被解释为 -10 分钟时区偏移量而且时间部分未被指定,因此被解释为午夜。

为了看到发生了什么,首先将字符串解析为 DateTimeOffset

> DateTimeOffset.Parse("06/16/2014 -0:10", CultureInfo.InvariantCulture)
16.06.2014 00:00:00 -00:10

然后将时间转换为本地时间(GMT-4:00是您的情况)

> time.ToLocalTime()
15.06.2014 20:10:00 -04:00

所有的都是正确的,除了你错过了输出中的日期是6/15而原始字符串中是6/16。我的本地时间是GMT-4。 - Joe Schmoe
@JoeSchmoe 我仍然不习惯使用上午/下午的表示法。 - CodesInChaos

1
我认为文本中的“-0”部分被视为时区,相对于本地时间。这将导致程序获取本地小时并将分钟设置为字符串中给定的十位数。

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