Last active
May 6, 2022 10:28
-
-
Save abiiranathan/6a6dc7e44fd747e515a1b5666b1c6552 to your computer and use it in GitHub Desktop.
A C program to calculate age from birth date.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// prints age given date of birth in form dd/mm/yyyy | |
// compile with: gcc age.c -o age | |
// Author: Dr. Abiira Nathan | |
// Date: May, 2022 | |
// Version: 1.0 | |
// License: MIT License | |
// Copyright (c) 2020 Dr. Abiira Nathan | |
#include <stdio.h> | |
#include <time.h> | |
#include <stdlib.h> | |
#include <stdbool.h> | |
typedef struct | |
{ | |
int date, month, year; | |
} date; | |
// returns the number of digits in an integer n | |
int num_digits(int n) | |
{ | |
int count = 0; | |
while (n > 0) | |
{ | |
n /= 10; | |
count++; | |
} | |
return count; | |
} | |
// Check if year is leap year | |
bool is_leap(int year) | |
{ | |
if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) | |
return true; | |
else | |
return false; | |
} | |
/* | |
Returns the age in a human readable format. | |
If age is greater than or equal to 1 year, it will return the age in years +/- months(if years < 2) | |
If the age is less than 1 year, it will return the age in months +/- days(months < 2). | |
If the age is less than 1 month, it will return the age in days. | |
*/ | |
char *humanize(int years, int months, int days) | |
{ | |
// return date of birth as a string | |
// e.g "22 years" or "4 years, 3 months" or "5 days" | |
char *str = (char *)malloc(sizeof(char) * 11); | |
// years or years and months | |
if (years > 0) | |
{ | |
sprintf(str, "%d year%s", years, (years > 1) ? "s" : ""); | |
if (months > 0 && years < 2) | |
sprintf(str, "%s, %d month%s", str, months, (months > 1) ? "s" : ""); | |
return str; | |
} | |
// months or months and days | |
if (months > 0) | |
{ | |
sprintf(str, "%d month%s", months, (months > 1) ? "s" : ""); | |
if (days > 0 && months < 2) | |
sprintf(str, "%s, %d day%s", str, days, (days > 1) ? "s" : ""); | |
return str; | |
} | |
// days | |
sprintf(str, "%d day%s", days, (days > 1) ? "s" : ""); | |
return str; | |
} | |
// calculates age given date of birth in days, months, years | |
// returns the date struct with the age in years, months, days | |
date findAge(int birth_date, int birth_month, int birth_year) | |
{ | |
struct tm *now_t; | |
time_t current = time(NULL); | |
now_t = localtime(¤t); | |
int current_date, current_month, current_year; | |
current_date = now_t->tm_mday; | |
current_month = now_t->tm_mon + 1; | |
current_year = now_t->tm_year + 1900; | |
// days of every month | |
int month[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; | |
// if leap year | |
if (is_leap(current_year)) | |
{ | |
month[1] = 29; | |
} | |
// if birth date is greater then current birth | |
// month then do not count this month and add 30 | |
// to the date so as to subtract the date and | |
// get the remaining days | |
if (birth_date > current_date) | |
{ | |
current_date = current_date + month[birth_month - 1]; | |
current_month = current_month - 1; | |
} | |
// if birth month exceeds current month, then do | |
// not count this year and add 12 to the month so | |
// that we can subtract and find out the difference | |
if (birth_month > current_month) | |
{ | |
current_year = current_year - 1; | |
current_month = current_month + 12; | |
} | |
// calculate date, month, year | |
date d; | |
d.year = current_year - birth_year; | |
d.month = current_month - birth_month; | |
d.date = current_date - birth_date; | |
return d; | |
} | |
int main(void) | |
{ | |
date dob; | |
struct tm bd_t; | |
printf("Enter the date of birth(dd/mm/yyyy): "); | |
int res = scanf("%d/%d/%d", &dob.date, &dob.month, &dob.year); | |
if (res != 3 || dob.date < 1 || dob.date > 31 || | |
dob.month < 1 || dob.month > 12 || dob.year < 1 || num_digits(dob.year) != 4) | |
{ | |
printf("Invalid birth date: %.2d/%.2d/%4d\n", dob.date, dob.month, dob.year); | |
return EXIT_FAILURE; | |
} | |
date age = findAge(dob.date, dob.month, dob.year); | |
char *age_str = humanize(age.year, age.month, age.date); | |
printf("Age: %s\n", age_str); | |
return EXIT_SUCCESS; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment