Что вызывает такое поведение в нашем типе C # DateTime?

#c#

#c#

Вопрос:

 [Test]
public void Sadness()
{
   var dateTime = DateTime.UtcNow;
   Assert.That(dateTime, Is.EqualTo(DateTime.Parse(dateTime.ToString())));
}
 

Сбой :

  Expected: 2011-10-31 06:12:44.000
 But was:  2011-10-31 06:12:44.350
 

Я хотел бы знать, что происходит за кулисами в toString() и т.д., чтобы вызвать такое поведение.

ОТРЕДАКТИРУЙТЕ, увидев ответ Джона :

 [Test]
public void NewSadness()
{
    var dateTime = DateTime.UtcNow;
    Assert.That(dateTime, Is.EqualTo(DateTime.Parse(dateTime.ToString("o"))));
}
 

Результат :

 Expected: 2011-10-31 12:03:04.161
But was:  2011-10-31 06:33:04.161
 

Тот же результат с большой буквы и маленькой буквы «о» . Я читаю документы, но все еще неясно.

Комментарии:

1. Добавление CultureInfo.InvariantCulture не помогло: оно создало Expected: 2011-10-31 12:09:51.928 But was: 2011-10-31 06:39:51.928

2. Некоторая логика синтаксического анализа / для строковой логики добавила к этому времени 6 часов и 30 минут : (

Ответ №1:

Посмотрите, что dateTime.ToString() получается — обычно это будет с точностью до секунды, хотя это зависит от культурных настроек. Если ToString() только дает результат с точностью до секунды, нет никакого способа, которым синтаксический анализ строки может дать больше информации…

Вы можете использовать строку стандартного формата «o», чтобы обеспечить представление строки с возможностью округления. Например, в данный момент он производит что-то вроде:

 2011-10-31T06:28:34.6425574Z
 

РЕДАКТИРОВАТЬ: вам нужно выполнить синтаксический анализ с тем же спецификатором, чтобы получить тот же результат обратно:

 string text = dateTime.ToString("o");
// Culture is irrelevant when using the "o" specifier
DateTime parsed = DateTime.ParseExact(text, "o", null,
                                      DateTimeStyles.RoundtripKind);
 

Комментарии:

1. 1. Зас, пожалуйста, ПРОЧТИТЕ статью MSDN, на которую ссылается Джон, особенно форматы «o» и «u». Существует подробное объяснение, как достичь туда и обратно.

2. Спасибо, это то, что я искал.

Ответ №2:

Спецификатором формата по умолчанию является «G» — формат общего назначения, который имеет ограниченную точность. Если вы хотите воспроизвести в точности то же самое, используйте спецификатор туда и обратно «O».

 string s = dateTime.ToString("O", CultureInfo.InvariantCulture);
Assert.That(dateTime, Is.EqualTo(DateTime.ParseExact(
       s, "O", CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind)));
 

Комментарии:

1. Я отредактировал свой вопрос, включив вашу идею — и результат странный, я все еще озадачен

2. @Zasz почему результат странный? Если вы добавляете путаницу в то, что в вашем тесте «ожидаемые» и «фактические» неправильные пути … это все, что мы здесь имеем в виду?

3. @Zasz попробуйте также использовать DateTime.Parse(s, null, DateTimeStyles.RoundtripKind)

4. @Zasz, чтобы подчеркнуть — важно убедиться, что синтаксический анализ знает, что он ожидает туда и обратно

5. Хороший призыв к необходимости RoundtripKind. Я только что попробовал, и это необходимо для правильного обхода. Это довольно странно, учитывая, что оно присутствует в форматированной строке. Странно.