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);
Related
Write a program that for a date read from SI (in the format DD MM YYYY) will print on standard output a message YES if the date is correct and possible, or NO if the date is not correct.
When deciding whether the date is correct or not correct, you have to consider the following factors:
is the month between January and December (1-12)
does the number for days correspond with the number of days in the specified month
if the month is February, is the year leap?
Leap years are those years who are divisible with 400, or they are divisible with 4, but not with 100
#include<stdio.h>
int main()
{
int day,month,year;
scanf("%d %d %d", &day, &month, &year);
for(month=1;month<=12;month++){
if (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0) ) {
printf("YES");
} else
printf("NO");
}
return 0;
}
You need an array of the days in a month and then check if the month is between 1 and 12. If the month is exactly 2, you should first check for leap years.
Something like this:
int daysInMonth = {31, 28, ...}; //replace ... with actual information
if(month < 1 || month > 13) {
//month isn't valid
printf("NO");
return 0;
}
month -= 1; //to convert to 0-indexed
if(month == 1 && ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)) {
//month is february and is leap year
daysInMonth[1] += 1; //february now has 29
}
if(day < 1 || day > daysInMonth[month]) {
//day isn't valid
printf("NO");
return 0;
}
//When getting to this point it means we have a valid date
printf("YES");
return 0;
Please note that this does not handle some very special edge cases, explained here. These include the days that don't exist because of the switch from Julian to Gregorian calendar. But I'm almost certain that these are not what the exercise was asking for anyways. You may also want to check against negative years, depending on the exact definition of a valid year.
As others have mentioned, you don't need to loop [on the month].
You should get the number of days in a month by indexing into an array (vs. switch).
Adding some extra boolean flags can help simplify things.
Anyway, here's a refactored version with some descriptive comments:
// is the month between January and December (1-12)
// does the number for days correspond with the number of days in the specified
// month
// if the month is February, is the year leap?
// Leap years are those years who are divisible with 400, or they are
// divisible with 4, but not with 100
#include <stdio.h>
#include <stdlib.h>
int days_in_month[12] = {
31, 28, 31, 30, 31, 30, 31, 31, 31, 31, 30, 31
};
int
main(int argc,char **argv)
{
int day, month, year;
int month_valid;
int leap_year;
int max_days;
int day_valid;
int date_valid;
--argc;
++argv;
if (argc == 3) {
month = atoi(argv[0]);
day = atoi(argv[1]);
year = atoi(argv[2]);
}
else {
if (0)
scanf("%d %d %d", &day, &month, &year);
else
scanf("%d %d %d", &month, &day, &year);
}
// is month in range?
month_valid = (month >= 1) && (month <= 12);
// is it a leap year?
leap_year = (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0));
// get number of days in month [if month is valid]
if (month_valid)
max_days = days_in_month[month - 1];
else
max_days = -1;
// february in a leap year has an extra day
if (month == 2)
max_days += leap_year;
// is day of the month valid?
day_valid = (day >= 1) && (day <= max_days);
// is entire date valid?
date_valid = month_valid && day_valid;
if (date_valid)
printf("YES\n");
else
printf("NO\n");
return 0;
}
I am working on a program that a user enters a date and then the program adds 7 days and prints out the date entered and then prints out the date with seven days added. I am getting the month and date correctly formatted and it appears that it is adding the seven days. However, the year is printing as four zeros and I am not quite sure what I am missing. Below is a screen show of the results and the code follows. Can someone let me know what is needed to print out the year please?
Result:
Please enter a date formatted as mm/dd/yyyy: 02/02/2000
The date you entered is: 02/16/0000
The date in seven days will be: 02/23/0000
Process returned 0 (0x0) execution time : 7.071 s
Press any key to continue.
#include <stdio.h>
#include <stdbool.h>
//This is a global definition of struct for date so it can be utilized for any function within the program.
struct date
{
int month;
int day;
int year;
};
//This will add the seven days to the date entered by the user
struct date newDate (struct date today)
{
struct date week;
int daysOfMonth (struct date d);
if(today.day != daysOfMonth(today))
{
week.day = today.day+7;
week.month = today.month;
week.year = today.year;
}
else if(today.month == 12)//end of month
{
week.day = 1;
week.month = today.month = 1;
week.year = today.year +1;
}
else //end of year
{
week.day = 1;
week.month = today.month+1;
week.year = today.year;
}
return week;
}
//Function to find the number of days in a month
int daysOfMonth (struct date d)
{
//Declare variables to be used within function
int days;
bool flagLeapYear (struct date d);
const int daysOfMonth [12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
if (flagLeapYear (d) == true && d.month == 2)
days = 29;
else
days = daysOfMonth[d.month - 1];
return days;
}
//Function to determine if it is a leap year
bool flagLeapYear (struct date d)
{
bool flagLeapYear;
if ((d.year % 4 == 0 && d.year % 100 != 0) || d.year % 400 == 0)
flagLeapYear = true; //It is a leap year
else
flagLeapYear = false; // Not a leap year
return flagLeapYear;
}
int main(void)
{
struct date newDate (struct date today);
struct date entered, seven;
printf("Please enter a date formatted as mm/dd/yyyy: ");
scanf(" %i%i%i", &entered.month, &entered.day, &entered.year);
seven = newDate (entered);
printf("\nThe date you entered is: %.2i/%.2i/%.4i", entered.month, entered.day, entered.year);
printf("\nThe date in seven days will be: %.2i/%.2i/%.4i", seven.month, seven.day, seven.year);
return 0;
}
Thanks,
Annette
You are using wrong format specifier, e.g. %.2i -> %02d:
// ...
printf("Please enter a date formatted as mm/dd/yyyy: ");
scanf("%d/%d/%d", &entered.month, &entered.day, &entered.year);
seven = newDate (entered);
printf("\nThe date you entered is: %02d/%02d/%04d", entered.month, entered.day, entered.year);
printf("\nThe date in seven days will be: %02d/%02d/%04d", seven.month, seven.day, seven.year);
// ...
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;
}
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;
}
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.