Как мне проанализировать и преобразовать DateTime в формат даты и времени RFC 3339?

Как преобразовать структуру DateTime в эквивалентное ей строковое представление в формате RFC 3339 и / или проанализировать это строковое представление обратно в структуру DateTime? Формат даты и времени RFC-3339 используется в ряде спецификаций, таких как Формат синдикации Atom.

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
47
0
39 482
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

Ответ принят как подходящий

Это реализация на C# того, как анализировать и преобразовывать DateTime в его представление 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?

Matt Howells 01.04.2010 18:50

Придется согласиться с Мэттом здесь. RFC3339 не обслуживается одним из стандартных форматов DateTime.ToString, что удивительно, но XmlConvert выполняет свою работу. Например. Я использую XmlConvert.ToString (значение, XmlDateTimeSerializationMode.Utc)

Andrew Webb 05.03.2012 21:23

Привет, @AndrewWebb, а что, если данные отформатированы вот так, 2015-05-04T10:08:15+00:00. Я слышал, что это также считается RFC3339, но RFC3339 не распознает его как действительный DateTime ни с одним из XmlDateTimeSerializationMode.

Stoyan Dimov 04.05.2015 14:50

@StoyanDimov: var d = System.Xml.XmlConvert.ToDateTime("2015-05-04T10:08:15+00:00"‌​, System.Xml.XmlDateTimeSerializationMode.Utc); у меня работает.

Andrew Webb 05.05.2015 15:51

Спасибо за это, если вы используете .NET Core, XmlConvert недоступен.

wonea 21.10.2016 12:41

.NET Core 3.1 (возможно, более ранний) имеет XmlConvert.

camios 13.03.2020 11:53

В .NET (при условии UTC):

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

DateTime.Parse() можно использовать для обратного преобразования в структуру DateTime.

Не думайте, что «ГГГГ-ММ-ДД'Т'ЧЧ: мм: сс» может быть правильным; у него нет ни смещения от UTC, ни "Z" (= нулевое смещение от UTC).

Andrew Webb 02.03.2012 18:05

У меня это не сработало. Пришлось использовать datetime.ToUniversalTime().ToString("yyyy-MM-dd'T'HH:mm:ssZ"‌​)

Tomáš Linhart 09.06.2016 00:29

Он работает только тогда, когда DateTime находится в часовом поясе UTC (всемирное время).

Mark Cidade 09.06.2016 03:20

должно быть гггг и дд, а не заглавные буквы

Aris 19.02.2021 22:32

Вам не нужно писать собственный код преобразования. Просто используйте

XmlConvert.ToDateTime(string s, XmlDateTimeSerializationMode dateTimeOption)

для анализа строки RFC-3339 и

XmlConvert.ToString(DateTime value, XmlDateTimeSerializationMode dateTimeOption)

для преобразования даты и времени (UTC) в строку.

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

Просто добавлю, что эта библиотека отлично работает, анализируя и конвертируя даты событий календаря Google в / из .NET Datetime.

Yiannis Mpourkelis 04.12.2014 02:35

Простое уравнение позволит получить результат, который вам нужен:

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

Для полноты картины Newtonsoft.Json тоже с радостью сделает это:

JsonConvert.SerializeObject(DateTime.Now);

(В отличие от XmlConvert будет избегать двойных кавычек на каждом конце.)

Другие вопросы по теме