14

尝试将日期/时间从字符串转换为 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。为什么会被抵消?我只是希望它具有相同的价值。

4

5 回答 5

24

您正在解析 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
于 2012-10-08T18:34:33.373 回答
5

您应该使用DateTimeStyles.AdjustToUniversal。输入DateTime已经是通用的,并且 AdjustToUniversal 枚举选项会将输入转换为本地时间,尽管您会得到结果 Kind of DateTimeKind.Unspecified

于 2012-10-08T18:33:15.480 回答
3

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

那时你可能在美国东部时间。

于 2012-10-08T18:29:37.880 回答
3

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

回到 OPs 代码片段,它没有执行 OP 预期的将 UTC 时间字符串存储为 UTCDateTime的原因是因为DateTimeStyles.AssumeUniversal唯一指定输入字符串是 UTC 字符串。默认情况下,C# 会将DateTime's 创建为DateTimeKind.Local. 在另一个答案中指出了这一点。这意味着时间从 UTC 转换为本地时间。

为确保您的最终结果是 UTC DateTime,您需要使用DateTimeStylesof 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);
于 2020-05-13T14:11:07.790 回答
2

我只是建议您要使用.AssumeLocal而不是.AssumeUniversal.

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

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

编辑:

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

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

于 2012-10-08T18:42:51.783 回答