【问题标题】:how to parse datetime from this format?如何从这种格式解析日期时间?
【发布时间】:2017-06-21 01:26:45
【问题描述】:

我有不同的日期时间格式。我收到错误“System.FormatException” 当我尝试解析它时。怎么解析?

    ?time
"20170620 21:22:02 EST"

?DateTime.Parse(time)
'DateTime.Parse(time)' threw an exception of type 'System.FormatException'
    Data: {System.Collections.ListDictionaryInternal}
    HResult: -2146233033
    HelpLink: null
    InnerException: null
    Message: "String was not recognized as a valid DateTime."
    Source: "mscorlib"
    StackTrace: "   at System.DateTimeParse.Parse(String s, DateTimeFormatInfo dtfi, DateTimeStyles styles)\r\n   at System.DateTime.Parse(String s)"
    TargetSite: {System.DateTime Parse(System.String, System.Globalization.DateTimeFormatInfo, System.Globalization.DateTimeStyles)}

由于偏移量是硬编码的或存在数据库派生,因此发布的答案均未涉及夏令时。

【问题讨论】:

标签: c#


【解决方案1】:

EST 比 UTC 晚 5 小时,因此使用 DateTime.ParseExact 可能符合您的需要:

String time = "20170620 21:22:02 EST";

DateTime.ParseExact(time.Replace("EST", "-05:00"), "yyyyMMdd HH:mm:ss zzz", CultureInfo.InvariantCulture);

UTC 结果:

6/21/2017 2:22:02 AM

注意:根据IANA's 数据,某些时区缩写根据文化具有不同的关联,因此没有确切的方法来定义应该解析哪个时区,而不是在应用程序上下文中定义它们(可能使用硬编码值)。

.NET Fiddle Example

【讨论】:

  • 这个选项的问题在于,由于夏令时,EST 并不总是 -05:00
  • 对于这种情况,您需要使用 EDT(夏令时版本)。如果您使用的是 EST/EDT 以外的其他时区,请先将它们指定到列表中。
  • 当你硬编码偏移量时,它不正确,因为偏移量根据周期而变化。 timeanddate.com/time/zone/canada/toronto
  • 我认为用非标准化句点硬编码偏移缩写不是一个好主意 - Jon Skeet 已经在这里解释过:stackoverflow.com/questions/8754563/…。但是使用精确的偏移值适用于 DateTimeOffset 或 Noda Time。
【解决方案2】:

DateTime.Parse() 方法无法识别您当前的日期时间字符串,因此您需要将其重新格式化为该方法可以理解的格式之一。 对于这个问题,下面的 sn-p 可能有点矫枉过正:-) 但它可以处理相当多的情况。

//  "20170620 21:22:02 EST" -> "wrong" format
//  "2017-06-20T21:22:02 -05:00" -> correct format
String input = "20170620 21:22:02 EST";
String temp = input;

//  Handle US time zones.
String[] timeZones = {"AST", "EST", "EDT", "CST", "CDT", "MST", "MDT", "PST", "PDT", "AKST", "AKDT", "HST", "HAST", "HADT", "SST", "SDT", "CHST"};

Int32[] utcOffsets = { -4, -5, -4, -6, -5, -7, -6, -8, -7, -9, -8, -10, -10, -9, -11, -10, 10 };

//  Correct the timezone part
for (int i = 0; i < timeZones.Length; i++)
{
    String timeZonePattern = @"\b" + timeZones[i] + @"\b";
    String timeZoneReplPattern = String.Format("{0}:00", utcOffsets[i].ToString("+00;-00"));

    temp = Regex.Replace(input, timeZonePattern, timeZoneReplPattern);
    if (temp != input)
    {
        break;
    }
}

//  Correct the date part
String datePattern = @"(?<year>[\d]{4})(?<month>[0][1-9]|[1][0-2])(?<day>[0][1-9]|[1-2][0-9]|3[0-1])\s*";
String dateReplPattern = @"${year}-${month}-${day}T";
temp = Regex.Replace(temp, datePattern, dateReplPattern);

//  Now we should have a correct date time string
DateTime dt;
try
{
    dt = DateTime.Parse(temp);
}
catch (Exception ex)
{
    Console.WriteLine(ex.Message);
}

希望这能有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-03-07
    • 1970-01-01
    • 1970-01-01
    • 2013-07-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-09
    相关资源
    最近更新 更多