medium +20 pts

Julian Day Number Converter

Convert between Gregorian calendar dates and astronomical Julian Day Numbers without external libraries.

Write two functions: 1. `date_to_jdn(year: int, month: int, day: int) -> int` — Given a valid Gregorian calendar date (proleptic, year can be negative or zero), return the corresponding Julian Day Number (JDN) as an integer. The JDN is the integer part of the Julian Date at noon UTC. 2. `jdn_to_date(jdn: int) -> tuple[int, int, int]` — Given a JDN, return the corresponding Gregorian calendar date as a tuple `(year, month, day)`. The two functions must be inverses of each other for all valid inputs. Use the standard astronomical algorithms (e.g., from the Explanatory Supplement to the Astronomical Almanac). You may implement any correct algorithm, but it must: - Work for positive and negative years (e.g., year 0 corresponds to 1 BC, -1 corresponds to 2 BC). - Handle leap years correctly according to the Gregorian calendar rules (divisible by 4, except centuries not divisible by 400). - Return exact integer JDN values. Your solution must not use any external libraries or the `datetime` module. Implement the arithmetic from scratch. **Function signatures:** ```python def date_to_jdn(year: int, month: int, day: int) -> int: ... def jdn_to_date(jdn: int) -> tuple[int, int, int]: ... ``` Both functions should be defined in your submission. **Note on JDN 0:** The standard astronomical convention is that Julian Day Number 0 corresponds to 1 January 4713 BC in the proleptic Julian calendar, which is **24 November 4714 BC** in the proleptic Gregorian calendar. Using the proleptic Gregorian calendar with astronomical year numbering (year 0 = 1 BC, -4713 = 4714 BC), JDN 0 corresponds to **-4713-11-24**.

Constraints

- For `date_to_jdn`: year can be any integer between -4712 and 9999, month 1–12, day 1–31 (valid for the month). - For `jdn_to_date`: any integer JDN between 0 and 4000000 is valid, but the expected date will be within the same range as above. - Time complexity: O(1) for each function. - Do not use any libraries beyond Python's built-ins.

Example

```python
>>> date_to_jdn(2000, 1, 1)
2451545
>>> jdn_to_date(2451545)
(2000, 1, 1)
>>> date_to_jdn(-4713, 11, 24)  # JDN 0 in proleptic Gregorian calendar
0
>>> jdn_to_date(0)
(-4713, 11, 24)
```
20 points ~20 min

Recent Submissions

No submissions yet — hit Run Tests to try!

Hints

For date_to_jdn, adjust the month and year so that January and February are treated as months 13 and 14 of the previous year, then use the standard JDN formula with integer arithmetic.
For jdn_to_date, invert the formula step by step: first compute an intermediate value `c` that corrects for centuries, then derive the year and month.
Remember that integer division in Python truncates toward negative infinity, which is exactly what these formulas expect. Use `//` carefully.
Test your conversion with known JDNs: 2000-01-01 is 2451545, and 1970-01-01 is 2440588. The proleptic Gregorian date for JDN 0 is -4713-11-24, not -4712-01-01.
Python 3
All tests passed!
Test Results
Press Ctrl+Enter or click Run Tests to execute your code.