2009-08-12 7 views
8

J'ai mon propre C++ DateTime classe définie comme:C++ DateTime classe

class DateTime 
{ 
public: 
    int year; 
    int month; 
    int day; 
    int hour; 
    int min; 
    int sec; 
    int millisec; 
}; 

J'ai 2 DateTime que je dois comparer pour voir qui est plus grand que (plus récente) d'autre part.

Y at-il disponible gratuitement classe C++ DateTime que je peux utiliser pour

  1. Convertir ma classe DateTime à leur classe DateTime
  2. Leur classe devrait fournir <,>, < =,> = opérateurs de comparaison

Si un exemple concret pouvait être fourni, ce serait génial. Notez que j'ai besoin de comparer jusqu'à milliseconde.

Je pensais à Boost ou Qt. Préféré Boost cependant.

+3

Si vous avez votre propre cours, pourquoi en avez-vous besoin? –

+7

Ou plus important encore, si vous allez utiliser la classe de quelqu'un d'autre, pourquoi l'utiliser uniquement pour des comparaisons? Utilisez juste leur classe. Le travail est fait pour vous. Baisse ta classe. – GManNickG

+0

La raison en est que mon application est une bibliothèque C++ que d'autres applications utiliseront. 1) Je ne veux pas qu'ils aient à inclure des bibliothèques Boost pour qu'ils puissent utiliser ma bibliothèque. 2) Cette classe DateTime a déjà été utilisée dans de nombreux endroits d'un système existant. Merci pour les commentaires cependant. – sivabudh

Répondre

18

Voir Boost Date Time library

Et votre classe ressemble beaucoup à struct tm

EDIT: Vous avez raison struct tm ne supporte pas la milliseconde.

Jetez un oeil à un Boost example. Est ce que ça aide?

+0

j'ai jeté un coup d'oeil sur cette documentation déjà..mais c'était tellement dense. Je ne pourrais pas non plus trouver un exemple avec millisec. Je cherchais un exemple le long de cette ligne: http://doc.trolltech.com/4.5/qdatetime.html. – sivabudh

+0

c'est vrai que ma classe ressemble beaucoup à struct tm ... cependant, la distinction cruciale est que j'ai aussi un champ milliseconde. – sivabudh

+0

struct tm ne supporte pas les millisecondes car, c'est une chose POSIX et l'heure normale de type UNIX n'est donnée qu'à la seconde. –

2

Quel est le problème avec l'utilisation du contenu de <time.h> pour implémenter votre classe? C'est la norme C90.

+0

rien ne va pas avec cela ... pourriez-vous s'il vous plaît fournir un exemple de la façon dont je pourrais utiliser ? – sivabudh

+3

Ceci est C++. Cela devrait être '#include ' – GManNickG

5

Je ne connais pas du haut de ma tête. Mais je considérerais réécrire votre classe de date pour tenir un seul entier de 64 bits décrivant des millisecondes depuis l'époque conventionnelle (1970 est-il?). Ensuite, vous pouvez diviser simplement par 1000 et utiliser les fonctions CRT normales pour le formatage comme une chaîne, plus vous pouvez prendre la valeur modulo 1000 pour obtenir la partie milliseconde.

opérateurs de comparaison deviennent alors facilement ..

+0

Je recommanderais quelque chose comme ça. Stockez les heures en interne sous la forme d'un nombre entier comme celui-ci afin que les comparaisons soient faciles, puis fournissez des accesseurs pour obtenir les différentes parties du temps décomposé (heure, mois, etc.). Si l'efficacité est une préoccupation, vous pouvez mettre en cache le temps décomposé jusqu'à ce que l'heure interne soit modifiée, de sorte que vous n'ayez pas besoin de recalculer l'année pour obtenir le mois, etc. –

+0

Autrement dit, si vous ne prévoyez pas utiliser boost. –

+0

Si seulement je pouvais upvote plus d'une fois .... – phonetagger

8

Vous pouvez consulter QDateTime de Qt, et possède l'un des opérateurs requis et ms précision.

conversion de votre classe pourrait se faire via

class DateTime 
{ 
public: 
    int year; 
    int month; 
    int day; 
    int hour; 
    int min; 
    int sec; 
    int millisec; 

    QDateTime toQDateTime() { 
    return QDateTime(QDate(year, month, day), QTime(hour, min, sec, millisec)); 
    } 
}; 

L'inverse est similaire ;-)

1

GNU R utilise un remplacement struct tm avec une précision microseconde - au lieu de (entier) secondes depuis l'époque, il utilise maintenant un nombre à virgule flottante. C'est vraiment très utile. Pour la plupart de mes applications, je n'ai plus que doubler et obtenir les conversions de temps. Voir R-2.9.1/src/main/datetime.c dans les sources R actuelles.Avoir cela dans une classe C++ autonome serait pratique.

4

