94 votes

Arrondissement d’objets DateTime

Je veux ronde dates/heures au plus proche de l'intervalle pour une application graphique. J'aimerais une méthode d'extension de signature comme suit, de sorte que l'arrondissement peut être obtenu pour n'importe quel niveau de précision:

static DateTime Round(this DateTime date, TimeSpan span);

L'idée est que si je passe dans un laps de temps de dix minutes, il va arrondir à la dizaine la plus proche minute d'intervalle. Je ne peux pas obtenir ma tête autour de la mise en œuvre et je suis en espérant que l'un d'entre vous l'ont écrit ou utilisé de quelque chose de semblable auparavant.

Je pense que ce soit un plancher, un plafond ou le plus proche de la mise en œuvre est très bien.

Des idées?

Edit: Merci à @tvanfosson & @ShuggyCoUk, la mise en œuvre ressemble à ceci:

public static class DateExtensions {
    public static DateTime Round(this DateTime date, TimeSpan span) {
        long ticks = (date.Ticks + (span.Ticks / 2) + 1)/ span.Ticks;
        return new DateTime(ticks * span.Ticks);
    }
    public static DateTime Floor(this DateTime date, TimeSpan span) {
        long ticks = (date.Ticks / span.Ticks);
        return new DateTime(ticks * span.Ticks);
    }
    public static DateTime Ceil(this DateTime date, TimeSpan span) {
        long ticks = (date.Ticks + span.Ticks - 1) / span.Ticks;
        return new DateTime(ticks * span.Ticks);
    }
}

Et est appelé de la sorte:

DateTime nearestHour = DateTime.Now.Round(new TimeSpan(1,0,0));
DateTime minuteCeiling = DateTime.Now.Ceil(new TimeSpan(0,1,0));
DateTime weekFloor = DateTime.Now.Floor(new TimeSpan(7,0,0,0));
...

Cheers!

115voto

tvanfosson Points 268301
<p>Plancher<pre><code></code></pre><p>Rond (vers le haut au milieu)</p><pre><code></code></pre><p>Au plafond</p><pre><code></code></pre></p>

29voto

aj.toulan Points 320
<p>Cela vous permettra tour à n’importe quel intervalle donné, est légèrement plus rapide que le divisant et en multipliant ensuite les tiques et surtout qu'il est lisible.<pre><code></code></pre></p>

10voto

ShuggyCoUk Points 24204

Vous devez également être clair si vous voulez que votre arrondi à:

  1. être pour le début, la fin ou le milieu de l'intervalle
    • commencer est la méthode la plus simple et souvent le prévu, mais vous devriez être clair dans votre premier spec.
  2. Comment vous voulez frontière des cas à la ronde.
    • normalement, seulement un problème si vous avez d'arrondi pour le moyen et non la fin.
    • Depuis arrondi au milieu est une tentative à un biais de libre-réponse dont vous avez besoin pour utiliser quelque chose comme les Banquiers Arrondissement techniquement ronde demi-même pour être vraiment libre de tout parti pris.

Il est tout à fait probable que vous avez vraiment ne se soucient que du premier point, mais dans ces "simples" questions le comportement résultant peut avoir de lourdes conséquences comme vous l'utiliser dans le monde réel (souvent à des intervalles adjacents à zéro)

tvanfosson la solution de la couverture de tous les cas énumérés à 1. Le milieu exemple est biaisé vers le haut. Il est douteux que ce serait un problème dans les temps liés à l'arrondissement des chiffres.

2voto

Lucero Points 38928
<p>Il suffit d’utiliser les tiques, en utilisant ce fossé, plancher/plafond/round la valeur et multiplier il retour.</p>

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by: