2012-07-06 18 views
13

Sono stato alla ricerca di un meccanismo di arrotondamento corretto, ma nulla di quello che trovo sembra essere esattamente ciò di cui ho bisogno.DateTime Round Up and Down

Devo arrotondare per eccesso e per difetto separatamente e devo anche rendere conto del caso quando è già arrotondato.

Ho bisogno il seguente arrotondamento per accadere

5:00 -> RoundDown() -> 5:00 
5:04 -> RoundDown() -> 5:00 
5:09 -> RoundDown() -> 5:00 
5:10 -> RoundDown() -> 5:10 

4:00 -> RoundUp() -> 4:00 
4:50 -> RoundUp() -> 4:50 
4:51 -> RoundUp() -> 5:00 
4:56 -> RoundUp() -> 5:00 

Fondamentalmente ho bisogno di RoundUp() o RoundDown() con l'approssimazione di 10 minuti in modo esplicito, ma si deve anche lasciare il tempo intatto se lo sia già in un multiplo di 10 minuti. Inoltre mi piacerebbe di troncare qualsiasi secondi che non hanno alcun effetto sulla procedura di arrotondamento

4:50:45 -> 04:50:00 -> RoundUp() -> 4:50

fa qualcuno ha qualche codice a portata di mano per realizzare questo.

Ho trovato questo codice da qualche parte ma arrotonda le 5:00 -> RoundUp() -> 5:10 invece di lasciarlo intatto perché è già un multiplo di 10 e non ha bisogno di arrotondamenti. Inoltre non sono sicuro di come i secondi avrebbero effetto

public static DateTime RoundDateTime(this DateTime dt, int minutes, RoundingDirection direction) 
{ 
    TimeSpan t; 
    switch (direction) 
    { 
     case RoundingDirection.Up: 
      t = (dt.Subtract(DateTime.MinValue)).Add(new TimeSpan(0, minutes, 0)); break; 
     case RoundingDirection.Down: 
      t = (dt.Subtract(DateTime.MinValue)); break; 
     default: 
      t = (dt.Subtract(DateTime.MinValue)).Add(new TimeSpan(0, minutes/2, 0)); break; 
    } 
    return DateTime.MinValue.Add(new TimeSpan(0, 
      (((int)t.TotalMinutes)/minutes) * minutes, 0)); 
} 

Spero che qualcuno possa modificare quel metodo per farlo funzionare per me. Grazie

+3

OK. Quindi hai il codice di arrotondamento lì. Perché non lo stai modificando per farlo fare ciò che devi fare? –

+3

Questo funzionerebbe? http://stackoverflow.com/questions/7029353/c-sharp-round-up-time-to-nearest-x-minutes – comecme

+0

La regola di arrotondamento non è chiara. Fai il giro 5:09 alle 5:00 ma dalle 4:56 alle 5:00. – Rawling

risposta

11

ne dite:

case RoundingDirection.Up: 
    t = dt.AddMinutes((60 - dt.Minute) % 10); 
case RoundingDirection.Down: 
    t = dt.AddMinutes(-dt.Minute % 10); 

Demo: http://ideone.com/AlB7Q

+1

Si prende cura dei secondi? – comecme

+0

@comecme: Newp. – mellamokb

27

Questo vi permetterà di selezione in conformità alle qualsiasi intervallo dato.

private static DateTime Floor(DateTime dateTime, TimeSpan interval) 
{ 
    return dateTime.AddTicks(-(dateTime.Ticks % interval.Ticks)); 
} 

private static DateTime Ceiling(DateTime dateTime, TimeSpan interval) 
{ 
    var overflow = dateTime.Ticks % interval.Ticks; 

    return overflow == 0 ? dateTime : dateTime.AddTicks(interval.Ticks - overflow); 
} 

private static DateTime Round(DateTime dateTime, TimeSpan interval) 
{ 
    var halfIntervelTicks = ((interval.Ticks + 1) >> 1); 

    return dateTime.AddTicks(halfIntervelTicks - ((dateTime.Ticks + halfIntervelTicks) % interval.Ticks)); 
} 

Per prendersi cura di troncare i secondi, che sarebbe sufficiente sottrarre i secondi e millesimi dalla data-ora prima di inviarli nelle funzioni di arrotondamento.

0

Ecco un modo veloce per troncare (arrotondato per difetto)

var now = DateTime.Now; 
var nowTicks = now.Ticks; 

//removing the nanoseconds, miliseconds, and seconds from the nowTicks 
var lastMinute = new DateTime(nowTicks - (nowTicks % (1000*1000*10*60))); 
0

Questa funzione arrotonda su o giù per l'intervallo più vicina (minuti).

private static DateTime NormalizeReadingInterval(DateTime originalTime, int interval) 
    { 
     if (originalTime.Minute % interval == 0) return originalTime; 
     var epochTime = new DateTime(1900, 1, 1); 
     var minutes = (originalTime - epochTime).TotalMinutes; 
     var numIntervals = minutes/interval; 
     var roundedNumIntervals = Math.Round(numIntervals, 0); 
     return epochTime.AddMinutes(roundedNumIntervals * interval); 
    } 
Problemi correlati