Bon, voici l'extrait de code final qui répond à ma propre question. J'ai pensé partager cela au cas où cela pourrait être utile à d'autres personnes dans le futur. Merci à Fred Larson d'avoir montré l'exemple Boost.

J'ai choisi Boost pour faire le calcul DateTime car mon application utilise déjà Boost ailleurs. Je pense que j'aurais pu aussi utiliser Qt, même si je ne peux pas confirmer complètement.

En supposant DateTime est défini comme:

class DateTime 
{ 
public: 
    int year; 
    int month; 
    int day; 
    int hour; 
    int min; 
    int sec; 
    int millisec; 
}; 

Pour faire une comparaison simple DateTime

bool DateTime::operator < (const DateTime& dt_) 
{ 
    using namespace boost::posix_time; 
    using namespace boost::gregorian; 

    ptime thisTime(date(this->year,this->month,this->day), 
        hours(this->hour) + 
        minutes(this->min) + 
        seconds(this->sec) + 
        boost::posix_time::millisec(int(this->millisec))); 

    ptime thatTime(date(dt_.year,dt_.month,dt_.day), 
        hours(dt_.hour) + 
        minutes(dt_.min) + 
        seconds(dt_.sec) + 
        boost::posix_time::millisec(int(dt_.millisec))); 

    return thisTime < thatTime; 
} 

Pour ajouter 2 DateTime ensemble pour retourner une nouvelle DateTime

DateTime DateTime::operator + (const DateTime& dt_) 
{ 
    using namespace boost::posix_time; 
    using namespace boost::gregorian; 

    date thisDate(this->year, this->month, this->day); 
    date newDate = thisDate + years(dt_.year) + months(dt_.month) + days(dt_.day); 

    ptime newDateTime(newDate, 
    hours(this->hour) + hours(dt_.hour) + 
    minutes(this->min) + minutes(dt_.min) + 
    seconds(this->sec) + seconds(dt_.sec) + 
    boost::posix_time::millisec(int(this->millisec)) + 
    boost::posix_time::millisec(int(dt_.millisec)) 
    ); 

    DateTime dateTime; 

    date t1_date = newDateTime.date(); 

    dateTime.year = t1_date.year(); 
    dateTime.month = t1_date.month(); 
    dateTime.day = t1_date.day(); 

    time_duration t1_time = newDateTime.time_of_day(); 

    dateTime.hour  = t1_time.hours(); 
    dateTime.min  = t1_time.minutes(); 
    dateTime.sec  = t1_time.seconds(); 
    dateTime.millisec = t1_time.fractional_seconds()/1000.0f; 

    return dateTime; 
} 
4

I fossé stockant des dates dans les âges grégoriens. Je stocke les dates sous la forme d'un entier 32 bits (sorte de date julienne). La date est donc composée de (Année * 1000) + DOY (DOY est le jour de l'année). I.e. - 2009001 Est 1 janvier 2009 - 2009365 ryt 31 2009

Ma classe bien sûr de la date fournit des méthodes pour obtenir l'année, le mois et le jour, addition, soustraction, incrémenter et décrémenter, comparer, obtenir le nombre de jours entre Pour la date et l'heure, j'utilise le flottant 64bit où la partie entière du nombre réel est la même que les dates entières (comme Julian) décrites ci-dessus, et la fraction représente le temps en fraction d'un jour.

I.e.

  • 2009001,04166666666 ~ Jan 1,2009 01h00
  • 2.009.001,06249999999 ~ Jan 1,2009 01:30
  • 2.009.001,95833333333 ~ Jan 1,2009 23h00

Si vous seulement besoin de précision minute, vous pouvez utiliser 32bit float pour la date et l'heure, mais vous ne pouvez pas correctement précision stocker secondes et millisecondes.

Les avantages de stockage des dates (et le temps) de cette manière sont les suivantes:

  • Vous avez seulement besoin 8 octets pour représenter les données et le temps par rapport à 28bytes (en supposant des nombres entiers de 32 bits) utilisés par le DateTime classe dans la question.

  • Par rapport aux dates enregistrées en secondes d'une époque, quand on regarde le nombre (par exemple dans le débogueur) vous pouvez plus ou moins identifier à partir le numéro de l'année et le jour de l'année, et environ heure de la journée (pour obtenir l'heure, minute, seconde après minuit simplement multiplier par 24, 1440, 86400 respectivement).

  • La comparaison de dates est triviale, il suffit de comparer les nombres (une opération de processeur unique par rapport aux plusieurs prendra pour l'exemple DateTime).

  • Moins d'opérations de comparaison pour faire l'arithmétique de date.

Le disadvange de ce (pour le temps de temps) est une légère perte de précision (ce qui est pratiquement un point muet) et vous devez faire un peu arrondi simple pour obtenir de belles valeurs entières quand convering aux valeurs entières d'heures minutes et secondes.

+0

J'aime ce style. –