How to display earliest date from user input? - c

I'm having a hard time finding earliest date from user input of a date format mm/dd/yy.
I did wrote a solution for printing greater date, but lowest date is always showing as 0/0/0 because I am breaking the while loop if /0/0/0 is typed.
The code is as follows:
int main(int argc, const char * argv[])
{
int month, day, year, earliestDay = 0, earliestMonth = 0 , earliestYear=0;
printf("Enter a date (mm/dd/yy): ");
scanf("%d/%d/%d", &month, &day, &year);
while (day && month && year !=0){
printf("Enter a date (mm/dd/yy): ");
scanf("%d/%d/%d", &month, &day, &year);
if ( earliestDay <= day)
earliestDay = day;
if (earliestMonth <= month)
earliestMonth = month;
if (earliestYear <= year)
earliestYear = year;
}
printf("%d/%d/%d is the greatest date!\n", earliestMonth, earliestDay, earliestYear);
}
I would appreciate if anyone can explain to me how can I print the lowest.
Thank you in advance!

As #RJFalconer says, you need to properly initialize things.
Also, if your "greatest date" solution used similar logic to this, I don't think you tested it very well: you can't treat the year, month and day independently. Following your logic, if 01/30/99 and 12/01/50 were entered, you'd report 12/30/99 as the greatest date, when it isn't either of the entered dates! Instead, you need logic like:
day1 < day2 IF day1.year < day2.year OR
(day1.year==day2.year AND (day1.month < day2.month OR
(day1.month==day2.month AND day1.day < day2.day)))

The idiomatic way of searching for a min/max value in a loop is
#include <limits.h>
int earliestDay = INT_MAX;
while (...) {
earliestDay = min(earliestDay, day);
}
or
#include <limits.h>
int latestDay = INT_MIN;
while (...) {
latestDay = max(latestDay, day);
}

After consulting replies from you all I think I found the right way to do it. Please review one more time and see if its alright, even thou I tested it and it works.
The edited code is :
int main(){
int month1, day1, year1, day2, month2 = 0, year2 = 0, earliestDay = 32, earliestMonth = 13 , earliestYear=3000;
printf("Enter a date (mm/dd/yy): ");
scanf("%d/%d/%d", &month1, &day1, &year1);
while (1){
printf("Enter a date (mm/dd/yy): ");
scanf("%d/%d/%d", &month2, &day2, &year2);
if((day1 ==0 && month1 && year1 ==0) || (day2 == 0 && month2== 0 && year2 ==0))
break;
if ( day1 < day2)
earliestDay = day1;
if (month1 < month2)
earliestMonth = month1;
if (year1 <= year2)
earliestYear = year1;
}
printf("%d/%d/%d is the earliest date!\n", earliestMonth, earliestDay, earliestYear);
}

Related

Create a c program that takes two dates and output the number of days between them

