2011-09-14 20 views
12

Quando un Double viene formattato come un arrotondamento stringa viene utilizzato. Per esempio.Perché la formattazione di un DateTime come una stringa viene troncata e non attorno ai millisecondi?

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

uscite

12346 

Tuttavia, quando un DateTime è formattato come viene utilizzato un troncamento stringa. Per esempio.

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

uscite

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

Qual è il ragionamento (se presente) alla base di questo comportamento?


arrotondamento al secondo più vicino può essere raggiunto aggiungendo mezzo secondo prima di formattare come una stringa:

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

uscite

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

risposta

16

Questo è un po 'personale, ma direi i valori di data e ora di arrotondamento anziché il loro troncamento determinerebbero un comportamento "più" imprevisto.

Ad esempio, l'arrotondamento new DateTime(2011, 1, 1, 23, 59, 59, 999) comporterebbe un nuovo giorno completamente. Questo suona molto più strano del semplice troncamento del valore.

+2

+1, grazie. Questa è una dimensione a cui non ho mai pensato. –

+1

E se il nuovo giorno è nel prossimo anno, l'arrotondamento si riduce a cascata fino all'anno. Nella maggior parte delle situazioni probabilmente non è quello che vuoi per le date. –

+1

Forse un altro modo per pensarci: le unità di tempo sono _spans_ non i punti di tempo. Un'unità di tempo si estende completamente fino all'inizio della successiva (stessa) unità. Quindi per esempio 0.99999 del modo in cui martedì è ancora considerato "martedì" - non "mercoledì". – Spike0xff

0

All'unità di misura finale, se si verifica un evento a quella frequenza, l'arrotondamento si riduce in basso aliasing.

Ad esempio, se il jitter fa entrare un secondo frame di dati in 2 mS nel secondo e il frame successivo per arrivare a 990 mS nello stesso frame, verranno entrambi timbrati come se fossero nello stesso secondo. Un jitter di pochi millisecondi determinerebbe molti valori chiave non univoci sparsi.

arrotondamento li avrebbe messi in alcuni secondi in modo pulito fino a quando il jitter ottenuto molto più grave, dicono +/- 499 ms.

Lo scopo dell'arrotondamento è di impedire alla risoluzione di continuare all'infinito. Quando l'incertezza è molto al di sotto della risoluzione, taglia tremendamente l'aliasing.

"Cascading" può avvenire solo a una risoluzione inferiore al limite. Ad esempio, un numero di anno di commutazione sembra scioccante, ma questo può verificarsi solo con meno di un secondo (o millisecondo, ecc.) Da mezzanotte di Capodanno. Niente di imprevisto o particolarmente impreciso.

Per prevenire veramente l'aliasing (lo stesso tempo menzionato due volte) è necessario implementare l'anti-aliasing (come avviene nella grafica), dopo l'arrotondamento.

1

Vecchia domanda, ma è stata rimandata da una nuova e le risposte trattano i motivi dell'arrotondamento o meno (che naturalmente sono validi), ma lascia la domanda senza risposta.

Il motivo per non arrotondare è che, ToString stampa solo le parti di data/ora richieste.

Così, ad esempio, né lo farà intorno al minuto più vicino:

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

uscita:

2011-09-03T03:18 

Con nessun parametro, ToString utilizza il/stringa di formato di data e ora di default del vostro ambiente .

Problemi correlati