2009-08-12 15 views
8

tengo mi propia C++ DateTime clase definida como:C++ DateTime clase

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

tengo 2 DateTime la que tengo que comparar para ver cuál es mayor que (más reciente) la otra.

¿Hay alguna C++ DateTime clase de libre acceso que puedo usar para

  1. Convertir mi clase DateTime a su clase DateTime
  2. su clase debería proporcionar <,>, < =,> = operadores de comparación

Si se pudiera proporcionar un ejemplo concreto, sería genial. Tenga en cuenta que tengo que comparar hasta milisegundos.

Estaba pensando en Boost o Qt. Preferido Boost sin embargo.

+3

Si tiene su propia clase ¿por qué necesita otra? –

+7

O, lo que es más importante, si va a usar la clase de otra persona, ¿por qué usarlo solo para las comparaciones? Solo usa su clase. El trabajo está hecho para ti. Deshazte de tu clase. – GManNickG

+0

La razón es porque mi aplicación es una biblioteca de C++ que otra aplicación utilizará. 1) No quiero que tengan que incluir bibliotecas de Boost para que hagan uso de mi biblioteca. 2) Esta clase DateTime ya se ha utilizado en muchos lugares de un sistema heredado. Gracias por los comentarios. – sivabudh

Respuesta

18

Ver Boost Date Time library

Y tu clase se parece mucho a struct tm

EDIT: Tienes razón que estructura tm no es compatible con una precisión de milisegundos.

Eche un vistazo a Boost example. ¿Eso ayuda?

+0

Eché un vistazo a esa documentación ya ... pero era tan densa. tampoco pude encontrar un ejemplo con milisegundos. Estaba buscando un ejemplo a lo largo de esta línea: http://doc.trolltech.com/4.5/qdatetime.html. – sivabudh

+0

es cierto que mi clase es muy parecida a struct tm ... sin embargo, la diferencia crucial es que también tengo un campo de milisegundos. – sivabudh

+0

struct tm no admite milisegundos, ya que es un elemento POSIX y el tiempo normal de UNIX solo se otorga al segundo. –

2

¿Qué tiene de malo utilizar el contenido de <time.h> para implementar su clase? Es estándar C90.

+0

no hay nada de malo en eso ... ¿podría dar un ejemplo de cómo podría usar el ? – sivabudh

+3

Esto es C++. Debería ser '#include ' – GManNickG

5

No sé de cualquier de la parte superior de la cabeza. Pero consideraría reescribir su clase de fecha para contener un único entero de 64 bits que describa milisegundos desde la época convencional (¿1970 es?). Entonces puede dividir por 1000 y usar las funciones CRT normales para formatear como una cadena, además puede tomar el valor módulo 1000 para obtener la parte en milisegundos.

Los operadores de comparación y luego llegar a ser fácil ..

+0

Recomendaría algo como esto. Almacene los tiempos internamente como un número entero como este para que las comparaciones sean fáciles, y luego proporcione accesos para obtener las diversas partes del tiempo descompuesto (hora, mes, etc.). Si la eficiencia es una preocupación, puede almacenar en caché el tiempo descompuesto hasta que se modifique el tiempo interno, de modo que no tenga que seguir recalculando el año para obtener el mes, etc. –

+0

Es decir, si no está planificando usar impulso –

+0

Si solo pudiera votar más de una vez ... – phonetagger

8

Es posible que desee comprobar hacia fuera QDateTime de Qt, cosa que tiene los operadores necesarios y exactitud ms.

conversión de su clase podría hacerse a través de

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)); 
    } 
}; 

El revés es similar ;-)

1

GNU R utiliza un reemplazo struct tm con una precisión de microsegundos - en lugar de segundos (entero) desde la época, ahora usa un número de punto flotante. Eso es realmente realmente útil. Para muchas de mis aplicaciones, acabo de duplicar y aún obtener las conversiones de tiempo. Ver R-2.9.1/src/main/datetime.c en las fuentes R actuales.

Tener eso en una clase de C++ independiente sería útil sin embargo.

4

Bien, aquí está el último fragmento de código que responde mi propia pregunta. Pensé en compartir esto en caso de que pueda ser útil para otras personas en el futuro. Gracias a Fred Larson por señalar el ejemplo de Boost.

Elegí Boost para hacer el cálculo DateTime porque mi aplicación ya hace uso de Boost en otro lugar. Creo que podría haber sido capaz de usar Qt también, aunque no puedo confirmarlo por completo.

Suponiendo DateTime se define como:

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

Para hacer una simple comparación 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; 
} 

Para añadir 2 DateTime juntos para devolver una nueva 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 zanja almacenar fechas en gregoriano hace siglos. Guardo las fechas como un entero de 32 bits (algo así como una fecha juliana). Entonces la fecha se compone como (Año * 1000) + DOY (DOY es día del año). Es decir - 2009001 es Jan 1 2009 - 2009365 será el 31 Dic 2009

Mi clase fecha del curso proporciona métodos para obtener el Año, Mes y Día, suma, resta, incremento y decremento, comparando, para obtener el número de días entre fechas, etc.

Para fecha y hora, uso float de 64 bits donde la parte entera del número real es igual a las fechas enteras (julianas) descritas anteriormente, y la fracción representa el tiempo en fracción de un día.

I.e.

  • 2009001,04166666666 ~ es Jan 1,2009 01 a.m.
  • 2009001.06249999999 ~ es Jan 1,2009 1:30 am
  • 2009001.95833333333 ~ es Jan 1,2009 23:00

Si solo necesita precisión minuciosa, puede usar flotador de 32 bits para la fecha y la hora, pero no puede especificar con precisión segundos de almacenamiento y milisegundos.

Las ventajas de almacenar fechas (y tiempo) en este modo son:

  • Sólo necesita 8 bytes para representar los datos y tiempo en comparación con 28bytes (asumiendo enteros de 32 bits) utilizados por el DateTime clase en la pregunta.

  • En comparación con las fechas almacenadas como segundos de una época, cuando se mira en el número (por ejemplo, en el depurador) puede más o menos identificar a partir el número del año y el día del año, y el aproximadas hora del día (para obtener la hora, minuto, segundo después de la medianoche, simplemente multiplique por 24, 1440, 86400, respectivamente).

  • fechas Comparando es trivial, simplemente comparar los números (Una operación única CPU en comparación con los varios que tomaría para que el ejemplo DateTime).

  • Menos operaciones de comparación para hacer aritmética de fecha.

El disadvange de esto (por el tiempo el tiempo) es una ligera pérdida de precisión (esto es prácticamente un punto silencio) y hay que hacer un poco de redondeo simple para obtener valores enteros agradable cuando convering a valores enteros de hora minutos y segundos.

+0

Me gusta este estilo. –