views:

2194

answers:

9
+3  Q: 

C++ DateTime class

I have my own C++ DateTime class defined as:

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

I have 2 DateTime which I need to compare to see which one is greater than (more recent) the other.

Is there any freely available C++ DateTime class that I can use to

  1. Convert my DateTime class to their DateTime class
  2. Their class should provide < , > , <= , >= operators for comparison

If a concrete example could be provided that would be great. Note that I need to compare down to millisecond.

I was thinking about Boost or Qt. Preferred Boost though.

+9  A: 

See Boost Date Time library

And your class looks very much like struct tm

EDIT: You're right that struct tm doesn't support millisecond precision.

Take a look at a Boost example. Does that help?

Fred Larson
i glanced over that documentation already..but it was so dense. i also couldnt find an example with millisec. i was looking for an example along this line: http://doc.trolltech.com/4.5/qdatetime.html.
ShaChris23
it's true my class is very much like struct tm...however, the crucial distinction is that i have a millisecond field as well.
ShaChris23
struct tm doesn't support milliseconds since, it's a POSIX thing and normal UNIX-style time is only given to the second.
Tyler McHenry
The docs seem pretty clear to me... boost::posix_time::ptime is the class that you would be converting to, and it is constructed from boost::gregorian::date(year, month, day), and boost::posix_time::time_duration(hours, minutes, seconds) + boost::posix_time::milliseconds(msec)
Greg Rogers
Fred, the example that you included definitely looks like something that can be used. I'm going to try it out in my app, and if all works well, I will accept your answer. Thank you! =)
ShaChris23
using the example you pointed out, i was able to write the code, and tested it. it worked as i expected. i posted what i did as one of this post's answers. thanks!
ShaChris23
A: 

What's wrong with using the content of <time.h> for implementing your class? It's standard C90.

AProgrammer
nothing is wrong with that...could you please perhaps provide an example of how i could go about using <time.h>?
ShaChris23
This is C++. That should be `#include <ctime>`
GMan
A: 

Look at MFC datetime classes CTime and COleDateTime classes More at http://www.codeproject.com/KB/datetime/datetimedisc.aspx

Learner
im sorry, i cannot use MFC since we intend to make this a cross-platform application.
ShaChris23
See link.. that may be useful.
Learner
+2  A: 

I don't know of any off the top of my head. But I'd consider rewriting your date class to hold a single 64-bit integer describing milliseconds since the conventional epoch (1970 is it?). Then you are free to simply divide by 1000 and use the normal CRT functions for formatting as a string, plus you can take the value modulo 1000 to get the millisecond part.

Comparison operators then become easy..

pauldoo
I would recommend something like this. Store the times internally as an integer like this so that comparisons are easy, and then provide accessors to get the various parts of the broken-down time (hour, month, etc). If efficiency is a concern, you can cache the broken-down time until the internal time is modified, so that you don't have to keep recomputing the year to get the month, etc.
Tyler McHenry
That is, if you're not planning to use boost.
Tyler McHenry
+5  A: 

You may want to check out QDateTime from Qt, wich has the required operators and ms accuracy.

Conversion from your class could be done 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));
  }
};

The other way around is similar ;-)

drhirsch
+1  A: 

GNU R uses a struct tm replacement with microsecond precision -- instead of (integer) seconds since the epoch, it now uses a floating point number. That is really really useful. For many of my applications, I just past doubles around and yet get the time conversions. See R-2.9.1/src/main/datetime.c in the current R sources.

Having that in a standalone C++ class would be handy though.

Dirk Eddelbuettel
A: 

Okay, here's the final code snippet that answers my own question. I thought of sharing this in case it might helpful to some other people in the future. Thanks to Fred Larson for pointing the Boost example.

I chose Boost to do the DateTime calculation because my application already makes use of Boost somewhere else. I think I might have been able to use Qt as well, though I cant completely confirm.

Assuming DateTime is defined as:

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

To do a simple DateTime comparison

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

To add 2 DateTime together to return a new 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;
}
ShaChris23
A: 

I ditch storing dates in gregorian ages ago. I store dates as an 32bit integer (sort of like a Julian date). So the date is composed as (Year * 1000) + DOY (DOY is day of year). I.e. - 2009001 Is Jan 1 2009 - 2009365 is Dec 31 2009

My date class of course provides methods for getting the Year, Month and Day, adding, subtracting, incrementing and decrementing, comparing, getting the number of days between dates etc..

For date and time, I use 64bit float where the integer portion of the real number is the same as integer (Julian like) dates described above, and the fraction represents the time in fraction of a day.

I.e.

  • 2009001.04166666666~ is Jan 1,2009 1:00am
  • 2009001.06249999999~ is Jan 1,2009 1:30am
  • 2009001.95833333333~ is Jan 1,2009 11:00pm

If you only need minute accuracy, you can use 32bit float for date and time but you can't adequately accurately store seconds and milliseconds.

The advantages of storing dates (and time) in this manner are:

  • You only need 8bytes to represent the data and time as compared to 28bytes (assuming 32bit integers) used by the DateTime class in the question.

  • Compared with dates stored as seconds from an epoch, when looking at the number (for example in the debugger) you can more or less identify from the number the year and the day of year, and the approximate time of day (to get the hour, minute, second after midnight simply mulitply by 24, 1440, 86400 respectively).

  • Comparing dates is trivial, simply compare the numbers (A single CPU operation compared to the several it would take for the example DateTime).

  • Fewer comparison operations to do date arithmetic.

The disadvange of this (for time time) is a slight loss of accuracy (this is practically a mute point) and you have to do some simple rounding to get nice integer values when convering to integer values of hours minutes and seconds.

Roger Nelson
A: 

can I find a replacement for RWDateTime class ..... which is a freeware and I can use it directly.

vinayak