我收到的邮件档案中有这样的日期。
Wed, 17 Dec 1997 13:36:23 +2
Mon, 16 Jun 1997 15:41:52 EST
Tue, 15 Jul 1997 14:37:00 EDT
Tue, 5 Aug 1997 08:37:56 PST
Tue, 5 Aug 1997 15:46:16 PDT
Thu, 5 Mar 1998 08:44:19 MET
Mon, 8 Nov 1999 17:49:25 GMT
Thu, 24 Feb 94 20:06:06 MST
Mon, 19 Dec 2005 14:17:06 CST
Thu, 14 Sep 95 19:15 CDT
Sat, 22 Feb 1997 05:16:55 UT
Mon, 8 Jul 1996 15:48:54 GMT-5
Mon, 25 Nov 1996 17:10:28 WET
Mon, 6 Jan 1997 23:43:48 UT
Fri, 13 Jun 1997 16:44:03 -0400
Ask将此时间转换为UTC。这就是我努力做到的。
static void Main(string[] args)
{
var possibleValues = new string[]
{
"Mon, 29 Sep 2014 08:33:35 +0200"
, "Fri, 29 Jun 2001 07:53:01 -0700"
,"Fri, 26 Sep 2014 15:57:04 +0000"
,"Wed, 17 Dec 1997 13:36:23 +2"
, "Fri, 13 Jun 1997 16:44:03 -0400"
, "Mon, 16 Jun 1997 15:41:52 EST"
, "Tue, 15 Jul 1997 14:37:00 EDT"
, "Tue, 5 Aug 1997 08:37:56 PST"
, "Tue, 5 Aug 1997 15:46:16 PDT"
, "Thu, 5 Mar 1998 08:44:19 MET"
, "Mon, 8 Nov 1999 17:49:25 GMT"
, "Thu, 24 Feb 94 20:06:06 MST"
, "Mon, 19 Dec 2005 14:17:06 CST"
, "Thu, 14 Sep 95 19:15:00 CDT"
, "Sat, 22 Feb 1997 05:16:55 UT"
, "Mon, 8 Jul 1996 15:48:54 GMT-5"
, "Mon, 25 Nov 1996 17:10:28 WET"
, "Mon, 6 Jan 1997 23:43:48 UT"
};
foreach (var item in possibleValues)
{
var dateParts = item.Split(' ');
var lastItem = dateParts[dateParts.Length - 1];
if (lastItem.StartsWith("+") || lastItem.StartsWith("-"))
{
try
{
DateTimeOffset offset = DateTimeOffset.Parse(item, CultureInfo.InvariantCulture);
Debug.WriteLine("Input: {0}, UTC Time: {1}", item, offset.UtcDateTime);
}
catch (Exception exc)
{
Debug.WriteLine("Failed - {0}, Error Message: {1}", item, exc.Message);
}
}
else
{
//Sometimes year is a two digit number and sometimes it is 4 digit number.
string dateFormat = string.Format("ddd, {0} MMM {1} {2}:mm:ss {3}", new string('d', dateParts[1].Length), new string('y', dateParts[3].Length), int.Parse(dateParts[4].Substring(0, 2)) > 12 ? "HH" : "hh", lastItem);
try
{
DateTimeOffset offset = DateTimeOffset.ParseExact(item, dateFormat, CultureInfo.InvariantCulture, DateTimeStyles.None);
Debug.WriteLine("Input: {0}, UTC Time: {1}", item, offset.UtcDateTime);
}
catch (Exception exc)
{
Debug.WriteLine("Failed - {0}, DateFormat Tried: {1}, Error Message: {2}", item, dateFormat, exc.Message);
}
}
}
}
我不知道如何处理所有的案件。我也愿意利用野田时间。
我已经通过SO和谷歌的许多链接找到了这个答案,但无法从这些链接中实现任何答案。如果你知道类似的问题,请告诉我。
我已经浏览了以下链接。
Convert.ToDateTime方法
在类型之间转换
夏令时和时区最佳实践
SO标签时区
在.NET Framework中使用DateTime编码最佳实践
转换-utc-date-time-string-in--c-sharp
这些日期似乎大多符合经RFC 1123§5.2.14修订的RFC 822§5.1。
但是,指定的几个时区不符合要求。
- "WET";通常为+0000
- "MET";是罕见的,但此处显示为+0100
- "GMT-5";应写成"-0500"
- "2〃;应写成"+0200"
该格式仅提供以下定义:
- "UT"/"GMT"=+0100
- "EDT"=-0400
- "EST"/"CDT"=-0500
- "CST"/"MDT"=-0600
- "MST"/"PDT"=-0700
- "PST"=-0800
请注意,在正常情况下,任何时区缩写都可能不明确。例如;CST";,正如您在这个列表中看到的。只有在这种特殊的格式中,缩写才有特定的上下文。换句话说;CST";是中国标准时间的有效缩写,您永远不会在RFC822/1123格式的值中使用CST。相反,您会使用"+0800";。
现在在.NET中,RFC822/1123格式包含在"R"
标准格式说明符中。通常,可以使用"R"
说明符调用DateTimeOffset.ParseExact
或DateTime.ParseExact
。然而,你不能在这里使用它,因为它不识别除"以外的任何时区缩写;GMT";,它也不适用于抵消或两位数的年份。
然而,非精确解析器(DateTimeOffset.Parse
或DateTime.Parse
)似乎可以识别大多数重要的比特,我们可以利用这一点。您必须进行一些预处理,以指定可以识别的时区偏移。
private static readonly Dictionary<string,string> TZMap = new Dictionary<string, string>
{
// Defined by RFC822, but not known to .NET
{"UT", "+0000"},
{"EST", "-0500"},
{"EDT", "-0400"},
{"CST", "-0600"},
{"CDT", "-0500"},
{"MST", "-0700"},
{"MDT", "-0600"},
{"PST", "-0800"},
{"PDT", "-0700"},
// Extraneous, as found in your data
{"WET", "+0000"},
{"MET", "+0100"}
};
public static DateTimeOffset Parse(string s)
{
// Get the time zone part of the string
var tz = s.Substring(s.LastIndexOf(' ') + 1);
// Replace time zones defined in the map
if (TZMap.ContainsKey(tz))
{
s = s.Substring(0, s.Length - tz.Length) + TZMap[tz];
}
// Replace time zone offsets with leading characters
if (tz.StartsWith("GMT+") || tz.StartsWith("GMT-") || tz.StartsWith("UTC+") || tz.StartsWith("UTC-"))
{
s = s.Substring(0, s.Length - tz.Length) + tz.Substring(3);
}
DateTimeOffset dto;
if (DateTimeOffset.TryParse(s, CultureInfo.InvariantCulture, DateTimeStyles.None, out dto))
{
return dto;
}
throw new ArgumentException("Could not parse value: " + s);
}
这将传递您提供的所有示例值,但是您可能会发现需要添加到映射中的更多无关值。在识别所有边缘案例之前,可能需要对数据进行多次检查。
当然,由于您在这里得到的是DateTimeOffset
,如果您想要UTC值,可以使用.UtcDateTime
或.ToUniversalTime()
。