2011-09-14 15 views
12

Cuando se formatea un Double se utiliza el redondeo de cadena. P.ej.¿Por qué el formatear un DateTime como una cadena trunca y no redondea los milisegundos?

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

salidas

12346 

Sin embargo, cuando un DateTime se formatea como se utiliza un truncamiento de cadena. P.ej.

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)); 

salidas

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

Cuál es el razonamiento (si lo hay) detrás de este comportamiento?


El redondeo hasta el último segundo se puede lograr mediante la adición de medio segundo antes de formatear como una cadena:

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)); 

salidas

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

Respuesta

16

Esto es un poco subjetivo, pero yo diría los valores de fecha y hora de redondeo en lugar de truncarlos generarían un comportamiento "más" inesperado.

Por ejemplo, el redondeo new DateTime(2011, 1, 1, 23, 59, 59, 999) daría lugar a un nuevo día completo. Esto suena mucho más raro que simplemente truncar el valor.

+2

+1, gracias. Esa es una dimensión en la que nunca pensé. –

+1

Y si el nuevo día es el próximo año, las cascadas de redondeo todo el año. En la mayoría de las situaciones, probablemente no sea lo que quieres para las fechas. –

+1

Quizás otra forma de pensarlo: las unidades de tiempo son _paneles_ no puntos temporales. Una unidad de tiempo se extiende completamente hasta el inicio de la siguiente (misma) unidad. Entonces, por ejemplo, 0.99999 del camino hasta el martes todavía se considera "Martes", no "Miércoles". – Spike0xff

0

En la unidad final de la medición, si se produce un evento en esa frecuencia, el redondeo cortes manera abajo en aliasing.

Por ejemplo, si la fluctuación hace que un segundo marco de datos entre 2 ms en el segundo y el siguiente marco para llegar a 990 mS en el mismo marco, ambos se sellarán como si estuvieran en el mismo segundo. Un jitter de solo unos pocos milisegundos daría como resultado muchos valores clave no exclusivos dispersos.

El redondeado los pondría en varios segundos limpiamente hasta que el jitter se volvió mucho más grave, digamos +/- 499 mS.

El propósito del redondeo es evitar que la resolución se repita para siempre. Cuando la incertidumbre está muy por debajo de la resolución, corta enormemente el aliasing.

"en cascada" sólo puede ocurrir a menos que la resolución de la frontera. Por ejemplo, un número de año de alternancia parece sorprendente, pero esto solo puede ocurrir a menos que a un segundo (o milisegundo, etc.) a partir de la medianoche de Año Nuevo. Nada inesperado o especialmente inexacto a eso.

Para evitar realmente el aliasing (al mismo tiempo mencionado dos veces) debe implementar anti-aliasing (como se hace en los gráficos), después del redondeo.

1

pregunta antiguo, pero ha sido remitido a partir de una nueva y discutir las respuestas razones de redondeo o no (que por supuesto son válidos) pero deja la pregunta sin respuesta.

La razón de que no es el redondeo, que ToString simplemente imprime la fecha/hora partes puede pedir.

Así, por ejemplo, tampoco es redonda al minuto más cercano:

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

Salida:

2011-09-03T03:18 

Con ningún parámetro, ToString utiliza la cadena de formato predeterminado de fecha/hora de su entorno .

Cuestiones relacionadas