This is my code to find the days in between days. For example 03 15 to 03 24 have 9 days between each other.
#include <stdio.h>
int main(void) {
int mm,dd,yy, mm2, dd2, yy2;
printf("Please enter in first date (MM/DD/YYYY format): ");
scanf("%d/%d/%d",&mm,&dd,&yy);
printf("Please enter in second date (MM/DD/YYYY format): ");
scanf("%d/%d/%d",&mm2,&dd2,&yy2);
if(yy>=2000 && yy<=2019) {//check year if it between 2000 to 2019
if(mm>=1 && mm<=12){ //check month
if((dd>=1 && dd<=31) && (mm==1 || mm==3 || mm==5 || mm==7 || mm==8 || mm==10 || mm==12)) //check the days of these months.
printf("The first date is valid.\n");
else if((dd>=1 && dd<=30) && (mm==4 || mm==6 || mm==9 || mm==11)) //check the days of these months.
printf("The first date is valid.\n");
else if((dd>=1 && dd<=28) && (mm==2)) //check the days of these month because February only have 28 days when its not a leap year
printf("The first date is valid.\n");
else if(dd==29 && mm==2 && (yy%400==0 ||(yy%4==0 && yy%100!=0))) // a leap year check
printf("The first date is valid.\n");
else
printf("The first day is invalid.\n"); // run if the user have enter in a invalid day
} else {
printf("The first month is not valid.\n"); // run if the user have enter in a invalid month
}
} else {
printf("The first year is not valid.\n"); // run if the user have enter in a invalid year
}
if(mm < mm2) { // check to see if mm2 is greater than mm
int s = dd2-dd;
s=s+dd2;
for (mm=mm;mm<mm2+1;mm++) {
s=s+mm;
}
printf("The total number states which is strictly between given two dates is: %d\n", s);
} else if(mm == mm2) {// check to see if it is in the same month
if(dd <= dd2) { // check to see if day2 is greater to equal to day1
// print out the number that are between those days
printf("The total number states which is strictly between given two dates is: %d\n", dd2-dd);
} else {
printf("Second date precedes the first date\n"); // if the second is greater then the first date, it will print this out
}
}
return 0;
}
For some reason when I enter in 02/10/2019 and 03/07/2019. I get 4 for the days in between which is wrong but when I do 01/01/2019 and 12/03/2019, I get 81 which is correct.
Here's a simpler version
#include<stdio.h>
#include<conio.h>
void days(int,int,int,int,int,int);
int month(int,int);
int mon[12]={31,28,31,30,31,30,31,31,30,31,30,31};
main()
{
int a1,b1,c1,a2,b2,c2;
clrscr();
printf("Enter first date(dd mm yyyy) : ");
scanf("%d%d%d",&a1,&b1,&c1);
printf("\nEnter second date(dd mm yyyy) : ");
scanf("%d%d%d",&a2,&b2,&c2);
if(c2>=c1)// checking which date is lesser
days(c1,c2,b1,b2,a1,a2);
else
days(c2,c1,b2,b1,a2,a1);
getch();
}
void days(int y1,int y2,int m1,int m2,int d1,int d2)
{
int count=0,i;
for(i=y1;i<y2;i++)//just adding days
{
if(i%4==0)//leap year
count+=366;
else
count+=365;
}
count-=month(m1,y1);//sub month
count-=d1;//day
count+=month(m2,y2);//add month
count+=d2;//day
if(count<0)
count=count*-1;
printf("The no. of days b/w the 2 dates = %d days",count);
}
int month(int a,int yy)
{
int x=0,c;
for(c=0;c<a-1;c++)
{
if(c==1)// feb
{
if(yy%4==0)
x+=29;
else
x+=28;
}
else
x+=mon[c];//get no. Of days in the month
}
return(x);
}
You already got one answer, and that one looks really good. I am adding answer to give you an optional method. Ultimately, you can always convert the date strings to timestamps. After that, you can look for the time difference between the two dates by subtracting the second date's timestamp to the first date time stamp. If that yields negative, that is a precedent day. If not, that is all fine.
To be able to do that, you can use mktime() and struct tm from . When you use "time.h" you would still need to validate your dates like now. It just, it would be easier on the calculation.
For tm_year from struct tm, you would need to subtract the year value to 1900. Also, it seemed that you only wanted your program to work for dates from the year 2000 - 2019. Thus, 19 years. Thus, I think a long or int_64 should be able to hold the maximum seconds different between two dates. Also, mktime() return value are seconds.
Take notice that I did not write the code to calculate where date 2 is before date 1. Thus, if you attempt to calculate that, it might give you an error.
#include <stdio.h>
#include <time.h>
int main(void) {
int mm,dd,yy, mm2, dd2, yy2;
printf("Please enter in first date (MM/DD/YYYY format): ");
scanf("%d/%d/%d",&mm,&dd,&yy);
printf("Please enter in second date (MM/DD/YYYY format): ");
scanf("%d/%d/%d",&mm2,&dd2,&yy2);
if(yy>=2000 && yy<=2019) {//check year if it between 2000 to 2019
if(mm>=1 && mm<=12){ //check month
if((dd>=1 && dd<=31) && (mm==1 || mm==3 || mm==5 || mm==7 || mm==8 || mm==10 || mm==12)) //check the days of these months.
printf("The first date is valid.\n");
else if((dd>=1 && dd<=30) && (mm==4 || mm==6 || mm==9 || mm==11)) //check the days of these months.
printf("The first date is valid.\n");
else if((dd>=1 && dd<=28) && (mm==2)) //check the days of these month because February only have 28 days when its not a leap year
printf("The first date is valid.\n");
else if(dd==29 && mm==2 && (yy%400==0 ||(yy%4==0 && yy%100!=0))) // a leap year check
printf("The first date is valid.\n");
else {
printf("The first day is invalid.\n"); // run if the user have enter in a invalid day
return 1;
}
} else {
printf("The first month is not valid.\n"); // run if the user have enter in a invalid month
return 1;
}
} else {
printf("The first year is not valid.\n"); // run if the user have enter in a invalid year
return 1;
}
struct tm firstDate;
struct tm secondDate;
firstDate.tm_sec = 0;
firstDate.tm_min = 0;
firstDate.tm_hour = 0;
firstDate.tm_mday = dd;
firstDate.tm_mon = mm;
firstDate.tm_year = yy-1900;
firstDate.tm_isdst = 0;
secondDate.tm_sec = 0;
secondDate.tm_min = 0;
secondDate.tm_hour = 0;
secondDate.tm_mday = dd2;
secondDate.tm_mon = mm2;
secondDate.tm_year = yy2-1900;
secondDate.tm_isdst = 0;
long epochFirstDate = (long) mktime(&firstDate);
long epochSecondDate = (long) mktime(&secondDate);
long dayDifferent = (epochSecondDate - epochFirstDate);
if ( dayDifferent > 0 ) dayDifferent = dayDifferent / 60 / 60 / 24;
if ( dayDifferent > -1 )
printf("The total number states which is strictly between given two dates is: %lu\n", dayDifferent);
else
printf("Second date precedes the first date\n"); // if the second is greater then the first date, it will print this out
return 0;
}

Date comparison program

Can anyone spot what's wrong with my code?
It should simply compare Dates and the earliest one should get recorded, however only my first input is. Walked through it slowly can't see where my logic error is.
#include <stdio.h>
int main(void)
{
int month=1, day=1, year=1;
int fmonth=0, fday=0, fyear=0;
while((month != 0) && (day != 0) && (year != 0))
{
printf("Enter the date: (0/0/0 to cancel) ");
scanf("%d/%d/%d", &month, &day, &year);
if(fyear < year)
{
fyear = year;
fmonth = month;
fday = day;
}
else if ((fyear == year) && (fmonth < month) && (fday <= day))
{
fyear=year;
fmonth=month;
fday=day;
}
}
printf("Earliest Date is: %d/%d/%d\n", fmonth,fday,fyear);
return 0;
}
Hah, this was kinda fun. Your primary problem was you had your comparisons turned around backwards. (and you needed to add a (month == fmonth) test) Your secondary problem was a total failure to validate user input -- it will bite you every time.
First, you want to check if (date < fdate) before assigning, not if (fdate < date) or you will overwrite your earlier date with a later one (as yuchaun correctly noted originally).
Always, always, validate user input. For all you know a cat may be stepping on the keyboard. At minimum, at least check the return of scanf to validate that the number of conversions to int you expected, did in fact take place (validating the values fall into valid month, day, year ranges is left to you).
Putting those pieces together, and replacing the "0/0/0" cancellation with a simple counter to determine when you have two dates entered, you could do something similar to:
#include <stdio.h>
int main (void) {
int month = 1, day = 1, year = 1,
fmonth = 0, fday = 0, fyear = 0,
n = 0; /* simple counter - no need for 0/0/0 */
while (1) { /* just loop until you have 2 dates */
printf ("Enter the date: ");
/* validate ALL User Input */
if (scanf ("%d/%d/%d", &month, &day, &year) != 3) {
fprintf (stderr, "error: invalid date, exiting.\n");
return 1;
}
/* if no fdate or if (date < fdate) then fdate = date */
if (!n || (year < fyear) ||
((year == fyear) && ((month < fmonth) ||
((month == fmonth) && (day < fday))))) {
fyear = year;
fmonth = month;
fday = day;
}
if (++n == 2) /* increment counter and test */
break;
}
printf ("Earliest Date : %d/%d/%d\n", fmonth, fday, fyear);
return 0;
}
Example Use/Output
$ ./bin/earlierdate
Enter the date: 12/21/1991
Enter the date: 12/22/1991
Earliest Date : 12/21/1991
$ ./bin/earlierdate
Enter the date: 12/22/1991
Enter the date: 12/21/1991
Earliest Date : 12/21/1991
When you run into a problem like this, always see How to debug small programs and don't be shy about talking to the duck... it works!
Look things over, and consider all answers, and let me know if you have any further questions.
Some errors in your code include:
if (fyear < year): Say previously I got fyear = 2015, now I scan year = 2012. Is 2015 < 2012 ? So, the conditions will be reversed, right?
Now the problem with reversing is, fmonth=0, fday=0, fyear=0. Suppose, I scan year = 2012. So, check (fyear > year) ⇒ (0 > 2012)? It won't be updated. So, change the initialization.
Lastly, if you scan 0/0/0, and say our present fyear = 2012 and year = 0. So, fyear > year ⇒ 2012 > 0, this updates the whole thing to 0/0/0. We need to take care the when to scan because while loop executes the whole thing before checking the previous scan.
(fyear == year) && (fmonth < month) && (fday <= day) What if only present month is less than the previous? The conditions should be ||
So, I think you can draw a solution like this,
#include <stdio.h>
#include <limits.h>
int main(void)
{
int fmonth=INT_MAX, fday=INT_MAX, fyear=INT_MAX, month=INT_MAX, year = INT_MAX, day = INT_MAX;
while(month != 0 && year != 0 && day != 0)
{
if(year<fyear || (year==fyear && month<fmonth) || (year==fyear && month==fmonth && day<fday))
{
fyear = year;
fmonth = month;
fday = day;
}
printf("Enter the date: (0/0/0 to cancel) ");
scanf("%d/%d/%d", &month, &day, &year);
}
printf("Earliest Date is: %d/%d/%d\n", fmonth,fday,fyear);
return 0;
}
Since the decision tree is hard to debug and write, you should first ensure that all months and days are within a proper range.
Then it's just a matter of assigning a proper weight to each digit in this possibly mixed radix number system:
int days_total = w_y * years + w_m * months + w_d * days;
And same for the other date. The comparison reduces to comparing this linearized date with any w_d >= 1, w_m >= 31, w_y >= 366.
Suggested values are 1,32 and 512 for best performance.
You're actually overwriting the value of fyear,fmonth,fdays when the date entered is LATER than the stored fyear/month/day, which I don't think is your intention
I get the following output:
$ ./a.out
Enter the date: (0/0/0 to cancel) 1/2/3
Enter the date: (0/0/0 to cancel) 3/4/5
Enter the date: (0/0/0 to cancel) 0/0/0
Earliest Date is: 3/4/5
$ ./a.out
Enter the date: (0/0/0 to cancel) 3/4/5
Enter the date: (0/0/0 to cancel) 1/2/3
Enter the date: (0/0/0 to cancel) 0/0/0
Earliest Date is: 3/4/5
$ ./a.out
Enter the date: (0/0/0 to cancel) 1/2/3
Enter the date: (0/0/0 to cancel) 0/0/0
Earliest Date is: 1/2/3
so it's not just the first input that's being captured, but the date recorded is the latest, not the earliest.
You made a little mistake when comparing in
if(fyear < year)
Since you save the user input in variable year, you only record the date which is the latest, not the earliest.
But simply changing the operator won't work here, you need to implement this program anew. Try imaging how the comparison works best.
Tips:
Maybe try using ranges for days and month (1 <= day <= 28, 30, 31 and 1 <= month <= 12)
Your idea to compare first the year in your second if-statement was okay, now try the same for month and day like this:
if(year <= fyear) {
if(month <= fmonth) {
if(day <= day) {
fday = day;
fmonth = month;
fyear = year;
}else{
/* nothing happens, since date
* is later than the current */
}
}else{
// your logic here
}
}else{
// your logic here
}
Maybe assign the values to the fyear, fmonth and fday variables immediately when they are all 0. Because when comparing to input dates, an if-statement which checks wether the input date is earlier than the initial (0/0/0) date will always fail.
Here, I edited your code and included some statements to make the program user friendly. I think this will ensure your requirement. And also you have to consider, Feb 29(leap year) month,year date > 0.
#include<stdio.h>
int main(void)
{
int month=1, day=1, year=1;
int fmonth, fday, fyear;
printf("Enter the date: (0/0/0 to cancel)\n ");
scanf("%d/%d/%d", &fday, &fmonth, &fyear);
while(1)
{
printf("1.Do you want to continue.\n2.print the result.\n");
int ch;
scanf("%d",&ch);
if(ch==2){break;}
printf("Enter the date: (0/0/0 to cancel)\n ");
scanf("%d/%d/%d", &day, &month, &year);
if(fyear > year)
{
fyear = year;
fmonth = month;
fday = day;
}
else if ((fyear == year) && (fmonth > month))
{
fyear=year;
fmonth=month;
fday=day;
}
else
{if ((fyear == year) && (fmonth == month) && (fday > day))
{
fyear=year;
fmonth=month;
fday=day;
}
}
}
printf("Earliest Date is: %d/%d/%d\n",fday,fmonth,fyear);
return 0;
}

Input today's date get tomorrow output

When I enter the date 08/01/2015 the program prints 00/00/00 instead of 08/01/2015. What seems to be the problem?
#include <stdio.h>
int main ()
{
int month = 0;
int day = 0;
int year = 0;
printf("Enter today's date (mm/dd/yyyy): ");
scanf("%i/%i/%i", &month, &day, &year);
printf("%.2i/%.2i/%.2i", month, day, year);
return 0;
}
I amended your original program to deal with several issues. But the main one was to use the correct format specifier %d in scanf(). Using %i will interpret an input as octal if it has a leading 0 - very likely when typing a date, especially as you encourage that with the output format. Months 01 to 07 did not fail because the octal input works correctly - but 08 and 09 do not, as 8 and 9 do not exist in octal number representation.
I also checked the return value from scanf() to ensure the integer date fields were correctly entered. If you had done that, you would have seen there was something wrong there.
Other things I changed are:
Checked the date you entered to be valid to avoid the GIGO syndrome.
Avoided writing to the array of days per month as commented earlier.
Restricted the year to the Gregorian calendar, as some days were missing.
Separated form from functionality. For example, your leapYear() function checked for a leap year and also tested (inadequately) - and reported errors in the date entered.
Moved the global date variables to be local vars, which are passed as function arguments.
#include <stdio.h>
struct date {
int month;
int day;
int year;
};
int daysPerMonth[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int leapyear(int year) {
return (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0));
}
int validdate(struct date now) {
int daysmon;
if (now.year <= 1582) // pre-Gregorian
return 0;
if (now.month < 1 || now.month > 12)
return 0;
daysmon = daysPerMonth[now.month-1];
if (leapyear(now.year) && now.month == 2)
daysmon++;
if (now.day < 1 || now.day > daysmon)
return 0;
return 1;
}
struct date bumpdate(struct date now) {
int daysmon = daysPerMonth[now.month-1];
if (leapyear(now.year) && now.month == 2)
daysmon++;
if (++now.day > daysmon) {
now.day = 1;
if (++now.month > 12) {
now.month = 1;
now.year++;
}
}
return now;
}
int main (void) {
struct date today, tomorrow;
printf("Enter today's date (mm/dd/yyyy): ");
if (3 != scanf("%d %*[/-] %d %*[/-] %d", &today.month, &today.day, &today.year)) {
printf ("Need the proper date format\n");
return 1;
}
if (!validdate(today)) {
printf ("Invalid date\n");
return 1;
}
tomorrow = bumpdate(today);
printf("Tomorrow's date is %02d/%02d/%04d", tomorrow.month, tomorrow.day, tomorrow.year);
return 0;
}

