Question

J'ai trouvé un bogue dans un ancien programme C ++ MFC qui calcule un décalage (en jours) pour une date donnée à partir d'une date de base fixe. Nous voyions des résultats qui ne convenaient pas pour une raison quelconque, et je les ai suivis jusqu'à ce que le programmeur d'origine ait utilisé la méthode CTimeSpan.GetDays (). Selon la documentation :

  

Notez que l'heure avancée peut amener GetDays à obtenir un résultat potentiellement surprenant. Par exemple, lorsque l'heure d'été est effective, GetDays indique que le nombre de jours compris entre le 1er avril et le 1er mai est de 29, et non de 30, car un jour d'avril est raccourci d'une heure et ne compte donc pas comme une journée complète.

Ma solution proposée consiste à utiliser (obj.GetTotalHours () + 1) / 24 à la place. Je pense que cela couvrirait tous les problèmes puisqu'il s'agit d'un travail par lots qui s'exécute à peu près à la même heure chaque jour, mais je pensais que je demanderais aux personnes intelligentes de le mettre en place avant de le mettre en œuvre s'il y avait une meilleure solution.

Ceci est juste une question secondaire, mais je suis également curieux de savoir comment cela serait géré si le programme pouvait être exécuté à tout moment.

Était-ce utile?

La solution

Votre solution fonctionne correctement pour obtenir le nombre de périodes complètes de 24 heures entre deux fois, à condition que les événements se produisent à la même heure chaque jour. Sinon, " + 1 " dans l'expression pourrait conduire à une erreur off-by-one.

Parfois, vous ne vous souciez pas de l'heure à laquelle l'événement s'est produit, vous voulez simplement savoir quel jour. Dans ce cas, vous devez mettre à zéro les heures, les minutes et les secondes, puis utiliser votre formule:

CTime startDay(start.GetYear(), start.GetMonth(), start.GetDay(), 0, 0, 0);
CTime finishDay(finish.GetYear(), finish.GetMonth(), finish.GetDay(), 0, 0, 0);
int days = ((finishDay - startDay).GetTotalHours() + 1) / 24;

Autres conseils

Une modification mineure de ce que Mark a suggéré et cela fonctionne sans recourir à l'arrondi: il suffit d'ajouter un paramètre supplémentaire de zéro au constructeur CTime . Cela oblige les deux heures à être à l'heure standard (pas l'heure avancée). La valeur par défaut de ce paramètre est -1, ce qui signifie "Calculer automatiquement si l'heure d'été est en vigueur".

// Discard hours, minutes, seconds, and daylight savings time
CTime startDay(start.GetYear(), start.GetMonth(), start.GetDay(), 0, 0, 0, 0);
CTime endDay(end.GetYear(), end.GetMonth(), end.GetDay(), 0, 0, 0, 0);

// Get number of days apart
CTimeSpan span = endDay - startDay;
int nDays = span.GetDays();

Testé et fonctionne.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top