I'm trying to calculate exact age of person using difference between now and the date of birth. I'm getting difference in seconds, which, I suppose is correct value. Then i'd like to convert seconds into struct tm
, using gmtime()
. But it is giving me a tm_year
on 70 bigger than it must be, and tm_mday
on 1 bigger than must be. It seems to be clear about tm_mday
- the range of it is from 1 to 31, I can just subtract 1 from, whereas tm_year
is the years from 1900. OK, so why does gmtime()
give me +70 years?
#include <iostream>
#include <ctime>
using namespace std;
int main() {
int min,h,d,m,y;
struct tm bd = {0};
cout << "Enter birth date in the format: hh:min/dd.mm.yyyy"<<endl;
scanf("%d:%d/%d.%d.%d",&h,&min,&d,&m,&y);
bd.tm_year = y-1900;
bd.tm_mon = m-1;
bd.tm_mday = d;
bd.tm_hour = h;
bd.tm_min = min;
time_t now = time(NULL);
cout << "NOW: "<<now<<" BD: "<<mktime(&bd)<<endl;
time_t seconds = difftime(now,mktime(&bd));//(end,beginning)
cout <<"seconds elapsed: "<< seconds<<endl;
struct tm * age;
age = gmtime (&seconds);
cout << "year" << age->tm_year << endl;
cout << "mon" << age->tm_mon << endl;
cout << "mday" << age->tm_mday << endl;
cout << "hour" << age->tm_hour << endl;
cout << "min" << age->tm_min << endl;
cout << "sec" << age->tm_sec << endl;
}
output:
Enter birth date in the format: hh:min/dd.mm.yyyy
13:28/04.03.2021
NOW: 1614853702 BD: 1614853680
seconds elapsed: 22
year 70
mon 0
mday 1
hour 0
min 0
sec 22
It is translating "unix epoch time", which is seconds since 1970, to a date.
It is not converting seconds to an amount of days/months/years. There is fundamentally no such conversion. 30 days can be less than or more than a month. 365 days can be a year, or 1 day less than a year. 24 times 60 times 60 seconds can be less than a day when a leap second happens.
Seconds after a point in time is a date. But seconds does not uniquely map to a number of days/months/years.
Find the two points in time - dates - and compare/subtract components to do that.