Reformat Date
Reformat Date is LeetCode 1507. You are given a date string in the format "Day Month Year", where:
- Day is a number from 1 to 31, followed by an ordinal suffix (
"st","nd","rd", or"th") - Month is a three-letter English abbreviation (
"Jan","Feb", ...,"Dec") - Year is a four-digit number
Your job is to convert it to the format "YYYY-MM-DD".
Example: "20th Oct 2052" returns "2052-10-20".
Why this problem matters
Date formatting is one of those tasks you will encounter constantly in real codebases. APIs return dates in one format, databases expect another, and UI layers need a third. The core skill is always the same: split the input into parts, normalize each part, and reassemble.
This problem distills that workflow into its simplest form. You parse a human-readable date, strip noise (the ordinal suffix), map a name to a number (month abbreviation to digit), and produce a machine-readable result. Every piece of this logic transfers directly to real-world string processing.
The key insight
The entire problem boils down to three small operations:
- Split the input on spaces to isolate day, month, and year.
- Strip the last two characters from the day token to remove the suffix.
- Map the month abbreviation to its numeric position (January = 01, February = 02, and so on).
Once you have the numeric day, numeric month, and year, you concatenate them with dashes and zero-pad where needed. There is no tricky edge case, no algorithmic complexity. The challenge is writing clean, readable parsing code.
You do not need to validate the suffix. The problem guarantees the input is well-formed, so you can always safely slice off the last two characters of the day token.
The solution
def reformatDate(date: str) -> str:
months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
parts = date.split()
day = parts[0][:-2]
month = str(months.index(parts[1]) + 1).zfill(2)
year = parts[2]
return f"{year}-{month}-{day.zfill(2)}"
Here is what each line does:
-
monthslist. A lookup table that maps month abbreviations to their 1-based index."Jan"is at index 0, soindex + 1gives 1."Dec"is at index 11, soindex + 1gives 12. -
parts = date.split(). Splits"20th Oct 2052"into["20th", "Oct", "2052"]. -
day = parts[0][:-2]. Slices off the ordinal suffix."20th"becomes"20","1st"becomes"1","3rd"becomes"3". -
month = str(months.index(parts[1]) + 1).zfill(2). Finds the position of"Oct"in the list (index 9), adds 1 to get 10, converts to string, and zero-pads to two digits. -
year = parts[2]. The year is already a four-digit string, so no conversion is needed. -
f"{year}-{month}-{day.zfill(2)}". Assembles the result.zfill(2)ensures single-digit days like"1"become"01".
Visual walkthrough
Here is the algorithm running on the input "20th Oct 2052". Each step card shows one operation in the parsing pipeline.
Step 1: Split the input on spaces
date.split(" ") gives three tokens: the day with its suffix, the month abbreviation, and the four-digit year.
Step 2: Strip the ordinal suffix from the day
Remove the last two characters ("st", "nd", "rd", or "th") to get the numeric day. "20th" becomes "20".
Step 3: Map the month abbreviation to its number
Look up "Oct" in the month list. It is at index 9 (0-based), so the month number is 10. Zero-pad to two digits.
Step 4: Assemble as "YYYY-MM-DD"
Concatenate year, month number, and day with dashes. Zero-pad month and day to two digits each. Result: "2052-10-20".
The pipeline is entirely linear. Each step produces one value that feeds into the final assembly. There are no loops, no conditionals, and no backtracking.
Complexity analysis
| Approach | Time | Space |
|---|---|---|
| Split, strip, map, format | O(1) | O(1) |
Time: O(1). The input is bounded. The day has at most 4 characters, the month is always 3 characters, and the year is always 4 characters. The month lookup scans a fixed list of 12 elements. Nothing scales with an arbitrary input size.
Space: O(1). You store a fixed-size list of month names and a few string variables. The output string is always exactly 10 characters.
Building blocks
This problem is built from two patterns that appear across many string problems.
Token splitting and extraction. Splitting a string on a delimiter and pulling out specific tokens is one of the most common operations in string parsing. You will use the same pattern in Simplify Path (splitting on "/"), in file path manipulation, and in any problem that involves structured text. The idea is always: split first, then process each piece independently.
Lookup table mapping. Converting a name to a number via a list or dictionary is a pattern you will reach for constantly. Month names to numbers, Roman numerals to values, character encodings. The technique is simple, but remembering to use a clean lookup instead of a chain of if-else statements is what separates readable code from messy code.
Edge cases
- Single-digit day with "st".
"1st Jan 2000"becomes"2000-01-01". Thezfill(2)call pads"1"to"01". - Single-digit day with "nd".
"2nd Mar 2015"becomes"2015-03-02". Same padding logic. - Single-digit day with "rd".
"3rd Dec 1999"becomes"1999-12-03". The suffix is always exactly two characters regardless of which ordinal it is. - Day 11, 12, 13 use "th".
"11th Nov 2020"becomes"2020-11-11". These days do not use "st", "nd", or "rd", but since you always strip the last two characters, it does not matter. - Last day of the month.
"31st Aug 2040"becomes"2040-08-31". No special handling needed for larger day numbers. - January and December boundaries.
"1st Jan 2000"maps to month"01"and"25th Dec 2099"maps to month"12". Both ends of the month list work correctly.
From understanding to recall
This problem feels simple when you read through the solution. Split, strip, map, format. Four clean steps. But under interview pressure, the details matter. Do you remember to slice off the suffix with [:-2]? Do you remember that index is 0-based and you need to add 1? Do you remember to zero-pad both the month and the day?
Spaced repetition makes these small details automatic. Type the solution from scratch today, again in a few days, again next week. After a handful of reps, the parsing pipeline flows out of your fingers without hesitation. When a similar string manipulation problem appears in an interview, you will not need to rediscover the approach.
Related posts
- String to Integer (atoi) - Another string parsing problem where you strip whitespace, handle signs, and extract digits
- Length of Last Word - Scanning a string to extract a specific token, using pointer logic instead of split
- Simplify Path - Splitting a string on a delimiter and processing tokens, with stack-based logic for path normalization