【问题标题】:How do I parse and convert a DateTime to the RFC 3339 date-time format?如何解析 DateTime 并将其转换为 RFC 3339 日期时间格式?
【发布时间】:2008-08-19 21:40:11
【问题描述】:

如何将 DateTime 结构转换为其等效的RFC 3339 格式化字符串表示和/或将此字符串表示解析回DateTime 结构? RFC-3339 日期时间格式用于许多规范,例如 Atom Syndication Format

【问题讨论】:

    标签: .net datetime rfc3339 atom-feed


    【解决方案1】:

    您无需编写自己的转换代码。只需使用

    XmlConvert.ToDateTime(string s, XmlDateTimeSerializationMode dateTimeOption)
    

    解析 RFC-3339 字符串,并且

    XmlConvert.ToString(DateTime value, XmlDateTimeSerializationMode dateTimeOption)
    

    将 (UTC) 日期时间转换为字符串。

    参考
    http://msdn.microsoft.com/en-us/library/ms162342(v=vs.110).aspx
    http://msdn.microsoft.com/en-us/library/ms162344(v=vs.110).aspx

    【讨论】:

    • 只是补充一点,这个库可以很好地解析和转换从谷歌日历事件到/从 .NET 日期时间的日期
    【解决方案2】:

    这是 C# 中的一个实现,说明如何解析 DateTime 并将其转换为 RFC-3339 表示和从它的 RFC-3339 表示转换。它的唯一限制是 DateTime 采用协调世界时 (UTC)。

    using System;
    using System.Globalization;
    
    namespace DateTimeConsoleApplication
    {
        /// <summary>
        /// Provides methods for converting <see cref="DateTime"/> structures to and from the equivalent RFC 3339 string representation.
        /// </summary>
        public static class Rfc3339DateTime
        {
            //============================================================
            //  Private members
            //============================================================
            #region Private Members
            /// <summary>
            /// Private member to hold array of formats that RFC 3339 date-time representations conform to.
            /// </summary>
            private static string[] formats = new string[0];
            /// <summary>
            /// Private member to hold the DateTime format string for representing a DateTime in the RFC 3339 format.
            /// </summary>
            private const string format = "yyyy-MM-dd'T'HH:mm:ss.fffK";
            #endregion
    
            //============================================================
            //  Public Properties
            //============================================================
            #region Rfc3339DateTimeFormat
            /// <summary>
            /// Gets the custom format specifier that may be used to represent a <see cref="DateTime"/> in the RFC 3339 format.
            /// </summary>
            /// <value>A <i>DateTime format string</i> that may be used to represent a <see cref="DateTime"/> in the RFC 3339 format.</value>
            /// <remarks>
            /// <para>
            /// This method returns a string representation of a <see cref="DateTime"/> that 
            /// is precise to the three most significant digits of the seconds fraction; that is, it represents 
            /// the milliseconds in a date and time value. The <see cref="Rfc3339DateTimeFormat"/> is a valid 
            /// date-time format string for use in the <see cref="DateTime.ToString(String, IFormatProvider)"/> method.
            /// </para>
            /// </remarks>
            public static string Rfc3339DateTimeFormat
            {
                get
                {
                    return format;
                }
            }
            #endregion
    
            #region Rfc3339DateTimePatterns
            /// <summary>
            /// Gets an array of the expected formats for RFC 3339 date-time string representations.
            /// </summary>
            /// <value>
            /// An array of the expected formats for RFC 3339 date-time string representations 
            /// that may used in the <see cref="DateTime.TryParseExact(String, string[], IFormatProvider, DateTimeStyles, out DateTime)"/> method.
            /// </value>
            public static string[] Rfc3339DateTimePatterns
            {
                get
                {
                    if (formats.Length > 0)
                    {
                        return formats;
                    }
                    else
                    {
                        formats = new string[11];
    
                        // Rfc3339DateTimePatterns
                        formats[0] = "yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fffffffK";
                        formats[1] = "yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'ffffffK";
                        formats[2] = "yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fffffK";
                        formats[3] = "yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'ffffK";
                        formats[4] = "yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fffK";
                        formats[5] = "yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'ffK";
                        formats[6] = "yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fK";
                        formats[7] = "yyyy'-'MM'-'dd'T'HH':'mm':'ssK";
    
                        // Fall back patterns
                        formats[8] = "yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fffffffK"; // RoundtripDateTimePattern
                        formats[9] = DateTimeFormatInfo.InvariantInfo.UniversalSortableDateTimePattern;
                        formats[10] = DateTimeFormatInfo.InvariantInfo.SortableDateTimePattern;
    
                        return formats;
                    }
                }
            }
            #endregion
    
            //============================================================
            //  Public Methods
            //============================================================
            #region Parse(string s)
            /// <summary>
            /// Converts the specified string representation of a date and time to its <see cref="DateTime"/> equivalent.
            /// </summary>
            /// <param name="s">A string containing a date and time to convert.</param>
            /// <returns>A <see cref="DateTime"/> equivalent to the date and time contained in <paramref name="s"/>.</returns>
            /// <remarks>
            /// The string <paramref name="s"/> is parsed using formatting information in the <see cref="DateTimeFormatInfo.InvariantInfo"/> object.
            /// </remarks>
            /// <exception cref="ArgumentNullException"><paramref name="s"/> is a <b>null</b> reference (Nothing in Visual Basic).</exception>
            /// <exception cref="FormatException"><paramref name="s"/> does not contain a valid RFC 3339 string representation of a date and time.</exception>
            public static DateTime Parse(string s)
            {
                //------------------------------------------------------------
                //  Validate parameter
                //------------------------------------------------------------
                if(s == null)
                {
                    throw new ArgumentNullException("s");
                }
    
                DateTime result;
                if (Rfc3339DateTime.TryParse(s, out result))
                {
                    return result;
                }
                else
                {
                    throw new FormatException(String.Format(null, "{0} is not a valid RFC 3339 string representation of a date and time.", s));
                }
            }
            #endregion
    
            #region ToString(DateTime utcDateTime)
            /// <summary>
            /// Converts the value of the specified <see cref="DateTime"/> object to its equivalent string representation.
            /// </summary>
            /// <param name="utcDateTime">The Coordinated Universal Time (UTC) <see cref="DateTime"/> to convert.</param>
            /// <returns>A RFC 3339 string representation of the value of the <paramref name="utcDateTime"/>.</returns>
            /// <remarks>
            /// <para>
            /// This method returns a string representation of the <paramref name="utcDateTime"/> that 
            /// is precise to the three most significant digits of the seconds fraction; that is, it represents 
            /// the milliseconds in a date and time value.
            /// </para>
            /// <para>
            /// While it is possible to display higher precision fractions of a second component of a time value, 
            /// that value may not be meaningful. The precision of date and time values depends on the resolution 
            /// of the system clock. On Windows NT 3.5 and later, and Windows Vista operating systems, the clock's 
            /// resolution is approximately 10-15 milliseconds.
            /// </para>
            /// </remarks>
            /// <exception cref="ArgumentException">The specified <paramref name="utcDateTime"/> object does not represent a <see cref="DateTimeKind.Utc">Coordinated Universal Time (UTC)</see> value.</exception>
            public static string ToString(DateTime utcDateTime)
            {
                if (utcDateTime.Kind != DateTimeKind.Utc)
                {
                    throw new ArgumentException("utcDateTime");
                }
    
                return utcDateTime.ToString(Rfc3339DateTime.Rfc3339DateTimeFormat, DateTimeFormatInfo.InvariantInfo);
            }
            #endregion
    
            #region TryParse(string s, out DateTime result)
            /// <summary>
            /// Converts the specified string representation of a date and time to its <see cref="DateTime"/> equivalent.
            /// </summary>
            /// <param name="s">A string containing a date and time to convert.</param>
            /// <param name="result">
            /// When this method returns, contains the <see cref="DateTime"/> value equivalent to the date and time 
            /// contained in <paramref name="s"/>, if the conversion succeeded, 
            /// or <see cref="DateTime.MinValue">MinValue</see> if the conversion failed. 
            /// The conversion fails if the s parameter is a <b>null</b> reference (Nothing in Visual Basic), 
            /// or does not contain a valid string representation of a date and time. 
            /// This parameter is passed uninitialized.
            /// </param>
            /// <returns><b>true</b> if the <paramref name="s"/> parameter was converted successfully; otherwise, <b>false</b>.</returns>
            /// <remarks>
            /// The string <paramref name="s"/> is parsed using formatting information in the <see cref="DateTimeFormatInfo.InvariantInfo"/> object.
            /// </remarks>
            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(s, Rfc3339DateTime.Rfc3339DateTimePatterns, DateTimeFormatInfo.InvariantInfo, DateTimeStyles.AdjustToUniversal, out parseResult))
                    {
                        result          = DateTime.SpecifyKind(parseResult, DateTimeKind.Utc);
                        wasConverted    = true;
                    }
                }
    
                return wasConverted;
            }
            #endregion
        }
    }
    

    【讨论】:

    • 为什么要为已经在 BCL 中的东西编写这段代码?
    • 这里必须同意马特的观点。 DateTime.ToString 标准格式之一不能满足 RFC3339 的要求——这令人惊讶——但 XmlConvert 可以完成这项工作。例如。我使用 XmlConvert.ToString(value, XmlDateTimeSerializationMode.Utc)
    • 嘿@AndrewWebb,如果数据格式像这样2015-05-04T10:08:15+00:00this。我听说这也被认为是 RFC3339 但RFC3339 不会将其识别为有效的 DateTime 而没有XmlDateTimeSerializationMode
    • @StoyanDimov: var d = System.Xml.XmlConvert.ToDateTime("2015-05-04T10:08:15+00:00", System.Xml.XmlDateTimeSerializationMode.Utc); 为我工作。
    • 感谢您,如果您使用的是 .NET Core XmlConvert 不可用。
    【解决方案3】:

    为了完整起见,Newtonsoft.Json 也很乐意这样做:

    JsonConvert.SerializeObject(DateTime.Now);
    

    (与 XmlConvert 不同的是,每端都会转义双引号。)

    【讨论】:

      【解决方案4】:

      System.Text.Json 也这样做:

      JsonSerializer.Serialize(DateTime.Now)
      

      【讨论】:

        【解决方案5】:
        <input asp-for="StartDate" class="form-control" value="@DateTime.Now.ToString("yyyy-MM-ddThh:mm:ss")" />
        

        【讨论】:

        • 请添加更多详细信息以扩展您的答案,例如工作代码或文档引用。
        【解决方案6】:

        在 .NET 中(假设 UTC):

         datetime.ToString("YYYY-MM-DD'T'HH:mm:ssZ")
        

        DateTime.Parse() 可用于转换回DateTime 结构。

        【讨论】:

        • 不要认为“YYYY-MM-DD'T'HH:mm:ss”可能是对的;它没有与 UTC 的偏移量,也没有“Z”(= 与 UTC 的零偏移量)。
        • 这对我不起作用。我不得不使用datetime.ToUniversalTime().ToString("yyyy-MM-dd'T'HH:mm:ssZ")
        • 仅当 DateTime 在 UTC 时区(通用时间)时有效。
        • 必须是 yyyy 和 dd,而不是大写
        【解决方案7】:

        一个简单的方程就能得到你想要的结果:

        rfcFormat = DateDiff("s", "1/1/1970", Now())
        

        【讨论】:

          猜你喜欢
          • 2010-09-22
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-08-27
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多