Logic behind adding dates in C

I want to add x number of days to a date.
Can someone help me with my logic especially in adding x number of days to a specific date.
It seems to work for small number of days added but if I add a large number of days, it starts to give really funny answers.
Also no functions please, just logic.
int
main(int argc, char *argv[]) {
int dd, mm, yyyy, daysthismonth, days, option;
printf("Please enter a date in the following format: dd/mm/yyyy:\n");
if(scanf("%d/%d/%d",&dd,&mm,&yyyy)!= 3){
printf("Please enter a valid date\n");
exit(EXIT_FAILURE);
/* Calculating days in a month */
}
if((mm == 4)|| (mm == 6) || (mm == 9) || (mm == 11)){
daysthismonth = 30;
}
else if((mm == 2)){
if((yyyy%4 == 0) && ( (yyyy%100 == 0) || (yyyy%400 == 0))){
daysthismonth = 29;
}
else{
daysthismonth = 28;
}
}
else {
daysthismonth = 31;
}
/* Calculating the validity of User Input */
if( (dd<0) || (dd>daysthismonth) || (mm<0) || (mm>12) || (yyyy < 0) || (yyyy>9999) ){
printf("Plase enter a valid date between from a day from 0 AD to 9999 AD\n.");
}
printf("Todays date: %02d/%02d/%04d\n"
"How many days would you like to go in the future? \n",dd,mm,yyyy);
if(scanf("%d",&days) != 1){
printf("Please enter a valid input\n");
}
printf("The date %d days in the future is:\n",days);
while(days > (daysthismonth - dd)){
mm = mm + 1;
days = days - (daysthismonth - dd);
if( days < daysthismonth){
dd = days;
}
if( mm>12){
mm = 1;
yyyy = yyyy + 1;
}
}
dd = dd + days;
}
printf(" %02d/%02d/%04d\n",dd,mm,yyyy);
exit(EXIT_SUCCESS);
}
I guess my logic was if you added a large number of days, it would subtract the next month's days until you get to a point where the days to be added is less than the days in the month. At that point the date can just be the days you have to add.
That's why I implemented a while? loop so it could reiterate
edited: scanf() != 1
Just store your day/month/year into a struct tm, call mktime() on it to convert to epoch seconds, add days*24*60*60 to advance it, then call localtime_r() (or localtime()) on the result to get day/month/year again.
Be mindful of daylight saving time: you should probably set the hours component to noon to avoid any possibility of gaining or losing a day when DST changes.
So you want to add days on a date.
The easy logic is to convert the date to days, add the x days, then convert days to date.
The complex logic is to just make the add like in maths
yyyy/mm/dd
+ dd
-----------
result
like in the maths the numbers can only be from 0-9 here the date / month / year have to be valid based on the rest.
converting the days you want to add to date before the add and then add before making valid can help.
Example in javascript (so that you can easy run it on the browser's console):
function daysInMonth(month,year){
// Does not matter how you make this function
return new Date(year, month, 0).getDate();
}
var year = 2014;
var month = 8;
var day = 8;
var daysToAdd = 123434;
day += daysToAdd;
var maxDay = daysInMonth( month, year);
while( day>maxDay ){
day -= maxDay;
month += 1;
if(month==13){
month = 1;
year += 1;
}
maxDay = daysInMonth( month, year);
}
console.log(day+'/'+month+'/'+year);
It works like a charm :)
C code (After a request) :
#include <stdio.h>
main(){
// Init the variables we use
int year = 0;
int month = 0;
int day = 0;
int maxDay = 0;
int daysToAdd = 0;
// Ask user for a date
printf("Please enter a date in the following format: dd/mm/yyyy:\n");
// Validate data
while( scanf( "%d/%d/%d", &day, &month, &year)!= 3 || day<=0 || month<=0 || year<0 || daysInMonth(month,year)<day ){
printf("Please enter a valid date.\n");
}
// Ask user for days to add
printf("Please enter days to add: \n");
// Validate data
while( scanf( "%d", &daysToAdd)!= 1 || daysToAdd<=0 ){
printf("Please enter a positive number.\n");
}
// Calculate date
day += daysToAdd;
maxDay = daysInMonth( month, year);
while( day>maxDay ){
day -= maxDay;
month += 1;
if(month==13){
month = 1;
year += 1;
}
maxDay = daysInMonth( month, year);
}
printf("Result date : %d/%d/%d", day, month, year);
return(0);
}
// Get days in the month
int daysInMonth( int month, int year){
if( month==4 || month==6 || month==9 || month==11 ){
return 30;
}else if( month== 2 ){
if( year%4==0 && ( year%100==0 || year%400==0) )
return 29;
else
return 28;
}else{
return 31;
}
}
Online test link : http://ideone.com/CGXgtP
Happy coding.

