web-dev-qa-db-fra.com

Nombre de jours entre deux dates C ++

J'ai vu des exemples pour C #, Java, mais pour C++ je ne peux pas trouver de solution pour calculer combien de jours entre deux dates.

Par exemple entre le 2012-01-24 et le 2013-01-08

Merci!

17
Breakdown

C'est une façon.

#include <iostream>
#include <ctime>

int main()
{
    struct std::tm a = {0,0,0,24,5,104}; /* June 24, 2004 */
    struct std::tm b = {0,0,0,5,6,104}; /* July 5, 2004 */
    std::time_t x = std::mktime(&a);
    std::time_t y = std::mktime(&b);
    if ( x != (std::time_t)(-1) && y != (std::time_t)(-1) )
    {
        double difference = std::difftime(y, x) / (60 * 60 * 24);
        std::cout << std::ctime(&x);
        std::cout << std::ctime(&y);
        std::cout << "difference = " << difference << " days" << std::endl;
    }
    return 0;
}

ma sortie

Thu Jun 24 01:00:00 2004
Mon Jul 05 01:00:00 2004
difference = 11 days

Voici une référence au post de l'auteur original

19
sharafjaffri

Convertissez vos dates en nombre entier indiquant le nombre de jours écoulés depuis une époque, puis soustrayez. Dans cet exemple, j'ai choisi Rata Die , une explication de l'algorithme peut être trouvée à < http://mysite.verizon.net/aesir_research/date/rata.htm > .

int
rdn(int y, int m, int d) { /* Rata Die day one is 0001-01-01 */
    if (m < 3)
        y--, m += 12;
    return 365*y + y/4 - y/100 + y/400 + (153*m - 457)/5 + d - 306;
}

int days = rdn(2013, 1, 8) - rdn(2012, 1, 24);
15
chansen

Nouvelle réponse à une ancienne question:

En utilisant ceci bibliothèque de dates uniquement en-tête C++ 11/C++ 14 , vous pouvez maintenant écrire:

#include "date.h"
#include <iostream>

int
main()
{
    using namespace date;
    using namespace std;
    auto x = 2012_y/1/24;
    auto y = 2013_y/1/8;
    cout << x << '\n';
    cout << y << '\n';
    cout << "difference = " << (sys_days{y} - sys_days{x}).count() << " days\n";
}

Quelles sorties:

2012-01-24
2013-01-08
difference = 350 days

Si vous ne voulez pas dépendre de cette bibliothèque, vous pouvez écrire les vôtres, en utilisant les mêmes algorithmes de date que la bibliothèque de dates ci-dessus utilise. On les trouve dans cet article: algorithmes de date de bas niveau chrono-compatibles . L'algorithme de cet article qui est utilisé dans cet exemple est celui-ci:

// Returns number of days since civil 1970-01-01.  Negative values indicate
//    days prior to 1970-01-01.
// Preconditions:  y-m-d represents a date in the civil (Gregorian) calendar
//                 m is in [1, 12]
//                 d is in [1, last_day_of_month(y, m)]
//                 y is "approximately" in
//                   [numeric_limits<Int>::min()/366, numeric_limits<Int>::max()/366]
//                 Exact range of validity is:
//                 [civil_from_days(numeric_limits<Int>::min()),
//                  civil_from_days(numeric_limits<Int>::max()-719468)]
template <class Int>
constexpr
Int
days_from_civil(Int y, unsigned m, unsigned d) noexcept
{
    static_assert(std::numeric_limits<unsigned>::digits >= 18,
             "This algorithm has not been ported to a 16 bit unsigned integer");
    static_assert(std::numeric_limits<Int>::digits >= 20,
             "This algorithm has not been ported to a 16 bit signed integer");
    y -= m <= 2;
    const Int era = (y >= 0 ? y : y-399) / 400;
    const unsigned yoe = static_cast<unsigned>(y - era * 400);      // [0, 399]
    const unsigned doy = (153*(m + (m > 2 ? -3 : 9)) + 2)/5 + d-1;  // [0, 365]
    const unsigned doe = yoe * 365 + yoe/4 - yoe/100 + doy;         // [0, 146096]
    return era * 146097 + static_cast<Int>(doe) - 719468;
}

Voir Algorithmes de date de bas niveau compatibles avec le chrono pour plus de détails sur le fonctionnement de cet algorithme, ses tests unitaires et sa plage de validité.

Cet algorithme modélise le calendrier grégorien proleptique , qui étend indéfiniment le calendrier grégorien, à la fois en avant et en arrière. Pour modéliser d'autres calendriers (comme le calendrier julien), vous aurez besoin d'autres algorithmes, tels que ceux montrés ici . Une fois que vous avez d'autres calendriers configurés et synchronisés avec la même époque série (ces algorithmes utilisent le 01-01-1970 grégorien, qui est également le heure Unix époque), vous pouvez facilement calculer le nombre de jours non seulement entre deux dates, mais également entre deux calendriers que vous avez modélisés.

Cela vous donne la liberté de ne pas avoir à coder en dur une date pour le passage de Julian à Gregorian. Il vous suffit de savoir à quel calendrier vos données d'entrée sont référencées.

Parfois, les dates dans les documents historiques qui pourraient autrement être ambiguës sont annotées avec Old Style/New Style pour indiquer le calendrier julien ou grégorien respectivement.

Si vous êtes également préoccupé par l'heure de la journée avec vos dates, cette même bibliothèque de dates s'intègre de manière transparente à la bibliothèque <chrono> Pour l'utilisation de hours, minutes, seconds, milliseconds, microseconds et nanoseconds, et avec system_clock::now() pour obtenir la date et l'heure actuelles.

Si vous êtes préoccupé par les fuseaux horaires, une bibliothèque supplémentaire (séparée) bibliothèque de fuseaux horaires est écrite au-dessus de bibliothèque de dates pour gérer les fuseaux horaires à l'aide de base de données de fuseaux horaires IANA . Si nécessaire, la bibliothèque de fuseaux horaires a également une fonction pour les calculs qui incluent secondes intercalaires .

11
Howard Hinnant

vous pouvez essayer la bibliothèque boost date_time

3
user1252446

Pour éviter de créer votre propre fonction, vous pouvez utiliser date_time de Boost.

0
Mihai8