Парсинг TeamCity (Java?) - сгенерированная метка времени в.NET?

Я пытаюсь интегрироваться с TeamCity REST API. Это содержит метки времени формы 20100804T104413+0100. Это - почти ISO 8601, но не содержит дефисы.

Как я преобразовываю это из a string к a DateTime в.NET? Я попробовал:

DateTime.ParseExact(s, "yyyyMMddTHHmmss+zzzz", CultureInfo.InvariantCulture);

(и без +zzzz), но я добираюсь String was not recognized as a valid DateTime.

7
задан Roger Lipscombe 4 August 2010 в 12:10
поделиться

2 ответа

У меня это работает:

using System;
using System.Globalization;

class Test
{
    static void Main()
    {
        string text = "20100804T104413+0100";

        DateTime dt = DateTime.ParseExact
            (text,
             "yyyyMMdd'T'HHmmsszzz",
             CultureInfo.InvariantCulture);
        Console.WriteLine(dt);           
    }
}

На самом деле вам не нужны кавычки вокруг буквы «Т», но я стараюсь вставить их, чтобы сделать шаблон более понятным. Точно так же «zzz» может быть «zzzz» - но я думаю, проблема была в «+», который был у вас до «zzz».

Обратите внимание, что если вы переформатируете его, используя тот же формат, вы получите ":" в середине спецификатора смещения: (

9
ответ дан 6 December 2019 в 14:00
поделиться

Я знаю вопрос. уже ответил, но я считаю, что есть несколько примечаний, если можно:

Проблемы с использованием DateTime

Я бы посоветовал не использовать DateTime в вашем сценарии, поскольку кажется вероятным, что вы хотите, чтобы представление было равным при обратном преобразовании (т. е. при обратном преобразовании в строку представление должно быть равным). Проблема с DateTime в том, что он не сохраняет точную информацию о часовом поясе.

Предлагаемое решение позволяет изменять информацию о часовом поясе. Это зависит от ввода, но, используя инвариантный язык и региональные параметры, вы получите объект DateTime {4-8-2010 11:44:13} . Я думал, что это можно исправить, используя DateTimeStyles.RoundtripKind , как в следующем примере, но, учитывая, что в DateTime нет информации о часовом поясе, это все равно не сработает:

// DON'T DO THIS, dangerous code ahead:

DateTime time = DateTime.ParseExact(
     "20100804T104413+0100", 
     "yyyyMMdd'T'HHmmssK", 
     CultureInfo.InvariantCulture, 
     DateTimeStyles.RoundtripKind);

// loosing data when converting back:
string convertedBack = time.ToString("yyyyMMdd'T'HHmmssK");
// convertedBack now contains "20100804T114413+02:00"

Вместо этого используйте DateTimeOffset

Эта проблема исчезнет, ​​если вы вместо этого используете DateTimeOffset для своих задач. Идея остается той же, но внезапно срабатывает обратный обмен:

// DO THIS instead:

DateTimeOffset parsedDate = DateTimeOffset.ParseExact(
     "20100804T104413+0100", 
     "yyyyMMdd'T'HHmmsszzz", 
     CultureInfo.InvariantCulture, 
     DateTimeStyles.RoundtripKind);

// converting back is now easy:
convertedBack = parsedDate.ToString("yyyyMMdd'T'HHmmssK");
// convertedBack contains the string "20100804T104413+01:00"

Конечно, важна ли информация о часовом поясе от вашей ситуации. Но это будет не первый раз, когда 10 часов изменится на 11, и тогда найти ошибку может быть сложно.

Работа с двоеточием в часовом поясе

Как упоминал Джон Скит, в вашем выводе есть двоеточие «:», которого не было на входе. Таким образом, полный обход кажется невозможным. К сожалению, в то время как DateTimeFormatInfo в любой культуре можно изменить для изменения почти каждого внешнего вида, то есть вы можете установить TimeSeparator в пустую строку, и двоеточия исчезают в форматированных временах, этот уровень детализации недоступен в смещении часового пояса. Хуже того, Reflector показывает, что он намеренно жестко запрограммирован (однажды у меня была такая же проблема с удалением «+» для положительных смещений):

if (offset >= TimeSpan.Zero)
{
    result.Append('+');
}
else
{
    result.Append('-');
    offset = offset.Negate();
}
result.AppendFormat(CultureInfo.InvariantCulture, "{0:00}:{1:00}", new object[] { offset.Hours, offset.Minutes });

Решение состоит в том, чтобы либо предоставить свой собственный IFormatProvider , либо чтобы быть прагматичным, просто удалите двоеточие:

convertedBack = parsedDate.ToString("yyyyMMdd'T'HHmmssK").Replace(":", "");
4
ответ дан 6 December 2019 в 14:00
поделиться
Другие вопросы по тегам:

Похожие вопросы: