C#datetime解析问题

时间:2012-10-08 18:26:53

标签: c# .net datetime

当尝试将日期/时间从字符串转换为DateTime时,我没有得到正确的值。

DateTime testDate = DateTime.ParseExact("2012-08-10T00:51:14.146Z", "yyyy-MM-ddTHH:mm:ss.fffZ",    CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal);

我的结果是2012-08-09 8:51:14 PM。为什么会被抵消?我只是想让它成为同样的价值。

5 个答案:

答案 0 :(得分:20)

您正在解析UTC日期,但DateTime.Kind是本地的。 您应该使用DateTimeStyles.AdjustToUniversal进行解析,以将Kind标记为Utc。

        DateTime testDate = DateTime.ParseExact("2012-08-10T00:51:14.146Z", "yyyy-MM-ddTHH:mm:ss.fffZ", CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal);

        Trace.WriteLine(testDate);  //  8/9/2012 8:51:14 PM
        Trace.WriteLine(testDate.ToString()); //  8/9/2012 8:51:14 PM
        Trace.WriteLine(testDate.ToUniversalTime()); //  8/10/2012 12:51:14 AM
        Trace.WriteLine(testDate.Kind); // Local

       testDate = DateTime.ParseExact("2012-08-10T00:51:14.146Z", "yyyy-MM-ddTHH:mm:ss.fffZ", CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal);

        Trace.WriteLine(testDate);//  8/10/2012 12:51:14 AM
        Trace.WriteLine(testDate.ToString());//  8/10/2012 12:51:14 AM
        Trace.WriteLine(testDate.ToUniversalTime());//  8/10/2012 12:51:14 AM
        Trace.WriteLine(testDate.Kind); // Utc

答案 1 :(得分:3)

您的服务器时区是多少,如果使用AssumeUniversal,它会将您的输入时间转换为UTC时间。

你可能在美国东部时间。

答案 2 :(得分:3)

您应该使用DateTimeStyles.AdjustToUniversal。输入DateTime已经是通用的,而AdjustToUniversal枚举选项会将输入转换为本地时间,但您将获得DateTimeKind.Unspecified的结果。

答案 3 :(得分:2)

我建议您只想使用.AssumeLocal代替.AssumeUniversal

你有一个带有未知时区的时间戳,如果你知道时间戳是指你当地时区发生的事件,那么你应该告诉解析假设时间戳是你本地的(即在你的时区)。

通过使用.AssumeUniversal,您指示解析器将时间戳视为UTC时间戳,当您使用本地时区显示时,它会自动抵消该数量。

修改

一个重要的事情:时间戳中的The capital "Z"表示它是UTC时间戳,这意味着您确实希望将其视为通用。如果要将其视为本地时间戳,则应从时间戳和相应的解析字符串中删除Z.

参考:http://msdn.microsoft.com/en-us/library/8kb3ddd4.aspx#KSpecifier

答案 4 :(得分:2)

意识到这是多年以后的答案,但是今天遇到了这个问题,一旦我解决了我的问题,便想添加一些我在其他答案中没有看到的上下文。

回到OP代码段,原因是它不执行OP期望的采用UTC时间字符串并将其存储为UTC DateTime的原因,因为DateTimeStyles.AssumeUniversal仅指定了输入字符串是UTC字符串。默认情况下,C#将创建DateTime作为DateTimeKind.Local。另一个答案指出了这一点。这意味着时间从UTC转换为本地时间。

为确保最终结果成为UTC DateTime,您需要使用DateTimeStyles中的DateTimeStyles.AdjustToUniversal。其他答案中也提到了这一点。但是,如果您输入的字符串没有明显的时区,则可以假定该字符串为本地,然后从本地转换为UTC。

幸运的是,DateTimeStyles实际上是一个标志枚举,这意味着我们可以同时使用上述两个选项。例如:

DateTime testDate = DateTime.ParseExact("2012-08-10T00:51:14.146Z", "yyyy-MM-ddTHH:mm:ss.fffZ",    CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal | DateTimeStyles.AssumeUniversal);