C# Datetime.ParseExact 用于解析包含 UTC 文本的字符串

C# Datetime.ParseExact for a parsing a string containing UTC text

我有一个日期时间字符串,如下所示:

13.08.2014 17:17:45.000 UTC-60

我试图将它解析为 C# 日期时间对象,但它没有像我预期的那样工作。

这是我尝试过的:

DateTime.ParseExact(dateToParse, "dd.MM.yyyy hh:mm:ss.fff Z", CultureInfo.InvariantCulture);

DateTime.ParseExact(dateToParse, "dd.MM.yyyy hh:mm:ss.fff UTC", CultureInfo.InvariantCulture);

DateTime.ParseExact(checkInDate, "dd.MM.yyyy hh:mm:ss.fff", CultureInfo.InvariantCulture);

他们都是return同样的错误

{"String was not recognized as a valid DateTime."}

一些现有的问题,如 this 也没有帮助。

有什么建议吗?

首先,您在解析时遇到的主要问题是您使用 hh 作为 24 小时格式。那应该是HH。这应该有效:

DateTime.ParseExact("13.08.2014 17:17:45.000", "dd.MM.yyyy HH:mm:ss.fff", null, System.Globalization.DateTimeStyles.AssumeUniversal)

至于UTC部分,那不是标准格式,所以我建议你创建一个辅助方法,将这个字符串一分为二,按照上面提供的方式解析第一部分,然后解析UTC之后的数字并将其添加到您的 DateTime:

myDate.AddMinutes(Int32.Parse("-60"))

或者创建一个 DateTimeOffset。无论哪种情况,您都必须单独解析它们。

您对时间格式有多少控制权。 .Net 日期时间解析预计您尝试解析的当前时间格式有 2 个错误:

首先,你有 24 小时制,所以在你的格式中你必须使用 HH 表示小时,小写 hh 表示小时将是 12 小时格式。

UTC 问题是另一个需要您先修改字符串的问题,.Net 需要 HH:mm 形式的时区信息,因此以下字符串和转换将起作用,请注意关键差异

var dateToParse = "13.08.2014 17:17:45.000 -01:00";
var value = DateTimeOffset.ParseExact(dateToParse, "dd.MM.yyyy HH:mm:ss.fff zzz", CultureInfo.InvariantCulture);
  1. 使用DateTimeOffset维护时区信息
  2. HH映射时间
  3. zzz映射时区信息

那么,为了解决您的问题,我们如何将字符串解析为一种格式,然后我们可以使用该格式解析为日期时间:

dateToParse = "13.08.2014 17:17:45.000 UTC-60";
string utc = null;
if (dateToParse.Contains("UTC"))
{
    var tokens = dateToParse.Split(new string[] { "UTC" }, StringSplitOptions.None);
    dateToParse = tokens[0];
    utc = tokens[1];

    int minutes = int.Parse(utc);
    var offset = TimeSpan.FromMinutes(minutes);
    bool negative = offset.Hours < 0;
    dateToParse += (negative ? "-" : "") + Math.Abs(offset.Hours).ToString().PadLeft(2,'0') + ":" + offset.Minutes.ToString().PadLeft(2,'0');
}
var value = DateTimeOffset.ParseExact(dateToParse, "dd.MM.yyyy HH:mm:ss.fff zzz", CultureInfo.InvariantCulture);

老实说,这比我想象的要复杂,可能有一些正则表达式可能会有所帮助,但是这种处理字符串的首要原则方法首先适用于您的字符串。

最后,既然我们有了 DateTimeOffset 值,您可以轻松地将其转换为任何本地或其他时区,而无需太多麻烦,如果您需要:

var asUtc = dateValue.UtcDateTime;
var asLocal = dateValue.LocalDateTime;
var asSpecific = dateValue.ToOffset(TimeSpan.FromHours(10)).DateTime;