Calculate Age, Given Date of Birth

Given a date of birth, how would I go about calculating an age in C?
For example, if today's date is 20/04/2010 and the date of birth given is 12/08/86, then age will be 23 years, 8 months, and 8 days.
Any suggestions would be appreciated.
Thanks!
For just the year (no months/days) :
1) Format the dates to yyyymmdd
2) Subtract the date of birth from date
3) Remove the last 4 numbers
(Language agnostic)
So for your example;
date 20/04/2010
birth 12/08/1986
convert
date 20100420
birth 19860812
subtract
20100420-19860812 = 239608
drop last 4 digits
23
I'm assuming, based on your description, that you have to print out the full difference, not just years.
One part of the problem is to input the dates correctly and break them down into components, I'll assume you already know how to do that or got sample code for that.
What you need to do now is to calculate the difference. One way to do this would be to pick a reference date (e.g., Jan 1st 1900), and calculate how many days it had been until the first date and the second date, and calculate the difference in days. Then you take the difference in days and break it back into years/months/days.
Two things to notice are:
1) Take leap years into account.
2) Figure out how to translate a number of dates into months, since each month has a different number of days.
3) If you had to input times and not just dates, you could be off by a day. Similarly if time zones are input.
I would check with the instructor whether you can make a simplifying assumption about that (E.g., months are always 30, leap years are ignored, etc.). I find it hard to believe that a homework assignment would require you to deal with these correctly.
The way to approach a problem like this is to figure out how you'd do it using a pencil and paper - then formalise that into a program.
For this particular problem, that means at a high level, "subtract birth date from current date". For this subtraction, you use a variation of the same algorithm you learn for subtraction in primary school - where you start by subtracting the lower value column (in this case, "days"), borrowing from the next-higher-value column if necessary. For example, to subtract 1986-09-15 from 2010-04-10, you would do:
2010-04-10 -
1986-09-15
----------
10 is less than 15, so you have to borrow from the months column. This means that the months column goes down by one (to 3), and the days column goes up by the number of days in month 3 (March - so 31). You can now do the subtraction of the days column:
2010-03-41 -
1986-09-15
----------
-26
We can now move on to the months column. 3 is less than 9, so we have to borrow again, this time from the year. Take one off the year, and add 12 to the month (since there are always 12 months in a year), then perform the subtraction:
2009-15-41 -
1986-09-15
----------
-06-26
We can now work on the years - there's never a need to borrow here (unless you're trying to calculate the age of someone born in the future!):
2009-15-41 -
1986-09-15
----------
23-06-26
This means the difference is 23 years, 6 months, 26 days.
You can now work on turning this into a program (hint: use three seperate integer variables for years, months and days). The trickiest part is the borrow from the months column - you need to know how many days are in that month, including leap years for February.
If you're allowed to use the libraries, it's not too hard. Look at strptime, struct tm, time, and localtime. Once you have it in "broken-down" form (struct tm), it's easy to compute the difference (look at tm_yday, tm_mon, and tm_yday).
If today's date falls after the birthday, the age is the difference between the birth year and today's year. If today's date falls before the birthday, subtract 1.
/* program for calculating the age */
/* author - nitin kumar pandey */
/* mail - nitindonpandey#gmail.com */
#include<stdio.h>
#include<conio.h>
int d1,d2,d3,m1,m2,m3,y1,y2,y3;
void year(int d1,int m1,int y1,int d2,int m2,int y2);
void main()
{
clrscr();
printf("please enter the current date \n");
printf("enter the day");
scanf("%d",&d1);
printf("enter the month");
scanf("%d",&m1);
printf("enter the year");
scanf("%d",&y1);
printf("Now thank you for your cooperation \n now please enter the date of birth");
printf("enter the day");
scanf("%d",&d2);
printf("enter the month");
scanf("%d",&m2);
printf("enter the year");
scanf("%d",&y2);
year(d1,m1,y1,d2,m2,y2);
getch();
}
void year(int d1,int m1,int y1,int d2,int m2,int y2)
{
if(d2>d1)
{
m1=m1-1;
d1=d1+30;
}
if(m2>m1)
{
y1=y1-1;
m1=m1+12;
}
if(y2>y1)
{
exit(0);
}
d3=d1-d2;
m3=m1-m2;
y3=y1-y2;
printf("current age is \n day %d \n month %d \n year %d ",d3,m3,y3);
}
//Age calculation. A simple c++ program
#include<iostream>
#include<iostream>
#include<ctime>
using namespace std;
void main()
{
system("cls");
time_t theTime = time(NULL);
struct tm *aTime = localtime(&theTime);
int currentday = aTime->tm_mday;
int currentmonth = aTime->tm_mon + 1; // Month is 0 - 11, add 1 to get a jan-dec 1-12 concept
int currentyear = aTime->tm_year + 1900;
int birthday,birthmonth,birthyear;
cout<<"Enter birth year: ";
cin>>birthyear;
if(birthyear>currentyear)
{
cout<<"Current year: "<<currentyear<<endl
<<"Birht year : "<<birthyear<<endl
<<"Invalid...."<<endl<<endl;
system("pause");
main();
}
else if(birthyear<1900)
{
cout<<"Birht year should greater than 1900...."<<endl;
system("pause");
main();
}
cout<<"Enter birth month: ";
cin>>birthmonth;
if(birthmonth<1 || birthmonth>12)
{
cout<<"Birth month should be 1-12"<<endl;
system("pause");
main();
}
else if(birthyear==currentyear && birthmonth>currentmonth)
{
cout<<"Current Month/Year: "<<currentmonth<<"/"<<currentyear<<endl
<<"Birth Month/Year : "<<birthmonth<<"/"<<birthyear<<endl
<<"Future Birth Date. Invalid...."<<endl;
system("pause");
main();
}
cout<<"Enter birth day: ";
cin>>birthday;
if(birthday<1 || birthday>31)
{
cout<<"Birth day should 1-31"<<endl;
system("pause");
main();
}
else if(birthyear==currentyear && birthmonth==currentmonth && birthday>currentday)
{
cout<<"Current Day/Month/Year: "<<currentday<<"/"<<currentmonth<<"/"<<currentyear<<endl
<<"Birth Day/Month/Year : "<<birthday<<"/"<<birthmonth<<"/"<<birthyear<<endl
<<"Future Birth Date. Invalid...."<<endl;
system("pause");
main();
}
else if(birthyear%4==0 && birthmonth==2 && birthday>29)
{
cout<<"Febuary should be 1-29"<<endl;
system("pause");
main();
}
else if( (birthmonth==4 || birthmonth==6 || birthmonth==9 || birthmonth==11) && birthday>31)
{
cout<<"This month cannot have 31 days...."<<endl;
system("pause");
main();
}
int ageday,agemonth,ageyear;
if(birthmonth>currentmonth)
{
agemonth=currentmonth;
ageyear=currentyear-birthyear-1;
ageday=currentday;
}
else
{
agemonth=currentmonth-birthmonth;
ageyear=currentyear-birthyear;
ageday=currentday-birthday;
}
if(ageyear==0 && agemonth==0)
{
cout<<"your Date of Birth: "<<birthday<<"/"<<birthmonth<<"/"<<birthyear<<endl;
cout<<"Current Date : "<<currentday<<"/"<<currentmonth<<"/"<<currentyear<<endl;
cout<<"your Age : "<<ageday<<" days"<<endl;
}
else if(ageyear==0)
{
cout<<"your Date of Birth: "<<birthday<<"/"<<birthmonth<<"/"<<birthyear<<endl;
cout<<"Current Date : "<<currentday<<"/"<<currentmonth<<"/"<<currentyear<<endl;
cout<<"your Age : "<<agemonth<<" Months"<<ageday<<" days"<<endl;
}
else if(agemonth==0)
{
cout<<"your Date of Birth: "<<birthday<<"/"<<birthmonth<<"/"<<birthyear<<endl;
cout<<"Current Date : "<<currentday<<"/"<<currentmonth<<"/"<<currentyear<<endl;
cout<<"your Age : "<<ageyear<<" years"<<ageday<<" days"<<endl;
}
else if(ageday==0)
{
cout<<"your Date of Birth: "<<birthday<<"/"<<birthmonth<<"/"<<birthyear<<endl;
cout<<"Current Date : "<<currentday<<"/"<<currentmonth<<"/"<<currentyear<<endl;
cout<<"your Age : "<<ageyear<<" years"<<agemonth<<" Months"<<endl;
}
else
cout<<"your Date of Birth: "<<birthday<<"/"<<birthmonth<<"/"<<birthyear<<endl;
cout<<"Current Date : "<<currentday<<"/"<<currentmonth<<"/"<<currentyear<<endl;
cout<<"your Age : "<<ageyear<<" years"<<agemonth<<" Months"<<ageday<<" days"<<endl;
system("pause");
}
//AAW
The only issue with this code is that it doesn't factor in if you are born on leap day. there can be another if statement for that though.
// Age Calculator
time_t t = time(NULL);
struct tm tm = *localtime(&t);
int num_day;
if ( month == 1 )
{
num_day = 31;
}
if ( month == 2 )
{
num_day = 28;
}
if ( month == 3 )
{
num_day = 31;
}
if ( month == 4 )
{
num_day = 30;
}
if ( month == 5 )
{
num_day = 31;
}
if ( month == 6 )
{
num_day = 30;
}
if ( month == 7 )
{
num_day = 31;
}
if ( month == 8 )
{
num_day = 31;
}
if ( month == 9 )
{
num_day = 30;
}
if ( month == 10 )
{
num_day = 31;
}
if ( month == 11 )
{
num_day = 30;
}
if ( month == 12 )
{
num_day = 31;
}
int age_year = (tm.tm_year + 1900) - year;
int age_month = (tm.tm_mon + 1) - month;
int age_day = (tm.tm_mday) - day;
if ( age_month <= 0 )
{
age_year = (tm.tm_year + 1900) - year - 1;
age_month = 12 + (tm.tm_mon + 1) - month;
}
if ( age_day <= 0 )
{
age_month = 12 + (tm.tm_mon + 1) - month - 1;
age_day = num_day + (tm.tm_mday) - day;
}
printf("Your age: %d years %d months %d days\n", age_year, age_month, age_day);

Resources