1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
|
#include <iostream>
#include <ctime>
#include <stdexcept>
#include <utility>
#include <tuple>
std::tm& sanitize( std::tm& tm )
{
if( std::mktime( std::addressof(tm) ) == -1 )
throw std::invalid_argument("invalid date") ;
return tm ;
}
// increment year to start of unix epoch; return number of years added
int increment_to_unix_epoch( std::tm& tm )
{
static constexpr int begin = 70 ;
int n = 0 ;
while( tm.tm_year < begin ) { ++tm.tm_year ; ++n ; }
sanitize(tm) ;
return n ;
}
enum month_t : int { JAN = 0, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC } ;
std::tm construct( int year, month_t month, int day, int bhour, int bmin, int bsec )
{
std::tm tm {} ;
tm.tm_mday = day ;
tm.tm_mon = month ;
tm.tm_year = year - 1900 ;
tm.tm_hour = bhour ;
tm.tm_min = bmin ;
tm.tm_sec = bsec ;
tm.tm_isdst = -1 ; // don't know
return tm ;
}
// return #increments added to n
int increment( std::tm& from, std::time_t till, int std::tm::*member, int n = 0 )
{
sanitize(from) ;
while( std::mktime(&from) < till ) { ++(from.*member) ; ++n ; }
if( std::mktime(&from) > till ) { --(from.*member) ; --n ; }
return n ;
}
int elapsed_years( std::tm& from, std::time_t till )
{
int n = increment_to_unix_epoch(from) ;
return increment( from, till, &std::tm::tm_year, n ) ;
}
int elapsed_months( std::tm& from, std::time_t till )
{ return increment( from, till, &std::tm::tm_mon ) ; }
int elapsed_days( std::tm& from, std::time_t till )
{ return increment( from, till, &std::tm::tm_mday ) ; }
int elapsed_hours( std::tm& from, std::time_t till )
{ return increment( from, till, &std::tm::tm_hour ) ; }
int elapsed_minutes( std::tm& from, std::time_t till )
{ return increment( from, till, &std::tm::tm_min ) ; }
int elapsed_seconds( std::tm& from, std::time_t till )
{ return increment( from, till, &std::tm::tm_sec ) ; }
int main()
{
int byear = 1922 ; // std::cin >> byear ;
int bmonth = NOV ; // std::cin >> bmonth ;
int bday = 30 ; // std::cin >> bday ;
int bhour = 14 ; // std::cin >> bhour ;
int bmin = 38 ; // std::cin >> bmin ;
int bsec = 24 ; // std::cin >> bsec ;
std::tm birth_date = construct( byear, month_t(bmonth), bday, bhour, bmin, bsec ) ;
const std::time_t now = std::time(nullptr) ;
// *** attention *** to be called in order: most significant to least significant
std::cout << elapsed_years( birth_date, now ) << " years, " ;
std::cout << elapsed_months( birth_date, now ) << " months, " ;
std::cout << elapsed_days( birth_date, now ) << " days, " ;
std::cout << elapsed_hours( birth_date, now ) << " hours, " ;
std::cout << elapsed_minutes( birth_date, now ) << " minutes and " ;
std::cout << elapsed_seconds( birth_date, now ) << " seconds\n" ;
}
|