Почему форматирование DateTime как строки усекается, а не округляется до миллисекунд? - PullRequest
13 голосов
/ 14 сентября 2011

Когда Double отформатирован как используется округление строки. Э.Г.

Console.WriteLine(12345.6.ToString("F0"));

выходы

12346

Однако, когда DateTime отформатирован как усечение строки, используется. Э.Г.

var ci = CultureInfo.InvariantCulture;
var dateTime = DateTime.Parse("2011-09-14T15:18:42.999", ci);
Console.WriteLine(dateTime.ToString("o", ci));
Console.WriteLine(dateTime.ToString("s", ci));
Console.WriteLine(dateTime.ToString("yyyy-MM-hhThh:mm:ss.f", ci));

1012 * выходы *

2011-09-14T15:18:42.9990000
2011-09-14T15:18:42
2011-09-14T15:18:42.9

В чем причина (если таковая имеется) такого поведения?


Округление до ближайшей секунды может быть достигнуто путем добавления полсекунды перед форматированием в виде строки:

var ci = CultureInfo.InvariantCulture;
var dateTime = DateTime.Parse("2010-12-31T23:59:59.999", ci);
Console.WriteLine(dateTime.ToString("s", ci));
var roundedDateTime = dateTime.AddMilliseconds(500);
Console.WriteLine(roundedDateTime.ToString("s", ci));

выходы

2010-12-31T23:59:59
2011-01-01T00:00:00

Ответы [ 3 ]

17 голосов
/ 14 сентября 2011

Это немного субъективно, но я бы сказал, что округление значений даты и времени, а не их усечение приведет к «более» неожиданному поведению.

Например, округление new DateTime(2011, 1, 1, 23, 59, 59, 999) приведетНовый день полностью.Это звучит гораздо более странно, чем просто усечение значения.

1 голос
/ 11 сентября 2015

Старый вопрос, но он был передан из нового, и ответы обсуждают причины округления или нет (что, конечно, верно), но оставляют вопрос без ответа.

Причина не округления в том, что ToString просто печатает части даты / времени, которые вы запрашиваете.

Таким образом, например, он также не округляется до ближайшей минуты:

Console.WriteLine(dateTime.ToString("yyyy-MM-hhThh:mm", ci));

Выход:

2011-09-03T03:18

Без параметров ToString использует строку формата даты / времени по умолчанию для вашей среды.

0 голосов
/ 22 января 2013

В конечной единице измерения, если событие происходит на этой частоте, округление сокращается при наложении псевдонимов.

Например, если из-за дрожания один второй кадр данных поступает через 2 мсек во второй, а следующий кадр поступает на 990 мсек в один и тот же кадр, они оба будут помечены как находящиеся в одной и той же секунде. Дрожание всего в несколько миллисекунд приведет к разбросу множества неуникальных значений ключа.

Округление поместило бы их в несколько секунд чисто пока дрожание не станет намного более сильным, скажем +/- 499 мс.

Цель округления состоит в том, чтобы остановить разрешение навсегда. Когда неопределенность намного ниже разрешающей способности, она сильно сокращает алиасинг.

«Каскадирование» может иметь место только при разрешении границы меньше. Например, число смены года кажется шокирующим, но это может произойти только при меньшей чем секунда (или миллисекунда и т. д.) с полуночи нового года. Ничего неожиданного или особенно неточно.

Чтобы действительно предотвратить алиасинг (то же самое время, упомянутое дважды), вам нужно реализовать сглаживание (как в графике) после округления.

...