转载自:https://stackoverflow.com/questions/284775/how-do-i-parse-and-convert-datetime-s-to-the-rfc-822-date-time-format
问:RFC822 日期-时间被很多应用到很多规范中,比如 RSS格式 ;在.NET中,我怎样将DateTime结构转换成等效RFC822日期时间格式
字符串展现,并且又能解析此字符串(string),重新用DateTime结构的呈现呢?
解决方法1:
DateTime today = DateTime.Now; String rfc822 = today.ToString("r"); Console.WriteLine("RFC-822 date: {0}", rfc822); DateTime parsedRFC822 = DateTime.Parse(rfc822); Console.WriteLine("Date: {0}", parsedRFC822);
传入DateTime.toString()方法格式符号"r"实际上产生的是RFC1123规范格日期时间串,基于http://www.w3.org/Protocols/rfc822/#z28规范得知,当时传入RFC-822日期也是可以的。
我已经使用该方法创建了RSS源,并且通过了http://validator.w3.org/feed/check.cgi校验器的验证。
该方法的缺点是,在转换中他将日期时间转换成GMT格式的,要转回本地时间,您需要使用本地时区偏移量。为此,您可以使用TimeZone类获取当前时区偏移量,并将GMT替换成时区偏移量时间的字符串。
TimeZone tz = TimeZone.CurrentTimeZone; String offset = tz.GetUtcOffset().ToString(); // My locale is Mountain time; offset is set to "-07:00:00" // if local time is behind utc time, offset should start with "-". // otherwise, add a plus sign to the beginning of the string. if (!offset.StartsWith("-")) offset = "+" + offset; // Add a (+) if it's a UTC+ timezone offset = offset.Substring(0,6); // only want the first 6 chars. offset = offset.Replace(":", ""); // remove colons. // offset now looks something like "-0700". rfc822 = rfc822.Replace("GMT", offset); // The rfc822 string can now be parsed back to a DateTime object, // with the local time accounted for. DateTime new = DateTime.Parse(rfc822);
解决方法2:
这是 C# 中有关如何解析 DateTime 并将其转换为其 RFC-822 表示形式和转换日期时间的实现。
它唯一的限制是DateTime是UTC格式的。我承认这不是很优雅的代码,但他是能运行的。
////// Provides methods for converting structures /// to and from the equivalent RFC 822 /// string representation. /// public class Rfc822DateTime { //============================================================ // Private members //============================================================ #region Private Members /// /// Private member to hold array of formats that RFC 822 date-time representations conform to. /// private static string[] formats = new string[0]; /// /// Private member to hold the DateTime format string for representing a DateTime in the RFC 822 format. /// private const string format = "ddd, dd MMM yyyy HH:mm:ss K"; #endregion //============================================================ // Public Properties //============================================================ #region Rfc822DateTimeFormat /// /// Gets the custom format specifier that may be used to represent a in the RFC 822 format. /// /// A DateTime format string that may be used to represent a in the RFC 822 format. /// /// /// This method returns a string representation of a that utilizes the time zone /// offset (local differential) to represent the offset from Greenwich mean time in hours and minutes. /// The is a valid date-time format string for use /// in the method. /// /// /// The RFC 822 Date and Time specification /// specifies that the year will be represented as a two-digit value, but the /// RSS Profile recommends that /// all date-time values should use a four-digit year. The class /// follows the RSS Profile recommendation when converting a to the equivalent /// RFC 822 string representation. /// /// public static string Rfc822DateTimeFormat { get { return format; } } #endregion #region Rfc822DateTimePatterns /// /// Gets an array of the expected formats for RFC 822 date-time string representations. /// /// /// An array of the expected formats for RFC 822 date-time string representations /// that may used in the method. /// /// /// The array of the expected formats that is returned assumes that the RFC 822 time zone /// is represented as or converted to a local differential representation. /// /// public static string[] Rfc822DateTimePatterns { get { if (formats.Length > 0) { return formats; } else { formats = new string[35]; // two-digit day, four-digit year patterns formats[0] = "ddd',' dd MMM yyyy HH':'mm':'ss'.'fffffff zzzz"; formats[1] = "ddd',' dd MMM yyyy HH':'mm':'ss'.'ffffff zzzz"; formats[2] = "ddd',' dd MMM yyyy HH':'mm':'ss'.'fffff zzzz"; formats[3] = "ddd',' dd MMM yyyy HH':'mm':'ss'.'ffff zzzz"; formats[4] = "ddd',' dd MMM yyyy HH':'mm':'ss'.'fff zzzz"; formats[5] = "ddd',' dd MMM yyyy HH':'mm':'ss'.'ff zzzz"; formats[6] = "ddd',' dd MMM yyyy HH':'mm':'ss'.'f zzzz"; formats[7] = "ddd',' dd MMM yyyy HH':'mm':'ss zzzz"; // two-digit day, two-digit year patterns formats[8] = "ddd',' dd MMM yy HH':'mm':'ss'.'fffffff zzzz"; formats[9] = "ddd',' dd MMM yy HH':'mm':'ss'.'ffffff zzzz"; formats[10] = "ddd',' dd MMM yy HH':'mm':'ss'.'fffff zzzz"; formats[11] = "ddd',' dd MMM yy HH':'mm':'ss'.'ffff zzzz"; formats[12] = "ddd',' dd MMM yy HH':'mm':'ss'.'fff zzzz"; formats[13] = "ddd',' dd MMM yy HH':'mm':'ss'.'ff zzzz"; formats[14] = "ddd',' dd MMM yy HH':'mm':'ss'.'f zzzz"; formats[15] = "ddd',' dd MMM yy HH':'mm':'ss zzzz"; // one-digit day, four-digit year patterns formats[16] = "ddd',' d MMM yyyy HH':'mm':'ss'.'fffffff zzzz"; formats[17] = "ddd',' d MMM yyyy HH':'mm':'ss'.'ffffff zzzz"; formats[18] = "ddd',' d MMM yyyy HH':'mm':'ss'.'fffff zzzz"; formats[19] = "ddd',' d MMM yyyy HH':'mm':'ss'.'ffff zzzz"; formats[20] = "ddd',' d MMM yyyy HH':'mm':'ss'.'fff zzzz"; formats[21] = "ddd',' d MMM yyyy HH':'mm':'ss'.'ff zzzz"; formats[22] = "ddd',' d MMM yyyy HH':'mm':'ss'.'f zzzz"; formats[23] = "ddd',' d MMM yyyy HH':'mm':'ss zzzz"; // two-digit day, two-digit year patterns formats[24] = "ddd',' d MMM yy HH':'mm':'ss'.'fffffff zzzz"; formats[25] = "ddd',' d MMM yy HH':'mm':'ss'.'ffffff zzzz"; formats[26] = "ddd',' d MMM yy HH':'mm':'ss'.'fffff zzzz"; formats[27] = "ddd',' d MMM yy HH':'mm':'ss'.'ffff zzzz"; formats[28] = "ddd',' d MMM yy HH':'mm':'ss'.'fff zzzz"; formats[29] = "ddd',' d MMM yy HH':'mm':'ss'.'ff zzzz"; formats[30] = "ddd',' d MMM yy HH':'mm':'ss'.'f zzzz"; formats[31] = "ddd',' d MMM yy HH':'mm':'ss zzzz"; // Fall back patterns formats[32] = "yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fffffffK"; // RoundtripDateTimePattern formats[33] = DateTimeFormatInfo.InvariantInfo.UniversalSortableDateTimePattern; formats[34] = DateTimeFormatInfo.InvariantInfo.SortableDateTimePattern; return formats; } } } #endregion //============================================================ // Public Methods //============================================================ #region Parse(string s) /// /// Converts the specified string representation of a date and time to its equivalent. /// /// A string containing a date and time to convert. /// /// A equivalent to the date and time contained in , /// expressed as Coordinated Universal Time (UTC). /// /// /// The string is parsed using formatting information in the object. /// /// is a null reference (Nothing in Visual Basic). /// is an empty string. /// does not contain a valid RFC 822 string representation of a date and time. public static DateTime Parse(string s) { //------------------------------------------------------------ // Validate parameter //------------------------------------------------------------ if (String.IsNullOrEmpty(s)) { throw new ArgumentNullException("s"); } DateTime result; if (Rfc822DateTime.TryParse(s, out result)) { return result; } else { throw new FormatException(String.Format(null, "{0} is not a valid RFC 822 string representation of a date and time.", s)); } } #endregion #region ConvertZoneToLocalDifferential(string s) /// /// Converts the time zone component of an RFC 822 date and time string representation to its local differential (time zone offset). /// /// A string containing an RFC 822 date and time to convert. /// A date and time string that uses local differential to describe the time zone equivalent to the date and time contained in . /// is a null reference (Nothing in Visual Basic). /// is an empty string. public static string ConvertZoneToLocalDifferential(string s) { string zoneRepresentedAsLocalDifferential = String.Empty; //------------------------------------------------------------ // Validate parameter //------------------------------------------------------------ if (String.IsNullOrEmpty(s)) { throw new ArgumentNullException("s"); } if(s.EndsWith(" UT", StringComparison.OrdinalIgnoreCase)) { zoneRepresentedAsLocalDifferential = String.Concat(s.Substring(0, (s.LastIndexOf(" UT") + 1) ), "+00:00"); } else if (s.EndsWith(" GMT", StringComparison.OrdinalIgnoreCase)) { zoneRepresentedAsLocalDifferential = String.Concat(s.Substring(0, (s.LastIndexOf(" GMT") + 1 ) ), "+00:00"); } else if (s.EndsWith(" EST", StringComparison.OrdinalIgnoreCase)) { zoneRepresentedAsLocalDifferential = String.Concat(s.Substring(0, (s.LastIndexOf(" EST") + 1)), "-05:00"); } else if (s.EndsWith(" EDT", StringComparison.OrdinalIgnoreCase)) { zoneRepresentedAsLocalDifferential = String.Concat(s.Substring(0, (s.LastIndexOf(" EDT") + 1)), "-04:00"); } else if (s.EndsWith(" CST", StringComparison.OrdinalIgnoreCase)) { zoneRepresentedAsLocalDifferential = String.Concat(s.Substring(0, (s.LastIndexOf(" CST") + 1)), "-06:00"); } else if (s.EndsWith(" CDT", StringComparison.OrdinalIgnoreCase)) { zoneRepresentedAsLocalDifferential = String.Concat(s.Substring(0, (s.LastIndexOf(" CDT") + 1)), "-05:00"); } else if (s.EndsWith(" MST", StringComparison.OrdinalIgnoreCase)) { zoneRepresentedAsLocalDifferential = String.Concat(s.Substring(0, (s.LastIndexOf(" MST") + 1)), "-07:00"); } else if (s.EndsWith(" MDT", StringComparison.OrdinalIgnoreCase)) { zoneRepresentedAsLocalDifferential = String.Concat(s.Substring(0, (s.LastIndexOf(" MDT") + 1)), "-06:00"); } else if (s.EndsWith(" PST", StringComparison.OrdinalIgnoreCase)) { zoneRepresentedAsLocalDifferential = String.Concat(s.Substring(0, (s.LastIndexOf(" PST") + 1)), "-08:00"); } else if (s.EndsWith(" PDT", StringComparison.OrdinalIgnoreCase)) { zoneRepresentedAsLocalDifferential = String.Concat(s.Substring(0, (s.LastIndexOf(" PDT") + 1)), "-07:00"); } else if (s.EndsWith(" Z", StringComparison.OrdinalIgnoreCase)) { zoneRepresentedAsLocalDifferential = String.Concat(s.Substring(0, (s.LastIndexOf(" Z") + 1)), "+00:00"); } else if (s.EndsWith(" A", StringComparison.OrdinalIgnoreCase)) { zoneRepresentedAsLocalDifferential = String.Concat(s.Substring(0, (s.LastIndexOf(" A") + 1)), "-01:00"); } else if (s.EndsWith(" M", StringComparison.OrdinalIgnoreCase)) { zoneRepresentedAsLocalDifferential = String.Concat(s.Substring(0, (s.LastIndexOf(" M") + 1)), "-12:00"); } else if (s.EndsWith(" N", StringComparison.OrdinalIgnoreCase)) { zoneRepresentedAsLocalDifferential = String.Concat(s.Substring(0, (s.LastIndexOf(" N") + 1)), "+01:00"); } else if (s.EndsWith(" Y", StringComparison.OrdinalIgnoreCase)) { zoneRepresentedAsLocalDifferential = String.Concat(s.Substring(0, (s.LastIndexOf(" Y") + 1)), "+12:00"); } else { zoneRepresentedAsLocalDifferential = s; } return zoneRepresentedAsLocalDifferential; } #endregion #region ToString(DateTime utcDateTime) /// /// Converts the value of the specified object to its equivalent string representation. /// /// The Coordinated Universal Time (UTC) to convert. /// A RFC 822 string representation of the value of the . /// The specified object does not represent a Coordinated Universal Time (UTC) value. public static string ToString(DateTime utcDateTime) { if (utcDateTime.Kind != DateTimeKind.Utc) { throw new ArgumentException("utcDateTime"); } return utcDateTime.ToString(Rfc822DateTime.Rfc822DateTimeFormat, DateTimeFormatInfo.InvariantInfo); } #endregion #region TryParse(string s, out DateTime result) /// /// Converts the specified string representation of a date and time to its equivalent. /// /// A string containing a date and time to convert. /// /// When this method returns, contains the value equivalent to the date and time /// contained in , expressed as Coordinated Universal Time (UTC), /// if the conversion succeeded, or MinValue if the conversion failed. /// The conversion fails if the s parameter is a null reference (Nothing in Visual Basic), /// or does not contain a valid string representation of a date and time. /// This parameter is passed uninitialized. /// /// true if the parameter was converted successfully; otherwise, false. /// /// The string is parsed using formatting information in the object. /// public static bool TryParse(string s, out DateTime result) { //------------------------------------------------------------ // Attempt to convert string representation //------------------------------------------------------------ bool wasConverted = false; result = DateTime.MinValue; if (!String.IsNullOrEmpty(s)) { DateTime parseResult; if (DateTime.TryParseExact(Rfc822DateTime.ConvertZoneToLocalDifferential(s), Rfc822DateTime.Rfc822DateTimePatterns, DateTimeFormatInfo.InvariantInfo, DateTimeStyles.AdjustToUniversal, out parseResult)) { result = DateTime.SpecifyKind(parseResult, DateTimeKind.Utc); wasConverted = true; } } return wasConverted; } #endregion }
评论:RFC822日期规范中,天和秒是可选的,以上代码没有处理。