c++ - Human-readable duration between two UNIX timestamps -


i'm trying calculate difference between 2 unix timestamps (i.e. seconds since 1970). want e.g. "3 years, 4 months, 6 days, etc" don't know how account leap years , months of different durations. surely solved problem..?

this different other questions want express approximate duration in 1 unit has fixed/homogeneous duration (e.g. 3 hours, or 7 weeks, etc.). results 1. jan 1. feb "1 month" , results 1. feb 1. mar "1 month" though number of days different.

i want express complete duration precisely in years/months/days/hours/minutes. solutions in c++ appreciated!

for older date, use leap year formula start counting number of days unix start date, jan1st 1970, first timestamp

(for leap seconds, dunno if need precise, out-of-scope?)

leap year calculated constraining date after 1600ad , algorithm gregorian calendar from: http://en.wikipedia.org/wiki/leap_year of

if year modulo 400 0 is_leap_year else if year modulo 100 0 not_leap_year else if year modulo 4 0 is_leap_year else not_leap_year

if year leap year, there 29days in feb, else 28days

now know month, day_of_month, year 1st variable

next, set of counts of days 2nd timestamp, using leap year formula till 2nd timestamp.

typedef struct {   int year;   int month;   int dayofmonth; } date_struct;  static int days_in_month[2][13] = {   {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},   {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, };  int isleapyear(int year) {   int value;   value = year;    //if year modulo 400 0   //   is_leap_year   value = year % 400;   if(value == 0) return 1;    //else if year modulo 100 0   //   not_leap_year   value = year % 100;   if(value == 0) return 0;    //else if year modulo 4 0   //   is_leap_year   value = year % 4;   if(value == 0) return 1;    //else   //   not_leap_year   return 0; }  date_struct addoneday(date_struct ds, int isleapyear){   int daysinmonth;    ds.dayofmonth++;    //if month february test leap year , adjust daysinmonth   if(ds.month == 2) {     daysinmonth = days_in_month[isleapyear][ds.month];   } else {     daysinmonth = days_in_month[0][ds.month];   }    if(ds.dayofmonth > daysinmonth) {     ds.month++;     ds.dayofmonth = 1;     if(ds.month > 12) {       ds.year += 1;       ds.month = 1;     }   }   return ds; }  long daysbetween(date_struct date1, date_struct date2){   long result = 0l;   date_struct mindate = min(date1, date2);   date_struct maxdate = max(date1, date2);    date_struct countingdate;   countingdate.year = mindate.year;   countingdate.month = mindate.month;   countingdate.dayofmonth = mindate.dayofmonth;    int leapyear = isleapyear(countingdate.year);   int countingyear = countingdate.year;    while(isleftdatesmaller(countingdate,maxdate)) {     countingdate = addoneday(countingdate,leapyear);     //if year changes while counting, check see if     //it new year     if(countingyear != countingdate.year) {       countingyear = countingdate.year;       leapyear = isleapyear(countingdate.year);     }      result++;   }    return result; } 

(i wrote open source program gives difference between 2 calendar dates, in c/c++. source code, posed above, might give inspiration own solution, or maybe can adapt of it, http://mrflash818.geophile.net/software/timediff/ )


Comments

Popular posts from this blog

SVG stroke-linecap doesn't work for circles in Firefox? -

routes - Laravel 4 Wildcard Routing to Different Controllers -

cross browser - XSLT namespace-alias Not Working in Firefox or Chrome -