|
1 | 1 | """ |
2 | | -Algorithm to calculate the absolute age difference between two people. |
| 2 | +Algorithm to calculate the absolute age difference between two dates (YYYY-MM-DD). |
3 | 3 |
|
4 | 4 | Wikipedia: https://en.wikipedia.org/wiki/Chronological_age |
5 | 5 | """ |
6 | 6 |
|
| 7 | +from __future__ import annotations |
7 | 8 |
|
8 | | -def age_difference(boy_age: int, girl_age: int) -> int: |
9 | | - """ |
10 | | - Return the absolute age difference between two people. |
| 9 | +from datetime import date |
11 | 10 |
|
12 | | - The function raises a ValueError if any of the ages is negative. |
13 | 11 |
|
14 | | - >>> age_difference(22, 20) |
15 | | - 2 |
16 | | - >>> age_difference(20, 22) |
17 | | - 2 |
18 | | - >>> age_difference(30, 30) |
19 | | - 0 |
20 | | - >>> age_difference(-1, 5) |
21 | | - Traceback (most recent call last): |
22 | | - ... |
23 | | - ValueError: Age cannot be negative. |
24 | | - >>> age_difference(18, -2) |
| 12 | +def parse_date(dob: str) -> date: |
| 13 | + """ |
| 14 | + Convert a YYYY-MM-DD date string to a `date` object. |
| 15 | +
|
| 16 | + >>> parse_date("2000-01-01") |
| 17 | + datetime.date(2000, 1, 1) |
| 18 | + >>> parse_date("1999-12-31") |
| 19 | + datetime.date(1999, 12, 31) |
| 20 | + >>> parse_date("2000-13-01") # Invalid month |
25 | 21 | Traceback (most recent call last): |
26 | | - ... |
27 | | - ValueError: Age cannot be negative. |
| 22 | + ... |
| 23 | + ValueError: Invalid date format or value: 2000-13-01 |
| 24 | + """ |
| 25 | + try: |
| 26 | + year, month, day = map(int, dob.split("-")) |
| 27 | + return date(year, month, day) |
| 28 | + except Exception as e: |
| 29 | + raise ValueError(f"Invalid date format or value: {dob}") from e |
| 30 | + |
| 31 | + |
| 32 | +def absolute_age_difference(dob1: str, dob2: str) -> tuple[int, int, int]: |
28 | 33 | """ |
29 | | - if boy_age < 0 or girl_age < 0: |
30 | | - raise ValueError("Age cannot be negative.") |
31 | | - return abs(boy_age - girl_age) |
| 34 | + Returns the absolute age difference as (years, months, days). |
| 35 | +
|
| 36 | + >>> absolute_age_difference("1990-05-10", "1995-07-15") |
| 37 | + (5, 2, 5) |
| 38 | + >>> absolute_age_difference("2000-02-29", "2001-02-28") |
| 39 | + (0, 11, 30) |
| 40 | + >>> absolute_age_difference("2000-01-01", "2000-01-01") |
| 41 | + (0, 0, 0) |
| 42 | + """ |
| 43 | + d1, d2 = parse_date(dob1), parse_date(dob2) |
| 44 | + |
| 45 | + if d1 == d2: |
| 46 | + return (0, 0, 0) |
| 47 | + |
| 48 | + # Order dates so d1 is always the earlier date |
| 49 | + if d1 > d2: |
| 50 | + d1, d2 = d2, d1 |
| 51 | + |
| 52 | + years = d2.year - d1.year |
| 53 | + months = d2.month - d1.month |
| 54 | + days = d2.day - d1.day |
| 55 | + |
| 56 | + # Adjust for negative days |
| 57 | + if days < 0: |
| 58 | + months -= 1 |
| 59 | + previous_month = d2.month - 1 or 12 |
| 60 | + previous_year = d2.year if d2.month != 1 else d2.year - 1 |
| 61 | + days += ( |
| 62 | + date(previous_year, previous_month + 1, 1) |
| 63 | + - date(previous_year, previous_month, 1) |
| 64 | + ).days |
32 | 65 |
|
| 66 | + # Adjust for negative months |
| 67 | + if months < 0: |
| 68 | + years -= 1 |
| 69 | + months += 12 |
33 | 70 |
|
34 | | -if __name__ == "__main__": |
35 | | - # Example usage (not required by TheAlgorithms, but for local testing) |
36 | | - print(age_difference(22, 20)) # 2 |
37 | | - print(age_difference(20, 22)) # 2 |
38 | | - print(age_difference(30, 30)) # 0 |
| 71 | + return years, months, days |
0 commit comments