Is there a standard algorithm that can take the output of difftime (which is in seconds) and use it to print out the number of minutes, hours, days, weeks, etc.?

I was going to try and calculate this myself by using the modulo, etc. but thought that something might pre-exist..

There's probably a function or set of functions that do what you want, but nothing in the standard library. It would be easier to just do it manually since the algorithm isn't that hard.

It's as simple as this, more or less:

#include <iostream>

int main()
{
  double seconds = 1234567;
  double minutes = seconds / 60;
  double hours = minutes / 60;
  double days = hours / 24;
  double weeks = days / 7;
  double months = weeks / 52;
  double years = months / 12;

  std::cout.setf(std::ios_base::fixed, std::ios_base::floatfield);
  std::cout.precision(3);

  std::cout << "Seconds: " << seconds << '\n'
    << "Minutes: " << minutes << '\n'
    << "Hours: " << hours << '\n'
    << "Days: " << days << '\n'
    << "Weeks: " << weeks << '\n'
    << "Months: " << months << '\n'
    << "Years: " << years << '\n';
}

Dogtree,

Thanks - I was planning however, to only show minutes if it was over 60 seconds, only show hours if it was over 60 minutes, etc.. That's where it got a little hairy..

Not hairy at all. If integral division results in 0, don't show it:

#include <functional>
#include <iostream>
#include <string>

template <typename Pred>
void print_if(int part, Pred p, std::string msg = "")
{
  if (p(part))
    std::cout << msg << part << '\n';
}

int main()
{
  int seconds = 1234567;
  int minutes = seconds / 60;
  int hours = minutes / 60;
  int days = hours / 24;
  int weeks = days / 7;
  int months = weeks / 52;
  int years = months / 12;

  std::cout.setf(std::ios_base::fixed, std::ios_base::floatfield);
  std::cout.precision(3);

  print_if(seconds, std::bind2nd(std::greater<int>(), 0), "Seconds: ");
  print_if(minutes, std::bind2nd(std::greater<int>(), 0), "Minutes: ");
  print_if(hours, std::bind2nd(std::greater<int>(), 0), "Hours: ");
  print_if(days, std::bind2nd(std::greater<int>(), 0), "Days: ");
  print_if(months, std::bind2nd(std::greater<int>(), 0), "Months: ");
  print_if(years, std::bind2nd(std::greater<int>(), 0), "Years: ");
}

This isn't the output I'm seeking - what you've provided is the conversion between seconds and each parameter (hours, minutes, etc.)

basically, if the minutes is above 60 I don't want to 61, etc.

This is how I ended up doing it:

string Date::operator - ( const Date& b )
{
double diff = difftime( rawtime, b.rawtime );
if ( diff < 0 )
diff*=-1;
ostringstream o;
 
 
if ( diff < 60 )
{
o<<diff<<" SECOND(S)"; 
return o.str();
}
 
if ( diff < 3600 )
{
	int min = (int)diff/60;
	int sec= (int)diff%60;
	o<<min<<" MINUTE(S), "<<sec<< " SECOND(S)"; 
}
else if ( diff < 86400 ) /* DAY */
{
	 int hours = (int) diff/3600;
	 int hourRemainder = (int)diff%3600;
	 int min = (int)hourRemainder/60;
	 int sec= (int)diff%60;
	 o<<hours<< " HOUR(S), "<< min<< " MINUTE(S), "<<sec<< " SECOND(S)"; 
}
else if ( diff < 31536000 ) /* YEAR */ 
{
	 int days = (int) diff/86400;
	 int daysRemainder = (int)diff%86400;
	 int hours = (int) daysRemainder/3600;
	 int hourRemainder = (int)(diff - 86400)%3600;
	 int min = (int)hourRemainder/60;
		int sec= (int)diff%60;
		o<<days<<" DAY(S), "<<hours<< " HOUR(S), "<< min<< " MINUTE(S), "<<sec<< " SECOND(S)"; 
}
else
{
	int years = (int) diff/31536000;
	int yearsRemainder = (int) diff%31536000;
	int days = (int) yearsRemainder/86400;
	int daysRemainder = (int)diff%86400;
	int hours = (int) daysRemainder/3600;
	int hourRemainder = (int)(diff - 86400)%3600;
	int min = (int)hourRemainder/60;
	 int sec= (int)diff%60;
	 o<<years<<" YEAR(S), "<<days<<" DAY(S), "<<hours<< " HOUR(S), "<< min<< " MINUTE(S), "<<sec<< " SECOND(S)"; 
}
 
 
 
return o.str();
}

Here's an example in action:
NOW:05/16/05 20:39:18
LATER:05/17/07 21:58:21
Difference:2 YEAR(S), 1 DAY(S), 1 HOUR(S), 19 MINUTE(S), 3 SECOND(S)

I wasn't trying to solve your problem for you, sorry if I gave you that impression. I'm glad you figured it out without my help anyway.

Well have you guys ever heard of the MOD (%) function.

Well let's say the count was 153 seconds.

char *print_time( int time )
{
  static char buf[20];
  char tmp[200];

  buf[0] = '\0';

  sprintf( tmp, "%d ", time );
  strcat( buf, tmp );

  return buf;
}

int main( void )
{
  int time[1];

  int seconds = 153;

  time[0] = seconds % 60;          // time[0] will equal 153 - 60 - 60, this will go on
                                   // until there isn't 60 left to subtract, then return
                                   // what is left
  seconds = seconds - time[0];     // we have the seconds so remove it
  time[1] = ( seconds / 60 ) % 60; // we divide by 60 cause there is 60 secs in a min.
                                   // the same will happen here as above but seeing
                                   // the seconds was 120 (153 - 33) it will return 2

  printf( "%s%s%s%s%s\n",
    time[1] > 0 ? print_time( time[1] ) : "", time[1] > 0 ? "minutes" : "",
    time[1] > 0 ? " and " : "", 
    time[0], " seconds" );

  return 0;
}

Basically this will return x minutes and x seconds if both are bigger than 0 or just the seconds, it is very adaptable, now using 153 seconds it would return 2 minutes and 33 seconds.

(Yes, I know - see my post #7)

I saw it, but honestly look at the amount of code you are using to calculate it and actually print it out.

Yes optimising that part of code wouldn't make such a huge difference when it is a client side program, but for me, running a game on a server and having anything from the odd 20 to 30 people calling that function at the same time could make a fraction of a second difference for each user, it also reduces server load, and frankly it looks easier to read.

Anyway, I am not here to tell people how bad they write their code or how to write it, it is just a different solution.

Although you used the mod function, you used several unneeded lines of code.

If you start adding in hours, days, and years, the number of lines go up...

Adding it up to years would increase the line count by nine lines. An actual fact the way you calculated things were 100% on the spot, the whole concept of using an if else statement here is very sloppy if I may say so.

If you would have just used the mod function by calculating the days and used a function to return a string value for each amount, as per char *print_time, it would decrease the lines of code more. Yes using a if else statement doesn't use up resources, but again look at time spent, space taken and readibility of the code.

Please do understand me correctly, I am not saying you did anything wrong nor do I say your way of programming is wrong, it is my mere opinion, a different solution to the same problem, and with the fact that most of my experience comes from writing server side applications I have the need for fast calculations, optimised code and to be able to go back and understand what I did some time ago, seeing that my online game at the moment, after removing about a third of code is still over 120 000 lines of code, excluding open spaces and comments.

Again please do not feel offended I was just trying to show you a better and easier way to do it.

This is my solution, should be easy enough to convert to C++, you can change the first line to any number of seconds you like, once you get the pattern you can add centuries, millenia etc...

total_seconds = 939000000

seconds = total_seconds % 60
total_minutes = total_seconds / 60
minutes = total_minutes % 60
total_hours = total_minutes / 60
hours = total_hours % 24
total_days = total_hours / 24
days = total_days % 365
years = total_days / 365

print years, days, hours, minutes, seconds


PS. I'm sorry the previous poster was so rude... sorry for him.

Hey there... just registered to the site. Looks like a great place to learn a few things.

Not a big developer but i have hired plenty of programers to develop ideas that i have for businesses as a project manager. Anyhow, here i am and i am interested in learning a few things to know what i am talking about.

In response to this email, i would like to know what application i need to use with OSX to use the above code?
I understand what the code effectively does but what do i do with it in OSX, in order for it to give me an answer of exactly how many Years, Months and days is 14.6397 years?

Warmly,

CaribbeanOSX

Is there a standard algorithm that can take the output of difftime (which is in seconds) and use it to print out the number of minutes, hours, days, weeks, etc.?

I was going to try and calculate this myself by using the modulo, etc. but thought that something might pre-exist..

i dont no about standard algorithm but here is some code which will help you to convert your seconds into days,hours minutes,seconds

days = (int)seconds / 86400;
hours = (int)(seconds / 3600) - (days * 24);
mins = (int)(seconds / 60) - (days * 1440) - (hours * 60);
secs = (int)seconds % 60;


where seconds indicates that input in seconds

Comments
Useless bump of 4 year old thread, adding no new information
This article has been dead for over six months. Start a new discussion instead.